第5讲 · 逻辑与循环 · 15分钟

第5讲 逻辑与循环

从执行路径理解顺序、分支与循环,再用真实运行结果验证规则。

1今天的任务:让学习打卡助手会判断、能重复
2先判断一次打卡,再处理多次打卡
3学习方法:预测 → 追踪 → 运行验证
知识点精讲随堂快练本讲练习

三种控制结构:用流程图看路径

知识路线

1顺序:读取时长 → 计算结果 → 显示结果
2分支:时长达到60分钟?是 → 表扬;否 → 鼓励
3循环:还有打卡?是 → 处理 → 返回判断;否 → 结束

语法拆解

矩形
表示处理步骤,例如读取时长、累计总时长
菱形
表示条件判断,沿是或否选择路径
箭头
表示执行方向;回到判断处的箭头体现循环

看图时沿箭头走:先找入口,再找条件和出口。

单分支 if:达到目标才提醒

checkin_if.py
minutes = 75
if minutes >= 60:
    print("目标达成")
print("打卡结束")
if 条件:
条件为真时,执行下面的缩进代码块
四个空格
缩进划定分支范围;冒号不能遗漏
恢复顶格
离开分支,无论条件真假都继续执行

知识点 01

1学习目标:每天至少60分钟
2minutes=75时,先输出目标达成,再输出打卡结束
3改为45时,跳过表扬,仍然输出打卡结束

单分支只处理条件成立的情况。

问题来了:没达标怎么办?if / else

checkin_if_else.py
minutes = 45
if minutes >= 60:
    print("目标达成")
else:
    print("继续加油")
if 条件: ... else: ...
条件成立走if,否则走else
else:
不再写条件,与if保持同层缩进

知识点 02

1达到60分钟:目标达成
2不足60分钟:继续加油
3两条路径互斥,一次判断只执行其中一条

运行后把45改成60,观察边界是否进入达标路径。

是否还能优化:if / elif / else 分三档

checkin_elif.py
minutes = 95
if minutes >= 90:
    print("超额完成")
elif minutes >= 60:
    print("目标达成")
else:
    print("继续加油")
if ... elif ... else ...
从上到下检查,只执行第一条命中的路径
elif 条件:
前面的条件均不成立时,才检查这一条
else:
前面的条件均不成立时,执行兜底路径

知识点 03

190分钟及以上:超额完成
260分钟及以上、不到90分钟:目标达成
3不足60分钟:继续加油

先判断>=90,再判断>=60,三档才能分别到达。

条件顺序、比较与短路

checkin_short_circuit.py
count = 0
total = 0
if count > 0 and total / count >= 60:
    print("平均时长达标")
else:
    print("暂无达标统计")
= 与 ==
前者赋值;后者比较。>=、<=、!=也产生布尔结果
A and B / A or B
and要求都成立;or要求至少一个成立
短路
and左侧为假、or左侧为真时,都不再计算右侧

知识点 04

1多分支先放严格条件;多个独立if则可能同时执行
2not反转条件;0和空字符串为假,非零数和非空字符串为真
3先检查count不为0,再计算平均时长,防止除零

分档边界用59、60、89、90检查;组合条件先读左侧。

快练1:95分钟为何只显示达标?

branch_order.py
minutes = 95
if minutes >= 60:
    print("目标达成")
elif minutes >= 90:
    print("超额完成")
else:
    print("继续加油")

快速练习

1先预测原程序的完整输出
2解释超额完成分支为什么没有执行
3只调整条件顺序,让三档都能到达

先独立思考片刻,再展开参考答案。

参考答案点击展开
minutes = 95
if minutes >= 90:
    print("超额完成")
elif minutes >= 60:
    print("目标达成")
else:
    print("继续加油")

原程序输出目标达成:95先命中>=60,整条分支链随即结束。

把>=90放在>=60前面,修复后输出超额完成。

用59、60、89、90测试边界,确认三条路径都能到达。

for:让学习打卡按次重复

checkin_for.py
for day in range(1, 4):
    print("第", day, "天:记得学习打卡")
print("提醒完成")
for day in range(1, 4):
每轮依次取一个整数,赋给day,再执行循环体
range(start, stop, step)
start为起点,stop不包含,step为步长且不能为0
range(3)
从0开始,默认步长1,依次取0、1、2

知识点 05

1知道重复次数时,优先使用for
2range(1, 4)依次取1、2、3,共执行3轮
3循环变量自动取下一个值,不需要手动加1

缩进中的提醒会重复;恢复顶格后的完成提示只执行一次。

快练2:range怎样输出倒计时?

range_practice.py
for remaining in range(10, 1, -2):
    print(remaining)

快速练习

1学习打卡倒计时:10、8、6、4、2
2先确定起点10、步长-2
3停止边界怎样写,才能保留最后的2?

