11 / 90

Day 11: Exceptions and isolated environments

Catch only the failures you expect, guarantee cleanup with with and finally, and reproduce a 'works on my machine' fault inside a fresh virtual environment. Diagnosis comes before regeneration; retrieval and lower-new-content review are part of the 480-minute ledger.

Self-Directed Learning & Python 480 active minutes (8 hours focused study)
01 120 min

Precise exception handling and guaranteed cleanup

Assistance allowed only after prediction and observed evidence are recorded.

Prerequisites

Complete the previous activity; use the listed recovery link if blocked.

Learning Objective

Predict which of try, except, else, and finally run when a file open succeeds and when it raises FileNotFoundError, then verify. Replace manual close() with a with block and explain why a bare except is prohibited.

Instructions

try holds the risky call. except FileNotFoundError as e handles exactly one expected failure, and e.filename names the missing path. else runs only when no exception occurred; finally always runs. A bare except: is prohibited because it also swallows KeyboardInterrupt and real programming errors, turning diagnosis into guesswork. For file objects, with is the predefined cleanup action and makes finally unnecessary.

Practice & Prediction Log

Work in an empty temporary folder. Run this script twice: first with notes.txt absent, then again after creating it with printf 'hi\n' > notes.txt.

try:
    f = open("notes.txt", encoding="utf-8")
except FileNotFoundError as e:
    print("cannot open", e.filename)
else:
    print("opened", f.name)
    f.close()
finally:
    print("cleanup")

Before each run, write down which of try / except / else / finally execute and the exact output. Then (1) rewrite it so a with block closes the file instead of else + f.close(), and show f.closed is True after the block; (2) name two things a bare except: would hide.

Independent Mastery Criterion

You state exactly which clauses run for success and for failure, convert the else/close() pattern into a with block correctly, and name two things a bare except would hide.

Authoritative Source Resources & Provenance

linking PSF License Version 2

The Python Tutorial: Errors and Exceptions

Author: Python Software Foundation | Original Source Link ↗

Relevant Section / Range: Sections 8.3–8.6 (handling exceptions, else, finally, cleanup actions)

Verified Version & Date: Python 3.12 documentation; verified 2026-10-30

Selection Rationale:

Primary reference for try/except/else/finally semantics and the with statement as predefined cleanup.

Source Prerequisites:

Safe Fallback (Offline Resilience):

Every clause behavior in the lesson is demonstrated by runnable local snippets.

Compared Candidate Sources & Selection Analysis (2)
MIT OCW 6.0001 Lecture on Exceptions ↗ compared_alternative [CC BY-NC-SA 4.0]

Solid lecture treatment, but paced for a semester course and requires video viewing; the tutorial section matches the exercise scope directly.

Python Standard Library: Built-in Exceptions ↗ compared_alternative [PSF License Version 2]

Reference-style exception hierarchy listing rather than the tutorial narrative; retained as lookup material for the recovery drills.

02 120 min

Failure clinic: from traceback to a targeted fix

Assistance allowed only after prediction and observed evidence are recorded.

Prerequisites

Complete the previous activity; use the listed recovery link if blocked.

Learning Objective

Given a script that crashes on a malformed score row, read the traceback bottom-up, name the fault line and the exception type, and apply the smallest fix: a targeted except ValueError around int() instead of a program-wide catch.

Instructions

A traceback lists calls from oldest to newest; the last line names the exception type and message: ValueError: invalid literal for int() with base 10: 'x9', and the frame above it points at the line total += int(raw). Reproduce the crash with the single bad row first. The narrow fix wraps only int(raw) in try/except ValueError, records the line number, and continues. Wrapping the whole program in except Exception would hide unrelated bugs and misreport them as data errors.

Practice & Prediction Log

In an empty temporary folder, create the clinic data:

printf 'ana,7\nbo,x9\ncy,5\n' > scores.csv

Save this as clinic.py:

total = 0
with open("scores.csv", encoding="utf-8") as fh:
    for lineno, line in enumerate(fh, start=1):
        name, raw = line.strip().split(",")
        total += int(raw)
print("total", total)

Run python3 clinic.py and read the traceback bottom-up. Record the diagnosis: fault line, exception type, and the narrowest fix. Then change clinic.py so it finishes, printing the total of the valid rows and the line numbers it skipped.

Independent Mastery Criterion

