1、课程信息
项目
内容
学习阶段
大二上学期
主要语言
Python
课程定位
函数、类与对象、封装、模块拆分
关键词
组合计算、类设计、菜单交互、数据管理
2、题目与训练点
编号
题目
主要训练内容
现在回看
A02
阶乘和组合
函数拆分、循环或递归、结果验证
适合练习把公式拆成可复用函数,并处理输入范围
B03
学生课程系统
类与对象、数据管理、菜单交互
开始接近小型管理系统,重点是对象职责和状态维护
3、A02 阶乘和组合 3.1 题目描述 输入 n 和 r,分别计算:
1 2 3 n! A(n, r) = n! / (n-r)! C(n, r) = n! / (r! × (n-r)!)
要求:
n 和 r 都是非负整数。
r 不能大于 n。
用函数拆分阶乘、排列和组合。
3.2 输入输出 输入:
输出:
1 2 3 5! = 120 A(5, 2) = 20 C(5, 2) = 10
3.3 完整代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 def factorial (n: int ) -> int : """Return n!.""" result = 1 for value in range (2 , n + 1 ): result *= value return result def permutation (n: int , r: int ) -> int : """Return A(n, r).""" result = 1 for value in range (n - r + 1 , n + 1 ): result *= value return result def combination (n: int , r: int ) -> int : """Return C(n, r).""" r = min (r, n - r) numerator = permutation(n, r) denominator = factorial(r) return numerator // denominator def validate (n: int , r: int ) -> bool : if n < 0 or r < 0 : print ("n and r must be non-negative integers." ) return False if r > n: print ("r must not be greater than n." ) return False return True def main () -> None : n, r = map (int , input ().split()) if not validate(n, r): return print (f"{n} ! = {factorial(n)} " ) print (f"A({n} , {r} ) = {permutation(n, r)} " ) print (f"C({n} , {r} ) = {combination(n, r)} " ) if __name__ == "__main__" : main()
3.4 复盘点 这个题可以直接用 math.factorial,但课程练习阶段更适合自己写循环。组合数计算时使用 r = min(r, n-r),可以减少乘法次数,也能顺手理解组合公式的对称性。
4、B03 学生课程系统 4.1 题目描述 设计一个简单的学生课程管理系统,支持:
添加学生。
添加课程。
学生选课。
录入成绩。
查询学生成绩单。
查询课程名单。
系统只使用内存保存数据,不连接数据库。这个版本的重点是类与对象、封装、字典管理和菜单交互。
4.2 类设计
类
作用
Student
保存学生学号和姓名
Course
保存课程编号、课程名和学分
Enrollment
保存某个学生在某门课中的成绩
CourseSystem
负责添加、选课、录入成绩和查询
4.3 完整代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 from dataclasses import dataclass@dataclass class Student : student_id: str name: str @dataclass class Course : course_id: str name: str credit: float @dataclass class Enrollment : student_id: str course_id: str score: float | None = None class CourseSystem : def __init__ (self ) -> None : self.students: dict [str , Student] = {} self.courses: dict [str , Course] = {} self.enrollments: dict [tuple [str , str ], Enrollment] = {} def add_student (self, student_id: str , name: str ) -> None : if student_id in self.students: print ("Student already exists." ) return self.students[student_id] = Student(student_id, name) print ("Student added." ) def add_course (self, course_id: str , name: str , credit: float ) -> None : if course_id in self.courses: print ("Course already exists." ) return self.courses[course_id] = Course(course_id, name, credit) print ("Course added." ) def enroll (self, student_id: str , course_id: str ) -> None : if student_id not in self.students: print ("Student not found." ) return if course_id not in self.courses: print ("Course not found." ) return key = (student_id, course_id) if key in self.enrollments: print ("This student has already selected the course." ) return self.enrollments[key] = Enrollment(student_id, course_id) print ("Enrollment saved." ) def set_score (self, student_id: str , course_id: str , score: float ) -> None : key = (student_id, course_id) if key not in self.enrollments: print ("Enrollment not found." ) return if not 0 <= score <= 100 : print ("Score must be between 0 and 100." ) return self.enrollments[key].score = score print ("Score updated." ) def print_student_report (self, student_id: str ) -> None : if student_id not in self.students: print ("Student not found." ) return student = self.students[student_id] print (f"\nTranscript: {student.student_id} {student.name} " ) print ("-" * 50 ) print (f"{'Course ID' :<12 } {'Course' :<18 } {'Credit' :<8 } {'Score' :<8 } " ) total_credit = 0.0 total_weighted_score = 0.0 has_score = False for enrollment in self.enrollments.values(): if enrollment.student_id != student_id: continue course = self.courses[enrollment.course_id] score_text = "N/A" if enrollment.score is None else f"{enrollment.score:.1 f} " print (f"{course.course_id:<12 } {course.name:<18 } {course.credit:<8.1 f} {score_text:<8 } " ) if enrollment.score is not None : has_score = True total_credit += course.credit total_weighted_score += course.credit * enrollment.score if has_score and total_credit > 0 : average = total_weighted_score / total_credit print ("-" * 50 ) print (f"Weighted average: {average:.2 f} " ) print () def print_course_roster (self, course_id: str ) -> None : if course_id not in self.courses: print ("Course not found." ) return course = self.courses[course_id] print (f"\nRoster: {course.course_id} {course.name} " ) print ("-" * 40 ) print (f"{'Student ID' :<14 } {'Name' :<14 } {'Score' :<8 } " ) for enrollment in self.enrollments.values(): if enrollment.course_id != course_id: continue student = self.students[enrollment.student_id] score_text = "N/A" if enrollment.score is None else f"{enrollment.score:.1 f} " print (f"{student.student_id:<14 } {student.name:<14 } {score_text:<8 } " ) print () def print_menu () -> None : print ("1. Add student" ) print ("2. Add course" ) print ("3. Enroll" ) print ("4. Set score" ) print ("5. Student report" ) print ("6. Course roster" ) print ("0. Exit" ) def main () -> None : system = CourseSystem() while True : print_menu() choice = input ("Choose: " ).strip() if choice == "1" : student_id = input ("Student ID: " ).strip() name = input ("Name: " ).strip() system.add_student(student_id, name) elif choice == "2" : course_id = input ("Course ID: " ).strip() name = input ("Course name: " ).strip() credit = float (input ("Credit: " )) system.add_course(course_id, name, credit) elif choice == "3" : student_id = input ("Student ID: " ).strip() course_id = input ("Course ID: " ).strip() system.enroll(student_id, course_id) elif choice == "4" : student_id = input ("Student ID: " ).strip() course_id = input ("Course ID: " ).strip() score = float (input ("Score: " )) system.set_score(student_id, course_id, score) elif choice == "5" : student_id = input ("Student ID: " ).strip() system.print_student_report(student_id) elif choice == "6" : course_id = input ("Course ID: " ).strip() system.print_course_roster(course_id) elif choice == "0" : break else : print ("Invalid choice." ) if __name__ == "__main__" : main()
4.4 测试流程 可以按下面顺序手动测试:
1 2 3 4 5 6 1 -> 202001 -> Ruiqing 2 -> CS101 -> Python -> 3 3 -> 202001 -> CS101 4 -> 202001 -> CS101 -> 92 5 -> 202001 6 -> CS101
5、学习重点 5.1 阶乘和组合 这类题的核心不只是计算结果,而是把阶乘、排列、组合等逻辑拆成清晰函数,并考虑非法输入、边界值和较大结果。它让我开始意识到:同一个数学公式,写成程序时需要额外处理输入、类型和可读性。
5.2 学生课程系统 学生课程系统更像后面后台管理项目的雏形:学生、课程、成绩或选课关系都可以抽象成对象,菜单负责调度操作,数据结构负责保存状态。它训练的不是某个语法点,而是“程序里有哪些角色,它们之间怎么协作”。
6、个人复盘 这门课程的核心价值是第一次从“写出一个答案”转向“组织一个程序”。现在回看,我最该保留的是类的职责划分、菜单程序的状态管理、数据校验和文件持久化思路。之后如果找到原始代码,我会把当时版本和现在更清晰的写法分开记录,方便看到自己的变化。