除错与测试:找出程式的病

进阶

错误三类:语法(格式错、无法启动)、运行时(跑到一半停,如除以零)、逻辑(跑完但结果错);用已知答案的测试资料验证,用 print 和追踪表找变数问题。

适合:中二资讯及通讯科技 · 单元:演算法与程式 · 建议学习路径第 7/12 课

学完呢课,你会识:
  • 错误三类:语法、运行时、逻辑。
  • 语法错误启动不了;运行时错误跑到一半停;逻辑错误跑完但结果错。
  • 错误讯息最后一行讲类型,上面讲行号 — 先读讯息再动手。
文体:方法指导课有声朗读

文体小知识:方法指导课教你一套有系统的做法,照步骤练习,遇到问题就不会毫无头绪。

资讯及通讯科技Information & Communication Technology

§课文原文 Passage

1程式出错是家常便饭,找出并修正错误的过程叫除错(Debugging)。错误分三大类:语法错误(Syntax error)— 写错格式,例如漏了冒号,程式一行都跑不到;运行时错误(Runtime error)— 执行到一半才停下,例如除以零或存取不存在的索引;逻辑错误(Logic error)— 程式顺利跑完,但结果不对,例如把加写成乘,最难察觉。

2Python 会直接告诉你语法和运行时错误:SyntaxError: invalid syntax、ZeroDivisionError: division by zero。看懂错误讯息的最后一行(错误类型)和上面的行号(出事位置),问题已经解决了一半。读错误讯息是每个程式员的基本功。

3逻辑错误电脑不会报错,要靠自己测试(Testing):用已知道答案的资料试跑,例如计平均分的程式,输入 [10, 20, 30] 应该得出 20;如果得出 6000(不小心乘了),就知道出了问题。这些「先知答案、再验证」的资料叫测试资料(Test data),还要包括边界情况:空清单、全 0、只有一个数。

4逐步追踪(Trace)是基本功:拿一张纸,一行一行写下每个变数的变化,例如 n=1 → 印 1 → n=2 → 印 2 → n=3 → 印 3 → n=4 条件不成立结束;也可以在程式中间加 print(n) 观察变数。养成「小改一步、测一次」的习惯,错误就不会积少成多。

1重点摘要 Summary

错误三类:语法(格式错、无法启动)、运行时(跑到一半停,如除以零)、逻辑(跑完但结果错);用已知答案的测试资料验证,用 print 和追踪表找变数问题。

2生字卡 Vocabulary

B
Bug程式错误

程式中的错误或缺陷,令程式不能运行或结果不对。

D
Debugging除错

找出错误位置和原因,并加以修正的过程。

S
Syntax error语法错误

程式格式不符合语言规则(如漏冒号),令程式完全无法启动。

R
Runtime error运行时错误

程式执行到一半才发生的错误,例如除以零、索引超出范围。

L
Logic error逻辑错误

程式顺利执行完毕,但因演算法写错而得出错误结果,最难发现。

E
Error message错误讯息

Python 显示的错误报告:最后一行是错误类型,上面有出事的行号。

T
Test data测试资料

答案已知的输入资料,用来验证程式是否正确,包括边界情况。

T
Trace table追踪表

逐行记录变数数值变化的表格,用来找出逻辑出错的位置。

B
Boundary case边界情况

输入范围极端的情况:最小值、最大值、0、空清单、只有一个元素。