Your diagnosis names the fault location and exception type, explains why the chosen except type is the narrowest correct one from the exception hierarchy, and shows the program completing with the skip report.

Authoritative Source Resources & Provenance

linking PSF License Version 2

Python Standard Library: Built-in Exceptions

Author: Python Software Foundation | Original Source Link ↗

Relevant Section / Range: Concrete exceptions and Exception hierarchy

Verified Version & Date: Python 3.12 documentation; verified 2026-10-30

Selection Rationale:

Normative hierarchy used to justify the narrowest correct except clause during diagnosis.

Source Prerequisites:

Safe Fallback (Offline Resilience):

The clinic traceback is reproduced locally; help(ValueError) documents the hierarchy offline.

Compared Candidate Sources & Selection Analysis (2)
W3Schools Python Exceptions ↗ compared_rejected_for_day11 [Proprietary]

Encourages broad except blocks; the clinic instead requires naming the exact hierarchy level.

The Python Tutorial: Errors and Exceptions ↗ compared_alternative [PSF License Version 2]

Friendlier first-pass narrative; the library reference was selected for the normative hierarchy the exercises name directly.

03 120 min

Isolated environments with venv

Assistance allowed only after prediction and observed evidence are recorded.

Prerequisites

Complete the previous activity; use the listed recovery link if blocked.

Learning Objective

In a disposable temporary folder, create a virtual environment with python3 -m venv --without-pip .venv, prove with sys.executable that its interpreter differs from python3, show that a module installed only into the venv is invisible to python3, and record dependencies in requirements.txt.

Instructions

Work only in a throwaway folder so every difference you observe is created by you, not assumed about your machine. Commands are for a Linux/macOS shell (on Windows the interpreter is .venv\Scripts\python.exe; not executed here). Do not activate the venv: call each interpreter by its path.

Use a dedicated disposable shell/session. Run this setup and all later steps in the same shell. Any setup failure exits it; do not continue. In a new shell, rerun the setup block. After setup, verify that pwd shows $work before continuing.

work=$(mktemp -d) &&
cd "$work" &&
python3 -m venv --without-pip .venv || exit 1

Run every later step in this same shell; if echo "$work" prints nothing, re-run the setup block first. --without-pip keeps creation offline; the new venv starts with only the standard library. sys.executable names the interpreter that is actually running. sysconfig.get_path('purelib') names that interpreter's site-packages folder, where installed modules live, so copying a one-file module there is a hand-made install that needs no network and no third-party package. It is a teaching shortcut, not what pip does: pip also writes installation metadata (a .dist-info folder), so pip would not record or be able to uninstall this hand copy. The venv's pyvenv.cfg says include-system-site-packages = false: it does not read the base interpreter's site-packages, and no other interpreter reads the venv's. Record dependencies as pinned lines in requirements.txt (never credentials) and never commit .venv. When finished: cd / && rm -rf "$work".

Practice & Prediction Log

From $work, predict each result before running it. Step 1: which interpreter runs?

python3 -c "import sys; print(sys.executable)"
.venv/bin/python -c "import sys; print(sys.executable)"

Step 2: can the fresh venv import day11_helper?

.venv/bin/python -c "import day11_helper"

Step 3: install a one-file module into the venv only, then import it there:

site=$(.venv/bin/python -c "import sysconfig; print(sysconfig.get_path('purelib'))")
printf 'def label():\n    return "helper from the venv"\n' > "$site/day11_helper.py"
.venv/bin/python -c "import day11_helper; print(day11_helper.label())"

Step 4: can python3 import it?

python3 -c "import day11_helper"

Step 5: isolation evidence, and whether this venv has pip:

grep include-system-site-packages .venv/pyvenv.cfg
.venv/bin/python -c "import sys; print(sys.prefix != sys.base_prefix)"
.venv/bin/python -m pip --version

Step 6: record a practice pin (do not install it; that would need pip and a package index):

printf 'packaging==24.1\n' > requirements.txt
cat requirements.txt

For steps 2 and 4, record the diagnosis: should you edit the import line or change the environment?

Independent Mastery Criterion

You prove the two interpreter paths differ, reproduce ModuleNotFoundError inside the fresh venv and again under python3 after installing the module only into the venv, and explain from pyvenv.cfg and sys.prefix why the venv and other interpreters cannot see each other's site-packages.

