Paths, encodings, and safe file reads
Assistance allowed only after prediction and observed evidence are recorded.
Prerequisites
Complete the previous activity; use the listed recovery link if blocked.
Learning Objective
Read a text file with an explicit UTF-8 encoding inside a with block and count its non-empty lines. Predict the count before running, then explain why a relative path depends on the current working directory.
Instructions
Study source: within this activity's existing reading/practice time, use Automate the Boring Stuff with Python, 3rd edition, Chapter 10; Practice Questions; Appendix B answers, then explain one connection to the local task in your own words. Keep the local exercise and acceptance checks; use its original explanation if the external source is unavailable. In a fresh directory create notes.txt containing exactly three lines: alpha, beta, gamma. A relative path such as open("notes.txt") is resolved against Path.cwd(), not against the folder that holds the script. Iterating the file object yields one line at a time; each line keeps its "\n" terminator except possibly the last one, which has none when the file does not end with a newline (a file written as "alpha\nbeta\ngamma" yields 'gamma' as its final line). line.strip() removes that newline and any surrounding whitespace, so it decides whether a line is empty. The with block is predefined cleanup: it closes the file even if reading raises an exception.
Practice & Prediction Log
count = 0
with open("notes.txt", encoding="utf-8") as f:
for line in f:
if line.strip():
count += 1
print(count, f.closed)
Before running, write down the exact line this prints and explain why each of the two values comes out the way it does. Would the result change if notes.txt did not end with a newline?
Predict before running. If the path confuses you, print Path.cwd() first. Compare the number of iterations with the number of non-empty lines; strip() decides emptiness, not the raw line.
count = 0
with open("notes.txt", encoding="utf-8") as f:
for line in f:
if line.strip():
count += 1
print(count, f.closed)
Output: 3 True. Trace: the loop receives 'alpha\n', 'beta\n', 'gamma\n' (or 'gamma' when the file has no final newline); each is non-empty after strip(), so count reaches 3, and a trailing newline on the last line does not create a fourth line. print runs after the with block has exited, so f is already closed and f.closed is True.
Your prediction matches the observed output, you state that relative paths resolve against Path.cwd(), and you show the file object's closed state (f.closed) after the with block exits.
Authoritative Source Resources & Provenance
Automate the Boring Stuff with Python, 3rd edition
Relevant Section / Range: Chapter 10; Practice Questions; Appendix B answers
Verified Version & Date: Public edition checked 2026-11-01; moving pages may change
Beginner teaching and answer-keyed practice before checking exact semantics in the Python reference; selected chapters only, not the book's entire automation stack.
No prior programming required for Chapter 1; later chapters assume its basic Python concepts.
Use the original localized explanations, exercises and checks already present in this activity; no external account or purchase is required for that fallback.
Compared Candidate Sources & Selection Analysis (2)
Guided Python syntax but assumes programming familiarity; paired with the beginner text rather than used as its replacement.
Lectures and problem sets teach a broader CS1 course; the book offers shorter text-first entry and an answer appendix.
The Python Tutorial: Input and Output
Relevant Section / Range: Section 7.2 (Reading and Writing Files)
Verified Version & Date: Python 3.12 documentation; verified 2026-10-30
Primary reference for open(), explicit encodings, and the with statement as guaranteed cleanup.
The lesson explains all required behavior locally and can be completed offline; help(open) also works in the interpreter.
Compared Candidate Sources & Selection Analysis (2)
Friendly walkthrough, but it is a secondary tutorial with mixed access tiers rather than the normative language reference.
Stream-layer reference for advanced cases; the tutorial chapter covers the open()/with patterns the drills require.