Day 3(周一 09-07,约 5 小时):收尾项目 + 结业测验 + 后续路线¶
今日目标:交付一个 120–200 行、有
project.py+test_project.py(≥5 个测试)+README.md、ruff check零警告、能反复运行且数据不丢的完整小程序;闭卷测验通过;用checklist.md完成三档自评,写下后续 4 周计划。今日节奏:5 小时用相对时间表示(从开工那一刻算起)。项目 3 小时拆成 3 个 50 分钟块,每块结束必须跑一次
pytest和ruff,这比最后一次性调试省时得多。
| 相对时间 | 块 | 内容 |
|---|---|---|
| 0:00–0:20 | 联合晨测 | Day 1 + Day 2 闭卷(下方 10 题),无电脑、无 AI |
| 0:20–0:35 | 开工准备 | 确认项目选择;把昨晚列的函数清单抄到 project/<名字>/README.md 的"函数清单"里;建好目录 |
| 0:35–1:25 | 项目 Block A | 数据模型 + 3 个纯函数 + 先写 3 个测试(红)→ 实现到绿 |
| 1:25–1:35 | 休息 | 离开屏幕 |
| 1:35–2:25 | 项目 Block B | 持久化(JSON/CSV 读写 + 文件不存在/损坏恢复)+ 主循环菜单 + 异常处理 |
| 2:25–2:35 | 休息 | |
| 2:35–3:25 | 项目 Block C | 补齐测试到 ≥5、完成 1 个可选扩展、写 README、ruff format |
| 3:25–3:55 | AI 评审 + 重构 | 模板 4 评审 → 只改前 3 条 → 重跑测试 |
| 3:55–4:30 | 结业测验 | 闭卷 20 分钟笔答 + 15 分钟限时编码(见下方) |
| 4:30–5:00 | 结业复盘 | checklist.md 三档自评;写后续 4 周计划;设置 D+1/D+3/D+7/D+30 提醒 |
联合晨测(20 分钟,闭卷;答案见 exercises/solutions/quiz_answers.md)¶
- 写出输出:
sorted([("b", 2), ("a", 2), ("c", 1)], key=lambda t: t[1])的结果是什么?(注意稳定排序)- 下面代码输出什么?
- 在 Windows 上
open("a.txt").read()读一个 UTF-8 中文文件可能报什么错?正确写法是什么?Python 3.15 之后会怎样? - 写出把字典
data保存为可读中文 JSON 文件out.json的完整代码(含with、编码、ensure_ascii、indent)。 - 写一个
@dataclass类Book,字段title: str、tags: list[str](默认空列表),并说明为什么不能写tags: list[str] = []。 class B(A)里的__init__想复用A的初始化,应该写哪一行?- 写一个 pytest 测试函数,验证
divide(1, 0)会抛出ZeroDivisionError。 - 写出输出:
- 用
match写一个函数kind(cmd: list[str]) -> str:["add", x, y]返回"加法",["quit"]返回"退出",其他返回"未知"。
评分:≥8 分直接开工;≤7 分先花 15 分钟重跑错题对应块的"预测"代码,再开工。
项目(3 小时):规格见 project/README.md¶
三个候选(详细功能清单、函数签名建议、验收标准、3 小时时间线都在 project/README.md):
- A. 命令行待办/记账管理器(推荐)——
list[dict]或list[dataclass]+ JSON 持久化 + 菜单循环 + 统计。最贴近"有数据、有存档、有交互"的真实小工具。 - B. 终端猜词游戏(Wordle 风格)——字符串算法 + 状态 + 随机 + 词库文件 + 战绩 JSON。算法最有趣,
evaluate_guess的重复字母边界是好测试题。 - C. CSV 成绩分析工具——是 Day 2 Block 7 的自然延伸(按班级聚合、排名、导出汇总 CSV、ASCII 直方图)。最稳妥、最容易在 3 小时内做完整。
通用硬性要求(三选一都适用):
1. 目录 project/<项目名>/,扁平结构:project.py、test_project.py、README.md、数据文件(data.json / words.txt / grades.csv)。
2. project.py 有 main() 和 if __name__ == "__main__": main();至少 3 个不做输入输出的纯函数(接收参数、返回结果),它们是测试对象。
3. test_project.py ≥ 5 个测试,至少 1 个 pytest.raises、1 个 parametrize;uv run pytest project -q 全绿。
4. 文件读写全部 encoding="utf-8";文件不存在或 JSON 损坏时程序不崩溃,用默认值恢复。
5. 用户输入全部经过校验循环(非法输入提示后重试,不崩溃)。
6. 每个函数 ≤ 25 行;没有全局可变状态(数据通过参数传递和返回)。
7. uv run ruff check project 零警告;uv run ruff format project 已执行。
8. README.md 含:一句话介绍、运行方式、功能列表、函数清单(名字 + 一句话)、已知限制、下一步想加什么。
做项目的顺序(防止 3 小时做不完的关键):
- Block A:先写数据模型(dataclass 或字典结构约定),再写 3 个纯函数和它们的测试,测试先红后绿。此时程序还没有菜单——没关系。
- Block B:写 load/save 与主循环菜单。菜单只需要 4–5 个选项。每写完一个选项就手动跑一遍。
- Block C:补测试、做 1 个扩展、写 README、格式化。若 Block B 结束时还没能跑通主循环,Block C 全部用来跑通,扩展砍掉。
AI 评审与重构(30 分钟)¶
- 用
ai-guide.md模板 4 把project.py发给 AI 评审(今天允许它看完整代码)。 - 只处理它列出的前 3 条;每改一条重跑
uv run pytest project -q。 - 若 AI 建议引入你没学过的东西(装饰器、
typing.Protocol、异步等),记到 README 的"下一步"里,不要现在改。
结业测验(35 分钟)¶
笔答(20 分钟,闭卷):
1. 用自己的话解释:列表的"别名"是什么,什么时候需要 copy()。
2. 写出读取 UTF-8 文本文件所有行到列表的正确代码(含 with)。
3. 一个函数应该"返回结果"还是"直接 print"?为什么这影响可测试性?
4. try/except/else/finally 四个块各在什么时候执行?
5. 写一个字典推导式:把 ["a", "bb", "ccc"] 变成 {"a": 1, "bb": 2, "ccc": 3}。
6. 说出 3 个你今天在项目里实际用到的标准库模块及用途。
7. @dataclass 帮你自动生成了哪三个方法?
8. 什么是 if __name__ == "__main__":,为什么测试文件 import 你的模块时需要它?
限时编码(15 分钟,闭卷,新建 exercises/day3/final_coding.py):
实现 def summarize_orders(orders: list[dict]) -> dict[str, float]:输入形如 [{"item": "笔", "price": 2.5, "qty": 4}, {"item": "本", "price": 5, "qty": 2}],返回每种商品的总金额 {"笔": 10.0, "本": 10.0}(同名商品累加),空列表返回 {};qty 或 price 为负数时 raise ValueError。写 3 个 assert 自测并运行通过。能在 15 分钟内不查资料写出来 = 三天目标达成。
参考答案与评分要点见 exercises/solutions/quiz_answers.md。
结业复盘(30 分钟)¶
- 打开
checklist.md的"三档自评表",对每个 A 档知识点诚实打勾:能默写 / 看提示能写 / 不会。"看提示能写"的点就是 D+3 复习的内容。 - 写下后续 4 周计划(
README.md第 6 节的通用版按你开学后每周可用小时数改一改)。 - 在手机日历设 4 个提醒:
- D+1(周二):15 分钟闭卷重写项目里最难的函数;
- D+3(周四):45 分钟,用模板 5 让 AI 出 10 题交错测验;
- D+7(下周日):90 分钟,不看旧代码重做另一个候选项目;
- D+30(10 月初):2 小时,做一个新的、结合字典 + 文件 + 类 + 测试的项目,并重新填三档自评表。
- 最后一件事:把这三天写的所有代码从头翻一遍(只看不改),感受一下 Day 1 上午的代码和现在的差别。
若时间不够:结业测验只做限时编码那一题;笔答留到 D+1。