08 / 90

Day 08:循环、循环不变量与函数的输入输出

新内容:遍历文本的 for 循环、用来解释循环为何正确的入门级循环不变量,以及输入和返回值都明确的函数。每项活动都以第 04–07 天的简短间隔复习(提取练习)开场,并记录预测、观察和恢复证据;小改动保存在一次性 Git 仓库中。

自主学习与 Python 480 分钟(8 小时专注学习)
01 120 分钟

for 循环与入门级循环不变量

智能体协助练习:先写下自己的预测和实际输出,之后才可以请 AI 智能体解释或审阅,并且必须在证据中记录所受的协助。

先决条件

已完成第 07 天(包括其独立检查)。恢复:第 07 天(值与条件);第 07 天的循环预览是可选的背景知识。

学习目标

逐个码位追踪遍历字符串的 for 循环,并陈述一个在循环前、每次迭代后和结束时都成立的循环不变量,包括空文本和 Unicode 文本的情况。

操作说明

学习来源:在本活动现有的阅读与练习时段内,参考 Automate the Boring Stuff with Python, 3rd edition 的 Chapter 3; Practice Questions; Appendix B answers,用自己的话解释一处与本地任务的联系。保留现有练习与验收检查;若外部资料无法访问,使用课程自写的解释。间隔复习热身(10 分钟): 凭记忆预测 bool("")、bool(" ") 和 "0" == 0,然后核对。有了昨天的复习,这应该很快;答得慢的地方就是需要回顾的地方。

新概念: for 循环对每个元素执行一次循环体;对字符串而言,每个元素是一个 Unicode 码位。循环不变量是关于变量的一句话,它在第一次迭代前成立,并在每次迭代后保持成立。计数时的不变量是:total 等于已访问字符中匹配字符的个数。

1. 运行前,按 visited / total / 不变量是否成立 三列填写追踪表。
2. 运行代码;它会打印同样的列,方便你核对表格。
3. 运行第二段代码,观察空文本的情况(循环体执行零次)以及一个与码位有关的意外结果。

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

练习与预测记录

运行前写出 text = "été"、target = "é" 的完整追踪表。然后陈述三个时刻的不变量:循环前(total = 0,尚未访问任何字符)、每次迭代后、结束时(visited == text,所以 total 就是答案)。最后预测空字符串的输出以及 len("e\u0301")。

独立掌握标准

追踪表在运行前写好且与实际各行一致;陈述了初始化、每次迭代后和结束时的不变量;正确预测了空文本情况和两个码位的分解形式情况。

来源资源与出处

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

Automate the Boring Stuff with Python, 3rd edition

作者 / 机构: Al Sweigart | 原始出处链接 ↗

对应章节 / 时间戳: Chapter 3; Practice Questions; Appendix B answers

验证版本与日期: 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.

对比候选资源与选型分析 (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

作者 / 机构: Python Software Foundation | 原始出处链接 ↗

对应章节 / 时间戳: 第 4.2–4.10 节(for、range、定义函数)

验证版本与日期: Python 3.12 文档(核验日期:2026-10-30)

入选理由:

用于查阅 Python 迭代、函数和容器的第一手参考资料。

来源前置条件:

第 01–06 天的 Python 表达式与文件系统基础

安全回退方案(离线弹性):

教材内已讲解所有必需的行为,可以离线完成。

对比候选资源与选型分析 (2)
The Python Language Reference: Compound statements ↗ compared_alternative [PSF License Version 2]

在语法层面定义相同的结构;选择教程章节是因为它循序渐进。

以讲座节奏讲解相同的控制流;由于本课程已通过终端练习推进这些概念,暂不采用。

02 120 分钟

函数:明确的输入、返回值与契约

智能体协助练习:先写下自己的预测和实际输出,之后才可以请 AI 智能体解释或审阅,并且必须在证据中记录所受的协助。

先决条件

今天的活动 1。恢复:计数不变量见活动 1;编写小型 def 见第 06 天活动 2。

学习目标

把计数循环封装成函数,明确输入(text、target)并返回整数,写下它的契约,并区分 return 与 print。

操作说明

学习来源:在本活动现有的阅读与练习时段内,参考 Automate the Boring Stuff with Python, 3rd edition 的 Chapter 4; Practice Questions; Appendix B answers,用自己的话解释一处与本地任务的联系。保留现有练习与验收检查;若外部资料无法访问,使用课程自写的解释。间隔复习热身: 凭记忆写出 a = [1]; b = a; a.append(2) 之后 b 的内容(第 05 天),然后核对。

新概念: 函数的契约说明它期望什么输入、返回什么、保证不改变什么。count_char 接收 text(字符串)和 target(恰好一个码位),返回 int,不修改输入。return 把值交还给调用者;print 只是显示文字,函数随后返回 None。

1. 预测 count_char 的全部七个输出,然后运行。
2. 预测 shout 示例的两行,然后运行。

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)

练习与预测记录

记录对七次 count_char 调用(空文本、重复字符、Unicode、预组合与分解形式的 "é"、保持不变的原字符串、两个字符的 target)以及 shout 示例的预测。然后用自己的话写出 count_char 的契约:输入、输出以及它绝不改变的东西。

独立掌握标准

九个预测都在运行前写好并解释了差异;你写的契约包含两个输入、target 的前置条件、int 输出和不修改的保证;能解释 shout 的结果为什么是 None。

来源资源与出处

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

Automate the Boring Stuff with Python, 3rd edition

作者 / 机构: Al Sweigart | 原始出处链接 ↗

对应章节 / 时间戳: Chapter 4; Practice Questions; Appendix B answers

验证版本与日期: 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.

