外观
第7周:第四次上机课(完整版)
课堂版 · py 作业 4 · py 练习 3 · py 作业 5
本页覆盖 py 作业 4 全部 5 题。统计来自 2026-10-22 的 OJ 各题统计页,共 838 次提交,461 次 Accepted;每次重试分别计数,次数不等于人数。错误分析抽取了统计页近期可读的 28 份提交,不是全部提交的错误原因普查。片段已匿名整理,省略处另行说明;反例由代码静态分析与手工推演得到,不代表 OJ 隐藏测试。
py 作业 3 的 9 题完整解析已公开。py 作业 4 于北京时间 10 月 27 日 13:00 截止,以下公开局部讲解与方法对照,完整参考答案沿用作业页的开放时间。
一、py4 作业讲评
01 · 数列求和
知识点与 PPT: 第4章第4–6、8、10页:函数、参数、返回值和局部变量;第3章第14–17页:循环;第2章第36–38页:格式化。
提交中出现的错误与定位
实际 WA:输出没有保留六位小数
python
sumV = seriesSum(n)
print(sumV)定位与修改: sumV 已是计算结果,问题在显示格式。输入 2 时,直接输出为 0.5,要求为 0.500000。
python
print(f"{sumV:.6f}")正确处理步骤
先确定分母序列,初始化累加量;循环内累加倒数,循环结束后返回;主程序按六位小数输出。函数参数、循环变量和返回值各有用途,不把 print 当作 return。
边界推演: n=2:分母只有 2;n=3:分母为 1、3。range 的终点不包含在内,不能将 0 放进分母。
已通过提交中的方法对照
本次两份 AC 样本都按奇偶选择正序分母:一种先确定 start,再共用循环;另一种在两个分支中分别循环。现有参考答案从 n 倒序每次减 2,省去奇偶判断。三种方法覆盖同一组分母;浮点累加次序不同可能带来末位差异,最终按题目要求格式化。
完整参考解析
本题答案暂未公开
北京时间 2026/10/27 13:00:00 解锁
正在检查解锁状态…
正在载入加密答案…
02 · 删除子串
知识点与 PPT: 第2章第30、32、35页:字符串方法与拆分;第4章第5–8页:参数和返回值。
提交中出现的错误与定位
实际 WA:失败分支只打印,没有返回
python
def remove_part(text, target, mode):
if target not in text:
print("Fail to delete")
# 其他分支略定位与修改: 这是实际提交的失败分支,变量名已整理。主程序还会 print 函数调用结果;输入 abc x 0 时,函数先打印 Fail to delete,随后主程序又打印 None。失败分支也要返回字符串。
python
return "Fail to delete"实际 RE:同一行三项,被读成两项
python
a, b = input().split()
mode = int(input())定位与修改: 题目一行给出长串、短串、模式。输入 abc a 0 时,第一行拆出三项,不能解包到两个变量;模式也不在下一行。
python
a, b, mode = input().split()
mode = int(mode)正确处理步骤
三项一起读取,只转换模式;先判断子串是否存在,再区分删除一次和删除全部;返回新字符串。replace 的次数参数与题目模式不是同一个含义。全部删除按原串的不重叠匹配处理。
边界推演: banana 删除 a:一次为 bnana,全部为 bnn;aababa 删除 aba:全部删除仍应留下 aba;没有匹配时返回 Fail to delete。
已通过提交中的方法对照
AC 样本出现了“下标扫描并跳过整段匹配”和“find 加切片”两类。扫描法通过移动指针保留未删除部分。要特别注意:本次一份被判 AC 的 find 写法会在每次删除后从新串开头继续找;对 aababa 删除 aba,它会进一步删除新形成的 aba。这与题面规则不一致,不能仅凭 AC 就当作标准答案。参考答案采用 replace 处理原串的不重叠匹配。
完整参考解析
本题答案暂未公开
北京时间 2026/10/27 13:00:00 解锁
正在检查解锁状态…
正在载入加密答案…
03 · 机器猜数
知识点与 PPT: 第3章第14–17页:while、退出条件与循环状态;第2章第14–17页:整除运算;第5章第24–26页:math。
提交中出现的错误与定位
实际 WA:猜中就返回,漏记当前轮
python
count = 0
middle = 51
if target == middle:
return count定位与修改: 片段位于函数内。target 为 51 时直接返回 0,正确应为 1。计数应对应本轮实际进行的猜测,在相等退出之前加一。
python
count += 1
if target == middle:
return count实际 WA:提前把下一轮算进去
python
count = 1
# 已经猜过第一轮,下面处理猜大了的情况
if middle > target:
count += 1
right = middle - 1定位与修改: 片段省略了其他分支。更新后可能已经只剩一个候选数,此时不需要下一次猜测;提前加一会多算。目标 5 应为 6 次。
python
# 每轮先确认 left < right,再计算中点并计数。正确处理步骤
维护包含目标的左右端点;仍有多个候选数时,向上取整取中点并计数;比较后排除中点,或在猜中时退出。只剩一个数时直接结束。
边界推演: 目标 51 → 1 次,26 → 2 次,5 → 6 次。观察 5 的最后范围 [5,5]:确定答案不等于又猜了一次。
已通过提交中的方法对照
两份 AC 样本分别使用 math.ceil((left + right) / 2) 与 (left + right + 1) // 2。退出结构分别是 while True 内部检查端点相等,以及直接写 while left < right。两种结构都先排除单元素区间,再计算并统计本轮。
完整参考解析
本题答案暂未公开
北京时间 2026/10/27 13:00:00 解锁
正在检查解锁状态…
正在载入加密答案…
04 · 自动判题
知识点与 PPT: 第2章第19、30、32、35、46–47页:round、字符串拆分与类型转换;第3章第5–11页:多分支。
提交中出现的错误与定位
实际 WA:格式化字符串与浮点数比较
python
result = "3.00"
value = 1 + 2
print(f"{value:.2f}" == float(result))定位与修改: 这是实际比较表达式的独立演示。左侧是字符串 "3.00",右侧是数字 3.0,结果为 False。两边先统一为数字,再按题意舍入比较。
python
print(round(value, 2) == float(result))实际 RE:用整行判断运算符
python
line = "2*3=-6.00"
left, right = line.split("=")
if "-" in line:
a, b = left.split("-")定位与修改: 这是对原提交分支的等价缩写。等号右边的负号触发减法分支,但左边是乘法,无法拆出两个数。等式不成立本来应该输出 false,而不是报错。
python
if "-" in left:
a, b = left.split("-")正确处理步骤
先沿等号拆开左右,再只分析左侧运算符;将两个操作数和右侧结果转成数字,按四则运算计算;保留两位后比较,输出小写 true 或 false。
边界推演: 1/3=0.33 与 1-2=-1.00 都为 true;2*3=-6.00 为 false。用这三组分别检查舍入、负结果和无效等式。
已通过提交中的方法对照
本次两份 AC 样本属于同一类:遍历左侧字符串寻找运算符位置,再切片得到两个数字。已有参考提示按四种运算符分别检查并 split,也利用了左侧操作数非负的条件。AC 样本在舍入后又比较极小误差;课堂按题目统一精度即可,不把容差当作跳过 round 的理由。
完整参考解析
本题答案暂未公开
北京时间 2026/10/27 13:00:00 解锁
正在检查解锁状态…
正在载入加密答案…
05 · 凯撒密码
知识点与 PPT: 第2章第41–44页:字符对应与加密;第3章第5–11、14–17页:分支与循环;第4章第4–8页:函数调用和返回值。
提交中出现的错误与定位
实际 WA:已经拼出结果,却忘记返回
python
def collect(text):
result = ""
for ch in text:
result += ch
print(collect("abc"))定位与修改: 这是保留原错误结构的教学简化:实际提交完成了字符转换和拼接,但正常路径没有 return,主程序得到 None。应在整个字符循环结束后返回。
python
return result # 与 for 对齐,放在循环之后实际 RE:整数不能直接接到字符串后面
python
result = ""
new_num = 0
result += new_num定位与修改: 数字分支计算得到的是整数,字符串拼接前需要转换。0 是数字,"0" 才是字符文本。
python
result += str(new_num)实际 RE:打印模式错误后仍继续运行
python
if mode in encrypt_modes:
shift = key
elif mode in decrypt_modes:
shift = -key
else:
print("Wrong Mode")
# 后面仍使用 shift 处理消息定位与修改: 非法模式时没有定义 shift,打印提示不会自动终止程序。原提交后续处理字母时会访问未定义变量。把转换过程放进合法模式的分支,或在函数中返回错误信息。
python
return "Wrong Mode" # 此写法必须位于函数内部正确处理步骤
完整匹配模式,确定移动方向;逐字符判断大写、小写、数字或其他字符,分别按 26、26、10 循环;保留空格标点;循环结束返回完整结果。
边界推演: 密钥 1 时,z→a、Z→A、9→0;解密反向返回。非法模式配字母消息应只得到 Wrong Mode,空格和句号应保持原样。
已通过提交中的方法对照
AC 样本一类把单字符转换封装成函数,再循环拼接;另一类在循环中分类处理,先存入列表再 join。列表与 join 可作为补充。仍须复核边界:统一 lower 后匹配模式会额外接受 ENCRYPT 等题面未列出的模式;isupper/islower/isdigit 接受的范围也比 ASCII 字母数字更广,课堂优先明确范围判断。
完整参考解析
本题答案暂未公开
北京时间 2026/10/27 13:00:00 解锁
正在检查解锁状态…
正在载入加密答案…
二、课程作业:py作业5 模块与库
两道必做题,三道课后练习。 完整题目、老师给出的函数框架和逐步提示见 py作业5 网页。
提交: 必做题 1、2 的源代码和运行结果截图,提交到 教学网;截止 10 月 27 日(周二)中午 12:00。OJ 的 py作业4 同一天 13:00 截止,两个作业的提交位置与时间不同。
1. 必做:正方形螺旋线
从外往里画连续螺旋,最大边长由用户输入,必须是 100–400 的偶数;相邻正方形间距 2,竖边绿色、横边黄色。

