xu#True

#xu#True

python 复制代码
"""
学生成绩管理系统
功能:管理学生信息,计算成绩统计
作者:AI助手
版本:1.0
"""

# ==================== 导入模块 ====================
import json  # 用于JSON数据操作
from typing import List, Dict, Optional  # 类型提示,提高代码可读性
from datetime import datetime  # 日期时间处理


# ==================== 常量定义 ====================
MAX_SCORE = 100  # 最高分数
MIN_SCORE = 0  # 最低分数
PASS_SCORE = 60  # 及格分数线
DATA_FILE = "students.json"  # 数据存储文件名


# ==================== 类定义 ====================
class Student:
    """
    学生类
    用于表示单个学生的信息和成绩
    
    属性:
        name (str): 学生姓名
        student_id (str): 学号
        scores (Dict[str, float]): 各科成绩字典
    """
    
    def __init__(self, name: str, student_id: str):
        """
        初始化学生对象
        
        参数:
            name: 学生姓名
            student_id: 学号,格式应为"20230001"
            
        异常:
            ValueError: 当学号长度不为8时抛出
        """
        if len(student_id) != 8:
            raise ValueError("学号长度必须为8位")
            
        self.name = name
        self.student_id = student_id
        self.scores = {}  # 初始化为空字典
        self.created_at = datetime.now()  # 记录创建时间
    
    def add_score(self, subject: str, score: float) -> bool:
        """
        添加或更新科目成绩
        
        参数:
            subject: 科目名称
            score: 分数,应在0-100之间
            
        返回:
            bool: 操作是否成功
            
        示例:
            >>> student.add_score("数学", 95.5)
            True
        """
        # 参数验证
        if not MIN_SCORE <= score <= MAX_SCORE:
            print(f"错误:分数必须在{MIN_SCORE}到{MAX_SCORE}之间")
            return False
            
        if not subject.strip():  # 检查科目名是否为空
            print("错误:科目名称不能为空")
            return False
        
        # 添加成绩
        self.scores[subject] = round(score, 1)  # 保留一位小数
        print(f"成功添加 {subject} 成绩: {score}")
        return True
    
    def calculate_average(self) -> Optional[float]:
        """
        计算平均分
        
        返回:
            float: 平均分,如果没有成绩则返回None
        """
        if not self.scores:  # 检查字典是否为空
            print(f"学生 {self.name} 暂无成绩")
            return None
        
        total = sum(self.scores.values())
        average = total / len(self.scores)
        return round(average, 2)  # 保留两位小数
    
    def is_pass(self) -> bool:
        """
        判断学生是否及格(平均分>=60)
        
        返回:
            bool: 是否及格
        """
        average = self.calculate_average()
        if average is None:
            return False
        return average >= PASS_SCORE
    
    def __str__(self) -> str:
        """
        返回学生信息的字符串表示
        
        返回:
            str: 格式化后的学生信息
        """
        avg_score = self.calculate_average()
        status = "及格" if self.is_pass() else "不及格"
        
        info_lines = [
            f"学生信息:",
            f"  姓名: {self.name}",
            f"  学号: {self.student_id}",
            f"  成绩单:"
        ]
        
        # 添加各科成绩
        for subject, score in self.scores.items():
            info_lines.append(f"    {subject}: {score}")
        
        # 添加统计信息
        if avg_score is not None:
            info_lines.append(f"  平均分: {avg_score}")
            info_lines.append(f"  状态: {status}")
        
        return "\n".join(info_lines)


