跳转至

代码实战项目2:学生成绩管理系统

项目概述

学生成绩管理系统是一个经典的管理信息系统项目,用于管理学生的基本信息和各科成绩。本系统将实现学生的增删改查、成绩统计、数据持久化等功能。

学习目标

  • 掌握面向对象编程的基本概念
  • 学会使用文件进行数据持久化
  • 理解数据结构在实际项目中的应用
  • 掌握用户界面设计的基本原则

功能需求

核心功能

  1. 学生信息管理
  2. 添加学生信息(学号、姓名、班级)
  3. 修改学生信息
  4. 删除学生信息
  5. 查询学生信息

  6. 成绩管理

  7. 录入学生成绩
  8. 修改学生成绩
  9. 删除学生成绩
  10. 查询学生成绩

  11. 统计功能

  12. 计算学生平均分
  13. 计算班级平均分
  14. 统计各科最高分和最低分
  15. 生成成绩排名

  16. 数据持久化

  17. 保存数据到文件
  18. 从文件加载数据

系统设计

数据结构设计

class Student:
    """学生类"""
    def __init__(self, student_id, name, class_name):
        self.student_id = student_id  # 学号
        self.name = name              # 姓名
        self.class_name = class_name  # 班级
        self.scores = {}              # 成绩字典 {科目: 分数}

class StudentManager:
    """学生管理类"""
    def __init__(self):
        self.students = {}  # 学生字典 {学号: Student对象}

文件结构

student_management/
├── main.py           # 主程序
├── student.py        # 学生类
├── manager.py        # 管理类
├── data.json         # 数据文件
└── README.md         # 说明文档

代码实现

1. 学生类(student.py)

class Student:
    """学生类"""

    def __init__(self, student_id, name, class_name):
        """
        初始化学生

        参数:
            student_id: 学号
            name: 姓名
            class_name: 班级
        """
        self.student_id = student_id
        self.name = name
        self.class_name = class_name
        self.scores = {}

    def add_score(self, subject, score):
        """
        添加成绩

        参数:
            subject: 科目
            score: 分数
        """
        if not 0 <= score <= 100:
            raise ValueError("成绩必须在0-100之间")
        self.scores[subject] = score

    def get_average(self):
        """计算平均分"""
        if not self.scores:
            return 0
        return sum(self.scores.values()) / len(self.scores)

    def get_total(self):
        """计算总分"""
        return sum(self.scores.values())

    def __str__(self):
        """字符串表示"""
        return f"学号: {self.student_id}, 姓名: {self.name}, 班级: {self.class_name}"

    def to_dict(self):
        """转换为字典"""
        return {
            'student_id': self.student_id,
            'name': self.name,
            'class_name': self.class_name,
            'scores': self.scores
        }

    @classmethod
    def from_dict(cls, data):
        """从字典创建对象"""
        student = cls(data['student_id'], data['name'], data['class_name'])
        student.scores = data.get('scores', {})
        return student

2. 管理类(manager.py)

import json
from student import Student