Authoritative Source Resources & Provenance

linking PSF License Version 2

The Python Tutorial: Virtual Environments and Packages

Author: Python Software Foundation | Original Source Link ↗

Relevant Section / Range: Section 12 (Virtual Environments and Packages; creating venvs, pip, requirements)

Verified Version & Date: Python 3.12 documentation; verified 2026-10-30

Selection Rationale:

Primary reference for python -m venv, interpreter isolation, and requirements files.

Source Prerequisites:

Safe Fallback (Offline Resilience):

The drill needs no network: venv creation, sys.executable inspection, and ModuleNotFoundError reproduction all run offline.

Compared Candidate Sources & Selection Analysis (2)
pip documentation ↗ compared_alternative [MIT]

Primary reference for pip commands, but the tutorial section covers the create-activate-install loop as one narrative better suited to beginners.

virtualenv documentation ↗ compared_alternative [MIT License]

Mature third-party environment tool with overlapping behavior; the stdlib venv tutorial was selected to avoid an extra dependency for first-time setup.

04 120 min

Wrong-environment diagnosis drill

Independent Mastery Check (no AI assistance).

Prerequisites

Complete the previous activity; use the listed recovery link if blocked.

Learning Objective

Independently diagnose a script that fails with ModuleNotFoundError under one of two controlled interpreters, produce sys.executable and find_spec evidence and a minimal environment fix, then wrap a file read in a precise except clause.

Instructions

Closed book. Build this fixture exactly; it guarantees that only the good venv has the dependency (Linux/macOS shell, no network, no third-party packages):

Use a dedicated disposable shell/session. Run this setup and all later steps in the same shell. Any setup failure exits it; do not continue. In a new shell, rerun the setup block. After setup, verify that pwd shows $work before continuing.

work=$(mktemp -d) &&
cd "$work" &&
python3 -m venv --without-pip good &&
python3 -m venv --without-pip .venv &&
good_site=$(good/bin/python -c "import sysconfig; print(sysconfig.get_path('purelib'))") &&
printf 'def label():\n    return "report ok"\n' > "$good_site/day11_helper.py" &&
printf 'import day11_helper\nprint(day11_helper.label())\n' > report.py || exit 1

Run every later step in this same shell; if echo "$work" prints nothing, re-run the setup block first. Symptom: .venv/bin/python report.py raises ModuleNotFoundError: No module named 'day11_helper', while good/bin/python report.py works. Task 1: collect evidence from both interpreters (which interpreter runs, can it find day11_helper), record the diagnosis, apply a minimal fix, and show .venv/bin/python report.py then prints report ok. Task 2: write read_text(path) that opens path with encoding="utf-8" inside try/except FileNotFoundError and prints missing plus e.filename instead of crashing. When finished: cd / && rm -rf "$work".

Practice & Prediction Log

Record: (a) the two sys.executable values; (b) whether each interpreter can find day11_helper; (c) the ModuleNotFoundError reproduced under .venv/bin/python; (d) the diagnosis category: code fault or environment fault; (e) the fix and the output proving it worked; (f) your read_text function and its output for no_such_file.txt.

Independent Mastery Criterion

Unaided, the diagnosis is evidence-based (sys.executable plus find_spec or ModuleNotFoundError from both interpreters), the fix targets the cause that evidence identifies and is proven by report ok, and the file read uses exactly except FileNotFoundError.

Authoritative Source Resources & Provenance

linking PSF License Version 2

The Python Tutorial: Virtual Environments and Packages

Author: Python Software Foundation | Original Source Link ↗

Relevant Section / Range: Section 12 (Virtual Environments and Packages; creating venvs, pip, requirements)

Verified Version & Date: Python 3.12 documentation; verified 2026-10-30

Selection Rationale:

Reference retained for the independent wrong-environment diagnosis assessment.

Source Prerequisites:

Safe Fallback (Offline Resilience):

The assessment reproduces ModuleNotFoundError with the local interpreter only.

Compared Candidate Sources & Selection Analysis (2)
pip documentation ↗ compared_alternative [MIT]

Reference for install commands if the learner chooses the install-based fix.

virtualenv documentation ↗ compared_alternative [MIT License]

Mature third-party environment tool with overlapping behavior; the stdlib venv tutorial was selected to avoid an extra dependency for first-time setup.