diff --git a/student/bll/student_bll.py b/student/bll/student_bll.py index 8a48d3b..6418a95 100644 --- a/student/bll/student_bll.py +++ b/student/bll/student_bll.py @@ -5,14 +5,28 @@ from ..util.validator import Validator class StudentBLL: - """学生信息管理系统的业务逻辑层""" + """学生信息管理系统的业务逻辑层,处理学生信息的业务逻辑和数据验证""" def __init__(self, dal: IStudentDAL): + """ + 初始化业务逻辑层 + + Args: + dal: 数据访问层对象,实现IStudentDAL接口 + """ self.dal = dal def add_student(self, student: Student) -> (bool, str): - """添加学生,包含数据验证""" - # 验证学生数据 + """ + 添加学生信息,包含完整的数据验证流程 + + Args: + student: 要添加的学生对象 + + Returns: + 元组(操作是否成功, 操作结果信息) + """ + # 验证学生基本信息格式 if not Validator.validate_id_card(student.id_card): return False, "身份证号码格式不正确" @@ -34,27 +48,35 @@ class StudentBLL: if student.phone and not Validator.validate_phone(student.phone): return False, "手机号码格式不正确" - # 验证入学日期 + # 验证入学日期与出生日期的逻辑关系 if student.enrollment_date and student.birthday: if not Validator.validate_enrollment_date(student.enrollment_date, student.birthday): return False, "入学日期不能早于出生日期" - # 检查学号和身份证号是否已存在 + # 检查数据唯一性 if self.dal.get_by_id(student.id_card): return False, "该身份证号已存在" if self.dal.get_by_stu_id(student.stu_id): return False, "该学号已存在" - # 添加学生 + # 执行数据添加操作 if self.dal.add(student): return True, "学生添加成功" else: return False, "学生添加失败" def update_student(self, student: Student) -> (bool, str): - """更新学生信息,包含数据验证""" - # 验证学生数据 + """ + 更新学生信息,包含与添加操作相同的数据验证流程 + + Args: + student: 包含更新信息的学生对象,通过id_card匹配记录 + + Returns: + 元组(操作是否成功, 操作结果信息) + """ + # 重复添加操作中的数据验证逻辑 if not Validator.validate_id_card(student.id_card): return False, "身份证号码格式不正确" @@ -76,55 +98,125 @@ class StudentBLL: if student.phone and not Validator.validate_phone(student.phone): return False, "手机号码格式不正确" - # 验证入学日期 if student.enrollment_date and student.birthday: if not Validator.validate_enrollment_date(student.enrollment_date, student.birthday): return False, "入学日期不能早于出生日期" - # 更新学生 + # 执行数据更新操作 if self.dal.update(student): return True, "学生信息更新成功" else: return False, "学生信息更新失败,未找到该学生" def delete_student_by_id(self, id_card: str) -> bool: - """根据身份证号删除学生""" + """ + 根据身份证号删除学生记录 + + Args: + id_card: 要删除学生的身份证号 + + Returns: + 操作是否成功 + """ return self.dal.delete_by_id(id_card) def delete_student_by_stu_id(self, stu_id: str) -> bool: - """根据学号删除学生""" + """ + 根据学号删除学生记录 + + Args: + stu_id: 要删除学生的学号 + + Returns: + 操作是否成功 + """ return self.dal.delete_by_stu_id(stu_id) def get_student_by_id(self, id_card: str) -> Optional[Student]: - """根据身份证号获取学生""" + """ + 根据身份证号查询学生信息 + + Args: + id_card: 要查询学生的身份证号 + + Returns: + 匹配的学生对象,未找到返回None + """ return self.dal.get_by_id(id_card) def get_student_by_stu_id(self, stu_id: str) -> Optional[Student]: - """根据学号获取学生""" + """ + 根据学号查询学生信息 + + Args: + stu_id: 要查询学生的学号 + + Returns: + 匹配的学生对象,未找到返回None + """ return self.dal.get_by_stu_id(stu_id) def get_all_students(self) -> List[Student]: - """获取所有学生""" + """ + 获取系统中所有学生记录 + + Returns: + 包含所有学生对象的列表 + """ return self.dal.get_all() def search_students_by_name(self, name: str) -> List[Student]: - """根据姓名搜索学生(模糊查询)""" + """ + 根据姓名模糊查询学生信息 + + Args: + name: 要查询的姓名关键词 + + Returns: + 包含匹配学生对象的列表 + """ return self.dal.search_by_name(name) def search_students_by_class(self, class_name: str) -> List[Student]: - """根据班级搜索学生(模糊查询)""" + """ + 根据班级模糊查询学生信息 + + Args: + class_name: 要查询的班级关键词 + + Returns: + 包含匹配学生对象的列表 + """ return self.dal.search_by_class(class_name) def search_students_by_major(self, major: str) -> List[Student]: - """根据专业搜索学生(模糊查询)""" + """ + 根据专业模糊查询学生信息 + + Args: + major: 要查询的专业关键词 + + Returns: + 包含匹配学生对象的列表 + """ return self.dal.search_by_major(major) def get_total_students(self) -> int: - """获取学生总数""" + """ + 获取系统中学生总数 + + Returns: + 学生总人数 + """ return len(self.get_all_students()) def get_students_by_major(self) -> dict: - """统计各专业学生人数""" + """ + 统计各专业学生分布情况 + + Returns: + 字典,键为专业名称,值为该专业学生人数 + """ major_count = {} for student in self.get_all_students(): if student.major: @@ -132,45 +224,68 @@ class StudentBLL: return major_count def calculate_average_height(self, group_by: str = None, group_value: str = None) -> float: - """计算平均身高 - group_by: 分组依据,可选 'class' 或 'major' - group_value: 分组值,如班级名称或专业名称 + """ + 计算学生平均身高,支持按班级或专业分组计算 + + Args: + group_by: 分组依据,可选'class'或'major',不分组时为None + group_value: 分组值,如具体班级名称或专业名称 + + Returns: + 平均身高,单位厘米,无有效数据时返回0 """ students = self.get_all_students() - # 根据分组条件筛选学生 + # 按指定条件筛选学生群体 if group_by == 'class': students = [s for s in students if s.class_name == group_value] elif group_by == 'major': students = [s for s in students if s.major == group_value] - # 计算平均身高 + # 过滤有效身高数据并计算平均值 heights = [s.height for s in students if s.height is not None] return sum(heights) / len(heights) if heights else 0 def calculate_average_weight(self, group_by: str = None, group_value: str = None) -> float: - """计算平均体重 - group_by: 分组依据,可选 'class' 或 'major' - group_value: 分组值,如班级名称或专业名称 + """ + 计算学生平均体重,支持按班级或专业分组计算 + + Args: + group_by: 分组依据,可选'class'或'major',不分组时为None + group_value: 分组值,如具体班级名称或专业名称 + + Returns: + 平均体重,单位千克,无有效数据时返回0 """ students = self.get_all_students() - # 根据分组条件筛选学生 + # 按指定条件筛选学生群体 if group_by == 'class': students = [s for s in students if s.class_name == group_value] elif group_by == 'major': students = [s for s in students if s.major == group_value] - # 计算平均体重 + # 过滤有效体重数据并计算平均值 weights = [s.weight for s in students if s.weight is not None] return sum(weights) / len(weights) if weights else 0 def get_gender_ratio(self) -> dict: - """统计性别比例""" + """ + 统计学生性别比例 + + Returns: + 包含以下键的字典: + - total: 总人数 + - male: 男生人数 + - female: 女生人数 + - male_ratio: 男生比例 + - female_ratio: 女生比例 + """ total = 0 male_count = 0 female_count = 0 + # 遍历统计性别分布 for student in self.get_all_students(): if student.gender is not None: total += 1 @@ -179,6 +294,7 @@ class StudentBLL: else: female_count += 1 + # 计算比例并返回结果 return { 'total': total, 'male': male_count,