CAICP-E · Python 编程基础
找东西和修 bug
从左到右找名字,读懂报错,补上一行。
这一节要学会什么
#what找书和改错别字
#hook书架上找一本数学书。一种办法:从左到右一本本看。 书如果按名字排好了,可以折半找。猜数字也一样:每次问中间那个。
程序写错了,也会留线索。红字报错像老师批改。 先看最后一行说了什么。再改一处。

如果觉得有点难 查找先从左边第一格问起。 调试先看报错最后一行说了什么。
如果已经会了 给顺序查找加上「找不到」的提示。 再故意写错一行,读报错改回来。 二分查找只仿用,不要自己发明 left、right、mid。
顺序查找:从左到右问
#explore-linear顺序查找:从左到右一本本问。架子乱放时,这个办法最老实。
先记下格子号。从 0 开始,看完一格加 1。
# 顺序查找:一个一个比
names = ["小明", "小红", "小派"]
target = "小红"
i = 0
found = False
while i < len(names):
if names[i] == target:
print("在第", i, "格")
found = True
break
i = i + 1
if not found:
print("没找到")找到就印格子号。用 break 可以提前停。
找不到就保持 False,再告诉你没找到。
也可以写成:
for i in range(len(names)):
if names[i] == target:
print("在第", i, "格")
break意思一样。都是从左边第一格走到右边。

列表不必先排序。这是最朴素的查找。
注释已经告诉你思路。仿用时,先读注释。
再把循环和 if 填完整。
enumerate:照着抄,不必发明
#explore-enum走过列表时,有时既要格子号,又要格子里的东西。主路仍是 i = 0 再 i = i + 1,
或者 for i in range(len(names))。
照着抄,不必发明 题目会把这一行写好。 你只要会填后面的
if和
shelf = ["语文", "数学", "英语"]
for i, book in enumerate(shelf):
print(i, book)会印出 0 语文、1 数学、2 英语。i 是编号,book 是这一格里的书。
这一段看见了会用就行。
折半猜数:想法先记住
#explore-binary老师心里想一个 1 到 16 的数。你每次猜正中间。
先猜 8。太大了,去左半边 1 到 7。 太小了,去右半边 9 到 16。范围越缩越小。
这就是二分查找的想法。前提:数字已经从小到大排好。 没排好时,不要折半,用顺序查找。
下面这段只用来仿用。不要自己发明 left、right、mid。
题目若出现,会把这一段写好。
# 仿用:先确认列表已排序。不要自己发明。
nums = [1, 3, 5, 7, 9]
target = 7
left = 0
right = len(nums) - 1
found = False
while left <= right:
mid = (left + right) // 2 # 中间位置
if nums[mid] == target:
found = True
break
elif nums[mid] < target:
left = mid + 1 # 去右半边
else:
right = mid - 1 # 去左半边
print(found)你只要能读注释,知道:
中间是 mid。比较后缩小范围。

猜数字时,别人会给你提示:太大了、太小了。程序里的 if,就是在听这个提示。
报错先看最后一行
#explore-error程序出错会说话。先看最后一行的错误名字。 再看它指出的行号。

先认准两种。
SyntaxError:语法错。句子还没写完。
常忘冒号、引号不成对、括号不成对。
print("你好)少了一个盖子。电脑看不懂这句话。
if score >= 60
print("及格")if 后面少了冒号。这也是语法错误。
NameError:名字还没定义。单词电脑不认识。
print(score)score 还没有赋值。电脑会说:这个名字我没见过。
缩进不对,常常是 IndentationError。它也和语法有关。
if 下面那一行必须缩进。
if score >= 60:
print("及格")第二行没有缩进,会报错。
读报错时,不要只看第一行英文。最后一行通常直接告诉你:错的类型叫什么。
一次只补一处
#explore-fix看这段残缺代码:
# 目标:打印 1 到 3
for n in range(1, 4)
print(n)缺了冒号。这是语法错误。
补上 : 就能跑。

再看哪一行错了:
print("你好)引号没盖严。先改这一处。 再跑。不要同时改十处。
顺序查找缺一行「找到就停」。最合适的常常是 break。
不是 continue,也不是 pass。
# 顺序查找 target 是否在 names 里
found = False
for n in names:
if n == target:
found = True
_____横线处填 break。
修 bug 的步骤可以记:
- 读最后一行报错
- 看它指出的行号
- 对照注释想「本来要做什么」
- 改一处,再试一次
语法错误:句子结构坏了。名字错误:某个词还没出现过。 先分清,再动手。
这节课我学会了
#review记住这些:
- 顺序查找:从左到右,
i = 0再i = i + 1,找到可以用break。 enumerate照着抄就行,题目会把这一行写好。- 二分查找:先排好序,每次看中间。只仿用,不要自己发明。
- 报错最后一行最重要。缺冒号、缺引号、名字没定义,都很常见。
- 一次只改一处。
算法负责想步骤。调试负责把步骤写对。
Python 主线先到这儿。会找,也会修,就可以自己写更多小工具了。
试一试
#evaluate看完就来检查一下。选错了也可以再想。
单选题
哪一行有语法错误
下面程序想打印 1 到 3。哪一行写错了?\n1 for n in range(1, 4)\n2 print(n)\n3 print(「结束」)
单选题
补全残缺代码
注释写着:顺序查找 target 是否在 names 里。残缺如下:\nfound = False\nfor n in names:\n if n == target:\n found = True\n _____\n应填哪一句最合适?
单选题
顺序查找找到谁
names = [「小明」, 「小红」, 「小派」]。i 从 0 开始,每次 i = i + 1,找「小红」。找到时 i 是?
多选题
查找和调试
下列说法正确的有哪些?可以多选。
可多选
未登录时不会保存学习进度