课程成绩统计程序 3:从继承到组合,解锁灵活开发新姿势!
以下是实现该课程成绩统计程序的Python代码: ```python # 分项成绩类,包含成绩分值和权重 class ItemScore: def __init__(self, score, weight): self.score = score self.weight = weight # 课程成绩类,组合分项成绩类 class CourseScore: def __init__(self, course, item_scores): self.course = course self.item_scores = item_scores # 计算课程总成绩 def calculate_total_score(self): total = 0 for item in self.item_scores: total += item.score * item.weight return int(total) # 课程类 class Course: def __init__(self, name, nature, access_mode, weights): self.name = name self.nature = nature self.access_mode = access_mode self.weights = weights # 学生类 class Student: def __init__(self, id, name): self.id = id self.name = name self.course_scores = [] # 计算学生所有课程的总成绩平均分 def calculate_average_score(self): if not self.course_scores: return None total = 0 for course_score in self.course_scores: total += course_score.calculate_total_score() return total // len(self.course_scores) # 班级类 class Class: def __init__(self, class_id): self.class_id = class_id self.students = [] # 计算班级所有课程的总成绩平均分 def calculate_average_score(self): if not self.students: return None total = 0 student_count = 0 for student in self.students: avg_score = student.calculate_average_score() if avg_score is not None: total += avg_score student_count += 1 if student_count == 0: return None return total // student_count # 主函数,处理输入和输出 def main(): courses = {} students = {} classes = {} while True: line = input().strip() if line == 'end': break parts = line.split() if len(parts) >= 3: if parts[1] in ['必修', '选修', '实验']: # 处理课程信息 course_name = parts[0] if course_name in courses: continue nature = parts[1] access_mode = parts[2] if (nature == '必修' and access_mode != '考试') or (nature == '实验' and access_mode != '实验'): print(f"{course_name} : course type & access mode mismatch") continue if access_mode == '考试': if len(parts) != 5: print("wrong format") continue weights = [float(parts[3]), float(parts[4])] if sum(weights) != 1: print(f"{course_name} : weight value error") continue elif access_mode == '考察': if len(parts) != 3: print("wrong format") continue weights = [1] elif access_mode == '实验': if len(parts) < 5 or len(parts) > 10: print("wrong format") continue n = int(parts[3]) if len(parts) - 4 != n or n < 4 or n > 9: print(f"{course_name} : number of scores does not match") continue weights = [float(x) for x in parts[4:]] if sum(weights) != 1: print(f"{course_name} : weight value error") continue course = Course(course_name, nature, access_mode, weights) courses[course_name] = course else: # 处理成绩信息 student_id = parts[0] name = parts[1] course_name = parts[2] if len(student_id) != 8 or not student_id.isdigit() or len(name) > 10 or len(course_name) > 10: print("wrong format") continue if course_name not in courses: print(f"{student_id} {name} : {course_name} does not exist") continue course = courses[course_name] access_mode = course.access_mode if access_mode == '考试': if len(parts) != 5: print(f"{student_id} {name} : access mode mismatch") continue scores = [int(parts[3]), int(parts[4])] if any(score < 0 or score > 100 for score in scores): print("wrong format") continue elif access_mode == '考察': if len(parts) != 4: print(f"{student_id} {name} : access mode mismatch") continue scores = [int(parts[3])] if scores[0] < 0 or scores[0] > 100: print("wrong format") continue elif access_mode == '实验': if len(parts) - 3 != len(course.weights): print(f"{student_id} {name} : access mode mismatch") continue scores = [int(x) for x in parts[3:]] if any(score < 0 or score > 100 for score in scores): print("wrong format") continue item_scores = [ItemScore(score, weight) for score, weight in zip(scores, course.weights)] course_score = CourseScore(course, item_scores) if student_id not in students: students[student_id] = Student(student_id, name) student = students[student_id] student.course_scores.append(course_score) class_id = student_id[:6] if class_id not in classes: classes[class_id] = Class(class_id) class_obj = classes[class_id] if student not in class_obj.students: class_obj.students.append(student) # 输出学生课程总成绩平均分 for student_id in sorted(students.keys()): student = students[student_id] avg_score = student.calculate_average_score() if avg_score is None: print(f"{student_id} {student.name} did not take any exams") else: print(f"{student_id} {student.name} {avg_score}") # 输出单门课程成绩 for course_name in sorted(courses.keys()): course = courses[course_name] total_scores = [] for student in students.values(): for course_score in student.course_scores: if course_score.course.name == course_name: total_scores.append(course_score.calculate_total_score()) if not total_scores: print(f"{course_name} has no grades yet") else: avg_score = sum(total_scores) // len(total_scores) print(f"{course_name} {avg_score}") # 输出班级所有课程总成绩平均分 for class_id in sorted(classes.keys()): class_obj = classes[class_id] avg_score = class_obj.calculate_average_score() if avg_score is None: print(f"{class_id} has no grades yet") else: print(f"{class_id} {avg_score}") if __name__ == "__main__": main() ``` 继承和组合关系的区别 - 继承:是一种“is-a”的关系,子类继承父类的属性和方法,子类可以重写父类的方法。继承可以实现代码的复用,但会使子类和父类之间的耦合度较高,父类的修改可能会影响到子类。 - 组合:是一种“has-a”的关系,一个类包含另一个类的对象。组合可以实现代码的复用,并且耦合度较低,一个类的修改不会影响到另一个类。 哪种关系更灵活 组合关系运用上更灵活,更能够适应变更。因为组合关系可以在运行时动态地改变对象的组成,而继承关系在编译时就已经确定了类之间的关系。当需求发生变化时,组合关系可以通过更换组合的对象来满足新的需求,而继承关系可能需要修改父类或创建新的子类。 我在以往的开发过程中,碰到过以下几点需要格外小心处理的地方: 1. 处理输入时,要严格检查输入的格式和范围,避免因输入错误导致程序崩溃。 2. 在计算平均值时,要注意处理没有成绩信息的情况,避免出现除零错误。 3. 对于重复的课程或成绩信息,要正确处理,避免数据的重复计算。 ######[AI写代码神器 | 2064点数解答 | 2025-12-04 10:47:33]
- C 语言:快速实现 5 个学生信息录入、按成绩升序排序并输出!(字节豆包 | 373点数解答 | 2024-10-30 00:37:20)411
- C语言实现:输入5名学生信息并按成绩升序排序输出(字节豆包 | 354点数解答 | 2024-10-30 18:45:58)354
- C语言:输入5个学生信息,按成绩升序排序并输出(字节豆包 | 373点数解答 | 2024-10-31 19:49:58)346
- C语言:输入5名学生信息并按成绩升序排序输出(字节豆包 | 326点数解答 | 2025-01-01 20:11:47)340
- 成绩等级统计:20个60 - 100分成绩的等级数量揭秘(字节豆包 | 219点数解答 | 2025-04-09 10:20:32)219
- 培训机构学员成绩与年龄更新:C++ 代码实现(DeepSeek | 186点数解答 | 2025-12-16 18:04:31)59
- Python 处理培训机构学员培训后年龄与 NOIP 成绩提升情况(DeepSeek | 73点数解答 | 2025-12-16 18:05:20)63
- 培训机构学员成绩提升:C++代码实现年龄与NOIP成绩更新(DeepSeek | 178点数解答 | 2025-12-31 12:20:24)60
- 车载系统 UML 类图设计:涵盖 Car、Engine、娱乐系统等的完整类定义与关系解析 (字节豆包 | 760点数解答 | 2024-08-15 22:51:04)309
- C++ 实现正方形黑白瓦片图案最小转换方法求解(字节豆包 | 817点数解答 | 2025-11-25 19:03:09)70
- C++ 实战:交通工具基类与小汽车类的继承实现及测试(字节豆包 | 391点数解答 | 2024-09-18 16:16:39)264
- Java 实现交通工具类继承:从 Vehicles 到 Car 的完整示例(字节豆包 | 289点数解答 | 2024-09-18 16:16:54)241