先修:起步 0 的赋值、函数和返回值。目标:用条件和整数运算求最少分组数,通过 Q2。
1. 条件产生 True 或 False
本节路线:先用表格比较,再学商和余数,最后实现foundations Q2。先修是起步0的参数与返回值;命令目录沿用 起步入口。学完留下三类输入的证据:0个、恰好整组、刚超出整组,解释哪一种需要补一组。
7 > 3 得到 True,7 == 3 得到 False。= 赋值,== 比较,不能互换。下面是一个完整示例:
def shipping_fee(items):
if items == 0:
return 0
else:
return 5
调用 shipping_fee(0) 返回 0,shipping_fee(2) 返回 5。if 后写条件,冒号后缩进的是条件成立时运行的代码;else 分支处理条件不成立的情况。执行 return 后就离开本次调用。
先预测 shipping_fee(-1)。这个例子没有检查负数,所以仍然返回 5。程序只执行你写下的规则,不会理解“件数不应该为负”。课程练习提供了非法输入检查:raise ValueError(...) 表示输入不符合契约并结束正常执行。
2. 商与余数必须一起看
整数除法 // 给出向下取整的商,% 给出余数。本题的输入均非负,因此可以直接按小学除法理解:
| 表达式 | 值 | 解释 |
|---|---|---|
7 // 3 | 2 | 装满了两组 |
7 % 3 | 1 | 还剩一个 |
6 // 3 | 2 | 装满了两组 |
6 % 3 | 0 | 没有剩余 |
普通除法 / 会产生浮点结果。整数计数不必绕到浮点再转换,特别大的整数在转换时还可能失去精度。
3. 先填表,再做 Q2
每组能装 4 个元素。填出下表的“最少组数”,同时画出每组装了几个:
| 元素数 | 满组数 | 剩余数 | 最少组数 |
|---|---|---|---|
| 0 | 0 | 0 | 自己填写 |
| 1 | 0 | 1 | 自己填写 |
| 8 | 2 | 0 | 自己填写 |
| 9 | 2 | 1 | 自己填写 |
表格核对与常见错误
组数依次为 0、1、2、3。一直写“商 + 1”会在 0 和 8 上多分一组;只写商会在 1 和 9 上少分一组。代码应根据余数是否为零选择分支。
Q2 已经算好了 full_groups 与 remainder,你负责组织分支和返回值。不能用浮点除法或 math.ceil;练习的是如何从边界情况推导整数算法。
python course/tools/grade.py foundations --question q2 --unlock
python course/tools/grade.py foundations --question q2 --failfast
4. 怎么证明没有少分或多分?
设答案是 g,容量是 b,元素数是 n。它应满足 g*b >= n:能装下所有元素。若 g>0,还应满足 (g-1)*b < n:少一组就装不下。两条一起才说明是“最少”。公开测试会检查这个性质,不仅检查几组固定答案。
给错误程序“总是返回 n 组”找一个反例;它可能满足能装下,却不满足最少。这个思考会在 GPU 尾块和分页浪费中再次用到。下一节是 列表与循环。