class StudentManager:
    """学生管理类"""

    def __init__(self):
        """初始化管理器"""
        self.students = {}

    def add_student(self, student_id, name, class_name):
        """
        添加学生

        参数:
            student_id: 学号
            name: 姓名
            class_name: 班级

        返回:
            bool: 添加成功返回True
        """
        if student_id in self.students:
            print(f"学号 {student_id} 已存在")
            return False

        student = Student(student_id, name, class_name)
        self.students[student_id] = student
        print(f"成功添加学生: {name}")
        return True

    def remove_student(self, student_id):
        """
        删除学生

        参数:
            student_id: 学号

        返回:
            bool: 删除成功返回True
        """
        if student_id not in self.students:
            print(f"学号 {student_id} 不存在")
            return False

        del self.students[student_id]
        print(f"成功删除学号 {student_id}")
        return True

    def update_student(self, student_id, name=None, class_name=None):
        """
        更新学生信息

        参数:
            student_id: 学号
            name: 新姓名(可选)
            class_name: 新班级(可选)
        """
        if student_id not in self.students:
            print(f"学号 {student_id} 不存在")
            return False

        student = self.students[student_id]
        if name:
            student.name = name
        if class_name:
            student.class_name = class_name

        print(f"成功更新学号 {student_id}")
        return True

    def add_score(self, student_id, subject, score):
        """
        添加成绩

        参数:
            student_id: 学号
            subject: 科目
            score: 分数
        """
        if student_id not in self.students:
            print(f"学号 {student_id} 不存在")
            return False

        try:
            self.students[student_id].add_score(subject, score)
            print(f"成功添加成绩: {subject} = {score}")
            return True
        except ValueError as e:
            print(f"错误: {e}")
            return False

    def query_student(self, student_id):
        """
        查询学生信息

        参数:
            student_id: 学号

        返回:
            Student: 学生对象
        """
        if student_id not in self.students:
            print(f"学号 {student_id} 不存在")
            return None
        return self.students[student_id]

    def list_all_students(self):
        """列出所有学生"""
        if not self.students:
            print("没有学生记录")
            return

        print("\n" + "="*60)
        print(f"{'学号':<10}{'姓名':<10}{'班级':<10}{'平均分':<10}")
        print("="*60)

        for student in self.students.values():
            avg = student.get_average()
            print(f"{student.student_id:<10}{student.name:<10}{student.class_name:<10}{avg:<10.2f}")

    def get_class_average(self, class_name, subject=None):
        """
        计算班级平均分

        参数:
            class_name: 班级名称
            subject: 科目(可选,不指定则计算所有科目)

        返回:
            float: 平均分
        """
        class_students = [s for s in self.students.values()
                         if s.class_name == class_name]

        if not class_students:
            return 0

        if subject:
            scores = [s.scores.get(subject, 0) for s in class_students
                     if subject in s.scores]
        else:
            scores = [s.get_average() for s in class_students]

        return sum(scores) / len(scores) if scores else 0

    def get_ranking(self, subject=None):
        """
        生成成绩排名

        参数:
            subject: 科目(可选)

        返回:
            list: 排名列表
        """
        students = list(self.students.values())

        if subject:
            # 按指定科目排名
            students_with_score = [(s, s.scores.get(subject, 0))
                                   for s in students if subject in s.scores]
            students_with_score.sort(key=lambda x: x[1], reverse=True)
            return students_with_score
        else:
            # 按平均分排名
            students.sort(key=lambda s: s.get_average(), reverse=True)
            return students

    def save_to_file(self, filename='data.json'):
        """
        保存数据到文件

        参数:
            filename: 文件名
        """
        data = {
            'students': [s.to_dict() for s in self.students.values()]
        }

        try:
            with open(filename, 'w', encoding='utf-8') as f:
                json.dump(data, f, ensure_ascii=False, indent=2)
            print(f"数据已保存到 {filename}")
        except Exception as e:
            print(f"保存失败: {e}")

    def load_from_file(self, filename='data.json'):
        """
        从文件加载数据

        参数:
            filename: 文件名
        """
        try:
            with open(filename, 'r', encoding='utf-8') as f:
                data = json.load(f)

            self.students = {
                s['student_id']: Student.from_dict(s)
                for s in data.get('students', [])
            }

            print(f"数据已从 {filename} 加载")
        except FileNotFoundError:
            print(f"文件 {filename} 不存在")
        except Exception as e:
            print(f"加载失败: {e}")

3. 主程序(main.py)

from manager import StudentManager

def display_menu():
    """显示菜单"""
    print("\n" + "="*50)
    print("学生成绩管理系统")
    print("="*50)
    print("1. 添加学生")
    print("2. 删除学生")
    print("3. 更新学生信息")
    print("4. 添加成绩")
    print("5. 查询学生")
    print("6. 列出所有学生")
    print("7. 班级平均分")
    print("8. 成绩排名")
    print("9. 保存数据")
    print("10. 加载数据")
    print("0. 退出")
    print("="*50)

