(二)从错误结果找出第一次状态差异
1. 用手算对照每轮判断
任务规定:一次阅读不少于 35 分钟就记为达标。三次记录为 20、35、45,所以应有两次达标。下面是另一个错误示例:
# 项目文件:debug_demo/goal_before.py
# 错误示例:把“不少于”写成了严格大于,恰好 35 分钟的记录被漏掉。
def count_met(minutes, goal):
count = 0
for value in minutes:
if value > goal:
count += 1
return count
if __name__ == "__main__":
print(count_met([20, 35, 45], 35))程序输出 1。先写出期望,再沿循环比较:
| 本轮分钟数 | 任务要求的判断 | 程序的判断 | 本轮后的正确计数 | 本轮后的实际计数 |
|---|---|---|---|---|
| 20 | 20 >= 35 为假 |
20 > 35 为假 |
0 | 0 |
| 35 | 35 >= 35 为真 |
35 > 35 为假 |
1 | 0 |
| 45 | 45 >= 35 为真 |
45 > 35 为真 |
2 | 1 |
差异第一次出现在第二轮,而不是最终的 return。再缩小为 count_met([35], 35):手算是 1,程序是 0。这一份数据直接区分 > 和 >=,不需要更多记录。
2. 先提出能被数据检验的猜想
发现“少算一次”时,可能猜循环漏了最后一项,也可能猜计数初值错误。分别换成 [45]、[20]、[35]:程序依次给出 1、0、0,只有最后一份与手算不同,比较条件更值得检查。每次只改变一处,记录预测和实际输出,避免几个修改互相掩盖。
同样的方法可用于第五章的重复求和。一本书有两条日志 20、35、两个标签,错误连接得到四行,合计为 110。先在 SQL 中查看连接后的中间行,发现每条日志出现两次,再改成 EXISTS 判断标签。修改最终显示格式不会改变那四行数据。