Review
Retrieve the chapter's boundary rules, file operations, path evidence, import choices, collection tools, and small-program structure before continuing.
Follow the Value Across Each Boundary
The chapter's measurement program follows one complete path:
stored bytes
-> decoded text
-> labelled text lines
-> parsed readings
-> computation
-> report text
-> stored output bytes
-> decoded read-back text
Each arrow crosses a boundary with a stated value type. A path names where a file should be; it is not the file or its contents. Opening a UTF-8 text file decodes stored bytes and gives the program strings. Parsing turns the stated fields in those strings into labels and numerical values. Computation should receive those clean values rather than reaching back into a particular file.
Keep Text and Bytes Distinct
A str is a sequence of characters. A bytes value is a sequence of stored
units whose indexed elements are integers from 0 through 255. UTF-8 encoding
maps text to bytes; strict decoding maps valid UTF-8 bytes back to text.
For the label "café", the number of characters and the number of UTF-8 bytes
differ. That difference is expected. The useful check is the round trip:
Use text mode when the program needs strings and binary mode when it must read or write the exact bytes. A text file does not turn numerical characters into numbers automatically.
Parse Near Input and Keep the Policy Narrow
The measurement format gives every non-empty line two comma-separated fields:
a sensor label and numeric text. Preserve the line number while parsing so a
rejected row can be identified. Convert the reading near this boundary, report
one understood ValueError, and skip only that row when the program's contract
allows the remaining data to be used.
Do not convert invalid numeric text to None merely to keep the loop running.
In this program, None already means that no legitimate mean is available.
The invalid row has a different meaning and receives a different response.
Write a Derived Result and Read It Back
Write mode replaces the generated report on each run. Append mode keeps the existing text and adds new text at the end. Choose from the result's meaning: a current summary normally replaces; a chronological log may append.
Supply every line ending deliberately. After the write block closes, reopen
the output, read it, and compare it with the intended report text. Successful
execution of write() is not evidence that the program chose the intended
path, mode, or contents.
Diagnose Paths Before Changing Them
A relative path begins at the current working directory. When input appears missing, inspect evidence in this order:
Create the parent directory for generated output when needed. Do not create an empty replacement for missing supplied input. The program owns its report; it does not own the measurements another source was expected to provide.
Keep Imported Names Traceable
A module is a Python file that provides definitions. import measurement_tools
keeps the module name beside each selected attribute. A selective import such
as from measurement_tools import parse_measurements binds the chosen function directly.
Avoid wildcard imports because they hide which names arrived and where they
came from.
Imports may refer to a local module, a standard-library module such as
collections, or an installed third-party package. Counter and
defaultdict are standard-library tools; they require no separate package.
Use them only after their manual dictionary loops are understood:
Counter(values)reproduces a keyed frequency count;defaultdict(list)creates a new empty list when an unseen key legitimately begins a group;defaultdict(Counter)nests those two roles without changing either rule.
Give the Runner One Clear Role
The reusable module owns parsing and computation on ordinary values. The runner owns paths and sequence: find input, read, call reusable functions, create the output location, write, and verify. Input data and generated reports remain in separate folders.
Run the complete program twice. Then introduce or encounter one path or parsing failure, record the evidence, repair its cause, and rerun the full workflow. The final read-back check should protect the exact report that the program claims to have saved.