对比候选资源与选型分析 (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

作者 / 机构: Python Software Foundation | 原始出处链接 ↗

对应章节 / 时间戳: 第 4.2–4.10 节(for、range、定义函数);数据结构见同一教程第 5 章

验证版本与日期: Python 3.12 文档(核验日期:2026-10-30)

入选理由:

用于查阅 Python 迭代、函数和容器的第一手参考资料。

来源前置条件:

第 01–06 天的 Python 表达式与文件系统基础

安全回退方案(离线弹性):

教材内已讲解所有必需的行为,可以离线完成。

对比候选资源与选型分析 (2)
The Python Language Reference: Compound statements ↗ compared_alternative [PSF License Version 2]

在语法层面定义相同的结构;选择教程章节是因为它循序渐进。

以讲座节奏讲解相同的控制流;由于本课程已通过终端练习推进这些概念,暂不采用。

03 120 分钟

双变量不变量,以及小提交与安全恢复

智能体协助练习:先写下自己的预测和实际输出,之后才可以请 AI 智能体解释或审阅,并且必须在证据中记录所受的协助。

先决条件

今天的活动 1–2;已安装 Git。恢复:git diff 与 git restore 见第 07 天活动 3。

学习目标

用两个循环变量并陈述不变量来实现 longest_run(text, target),然后在一次性仓库中记录它,检查一处不需要的未提交修改,并用 git restore 安全地丢弃。

操作说明

间隔复习: Git 部分用 Python 文件重复第 07 天的恢复流程,命令应该已经眼熟。

双变量不变量: 每次迭代后,run 是以刚访问的字符结尾的 target 连续段长度,best 是目前已访问部分中最长的连续段。

1. 运行前预测四个输出,并为 "aabaaa" 写出追踪表(ch / run / best)。

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. 在新的临时目录中提交该函数,加入一行不需要的调试代码,检查后恢复。先预测每一项输出:

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

练习与预测记录

提交 longest_run("aabaaa", "a") 的追踪表,四次调用(包括空字符串和 "猫猫犬猫")的预测与观察,以及 Git 记录:显示调试行出现、差异摘要,以及 git restore 之后状态干净、输出不变。

独立掌握标准

追踪表与参考各行一致;四次调用预测正确或已解释不符;Git 记录与参考输出一致,证明在不触碰提交历史的情况下去掉了不需要的修改。

来源资源与出处

linking PSF License Version 2

The Python Tutorial: More Control Flow Tools

作者 / 机构: Python Software Foundation | 原始出处链接 ↗

对应章节 / 时间戳: 第 4.2–4.10 节(for、range、定义函数);数据结构见同一教程第 5 章

验证版本与日期: Python 3.12 文档(核验日期:2026-10-30)

入选理由:

用于查阅 Python 迭代、函数和容器的第一手参考资料。

来源前置条件:

第 01–06 天的 Python 表达式与文件系统基础

安全回退方案(离线弹性):

教材内已讲解所有必需的行为,可以离线完成。

对比候选资源与选型分析 (2)
The Python Language Reference: Compound statements ↗ compared_alternative [PSF License Version 2]

在语法层面定义相同的结构;选择教程章节是因为它循序渐进。

以讲座节奏讲解相同的控制流;由于本课程已通过终端练习推进这些概念,暂不采用。

04 120 分钟

独立检查:预测循环并编写函数

独立掌握检查:提交证据之前不使用任何 AI 协助,也不查看参考答案;如实申报所受的协助。

先决条件

已完成今天的活动 1–3 并记录证据。恢复:活动 1(不变量)、活动 2(契约)、第 07 天(条件)。

学习目标

在无协助的情况下追踪一个带分支的循环,并实现 count_in(text, chars),陈述其不变量,按码位粒度正确处理空、重复和 Unicode 文本。

操作说明

间隔复习: 循环中的分支复用了第 06 天的条件。提交证据之前,不要打开参考答案,也不要使用 AI。

1. 预测这个循环打印的数字,然后运行。同时预测字符串为空时的结果。

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

2. 实现 count_in(text, chars):返回 text 中出现在 chars 里的码位个数(对单个字符 ch,表达式 ch in chars 在 ch 出现在 chars 中时为 True)。先用注释或一句话写出不变量,再预测并测试:count_in("", "aeiou")、count_in("banana", "an")、count_in("naïve", "aeiouï")、count_in("cafe\u0301", "é")、count_in("猫と犬", "猫犬")。

练习与预测记录

提交:循环预测(非空和空两种情况)、带不变量的 count_in 代码、五个预测与五个实测结果,以及一句话解释为什么 count_in("cafe\u0301", "é") 为 0。

独立掌握标准

无协助:循环预测(包括空的情况)正确;count_in 通过全部五个用例;不变量陈述正确;能在码位层面解释分解重音的情况。

来源资源与出处

linking PSF License Version 2

The Python Tutorial: More Control Flow Tools

作者 / 机构: Python Software Foundation | 原始出处链接 ↗

对应章节 / 时间戳: 第 4.2–4.10 节(for、range、定义函数)

验证版本与日期: Python 3.12 文档(核验日期:2026-10-30)

入选理由:

用于查阅 Python 迭代、函数和容器的第一手参考资料。

来源前置条件:

第 01–06 天的 Python 表达式与文件系统基础

安全回退方案(离线弹性):

教材内已讲解所有必需的行为,可以离线完成。

对比候选资源与选型分析 (2)
The Python Language Reference: Compound statements ↗ compared_alternative [PSF License Version 2]

在语法层面定义相同的结构;选择教程章节是因为它循序渐进。

以讲座节奏讲解相同的控制流;由于本课程已通过终端练习推进这些概念,暂不采用。