目录

  • 简介
  • 目标读者与学习目标
  • 先决条件
  • 环境安装(Windows / macOS / Linux)
  • 快速开始:运行示例程序(完整代码)
  • 代码详解(逐行说明)
  • 交互增强与输入校验(改进版本)
  • 单元测试与自动化测试
  • 部署与发布建议
  • 常见问题(FAQ)与故障排查
  • 进阶扩展方向与学习路线
  • 附录:完整代码清单(多个版本)

简介

本教程演示如何使用 Python 编写一个简单的学生成绩计算程序。程序功能包括接收若干科目的分数,计算总分、平均分并给出字母等级(A/B/C/D/F)。本文不仅提供基础实现,还讲解如何进行输入校验、如何将程序改造成模块、如何编写测试以及如何部署与扩展。


目标读者与学习目标

  • 目标读者:Python 初学者、想练习小型命令行程序的开发者、需要将成绩计算集成到其他系统的工程师。
  • 学习目标:
    • 理解如何从用户接收输入并处理数值数据。
    • 掌握函数设计、返回值与可复用性。
    • 学会基本的输入校验与异常处理。
    • 掌握如何编写单元测试并做简单部署。

先决条件

  • 基本的 Python 语法(变量、函数、条件判断、循环)。
  • 能在终端/命令行运行程序。

环境安装(一步步)

下面给出在各主流平台上安装 Python 的详细步骤,并说明如何验证安装成功。

Windows

  1. 打开浏览器,访问 Python 官方下载页: https://www.python.org/downloads/
  2. 点击“Download Python X.Y.Z”(推荐下载最新稳定版,例如 3.11 或 3.12)。
  3. 下载完成后,运行安装程序。
    • 重要:在安装界面勾选 “Add Python X.Y to PATH” 选项,然后点击 “Install Now”。
  4. 安装完成后,打开“命令提示符”(Win + R,输入 cmd 回车)。
  5. 输入命令验证安装:
    python --version
    
    你应该看到类似 Python 3.11.4 的输出。

