Python基础语法练习题(72)

第七十二题,简单版学生成绩管理系统

这题没有写成一坨脚本,而是拆成了两个各司其职的类。这是我从之前"学生类"、"银行账户类"一路摸爬滚打出来的直觉:数据归数据,管理归管理。

先上代码

实现一个简单的学生成绩管理系统,支持添加学生、记录学生成绩,并计算每个学生成绩的平均值

---------- 学生类 ----------

class Student:

"""用于表示一个学生及其成绩列表"""

def init(self, name):

self.name = name # 学生姓名

self.grades: listfloat = \[\] # 成绩列表,显式注解避免推断成 Any

def add_grade(self, grade):

"""添加一条学生成绩"""

self.grades.append(grade)

def calculate_average(self):

"""计算该学生成绩的平均值,无成绩时返回 0.0"""

if not self.grades:

return 0.0

return sum(self.grades) / len(self.grades)

def info(self):

"""汇总该学生的成绩信息"""

if not self.grades:

return f' {self.name}:尚未记录任何成绩'

average = self.calculate_average()

return (

f' {self.name}:共 {len(self.grades)} 条成绩 '

f'{self.grades},平均分 {average:.2f}'

)

---------- 学生成绩管理类 ----------

class StudentGradeManager:

"""学生成绩管理类,负责学生的增删查与成绩维护"""

def init(self):

键为学生姓名,值为 Student 对象

self.students: dictstr, Student = {}

def add_student(self, name):

if name in self.students:

print(f' 学生 {name} 已经存在,无需重复添加。')

return False

self.studentsname = Student(name)

print(f' 学生 {name} 添加成功。')

return True

def add_grade(self, name, grade):

if name not in self.students:

print(f' 查无此人:{name},请先添加该学生。')

return False

self.studentsname.add_grade(grade)

print(f' 已为 {name} 记录成绩 {grade}。')

return True

def show_average(self, name):

if name not in self.students:

print(f' 查无此人:{name},请先添加该学生。')

return False

student = self.studentsname

if not student.grades:

print(f' {name} 尚未记录任何成绩,无法计算平均分。')

return False

average = student.calculate_average()

print(f' {name} 的平均分为:{average:.2f}')

return True

def show_all(self):

print('\n' + '=' * 40)

print(f' 学生成绩汇总 (共 {len(self.students)} 人)')

print('=' * 40)

if not self.students:

print(' 系统中还没有任何学生。')

else:

for student in self.students.values():

print(student.info())

print('=' * 40)

---------- 输入辅助函数 ----------

def input_name(prompt):

"""输入姓名:不能为空"""

name = ''

valid = False

while not valid:

raw = input(prompt).strip()

if not raw:

print(' 输入无效 姓名不能为空,请重新输入。')

continue

name = raw

valid = True

return name

def input_grade(prompt):

"""输入成绩:必须是 0-100 之间的数字"""

grade = 0.0

valid = False

while not valid:

try:

value = float(input(prompt))

except ValueError:

print(' 输入无效 成绩必须是数字,请不要输入字母或符号。')

continue

if value < 0 or value > 100:

print(' 输入无效 成绩超出合理范围(0-100),请重新输入。')

continue

grade = value

valid = True

return grade

---------- 主程序 ----------

if name == 'main':

print('==== 欢迎使用简单版学生成绩管理系统 ====')

manager = StudentGradeManager()

while True:

print('\n请选择要执行的操作:')

print('1. 添加学生')

print('2. 为学生记录成绩')

print('3. 查询学生平均分')

print('4. 查看所有学生成绩')

print('0. 退出系统')

choice = input('请输入您的选择(0 / 1 / 2 / 3 / 4):').strip()

if choice == '1':

name = input_name(' 请输入要添加的学生姓名:')

manager.add_student(name)

elif choice == '2':

name = input_name(' 请输入要记录成绩的学生姓名:')

grade = input_grade(' 请输入该学生的成绩(0-100):')

manager.add_grade(name, grade)

elif choice == '3':

name = input_name(' 请输入要查询平均分的学生姓名:')

manager.show_average(name)

elif choice == '4':

manager.show_all()

elif choice == '0':

print('已退出系统,感谢使用,再见!')

break

else:

print(' 无效的选项,请输入 0、1、2、3 或 4。')

我的思路:各司其职,互不牵连

这套代码的骨架是两个类:

  • Student:只管"一个学生"的事------叫什么、考了几分、自己算自己的平均分。

  • StudentGradeManager:充当"教务处",用字典(键是姓名,值是 Student 对象)把所有人存起来,对外提供添加、记录、查询的入口。

这样设计的好处是:要改"平均分怎么算"只动 Student,要改"怎么找学生"只动管理类。

关键点一:修了原版的"越界"Bug

原版在计算平均分时,竟然去引用了一个不存在的 self.students(学生个人身上怎么会有全班学生的数据?)。一调就报错。

我把它改回了天经地义的样子:学生只算自己那份 sum(self.grades) / len(self.grades)。封装,就是管好自己,别瞎碰别人的数据。

关键点二:字典存储 + 存在性校验

管理类里,不管你是加成绩还是查平均分,我都先过一道"查无此人"的安检。不在字典里就提示,绝不让你报 KeyError 崩掉。查平均分时还多看一眼有没有成绩,空列表就老实提示。每步都有兜底。

关键点三:输入防呆(标志位循环)

姓名不能为空,成绩必须是在 0-100 的数字。这俩我都用了 while not valid 的标志位循环 + 循环外统一 return。

这不仅是为了输错不崩溃,还是为了绕开 PyCharm 的毛病------它老是把 while True 里的 return 误判为可能返回 None,搞得下游一堆警告。换成标志位,类型提示就清净了。成绩的 try/except 我也照旧把范围检查放在外面。

关键点四:菜单式"服务台"

主程序外面套个 while True 菜单,按选项分发,算完不清场,输 0 才退出。这就是把脚本变成能反复使用的小程序。

相关推荐
无忧.芙桃1 小时前
C++语言原理与实践(十三):stack、queue 和 priority_queue的介绍与使用
开发语言·c++·栈·队列
171320330计算机毕设编程1 小时前
计算机毕业设计 基于Hadoop的新能源汽车发展前景分析 LW PPT
java·大数据·hadoop·python·算法·随机森林·线性回归
Shaoshing2 小时前
消息发送
java·开发语言
haluhalu.2 小时前
深入理解 AI Agent(1.2):Harness 工程——模型之外的竞争力
前端·数据结构·人工智能·python·langchain·个人开发
乌暮2 小时前
从 `println` 到生产级日志:Spring Boot 日志体系完全指南
java·开发语言·jvm·spring boot·后端·学习·面试
东莞市云毅网络有限公司2 小时前
把网页表格与列表还原成结构化条目:抽取与对账实现
python·文本处理·数据抽取
夜瞬2 小时前
从零微调 Qwen3-8B:基于 LoRA 与 LLaMA-Factory 打造专属 AI 编程助教
人工智能·python·llama
星夜离尘562 小时前
MATLAB 定点量化误差实验 半个 LSB 的界限为什么挡不住削顶失真
开发语言·matlab
Wang's Blog2 小时前
Java 项目实战: 交友项目 - 百度人脸识别:介绍
java·开发语言·交友