Python · Day 15

阶段综合:
可输入的成绩分析器

第十五天,我没有继续增加大量新语法,而是把输入、条件判断、循环、列表、函数和字典组合起来,完成目前最长的一份 Python 程序。

只收集三个有效成绩

程序先创建空列表,再用 while len(student_scores) < 3 检查已经保存了几个有效成绩。输入超出 0~100 时,只显示错误提示,不会加入列表,也不会占用三个名额。

day15.py
student_scores = []                              # 创建空成绩列表
while len(student_scores) < 3:                   # 不足三个有效成绩时继续
    score = int(input("请输入成绩: "))          # 输入并转换为整数
    if score < 0 or score > 100:               # 检查有效范围
        print("请输入0-100之间的成绩")          # 无效成绩不加入列表
    else:                                         # 成绩有效时
        student_scores.append(score)              # 保存当前成绩
        print("已录入成绩:", score)              # 显示成功结果

第一次测试使用三个正常成绩,随后专门输入 120、130 和 -5 验证边界保护。无效数字都被拦截,循环仍会继续等待三个有效成绩。

把录入过程封装成函数

完成基础测试后,录入过程被放进 input_scores(count)。调用处传入 3,形参 count 决定需要收集几个有效成绩;函数内部的 scores 收集完成后通过 return 送回主程序。

day15.py
def input_scores(count):                         # count接收需要录入的数量
    scores = []                                    # 函数内部的成绩列表
    while len(scores) < count:                     # 有效成绩不足时继续
        score = int(input("请输入成绩: "))        # 获取一个整数成绩
        if score < 0 or score > 100:             # 判断输入范围
            print("请输入0-100之间的成绩")        # 无效时只提示
        else:                                       # 有效时加入列表
            scores.append(score)                    # 列表长度增加1
            print("已录入成绩:", score)            # 显示成功录入
    return scores                                  # 循环完成后返回整个列表

student_scores = input_scores(3)                   # 接住函数返回的列表

函数内部叫 scores,外部叫 student_scores,名字不同并不妨碍传递数据:关键是 return scores 产生返回值,再由左侧变量接住。

让多个函数分析同一份列表

录入完成后,成绩列表继续交给总分、平均分、等级和最高分函数。平均分函数内部会再次调用总分函数,因此需要同时追踪直接调用和间接调用。

day15.py
def calculate_total(scores):                    # 接收成绩列表
    total = 0                                      # 总分从0开始
    for score in scores:                         # 逐项处理成绩
        total = total + score                      # 累加当前成绩
    return total                                 # 返回最终总分

def calculate_average(scores):                  # 定义平均分函数
    if len(scores) == 0:                         # 保护空列表
        return 0                                  # 避免除以0
    else:                                        # 列表不为空时
        total = calculate_total(scores)             # 调用总分函数
        average = total / len(scores)               # 计算浮点数平均分
        return average                           # 返回平均分

在阶段练习中,我已经能根据终端结果说出变量保存的具体值,而不只说“这是总分”或“这是列表”。例如列表 [44, 55, 66] 对应总分 165 和平均分 55.0

由总管函数生成字典报告

最后,create_report() 依次调用四个分析函数,将结果放进字典。主程序只负责录入、请求报告和按键输出,不再分别管理每一次计算。

day15.py
def create_report(scores):                        # 定义总管函数
    total = calculate_total(scores)                 # 得到总分
    average = calculate_average(scores)             # 得到平均分
    level = get_level(average)                      # 根据平均分得到等级
    highest = find_highest_score(scores)            # 得到最高分
    report = {"total": total, "average": average,
              "level": level, "highest": highest} # 组成字典
    return report                                 # 返回完整报告

student_scores = input_scores(3)                    # 先录入有效成绩
final_report = create_report(student_scores)         # 再生成分析报告
print("总分:", final_report["total"])             # 按键读取总分
print("平均分:", final_report["average"])         # 按键读取平均分
print("成绩等级:", final_report["level"])         # 按键读取等级
print("最高分:", final_report["highest"])         # 按键读取最高分

最终测试先输入 -5,再输入 80、70、60。无效成绩被拦截,最后正确输出列表 [80, 70, 60]、总分 210、平均分 70.0、等级“及格”和最高分 80。

用流程图梳理六十行程序

程序增长到约六十行后,我发现一次阅读全部代码已经比较困难,因此开始用流程图只看主路线:

定义函数 → input_scores(3) 收集有效成绩 → student_scores 接住列表 → create_report() 调用四个分析函数 → final_report 接住字典 → 根据键输出结果。

函数定义像预先准备好的工具。程序开始时会依次执行 def 并记住这些函数,直到主程序真正调用它们时,函数体才开始工作。课后不需要背下全部代码,先沿着这条主路线逐层展开即可。

今天真正完成了什么

  • 使用 while 持续收集指定数量的有效成绩
  • 使用条件判断拦截小于 0 或大于 100 的输入
  • 让函数返回列表,并由外部变量接住结果
  • 把输入、列表、循环、条件和函数组合到同一程序
  • 让多个分析函数共同处理一份成绩列表
  • 使用总管函数返回包含四项结果的字典
  • 根据字典键输出总分、平均分、等级和最高分
  • 面对较长程序时,用流程图梳理主程序和函数调用路线

这是目前最长的一次练习。困难不再来自某一条陌生语法,而是来自很多熟悉知识同时出现。能够运行、测试并主动提出用流程图梳理,正是从单个知识点走向完整程序的一步。