macOS

  1. macOS 通常自带系统 Python(可能是旧版),建议安装最新版。
  2. 推荐使用 Homebrew(若未安装 Homebrew,请先访问 https://brew.sh/ 并按提示安装)。
  3. 使用 Homebrew 安装 Python:
    brew install python
    
  4. 验证:
    python3 --version
    
    输出应为 Python 3.x.x

Linux(以 Ubuntu 为例)

  1. 更新软件源并安装 Python:
    sudo apt update
    sudo apt install python3 python3-pip -y
    
  2. 验证:
    python3 --version
    

建议的开发工具

  • 简单:IDLE(随 Python 自带)
  • 推荐:VS Code(安装 Python 扩展)、PyCharm(社区版)
  • 在命令行运行脚本,或使用编辑器直接运行。

快速开始:示例程序(可直接运行)

下面给出一个最简洁的实现。复制为 grades.py,在终端运行 python grades.py(或 python3 grades.py)。

# grades.py - 简单版
def calculate_grade(scores):
    """
    输入: scores - 可迭代的数字序列(例如 list 或 tuple)
    返回: total, average, grade
    """
    total = sum(scores)
    average = total / len(scores) if len(scores) > 0 else 0

    if average >= 90:
        grade = 'A'
    elif average >= 80:
        grade = 'B'
    elif average >= 70:
        grade = 'C'
    elif average >= 60:
        grade = 'D'
    else:
        grade = 'F'

    return total, average, grade


def main():
    print("\n============= 计算学生成绩 =============\n")
    try:
        s1 = int(input("输入科目 1 成绩 (0-100): "))
        s2 = int(input("输入科目 2 成绩 (0-100): "))
        s3 = int(input("输入科目 3 成绩 (0-100): "))
        s4 = int(input("输入科目 4 成绩 (0-100): "))
        s5 = int(input("输入科目 5 成绩 (0-100): "))
    except ValueError:
        print("输入无效,请输入整数分数(0-100)。")
        return

    scores = [s1, s2, s3, s4, s5]
    total, average, grade = calculate_grade(scores)

    print("\n")
    print(f"总分:{total}")
    print(f"平均分:{average:.2f}")
    print(f"成绩等级:{grade}")


if __name__ == "__main__":
    main()

运行方式(在终端):

python grades.py
# 或
python3 grades.py

代码详解(逐行与设计说明)

  • calculate_grade(scores)

    • 功能:接收一个包含分数的可迭代对象,返回总分、平均分和等级。
    • 为什么单独成函数:利于测试与重用,可替换分数数量或评分规则。
  • 主函数 main()

    • 通过 input() 获取 5 科分数并转换为 int。
    • 使用 try/except 捕获非整数输入,防止程序崩溃。
    • 将列表传入 calculate_grade 并输出格式化结果。

评分规则:

  • 平均 >= 90 → A
  • 平均 >= 80 → B
  • 平均 >= 70 → C
  • 平均 >= 60 → D
  • 其他 → F

设计考虑:

  • 简洁易懂,适合教学。
  • 未对分数范围做严格校验(后面改进版本将补上)。

交互增强与输入校验(改进版)

下面给出更健壮的实现,支持任意数量科目、强校验、允许重复运行并能处理异常输入。

# grades_improved.py - 改进版
def calculate_grade(scores):
    if not scores:
        return 0, 0.0, 'N/A'
    total = sum(scores)
    average = total / len(scores)

    if average >= 90:
        grade = 'A'
    elif average >= 80:
        grade = 'B'
    elif average >= 70:
        grade = 'C'
    elif average >= 60:
        grade = 'D'
    else:
        grade = 'F'
    return total, average, grade


def input_score(prompt):
    while True:
        val = input(prompt)
        if val.strip() == "":
            print("输入不能为空,请输入 0-100 之间的整数。")
            continue
        try:
            n = int(val)
            if 0 <= n <= 100:
                return n
            else:
                print("分数应为 0-100 之间的整数。")
        except ValueError:
            print("输入无效,请输入整数。")


def main():
    print("\n============= 改进版:计算学生成绩 =============\n")
    num_subjects = 5
    print(f"请输入 {num_subjects} 门科目的成绩(0-100):")
    scores = []
    for i in range(1, num_subjects + 1):
        s = input_score(f"科目 {i} 成绩: ")
        scores.append(s)

    total, average, grade = calculate_grade(scores)
    print("\n")
    print(f"总分:{total}")
    print(f"平均分:{average:.2f}")
    print(f"成绩等级:{grade}")

    while True:
        opt = input("\n您想再试一次吗?(yes/no):").strip().lower()
        if opt in ('yes', 'y'):
            main()
            return
        elif opt in ('no', 'n'):
            print("退出程序……")
            return
        else:
            print("请输入 'yes' 或 'no'。")


if __name__ == "__main__":
    main()

改进点说明:

  • input_score:循环提示并校验输入是否为 0-100 的整数。
  • 支持任意科目数量(通过更改 num_subjects)。
  • 主动处理空输入、非法字符、超出范围数值。

单元测试与自动化测试

良好的工程实践要求为函数编写测试。下面示例使用 Python 的内置 unittest 编写对于 calculate_grade 的测试。

创建 test_grades.py

# test_grades.py
import unittest
from grades import calculate_grade  # 若是 grades_improved.py,请相应修改导入

class TestCalculateGrade(unittest.TestCase):
    def test_empty(self):
        total, avg, grade = calculate_grade([])
        self.assertEqual(total, 0)
        self.assertEqual(avg, 0.0)
        self.assertEqual(grade, 'N/A')

    def test_all_high(self):
        total, avg, grade = calculate_grade([95, 92, 90])
        self.assertEqual(grade, 'A')

    def test_boundaries(self):
        _, avg1, g1 = calculate_grade([90])
        _, avg2, g2 = calculate_grade([80])
        _, avg3, g3 = calculate_grade([70])
        _, avg4, g4 = calculate_grade([60])
        self.assertEqual(g1, 'A')
        self.assertEqual(g2, 'B')
        self.assertEqual(g3, 'C')
        self.assertEqual(g4, 'D')

if __name__ == "__main__":
    unittest.main()

运行测试:

python -m unittest test_grades.py
# 或
pytest test_grades.py  # 如果安装 pytest

部署与发布建议

该程序为命令行工具,可直接分发 Python 源文件。若需要在更广范围部署或集成,可参考下列方法:

  • 打包为可执行文件:

    • 使用 PyInstaller:pip install pyinstaller,然后:
      pyinstaller --onefile grades.py
      
      dist/ 中会生成平台相关的可执行文件。
  • 做为模块供其他程序调用:

    • 将核心逻辑封装在 calculate_grade 函数中,打包为 Python 包(使用 setup.py / pyproject.toml)。
  • Web / GUI 集成:

    • 简单 Web:使用 Flask 或 FastAPI 提供 HTTP 接口,前端用简单表单提交分数并返回结果。
    • GUI:使用 Tkinter(跨平台)、PyQt 或 Kivy 构建桌面应用。

示例:用 Flask 包装的最小后端

# app.py
from flask import Flask, request, jsonify
from grades import calculate_grade

app = Flask(__name__)

@app.route('/grade', methods=['POST'])
def grade_endpoint():
    data = request.json
    scores = data.get('scores', [])
    total, average, grade = calculate_grade(scores)
    return jsonify({'total': total, 'average': average, 'grade': grade})

if __name__ == '__main__':
    app.run(debug=True)

运行:

pip install flask
python app.py
# POST JSON 示例:
# {"scores": [90, 80, 70, 60, 100]}

常见问题(FAQ)与故障排查

  • 问:输入小数分数怎么办?

    • 答:当前实现期望整数。若需支持小数,将 int() 改为 float() 并相应校验范围(0.0-100.0)。
  • 问:如何处理缺考或无效成绩(例如“ABS”)?

    • 答:可以将缺考表示为 None 或特殊值,在函数中忽略或按业务规则处理(如平均分按实际出勤科目计算或计为 0)。
  • 问:如何改变评分规则?

    • 答:将 calculate_grade 中的 if/elif 阶梯替换为你需要的规则,或通过参数传入阈值字典,实现可配置化。
  • 问:程序卡住或抛出异常怎么办?

    • 答:检查输入是否合法,确保在命令行中输入后按回车;使用 try/except 包裹输入转换防止 ValueError。

进阶扩展方向与持续学习建议

  • 将成绩统计扩展为班级统计:最高分、最低分、中位数、标准差(使用 statistics 模块)。
  • 支持 CSV 输入/输出:读取学生名单与成绩并批量处理(使用 csv 或 pandas)。
  • 数据持久化:将结果保存到 SQLite 或其它数据库(sqlite3、SQLAlchemy)。
  • Web 前端:学习 Flask/ FastAPI + 前端框架(Vue/React)构建完整应用。
  • 部署:学习容器化(Docker),持续集成(CI)、自动化测试。
  • 学习资源:Python 官方文档、Real Python、Automate the Boring Stuff、深入学习 pytest、Flask/Tutorial、FastAPI 文档。

附录:完整代码清单(最终版示例,含 CLI、校验、日志)

# grades_full.py
import logging

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

def calculate_grade(scores):
    if not scores:
        return 0, 0.0, 'N/A'
    total = sum(scores)
    average = total / len(scores)
    if average >= 90:
        grade = 'A'
    elif average >= 80:
        grade = 'B'
    elif average >= 70:
        grade = 'C'
    elif average >= 60:
        grade = 'D'
    else:
        grade = 'F'
    logging.info("Calculated total=%s average=%.2f grade=%s", total, average, grade)
    return total, average, grade

def input_score(prompt):
    while True:
        val = input(prompt).strip()
        if val == "":
            print("输入不能为空。")
            continue
        try:
            n = float(val)
            if n.is_integer():
                n = int(n)
            if 0 <= n <= 100:
                return n
            else:
                print("分数请限定在 0 到 100。")
        except ValueError:
            print("请输入数字。")

def cli_run():
    print("\n============= 成绩计算器 =============\n")
    while True:
        try:
            num = int(input("请输入需要输入的科目数量(回车默认 5):") or 5)
            if num <= 0:
                print("请至少输入 1 门科目。")
                continue
            break
        except ValueError:
            print("请输入正整数。")

    scores = []
    for i in range(1, num + 1):
        s = input_score(f"科目 {i} 成绩: ")
        scores.append(s)

    total, avg, grade = calculate_grade(scores)
    print("\n结果:")
    print(f"总分:{total}")
    print(f"平均分:{avg:.2f}")
    print(f"等级:{grade}")

    opt = input("\n是否继续?(yes/no): ").strip().lower()
    if opt in ('yes', 'y'):
        cli_run()
    else:
        print("退出。")

if __name__ == "__main__":
    cli_run()

最后建议(面向读者的话)

  • 对初学者:从示例开始,逐行运行、修改并观察结果。把简单功能模块化(如 calculate_grade),再为其编写测试。
  • 对有经验的开发者:把该功能作为小服务封装,加入输入校验、日志、异常处理、测试与 CI/CD 流程;考虑安全与国际化(如不同评分体系、多语言提示)。
  • 持续学习:把小项目扩展为更复杂的系统(批量处理、数据库、Web 服务),并学习测试驱动开发(TDD)与良好的工程化实践。
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