简介:打造“防弹”程序
欢迎来到 H2 计算机科学(Computing)课程中最实用的一章!你有没有想过,为什么网站会提示你的密码太短,或者当你输入字母而非数字时,程序会突然“崩溃”(crash)?
在本章中,我们将学习如何防止这些问题。我们将探讨数据验证(Data Validation)(确保输入的数据合理)、程序测试(Program Testing)(在用户发现 Bug 之前先行找出问题),以及错误处理(Error Handling)(确保程序在出错时能优雅地处理)。掌握这些技能,正是将“业余编码员”蜕变为专业程序员的关键。
1. 验证(Validation)与核对(Verification):有什么区别?
人们常混用这两个词,但在计算机科学中,它们的意义截然不同。
数据验证(Data Validation)是指计算机执行的自动检查,旨在确保输入的数据合理(sensible)且符合特定规则。它并不保证数据正确无误,只保证该数据是“被允许输入的”。
数据核对(Data Verification)是指确保输入的数据与原始来源完全一致(exactly matches)的检查。
生活中的类比
想象你正在注册健身房会籍:
- 验证:计算机检查你的“年龄”是否为 12 到 100 之间的数字。如果你输入“200”,它会拒绝,因为这不合理。
- 核对:职员查阅你的身份证,确保你在屏幕上输入的名字确实是你的真实姓名。
重点总结
验证检查数据是否合理。
核对检查数据是否正确。
2. 数据验证技巧
为了防止系统出现“垃圾数据”,我们会使用几种特定的检查方式。如果清单看起来很长,别担心,大多数技巧都非常直观!
1. 存在性检查(Presence Check)
确保字段没有被留空。
例子:表格中电邮字段旁边的“必填”星号。
2. 检索检查(Existence Check)
检查输入的数据是否已经存在于系统中,或是清单中的有效项目。
例子:当你尝试注册用户名时,系统显示“用户名已被占用”。
3. 范围检查(Range Check)
检查数字是否落在特定的边界范围内。
例子:考试分数必须在 \(0\) 到 \(100\) 之间。
4. 长度检查(Length Check)
确保输入内容具有特定的字符数量,或在一定的长度范围内。
例子:新加坡电话号码必须刚好是 8 位数字。
5. 类型检查(Type Check)
确保数据属于正确的数据类型(例如:整数、字符串、浮点数)。
例子:在数量字段输入“Five”而非“5”将会导致类型检查失败。
6. 格式检查(Format Check)
检查数据是否遵循特定的模式或“掩码”(mask)。
例子:日期必须采用 DD/MM/YYYY 的格式。
7. 校验码(Check Digit)
这是一个根据数字中的其他位数计算出的特殊位数(通常是最后一位)。它用于检测手动输入时发生的错误(例如数字互换)。
例子:身份证号码(NRIC)或条形码的最后一个字符。
记忆口诀:“P.E.R.F.L.T”
试着记住“PERFect Little Techniques”(完美的技巧):
Presence (存在性), Existence (检索), Range (范围), Format (格式), Length (长度), Type (类型)(别忘了还有校验码!)。
3. 识别与修正错误
即使是最优秀的程序员也会犯错!你需要了解三种主要的错误类型:
A. 语法错误(Syntax Errors)
这是代码中的“文法”错误。程序将完全无法执行。
例子:将 prnt("Hello") 写成 print("Hello"),或者在 if 语句后忘记加上冒号。
B. 运行时错误(Runtime Errors)
代码本身写得正确(没有语法错误),但在程序运行时发生了问题,导致程序崩溃。
例子:除以零或尝试打开一个不存在的文件。
C. 逻辑错误(Logic Errors)
程序可以运行且不会崩溃,但给出的结果错误。这些错误最难发现!
例子:你想计算正方形面积,却写成 Area = Side + Side 而非 Area = Side * Side。
快速回顾
- 语法错误:无法启动(代码文法错)。
- 运行时错误:中途崩溃(运行时崩溃)。
- 逻辑错误:结果错误(大脑当机)。
4. 设计测试案例(Test Cases)
为了确保程序运作正常,你必须使用不同类型的数据进行测试。假设我们正在测试一个接受学生年龄(范围:13 到 18)的程序。
1. 正常数据(Normal Data)
落在可接受范围内的数据。
例子:15, 16。
2. 边界(极端)数据(Boundary Data)
处于范围边缘的数据。错误通常发生在这里!
例子:13 和 18。
3. 错误数据(Erroneous/Invalid Data)
超出范围或类型错误的数据。程序应拒绝这些数据。
例子:12, 19, "Hello", 或 \( -1 \)。
避免常见错误
学生经常忘记测试边界数据。请务必测试确切的最小值和最大值!对于 1 到 100 的范围,你的测试案例绝对应包含 1 和 100。
5. 程序追踪(Program Tracing):扮演计算机
追踪是跟随程序执行步骤,观察变量值如何变化的进程。
追踪表(用于非递归程序)
追踪表(Trace Table)是一个表格,每一列代表一个变量,每一行代表程序执行的一个步骤。
小贴士:填写追踪表时,只需在变量值改变时写入。如果值保持不变,可以留空或使用引号,以保持表格整洁。
递归树(用于递归程序)
对于会自我调用的函数,追踪表可能会变得很乱。这时我们改用递归树(Recursion Tree)。
1. 从最上方的初始调用开始。
2. 每次函数调用自己时,就画出分支。
3. 当返回值“冒泡”回到顶端时,写下这些值。
如果起初觉得有点难也别担心!递归树只是函数“旅程”的地图而已。
6. 错误与异常处理(Error and Exception Handling)
有时错误是不可避免的(例如用户在下载过程中拔掉了网络)。我们使用异常处理(Exception Handling),而不是让程序直接崩溃。
在 Python 中,我们使用 try...except 块:
try:
# 可能导致错误的代码
number = int(input("输入一个数字: "))
result = 10 / number
except ZeroDivisionError:
# 若用户输入 0 时的处理方式
print("你不能除以零!")
except ValueError:
# 若用户输入 "hello" 时的处理方式
print("那不是数字!")
重点总结
异常处理能使你的程序变得稳健(robust)。它允许程序告诉用户哪里出错了,并能继续执行,而不是直接强制退出。
最后鼓励:你已经完成了数据验证和程序测试的基础!请记住,这一章的目标不仅是为了通过考试,更是为了帮助你建立人们真正能信赖的软件。继续多练习那些追踪表吧!