3逐步讲解 Steps

  1. 辨认语法错误语法错误是程式的「文法」写错了,例如 if x > 5 漏了结尾的冒号,或者 print('hi' 漏了右括号,Python 都会报 SyntaxError。特征非常明显:程式无法执行任何一行,一启动便报错,错误讯息会指出出事的行号。初学者最常犯的是漏冒号、括号不配对,以及中英文标点混用,例如输入了全形冒号。见到 SyntaxError,先检查该行和上一行的符号是否齐全。
  2. 辨认运行时错误运行时错误是程式执行到一半才发生的错误,例如 10 / 0 会报 ZeroDivisionError;清单 [1, 2] 只有两个元素,却取第 6 个位置的元素(索引 5),便会报 IndexError,因为索引 5 并不存在。特征是:程式能够启动,执行到某一句时突然停止,错误讯息会指出停在哪一行。处理方法:按行号找到该句,检查除数是否可能为零、索引是否超出范围、档案是否存在等。
  3. 辨认逻辑错误逻辑错误最危险:程式正常跑完,没有任何报错,但答案不对。例如想计平均数,却写成 sum(nums) * len(nums),输入 [10, 20, 30] 时输出 1800,而不是正确的 20。电脑不会提醒你,唯一办法是用已知道答案的资料测试。常见的逻辑错误还包括把加写成乘、把 >= 写成 >、循环次数差一。养成测试习惯,逻辑错误便无所遁形。
  4. 读懂错误讯息Python 的错误讯息是最有用的线索。例如萤幕出现 ZeroDivisionError: division by zero,还附有一个行号:最后一行讲错误类型,上面的行号指出哪一行出事。阅读次序是先看最后一行知道错误类型,再按行号找到位置,检查那句程式码。看懂错误讯息是每个程式员的基本功,遇到不明白的错误名称,可以先搜寻它的意思,再对照自己的程式码逐步修正。
  5. 用测试资料验证测试资料是「先知道答案、再验证程式」的资料。以计平均数的程式为例:用 [10, 20, 30] 测试,心算答案 20;用 [5] 测试,只有一个数,答案 5;用 [0, 0] 测试,答案 0。正常值、单一值、边界值全部都要试,因为不同情况触发的错误不同,例如只有一个数时,某些写法便会出错。考试常要求列出测试资料和解释原因,答题时每组资料都要写明预期输出。
  6. 纸笔追踪表追踪表是找出逻辑错误的基本功。拿一张纸画表格,一行一行记录每个变数的变化。例如 n = 1,程式是 while n < 4: print(n),然后 n = n + 1:第一圈 n 是 1,印出 1;第二圈 n 是 2,印出 2;第三圈 n 是 3,印出 3;第四圈 n 是 4,条件不成立,结束。变数由哪一圈开始与预期不符,表格一目了然,错误的位置便无所遁形。
  7. print 除错法结果不对时,可以在关键位置加入 print 观察中间值,例如 print('总分:', total),看看总分究竟是多少,从而判断问题出在前半还是后半。找到问题之后,把这些临时 print 删除,保持程式整洁。最重要的原则是:小改一步、测一次,不要一次改五处,否则根本无法知道哪一个修改有效。遵守这个纪律,除错便会事半功倍。

4图解 Diagrams

除错与测试:程式嘅体检 Debug & test发现 bug↓ 读错误讯息定位 → 修正→ 再测试 ↑读 error 讯息佢会话你知第几行错print 追踪中途 print 出嚟睇值测极端值0·负数·空值都试心态:bug 唔系失败,系常态——专业程序员一日都系不断 debug
图 1:除错与测试循环

5例题示范 Example

例题:以下程式想计算 [8, 9, 10] 的平均,但输出 27。找出错误类型并修正。程式码:total = 0;for s in [8, 9, 10]: total = total + s;average = total * 3;print(average)。

  1. 先分类:程式能够跑完,全程没有报错,所以排除语法错误和运行时错误,剩下的是逻辑错误。
  2. 用测试资料心算验证:8 + 9 + 10 = 27,总分正确;但题目要的是平均,27 其实是总分而非平均。
  3. 逐行检查,找到问题行:average = total * 3 把乘号用错了位置,应该是 average = total / 3。
  4. 修正后测试:27 除以 3 等于 9.0,正确;再用 [10, 20, 30] 验证一次,输出 20,通过测试。
  5. 答案:这是逻辑错误:程式没有报错但结果不对。把 average = total * 3 改为 average = total / 3,输出变成 9.0;再用 [10, 20, 30] 测试得 20,两组测试资料都通过,修正完成。

6常见错误 Mistakes

✗ 「程式跑完没有报错,即是一定对。」
✓ 逻辑错误不会报错,程式照样跑完但答案错;必须用测试资料验证结果。
✗ 「SyntaxError 不用理,跑到就算。」
✓ 语法错误令程式完全无法启动;要按讯息行号修正格式(漏冒号、漏括号等)。
✗ 「除错就是一次过改全所有地方。」
✓ 一次改多处会引入新错误;正确做法是「小改一步、测一次」。
✗ 「用一组数据测试就够。」
✓ 要试正常值、边界值(0、空清单、只有一个数)和错误值;一组数据测不出所有问题。
✗ 「错误讯息是英文,很烦,不用看。」
✓ 错误讯息最后一行已讲明错误类型,是免费提示;先读讯息的习惯可以省一半时间。

75 题快测 Quick check

Q1print("hello(漏了右括号)属于哪类错误?

Q2执行 10 / 0 会发生什么事?

Q3程式顺利跑完,但平均分计错。这是哪类错误?为什么最难发现?

Q4想验证计平均的程式,输入 [10, 20, 30] 时应该期望什么结果?

Q5写出除错的三个好方法(任何三个)。

8重点回顾 Recap

  • 错误三类:语法、运行时、逻辑。
  • 语法错误启动不了;运行时错误跑到一半停;逻辑错误跑完但结果错。
  • 错误讯息最后一行讲类型,上面讲行号 — 先读讯息再动手。
  • 用已知答案的测试资料验证,边界情况也要试。
  • 除错习惯:小改一步、测一次;善用 print 和追踪表。

同级其他科

同一科其他级别