08 / 90

Day 08: Loops, loop invariants, and function inputs and outputs

New material: for loops over text, beginner loop invariants that explain why a loop is correct, and functions with explicit inputs and return values. Each activity opens with a short spaced-review retrieval from Days 04–07 and records prediction, observation, and recovery evidence; small changes are kept in a disposable Git repository.

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

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").

Independent Mastery Criterion

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

linking Copyright Al Sweigart; edition-specific reuse terms unverified linking only; no reproduction

Automate the Boring Stuff with Python, 3rd edition

Author: Al Sweigart | Original Source Link ↗

Relevant Section / Range: Chapter 3; Practice Questions; Appendix B answers

Verified Version & Date: Public edition checked 2026-11-01; moving pages may change

Selection Rationale:

Beginner teaching and answer-keyed practice before checking exact semantics in the Python reference; selected chapters only, not the book's entire automation stack.

Source Prerequisites:

No prior programming required for Chapter 1; later chapters assume its basic Python concepts.

Safe Fallback (Offline Resilience):

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)
The Python Tutorial ↗ compared_alternative [PSF License Version 2]

Guided Python syntax but assumes programming familiarity; paired with the beginner text rather than used as its replacement.

MIT OCW 6.0001 ↗ compared_alternative [CC BY-NC-SA 4.0]

Lectures and problem sets teach a broader CS1 course; the book offers shorter text-first entry and an answer appendix.

linking PSF License Version 2

The Python Tutorial: More Control Flow Tools

Author: Python Software Foundation | Original Source Link ↗

Relevant Section / Range: Sections 4.2–4.10 (for, range, defining functions)

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

Selection Rationale:

Primary reference for Python iteration, functions, and containers.

Source Prerequisites:

Study Days 01-06 Python expression and filesystem fundamentals

Safe Fallback (Offline Resilience):

The lesson explains all required behavior locally and can be completed offline.

Compared Candidate Sources & Selection Analysis (2)
The Python Language Reference: Compound statements ↗ compared_alternative [PSF License Version 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.

02 120 min

Functions: explicit inputs, return values, and contracts

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

Today's activity 1. Recovery: revisit activity 1 for the counting invariant; Day 06 activity 2 for writing a small def.

Learning Objective

Wrap the counting loop in a function with explicit inputs (text, target) and a returned integer, document its contract, and distinguish return from print.

Instructions

Study source: within this activity's existing reading/practice time, use Automate the Boring Stuff with Python, 3rd edition, Chapter 4; 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: from memory, write what a = [1]; b = a; a.append(2) leaves in b (Day 05), then check.

New idea: a function's contract says what inputs it expects, what it returns, and what it leaves unchanged. count_char expects text (a string) and target (exactly one code point), returns an int, and does not modify its input. return hands a value back to the caller; print only displays text and the function then returns None.

1. Predict all seven outputs of count_char, then run it.
2. Predict the two lines of the shout example, then run it.

def count_char(text, target):
    """Return how many code points in text are equal to target (one code point)."""
    total = 0
    for ch in text:
        if ch == target:
            total += 1
    return total
print(count_char("", "a"))
print(count_char("aaaa", "a"))
print(count_char("猫猫犬", "猫"))
print(count_char("café", "e"))
print(count_char("cafe\u0301", "e"))
original = "été"
print(count_char(original, "é"), original)
print(count_char("abc", "ab"))
def shout(text):
    print(text.upper())
result = shout("hi")
print(result)

Practice & Prediction Log

Record predictions for the seven count_char calls (empty text, a repeated character, Unicode, precomposed versus decomposed "é", an unchanged original string, and a two-character target) and for the shout example. Then write the contract of count_char in your own words: inputs, output, and what it never changes.

Independent Mastery Criterion

All nine predictions are written before running and differences are explained; your written contract names both inputs, the precondition on target, the int output, and the no-modification guarantee; you can explain why the shout result is None.

Authoritative Source Resources & Provenance

linking Copyright Al Sweigart; edition-specific reuse terms unverified linking only; no reproduction

Automate the Boring Stuff with Python, 3rd edition

Author: Al Sweigart | Original Source Link ↗

Relevant Section / Range: Chapter 4; Practice Questions; Appendix B answers

Verified Version & Date: Public edition checked 2026-11-01; moving pages may change

Selection Rationale:

Beginner teaching and answer-keyed practice before checking exact semantics in the Python reference; selected chapters only, not the book's entire automation stack.

Source Prerequisites:

No prior programming required for Chapter 1; later chapters assume its basic Python concepts.

Safe Fallback (Offline Resilience):

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)
The Python Tutorial ↗ compared_alternative [PSF License Version 2]

Guided Python syntax but assumes programming familiarity; paired with the beginner text rather than used as its replacement.

MIT OCW 6.0001 ↗ compared_alternative [CC BY-NC-SA 4.0]

Lectures and problem sets teach a broader CS1 course; the book offers shorter text-first entry and an answer appendix.

linking PSF License Version 2

The Python Tutorial: More Control Flow Tools

Author: Python Software Foundation | Original Source Link ↗

Relevant Section / Range: Sections 4.2–4.10 (for, range, defining functions); data structures are in Chapter 5 of the same tutorial

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

Selection Rationale:

Primary reference for Python iteration, functions, and containers.

Source Prerequisites:

Study Days 01-06 Python expression and filesystem fundamentals

Safe Fallback (Offline Resilience):

