· about 35 minutes · runs on ubuntu-26.04-devops · unrated
An unrated lab. It runs on your machine with no account and no network, and everything about it — the faults, the checks, the hints and the reference solution — is in the repository. An attempt on it is recorded on your profile and never moves a rating: only rated labs do. Rated and unrated labs.
/opt/members/report.py reads the membership exports in /srv/members/ and writes a summary of the
members per city to /var/lib/members/summary.csv. members-report.timer runs it shortly after boot
and every night.
Two systems export into that directory. The new one writes UTF-8. The old one, a Windows tool nobody
maintains, writes cp1252 — its files are named *.cp1252.csv, and that is documented in
/srv/members/README. Since a member called Ruiz Peña joined, the job has failed every night with a
UnicodeDecodeError, and the summary is a week old. A colleague "fixed" it once by ignoring the
characters that would not decode, and the report then listed Pea as a member's name.
What is expected, and graded — the grader runs report.py itself, through the MEMBERS_DIR and
SUMMARY_OUT variables the script already reads:
*.cp1252.csv file as cp1252, every other *.csv as UTF-8.members-report.timer succeeds and the summary holds every city — and still
does after a reboot.You have root through sudo.
The machine is checked, rebooted, and checked again. A check passes only if it passes both times.
| Check | Objective |
|---|---|
| 01_the_old_export_is_read | Read and write text files with the encoding stated, not the machine's |
| 02_every_name_survives | Keep every character of the data, instead of dropping what does not decode |
| 03_the_output_is_utf8 | Read and write text files with the encoding stated, not the machine's |
| 04_the_nightly_run_succeeds | Run a job from a systemd timer and prove its output is complete |
Where the lab's hints send you, level by level, as you ask for them (h, then l opens a journal section in the TUI).
man 1 journalctlman 5 systemd.service4 questions on the same topic, in the lab's Theory tab. They never affect the lab's grade. Three of them, to answer here:
What does this print?
data = 'Peña'.encode('cp1252')
print(data.decode('utf-8', errors='ignore'))
Pea
In cp1252 ñ is the single byte 0xf1, which is not valid UTF-8. errors='ignore' drops the byte instead of raising, so the name loses a letter and nothing says so. errors='replace' would give Pe�a, and the only correct answer is to decode with the encoding the file was written in.
https://docs.python.org/3/library/codecs.html#error-handlers · executed in a sandbox
What does this print?
data = 'München'.encode('utf-8')
print(data.decode('latin-1'))
München
latin-1 maps every one of the 256 byte values to a character, so it never raises — it just gives the wrong characters when the bytes were not latin-1. The two UTF-8 bytes of ü become à and ¼. "Decode as latin-1 so it never fails" turns an error into silent mojibake.
https://docs.python.org/3/library/codecs.html#standard-encodings · executed in a sandbox
A Python program calls `open("/srv/export.csv")` with no `encoding=`. Which encoding is used to decode the file?
the process's locale encoding when it started
Text mode uses locale.getpreferredencoding(False) unless UTF-8 mode is on, so the result depends on the machine and on how the program was started, not on the file. sys.getdefaultencoding() is about str/bytes conversions inside Python and is always utf-8; a CSV file declares nothing.
https://docs.python.org/3/library/functions.html#open