class StudentManager:
    """
    学生管理器类
    管理多个学生对象,提供批量操作
    """
    
    def __init__(self):
        """初始化学生管理器"""
        self.students: Dict[str, Student] = {}  # 用学号作为键存储学生
        
    def add_student(self, student: Student) -> bool:
        """
        添加学生到管理器
        
        参数:
            student: Student对象
            
        返回:
            bool: 是否添加成功
        """
        if student.student_id in self.students:
            print(f"错误:学号 {student.student_id} 已存在")
            return False
        
        self.students[student.student_id] = student
        print(f"成功添加学生: {student.name}")
        return True
    
    def find_student(self, student_id: str) -> Optional[Student]:
        """
        根据学号查找学生
        
        参数:
            student_id: 学号
            
        返回:
            Student: 找到的学生对象,未找到返回None
        """
        return self.students.get(student_id)
    
    def calculate_class_average(self) -> float:
        """
        计算全班平均分
        
        返回:
            float: 全班平均分
        """
        if not self.students:
            return 0.0
        
        total_average = 0
        count = 0
        
        for student in self.students.values():
            avg = student.calculate_average()
            if avg is not None:  # 只统计有成绩的学生
                total_average += avg
                count += 1
        
        return round(total_average / count, 2) if count > 0 else 0.0
    
    def save_to_file(self, filename: str = DATA_FILE) -> bool:
        """
        将学生数据保存到JSON文件
        
        参数:
            filename: 文件名
            
        返回:
            bool: 保存是否成功
        """
        try:
            data = {
                "students": [],
                "metadata": {
                    "saved_at": datetime.now().isoformat(),
                    "total_students": len(self.students)
                }
            }
            
            for student in self.students.values():
                student_data = {
                    "name": student.name,
                    "student_id": student.student_id,
                    "scores": student.scores,
                    "created_at": student.created_at.isoformat()
                }
                data["students"].append(student_data)
            
            with open(filename, 'w', encoding='utf-8') as f:
                json.dump(data, f, indent=2, ensure_ascii=False)
            
            print(f"数据已保存到 {filename}")
            return True
            
        except (IOError, TypeError) as e:
            print(f"保存文件失败: {e}")
            return False
    
    def load_from_file(self, filename: str = DATA_FILE) -> bool:
        """
        从JSON文件加载学生数据
        
        参数:
            filename: 文件名
            
        返回:
            bool: 加载是否成功
        """
        try:
            with open(filename, 'r', encoding='utf-8') as f:
                data = json.load(f)
            
            self.students.clear()  # 清空当前数据
            
            for student_data in data.get("students", []):
                student = Student(
                    name=student_data["name"],
                    student_id=student_data["student_id"]
                )
                student.scores = student_data.get("scores", {})
                # 注意:实际项目中需要处理日期转换
                self.students[student.student_id] = student
            
            print(f"从 {filename} 加载了 {len(self.students)} 名学生")
            return True
            
        except FileNotFoundError:
            print(f"文件 {filename} 不存在")
            return False
        except (json.JSONDecodeError, KeyError) as e:
            print(f"文件格式错误: {e}")
            return False


# ==================== 工具函数 ====================
def display_menu() -> None:
    """
    显示主菜单
    
    返回:
        None
    """
    menu_items = [
        "=" * 40,
        "学生成绩管理系统",
        "=" * 40,
        "1. 添加学生",
        "2. 添加成绩",
        "3. 查看学生",
        "4. 查看所有学生",
        "5. 计算统计信息",
        "6. 保存数据",
        "7. 加载数据",
        "8. 退出系统",
        "=" * 40
    ]
    
    print("\n".join(menu_items))


def get_valid_input(prompt: str, input_type=str, validation_func=None) -> any:
    """
    获取有效的用户输入
    
    参数:
        prompt: 提示信息
        input_type: 期望的输入类型
        validation_func: 自定义验证函数
        
    返回:
        验证后的输入值
    """
    while True:
        try:
            user_input = input(prompt).strip()
            
            # 类型转换
            if input_type != str:
                user_input = input_type(user_input)
            
            # 自定义验证
            if validation_func and not validation_func(user_input):
                print("输入不符合要求,请重新输入")
                continue
                
            return user_input
            
        except ValueError:
            print(f"错误:请输入有效的{input_type.__name__}类型")
        except KeyboardInterrupt:
            print("\n用户中断操作")
            raise