PPT 第5章第10–16页。沿用老师的 main → initializeBrush → drawSquareHelix → recoverBrush 框架,需要补充 getMaxSide() 与 drawSquareHelix(length)。
- 起点为
(-length / 2, -length / 2),朝向为 90 度;移动到起点前先抬笔。 - 0、180 度是水平,90、270 度是垂直。每条边先根据
heading()设置颜色,再前进,再右转 90 度。 - 先追踪长度
L、L、L-2、L-2、L-4、L-4,理解如何持续向内收缩;不要画成多个闭合正方形。 - 边长变为 0 后停止,结束使用
t.done()保留窗口。
2. 必做:随机发红包
PPT 第5章第27–28页。总金额、红包数只输入一次,用相同参数模拟 10 次;每次返回一个列表,保证 数量正确、每份至少 1 元、总额不变。
老师给出的方法 1 逐个随机发金额,给后面每份预留 1 元;方法 2 先生成随机权重,再按占比分配,需要补全。
| 情形 | 先检查什么 |
|---|---|
| 10 元分给 3 人 | 先各预留 1 元,再按权重分配剩下的 7 元 |
| 3 元分给 3 人 | 只能是 [1, 1, 1],没有金额变化是正常的 |
| 2 元分给 3 人 | 无法满足每份至少 1 元,应提示输入不合法 |
| 10 元分给 1 人 | 唯一一份就是 10 元 |
取整后把余款留给最后一份;不要让各份独立随机后总和超过总额,也不要每轮重新输入。append() 修改列表而不返回新列表,函数最后要 return 整个结果。
3. 课后练习
| 练习 | 核心问题 |
|---|---|
| 自动出题并判分 | 10 道题,包含除法和乘方;答对题数与总得分分开统计,特定题型答对得 2 分 |
| 同心圆 | drawMCircle(radius, dist, num);每个圆的起笔位置、方向要保证圆心相同 |
| 随机多边形装饰画 | 随机边数、边长、颜色与位置;每次转外角 360 / 边数,配合填充 |