for loops and a beginner loop invariant
Agent-assisted practice: write your own prediction and observed output first; only then may you ask an AI agent to explain or review, and you must record that assistance in your evidence.
Prerequisites
Day 07 completed, including its independent check. Recovery: Day 07 (values and conditions); the Day 07 loop preview is optional background.
Learning Objective
Trace a for loop over a string one code point at a time and state a loop invariant that is true before the loop, after every iteration, and at the end, including for empty and Unicode text.
Instructions
Study source: within this activity's existing reading/practice time, use Automate the Boring Stuff with Python, 3rd edition, Chapter 3; 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. Spaced-review warm-up (10 minutes): from memory, predict bool(""), bool(" "), and "0" == 0, then check them. Yesterday's review makes this quick; slow answers tell you what to revisit.
New idea: a for loop runs its body once for each item; for a string, each item is one Unicode code point. A loop invariant is a sentence about your variables that is true before the first iteration and stays true after every iteration. For counting, the invariant is: total equals the number of matches among the characters visited so far.
1. Before running, fill in a trace table with columns visited / total / invariant holds?
2. Run the snippet; it prints the same columns so you can check your table.
3. Run the second snippet to see the empty case (the body runs zero times) and a code-point surprise.
text = "été"
target = "é"
total = 0
visited = ""
for ch in text:
if ch == target:
total += 1
visited += ch
print(repr(visited), total, total == visited.count(target))
print("final", total, visited == text)
text = ""
total = 0
for ch in text:
total += 1
print("final", total)
print(len("é"), len("e\u0301"), "é" == "e\u0301")
Practice & Prediction Log
Write the full trace table for text = "été", target = "é" before running. Then state the invariant at three moments: before the loop (total = 0, nothing visited), after each iteration, and at termination (visited == text, so total is the answer). Finally predict the output for the empty string and for len("e\u0301").
Before the loop, nothing has been visited and total is 0, so the invariant already holds. Each iteration adds one character to visited and adds 1 to total only if that character matches, so the invariant still holds. "é" written as one code point (U+00E9) is different from "e" followed by a combining accent (U+0301), which is two code points.
Output of the first snippet:
'é' 1 True
'ét' 1 True
'été' 2 True
final 2 True
Worked trace: start visited = "", total = 0 (invariant true: no matches in nothing). Step 1: ch = "é" matches, total = 1, visited = "é". Step 2: ch = "t" does not match, total stays 1, visited = "ét". Step 3: ch = "é" matches, total = 2, visited = "été". At termination visited equals text, so the invariant says total is the number of matches in the whole text: 2.
Output of the second snippet:
final 0
1 2 False
For empty text the body never runs, total stays 0, and the invariant still holds at termination. len("e\u0301") is 2 because Python counts code points, so the decomposed form is not equal to the single code point "é".
Your trace table is written before running and matches the observed rows; you state the invariant at initialization, after each iteration, and at termination, and you correctly predict the empty case and the two-code-point decomposed case.
Authoritative Source Resources & Provenance
Automate the Boring Stuff with Python, 3rd edition
Relevant Section / Range: Chapter 3; 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: More Control Flow Tools
Relevant Section / Range: Sections 4.2–4.10 (for, range, defining functions)
Verified Version & Date: Python 3.12 documentation; verified 2026-10-30
Primary reference for Python iteration, functions, and containers.
Study Days 01-06 Python expression and filesystem fundamentals
The lesson explains all required behavior locally and can be completed offline.
Compared Candidate Sources & Selection Analysis (2)
Grammar-level definition of the same constructs; the tutorial chapter was selected for its guided pacing.
Lecture-paced coverage of the same control flow; deferred because the curriculum already drives the concepts through terminal drills.