# ==================== 主程序 ====================
def main():
    """
    主函数
    程序的入口点,管理主要流程
    """
    manager = StudentManager()
    
    print("欢迎使用学生成绩管理系统")
    
    while True:
        try:
            display_menu()
            choice = get_valid_input(
                "请选择操作 (1-8): ",
                input_type=int,
                validation_func=lambda x: 1 <= x <= 8
            )
            
            if choice == 1:  # 添加学生
                name = get_valid_input("请输入学生姓名: ")
                student_id = get_valid_input(
                    "请输入学号 (8位数字): ",
                    validation_func=lambda x: x.isdigit() and len(x) == 8
                )
                
                try:
                    student = Student(name, student_id)
                    if manager.add_student(student):
                        print("添加成功!")
                except ValueError as e:
                    print(f"创建学生失败: {e}")
            
            elif choice == 2:  # 添加成绩
                student_id = get_valid_input("请输入学号: ")
                student = manager.find_student(student_id)
                
                if student:
                    subject = get_valid_input("请输入科目名称: ")
                    score = get_valid_input(
                        f"请输入{subject}成绩 (0-100): ",
                        input_type=float,
                        validation_func=lambda x: MIN_SCORE <= x <= MAX_SCORE
                    )
                    student.add_score(subject, score)
                else:
                    print("未找到该学生")
            
            elif choice == 3:  # 查看单个学生
                student_id = get_valid_input("请输入学号: ")
                student = manager.find_student(student_id)
                
                if student:
                    print("\n" + str(student))
                else:
                    print("未找到该学生")
            
            elif choice == 4:  # 查看所有学生
                if not manager.students:
                    print("当前没有学生记录")
                    continue
                    
                print(f"\n共有 {len(manager.students)} 名学生:")
                for i, student in enumerate(manager.students.values(), 1):
                    print(f"\n{i}. {student.name} ({student.student_id})")
                    avg = student.calculate_average()
                    if avg:
                        print(f"   平均分: {avg}, 状态: {'及格' if student.is_pass() else '不及格'}")
            
            elif choice == 5:  # 计算统计信息
                class_avg = manager.calculate_class_average()
                pass_count = sum(1 for s in manager.students.values() if s.is_pass())
                
                print("\n班级统计信息:")
                print(f"  学生总数: {len(manager.students)}")
                print(f"  及格人数: {pass_count}")
                print(f"  不及格人数: {len(manager.students) - pass_count}")
                print(f"  班级平均分: {class_avg}")
            
            elif choice == 6:  # 保存数据
                manager.save_to_file()
            
            elif choice == 7:  # 加载数据
                manager.load_from_file()
            
            elif choice == 8:  # 退出
                save_choice = get_valid_input(
                    "是否保存数据后退出? (y/n): ",
                    validation_func=lambda x: x.lower() in ['y', 'n']
                )
                
                if save_choice.lower() == 'y':
                    manager.save_to_file()
                
                print("感谢使用,再见!")
                break
            
            # 操作间隔
            input("\n按回车键继续...")
            
        except KeyboardInterrupt:
            print("\n\n程序被用户中断")
            break
        except Exception as e:
            print(f"发生未知错误: {e}")
            print("程序将继续运行...")


# ==================== 程序入口 ====================
if __name__ == "__main__":
    """
    这是程序的入口点。
    当直接运行此脚本时,会执行main()函数。
    当作为模块导入时,不会自动运行。
    """
    main()
相关推荐
DeepModel2 小时前
【概率分布】均匀分布的原理、推导与Python实现
python·算法·概率论
wmfglpz882 小时前
Django全栈开发入门:构建一个博客系统
jvm·数据库·python
zzb15802 小时前
Agent学习-Reflection框架
java·人工智能·python·学习·ai
2301_764441332 小时前
使用python实现脉冲神经网络,用于分类任务
python·神经网络·分类
qyzm2 小时前
AtCoder Beginner Contest 449
数据结构·python·算法·贪心算法
no_work2 小时前
python-深度学习快速入门实战-数据集和源码
开发语言·人工智能·python·深度学习·神经网络·cnn
MoRanzhi12032 小时前
一维概率分布可视化实践:基于 Python 的理论曲线与样本图对照
python·概率论·matplotlib·seaborn·scipy·统计学·概率分布可视化
jay神2 小时前
基于深度学习的人脸检测与识别系统
人工智能·python·深度学习·可视化·计算机毕业设计
KIHU快狐2 小时前
KIHU快狐|RK3399系统户外触摸一体机强悍算力支持超清播放
大数据·人工智能·python