The lesson explains all required behavior locally and can be completed offline.

Compared Candidate Sources & Selection Analysis (2)
The Python Language Reference: Compound statements ↗ compared_alternative [PSF License Version 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.

03 120 min

A two-variable invariant, plus small commits and a safe restore

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

Today's activities 1–2; Git installed. Recovery: Day 07 activity 3 for git diff and git restore.

Learning Objective

Implement longest_run(text, target) with two loop variables and a stated invariant, then record it in a disposable repository, inspect an unwanted uncommitted edit, and discard it safely with git restore.

Instructions

Spaced review: the Git part reuses Day 07's restore sequence with a Python file, so the commands should feel familiar.

Invariant for two variables: after each iteration, run is the length of the streak of target that ends at the character just visited, and best is the longest streak among all characters visited so far.

1. Predict the four outputs and write a trace table (ch / run / best) for "aabaaa" before running.

def longest_run(text, target):
    best = 0
    run = 0
    for ch in text:
        if ch == target:
            run += 1
        else:
            run = 0
        if run > best:
            best = run
    return best
print(longest_run("", "a"))
print(longest_run("baaab", "a"))
print(longest_run("aabaaa", "a"))
print(longest_run("猫猫犬猫", "猫"))

2. In a new temporary directory, commit the function, add an unwanted debug line, inspect it, and restore. Predict every output first:

cd "$(mktemp -d)"
git init -q
git config user.name "Learner"
git config user.email "[email protected]"
cat > stats.py <<'EOF'
def longest_run(text, target):
    best = 0
    run = 0
    for ch in text:
        if ch == target:
            run += 1
        else:
            run = 0
        if run > best:
            best = run
    return best
print(longest_run("猫猫犬猫", "猫"))
EOF
git add stats.py
git commit -q -m "Add longest_run"
python3 stats.py
printf 'print("debug", longest_run("", "a"))\n' >> stats.py
python3 stats.py
git diff --stat
git restore stats.py
git status --short
python3 stats.py
git log --format=%s

Practice & Prediction Log

Submit your trace table for longest_run("aabaaa", "a"), your predictions and observations for the four calls (including the empty string and "猫猫犬猫"), and the Git transcript showing the debug line appearing, the diff summary, and the clean status and unchanged output after git restore.

Independent Mastery Criterion

Your trace table matches the reference rows; all four calls are predicted correctly or the mismatch is explained; the Git transcript matches the reference output and proves the unwanted edit was removed without touching the commit history.

Authoritative Source Resources & Provenance

linking PSF License Version 2

The Python Tutorial: More Control Flow Tools

Author: Python Software Foundation | Original Source Link ↗

Relevant Section / Range: Sections 4.2–4.10 (for, range, defining functions); data structures are in Chapter 5 of the same tutorial

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

Selection Rationale:

Primary reference for Python iteration, functions, and containers.

Source Prerequisites:

Study Days 01-06 Python expression and filesystem fundamentals

Safe Fallback (Offline Resilience):

The lesson explains all required behavior locally and can be completed offline.

Compared Candidate Sources & Selection Analysis (2)
The Python Language Reference: Compound statements ↗ compared_alternative [PSF License Version 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.

04 120 min

Independent check: predict a loop and write a function

Independent mastery check: no AI assistance and no reference answer until your evidence is submitted; declare your assistance honestly.

Prerequisites

Today's activities 1–3 with recorded evidence. Recovery: activity 1 (invariants), activity 2 (contracts), Day 07 (conditions).

Learning Objective

Without assistance, trace a loop with a branch, then implement count_in(text, chars) with a stated invariant that handles empty, repeated, and Unicode text at code-point granularity.

Instructions

Spaced review: the branch inside the loop reuses Day 06 conditions. Do not open the reference answer or use AI until your evidence is submitted.

1. Predict the number printed by this loop, then run it. Also predict the result if the string were empty.

total = 0
for ch in "a猫a":
    if ch != "a":
        total += 10
    else:
        total += 1
print(total)

2. Implement count_in(text, chars): return how many code points of text occur anywhere in chars (for a single character ch, the expression ch in chars is True when ch appears in chars). Write the invariant as a comment or sentence, then predict and test: count_in("", "aeiou"), count_in("banana", "an"), count_in("naïve", "aeiouï"), count_in("cafe\u0301", "é"), count_in("猫と犬", "猫犬").

Practice & Prediction Log

Submit your loop prediction (non-empty and empty), your count_in code with its invariant, five predictions with five observed results, and one sentence on why count_in("cafe\u0301", "é") is 0.

Independent Mastery Criterion

Unaided: the loop prediction (including the empty case) is correct, count_in passes all five cases, the invariant is stated correctly, and the decomposed-accent case is explained at code-point level.

Authoritative Source Resources & Provenance

linking PSF License Version 2

The Python Tutorial: More Control Flow Tools

Author: Python Software Foundation | Original Source Link ↗

Relevant Section / Range: Sections 4.2–4.10 (for, range, defining functions)

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

Selection Rationale:

Primary reference for Python iteration, functions, and containers.

Source Prerequisites:

Study Days 01-06 Python expression and filesystem fundamentals

Safe Fallback (Offline Resilience):

The lesson explains all required behavior locally and can be completed offline.

Compared Candidate Sources & Selection Analysis (2)
The Python Language Reference: Compound statements ↗ compared_alternative [PSF License Version 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.