def main():
    """主函数"""
    manager = StudentManager()

    while True:
        display_menu()
        choice = input("请选择操作: ").strip()

        if choice == '0':
            print("感谢使用,再见!")
            break

        elif choice == '1':
            # 添加学生
            student_id = input("学号: ").strip()
            name = input("姓名: ").strip()
            class_name = input("班级: ").strip()
            manager.add_student(student_id, name, class_name)

        elif choice == '2':
            # 删除学生
            student_id = input("学号: ").strip()
            manager.remove_student(student_id)

        elif choice == '3':
            # 更新学生信息
            student_id = input("学号: ").strip()
            name = input("新姓名(留空不修改): ").strip()
            class_name = input("新班级(留空不修改): ").strip()
            manager.update_student(student_id, name or None, class_name or None)

        elif choice == '4':
            # 添加成绩
            student_id = input("学号: ").strip()
            subject = input("科目: ").strip()
            try:
                score = float(input("分数: "))
                manager.add_score(student_id, subject, score)
            except ValueError:
                print("请输入有效的数字")

        elif choice == '5':
            # 查询学生
            student_id = input("学号: ").strip()
            student = manager.query_student(student_id)
            if student:
                print(f"\n{student}")
                print("成绩:")
                for subject, score in student.scores.items():
                    print(f"  {subject}: {score}")
                print(f"平均分: {student.get_average():.2f}")
                print(f"总分: {student.get_total()}")

        elif choice == '6':
            # 列出所有学生
            manager.list_all_students()

        elif choice == '7':
            # 班级平均分
            class_name = input("班级: ").strip()
            subject = input("科目(留空计算所有科目): ").strip() or None
            avg = manager.get_class_average(class_name, subject)
            print(f"班级 {class_name} 的平均分: {avg:.2f}")

        elif choice == '8':
            # 成绩排名
            subject = input("科目(留空按平均分排名): ").strip() or None
            ranking = manager.get_ranking(subject)

            print("\n" + "="*60)
            print(f"{'排名':<5}{'学号':<10}{'姓名':<10}{'班级':<10}{'分数':<10}")
            print("="*60)

            if subject:
                for rank, (student, score) in enumerate(ranking, 1):
                    print(f"{rank:<5}{student.student_id:<10}{student.name:<10}{student.class_name:<10}{score:<10.2f}")
            else:
                for rank, student in enumerate(ranking, 1):
                    avg = student.get_average()
                    print(f"{rank:<5}{student.student_id:<10}{student.name:<10}{student.class_name:<10}{avg:<10.2f}")

        elif choice == '9':
            # 保存数据
            filename = input("文件名(默认data.json): ").strip() or 'data.json'
            manager.save_to_file(filename)

        elif choice == '10':
            # 加载数据
            filename = input("文件名(默认data.json): ").strip() or 'data.json'
            manager.load_from_file(filename)

        else:
            print("无效的选择,请重新输入")

if __name__ == '__main__':
    main()

运行指南

1. 安装依赖

本项目只使用 Python 标准库,无需安装额外依赖。

2. 运行程序

python main.py

3. 使用说明

  1. 首先添加学生信息
  2. 为学生录入各科成绩
  3. 可以随时查询、修改、删除信息
  4. 使用统计功能分析成绩
  5. 定期保存数据

扩展功能建议

基础扩展

  1. 批量导入/导出
  2. 支持 CSV 格式的批量导入
  3. 支持导出为 Excel 格式

  4. 数据验证

  5. 学号格式验证
  6. 成绩范围验证
  7. 必填项检查

  8. 高级查询

  9. 按姓名模糊查询
  10. 按班级查询
  11. 按成绩范围查询

进阶扩展

  1. 图表可视化
  2. 成绩分布图
  3. 班级对比图
  4. 趋势分析图

  5. 多科目管理

  6. 支持不同科目的权重设置
  7. 支持选修课和必修课区分
  8. 支持学分计算

  9. 用户权限

  10. 管理员权限
  11. 教师权限
  12. 学生权限

高级扩展

  1. 数据库支持
  2. 使用 SQLite 或 MySQL 存储数据
  3. 支持多用户并发访问

  4. Web 界面

  5. 使用 Flask/Django 开发 Web 版
  6. 支持在线访问

常见问题

Q: 数据保存在哪里?

A: 默认保存在程序目录下的 data.json 文件中。你可以在保存时指定其他文件名。

Q: 如何备份我的数据?

A: 直接复制 data.json 文件即可。建议定期备份。

Q: 成绩可以是负数吗?

A: 不可以,成绩必须在 0-100 之间。系统会自动验证。

Q: 如何删除所有数据?

A: 删除 data.json 文件或选择退出时不保存。

项目总结

本项目实现了一个功能完整的学生成绩管理系统,涵盖了:

  1. 面向对象设计:使用类和对象来组织代码
  2. 数据持久化:使用 JSON 文件保存数据
  3. 用户交互:提供友好的命令行界面
  4. 数据统计:实现多种统计分析功能

通过本项目,你将掌握: - Python 面向对象编程 - 文件操作和数据序列化 - 程序设计和模块化 - 用户体验设计

下一步

尝试添加更多功能,如: - 图表可视化(使用 matplotlib) - Web 界面(使用 Flask) - 数据库支持(使用 SQLite) - 单元测试


祝学习愉快!