先口答并写下预测;运行后把stop改成2,验证差异。

参考答案点击展开
for remaining in range(10, 1, -2):
    print(remaining)

start=10,step=-2,stop=1且不包含,因此2仍能进入序列。

stop也可写0;若写2,则2被排除,只输出到4。

负步长向下走,起点需要高于停止边界,才会产生轮次。

while:学到目标才结束

checkin_while.py
total = 0
while total < 60:
    total += 20
    print("累计分钟:", total)
print("今日目标达成")
while 条件:
每轮开始前重新判断,条件为真就继续
初始化 → 判断 → 执行 → 更新
四个环节共同保证循环能到达出口

知识点 06

1模拟每轮学习20分钟,累计到60分钟停止
2total依次变为20、40、60;下一次判断为假
3漏掉更新,或者更新方向错误,都可能导致死循环

排查while:初值是什么?条件依赖谁?哪一行推动它接近出口?

循环扩展:else与嵌套

checkin_extension.py
for day in range(1, 3):
    for session in range(1, 3):
        print("第", day, "天,第", session, "轮")
else:
    print("两天计划完成")
for / while ... else ...
循环自然结束时执行else;该循环自身被break终止时不执行
嵌套循环
外层执行一轮,内层完整执行一遍

拓展认识

1循环else与循环同层缩进,不是if的else
2两天、每天两轮学习:外层2轮 × 内层2轮 = 4次
3先会辨认路径;复杂嵌套不作为本讲练习重点

先观察正常结束;下一页解释break怎样让循环提前终止。

break、continue、pass:下一步去哪?

checkin_control.py
for day in range(1, 5):
    if day == 2:
        continue
    if day == 4:
        break
    if day == 3:
        pass
    print("完成打卡:", day)
break
立即离开当前最内层循环,取消后续轮次
continue
跳过本轮剩余语句,进入下一轮判断或取值
pass
什么也不做,仅用于语法占位,后续语句照常执行

知识点 07

1第2天跳过;第4天停止;第3天pass后仍然打印
2嵌套循环中的break只退出它所在的最内层
3while中的continue不能跳过必要的状态更新

区分作用范围:结束整个当前循环、结束当前一轮、原地不做事。

快练3:逐轮追踪打卡输出

jump_trace.py
for day in range(1, 8):
    if day % 2 == 0:
        continue
    if day == 5:
        break
    print(day)

快速练习

1写出完整输出,不只报最后一个数
2标出哪些天被continue跳过
3指出哪一天触发break,后面还有轮次吗?

先逐轮检查day=1、2、3、4、5,再运行核对。

参考答案点击展开
# 完整输出
1
3

第2、4天命中continue,不再执行本轮后续判断与打印。

第5天不是偶数,继续检查后命中break,立即结束循环。

第6、7天不再进入;完整输出只有1和3。

综合练习:学习打卡助手

study_checkin.py
# 学习打卡助手:先搭入口和出口,再添加统计
count = 0
total = 0
deep_days = 0

# TODO:while True读取raw = input()
# TODO:raw等于q时break,否则转为整数minutes
# TODO:不在1到240之间时提示无效时长,并continue
# TODO:累计有效天数与总时长;>=60时累计深度学习天数
# TODO:count大于0时输出统计和平均时长,否则提示没有有效打卡

独立练习

1每行输入一天的学习分钟数;输入q结束
2有效范围1~240;无效时长提示后continue,不参与统计
3累计有效天数、总时长;至少60分钟记为一个深度学习日
4有有效记录才计算平均时长;没有记录则单独提示

约定:除q外输入均为整数文本。测试输入依次为45、75、300、60、q;可暂停完成。

参考实现与四问总结

study_checkin.py
count = 0
total = 0
deep_days = 0

while True:
    raw = input()
    if raw == "q":
        break
    minutes = int(raw)
    if minutes < 1 or minutes > 240:
        print("无效时长:请输入1到240分钟")
        continue
    count += 1
    total += minutes
    if minutes >= 60:
        deep_days += 1

if count > 0:
    print("有效天数:", count)
    print("总时长:", total)
    print("平均时长:", total / count)
    print("深度学习天数:", deep_days)
else:
    print("没有有效打卡")

练习讲评

1入口是什么?初始化统计变量,进入while True读取输入
2路径怎样选?q退出;无效值跳过;有效值才累计
3状态怎样更新?天数加1、时长累加,达60分钟增加深度学习天数
4出口在哪?break结束读取;count>0保护平均值计算

核对:300无效;有效3天,总时长180分钟,平均60.0分钟,深度学习2天。下一讲:列表,把多天记录保存起来。

课堂 Python 解释器
点击“逐步运行”后,这里会显示结果。
Python:按执行步骤显示结果。