代码实战项目2:学生成绩管理系统¶
项目概述¶
学生成绩管理系统是一个经典的管理信息系统项目,用于管理学生的基本信息和各科成绩。本系统将实现学生的增删改查、成绩统计、数据持久化等功能。
学习目标¶
- 掌握面向对象编程的基本概念
- 学会使用文件进行数据持久化
- 理解数据结构在实际项目中的应用
- 掌握用户界面设计的基本原则
功能需求¶
核心功能¶
- 学生信息管理
- 添加学生信息(学号、姓名、班级)
- 修改学生信息
- 删除学生信息
-
查询学生信息
-
成绩管理
- 录入学生成绩
- 修改学生成绩
- 删除学生成绩
-
查询学生成绩
-
统计功能
- 计算学生平均分
- 计算班级平均分
- 统计各科最高分和最低分
-
生成成绩排名
-
数据持久化
- 保存数据到文件
- 从文件加载数据
系统设计¶
数据结构设计¶
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. 运行程序¶
3. 使用说明¶
- 首先添加学生信息
- 为学生录入各科成绩
- 可以随时查询、修改、删除信息
- 使用统计功能分析成绩
- 定期保存数据
扩展功能建议¶
基础扩展¶
- 批量导入/导出
- 支持 CSV 格式的批量导入
-
支持导出为 Excel 格式
-
数据验证
- 学号格式验证
- 成绩范围验证
-
必填项检查
-
高级查询
- 按姓名模糊查询
- 按班级查询
- 按成绩范围查询
进阶扩展¶
- 图表可视化
- 成绩分布图
- 班级对比图
-
趋势分析图
-
多科目管理
- 支持不同科目的权重设置
- 支持选修课和必修课区分
-
支持学分计算
-
用户权限
- 管理员权限
- 教师权限
- 学生权限
高级扩展¶
- 数据库支持
- 使用 SQLite 或 MySQL 存储数据
-
支持多用户并发访问
-
Web 界面
- 使用 Flask/Django 开发 Web 版
- 支持在线访问
常见问题¶
Q: 数据保存在哪里?¶
A: 默认保存在程序目录下的 data.json 文件中。你可以在保存时指定其他文件名。
Q: 如何备份我的数据?¶
A: 直接复制 data.json 文件即可。建议定期备份。
Q: 成绩可以是负数吗?¶
A: 不可以,成绩必须在 0-100 之间。系统会自动验证。
Q: 如何删除所有数据?¶
A: 删除 data.json 文件或选择退出时不保存。
项目总结¶
本项目实现了一个功能完整的学生成绩管理系统,涵盖了:
- 面向对象设计:使用类和对象来组织代码
- 数据持久化:使用 JSON 文件保存数据
- 用户交互:提供友好的命令行界面
- 数据统计:实现多种统计分析功能
通过本项目,你将掌握: - Python 面向对象编程 - 文件操作和数据序列化 - 程序设计和模块化 - 用户体验设计
下一步¶
尝试添加更多功能,如: - 图表可视化(使用 matplotlib) - Web 界面(使用 Flask) - 数据库支持(使用 SQLite) - 单元测试
祝学习愉快!