案例:学生信息管理系统(基础版)
当学生名单和三科成绩需要反复新增、查询、修改和删除时,如何先用流程控制与容器做出一个能持续运行的管理系统?本章从内存数据开始实现基础版。
本章不引入新语法,只组合 while、if、列表和字典。数据暂时保存在内存中,程序关闭后的持久化放到下一节解决。
案例:学生管理需求
需求: 管理学生姓名、语文成绩、数学成绩和英语成绩,计算总分,并支持新增、显示、查询、修改、删除和退出。
功能分析: 用 while True 保持菜单运行,用列表保存多名学生,用字典描述一名学生,再为每个菜单分支补充具体操作。
系统需要完成以下操作:
- 启动后显示功能菜单
- 根据用户输入执行对应操作
- 记录学生的姓名、语文成绩、数学成绩、英语成绩和总分
- 支持新增、显示、查询、修改和删除学生信息
- 输入
0时退出系统
这一版用姓名查找学生。为了让练习重点落在容器和流程控制上,暂时不处理重名,也不校验成绩的输入格式。
菜单循环与功能分支
面对这组需求,先把程序拆成三部分:
- 用
while True让菜单持续运行 - 用列表和字典保存学生数据
- 在不同菜单分支中完成增、查、改、删
先把主循环搭起来,再逐个填充功能。
主循环框架:
系统需要反复显示菜单、接收选择并执行操作,因此第一步只搭建持续运行的主循环,不急着填写具体功能。
while True:
action = input("请选择操作功能:")
# TODO 新增数据
# TODO 显示全部数据
# TODO 查询数据
# TODO 修改数据
# TODO 删除数据
# TODO 退出系统占位实现:
pass 是空语句,执行后不会产生任何效果。它可以在功能尚未实现时保留代码位置,让程序先运行起来。
菜单分支:
主循环可以运行后,再用 if...elif...else 根据用户输入选择功能:
while True:
action = input("请选择操作功能:")
# TODO 新增数据
if action == "1":
pass
# TODO 显示全部数据
elif action == "2":
pass
# TODO 查询数据
elif action == "3":
pass
# TODO 修改数据
elif action == "4":
pass
# TODO 删除数据
elif action == "5":
pass
# TODO 退出系统
elif action == "0":
break
else:
print("输入错误,请重新输入")这里的 break 会结束 while True,让程序真正退出。其他功能暂时继续用 pass 占位。
功能菜单:
如果只让用户输入数字而不显示说明,用户不知道每个数字对应什么操作。因此,程序启动后先显示完整菜单:
**************************************************
欢迎使用【学生信息管理系统】V1.0
请选择你想要进行的操作
1. 新建学生信息
2. 显示全部信息
3. 查询学生信息
4. 修改学生信息
5. 删除学生信息
0. 退出系统
**************************************************菜单放在 while True 中。一次操作结束后,循环回到开头,菜单会再次显示,用户可以继续处理下一条学生信息。
学生数据结构
一个学生包含姓名、三科成绩和总分,如何把这些字段组织在一起?适合用字典保存一名学生的信息:
student = {
"name": "张三",
"chinese": 88,
"math": 92,
"english": 85,
"total": 265,
}多个学生需要集中保存并按顺序处理,所以再用列表保存这些字典:
# 保存所有学生信息
student_list = [] 这个结构可以概括为“列表套字典”:
- 列表负责保存多名学生
- 字典负责保存一名学生的各项信息
程序刚启动时还没有学生数据,因此先使用空列表。
学生信息增删改查
新增记录
用户选择“新建学生信息”后,需要完成四步:
- 输入姓名和三科成绩
- 计算总分
- 把一名学生的信息整理成字典
- 使用
append()把字典加入列表
student_list = []
# 输入学生信息
name = input("请输入姓名:")
chinese = int(input("请输入语文成绩:"))
math = int(input("请输入数学成绩:"))
english = int(input("请输入英语成绩:"))
total = chinese + math + english
# 使用字典保存一名学生的信息
student = {
"name": name,
"chinese": chinese,
"math": math,
"english": english,
"total": total,
}
# 把学生字典添加到列表
student_list.append(student)
print("成功添加 %s 的信息" % student["name"])成绩输入后立即转成整数。这样计算总分、修改成绩时,列表中的数据类型能够保持一致。
显示与查询
新增后如何确认数据已经保存?显示全部信息时,遍历列表并打印每一个学生字典。
如果只需要查找一名学生,同样遍历列表,再比较姓名:
student_list = [
{"name": "张三", "chinese": 88, "math": 92, "english": 85, "total": 265},
{"name": "李四", "chinese": 76, "math": 81, "english": 90, "total": 247},
{"name": "王五", "chinese": 95, "math": 89, "english": 87, "total": 271},
]
name = input("请输入要查询的学生姓名:")
# 从列表中逐个取出学生信息
for student in student_list:
if name == student["name"]:
print("姓名\t语文\t数学\t英语\t总分")
row_format = "{}\t{}\t{}\t{}\t{}"
print(row_format.format(*student.values()))
break
else:
print("该学生不存在,请检查姓名是否输入正确")找到学生后执行 break,立即停止遍历。如果整个循环都没有触发 break,就会执行 for 后面的 else,提示学生不存在。
删除记录
删除操作仍然先按姓名查找学生。找到对应的字典后,使用 remove() 从列表中删除:
student_list = [
{"name": "张三", "chinese": 88, "math": 92, "english": 85, "total": 265},
{"name": "李四", "chinese": 76, "math": 81, "english": 90, "total": 247},
{"name": "王五", "chinese": 95, "math": 89, "english": 87, "total": 271},
]
name = input("请输入要删除的学生姓名:")
for student in student_list:
if name == student["name"]:
# 也可以先找到索引,再使用 pop() 或 del 删除
student_list.remove(student)
print("成功删除 %s 的信息" % name)
break
else:
print("该学生不存在,请检查姓名是否输入正确")
print(student_list)删除后立即 break,可以避免一边遍历列表,一边继续修改列表。
修改记录
修改操作先找到学生,再更新字典中对应键的值。问题在于:如果用户只修改一科成绩,总分也必须保持同步。
这一次允许直接按回车保留原内容:
student_list = [
{"name": "张三", "chinese": 88, "math": 92, "english": 85, "total": 265},
{"name": "李四", "chinese": 76, "math": 81, "english": 90, "total": 247},
{"name": "王五", "chinese": 95, "math": 89, "english": 87, "total": 271},
]
name = input("请输入要修改的学生姓名:")
for student in student_list:
if name == student["name"]:
# 输入为空时,保留原来的内容
print("直接按回车可以保留原内容")
new_name = input("请输入姓名:")
if new_name:
student["name"] = new_name
chinese = input("请输入语文成绩:")
if chinese:
student["chinese"] = int(chinese)
math = input("请输入数学成绩:")
if math:
student["math"] = int(math)
english = input("请输入英语成绩:")
if english:
student["english"] = int(english)
# 单科成绩可能发生变化,需要重新计算总分
student["total"] = student["chinese"] + student["math"] + student["english"]
print("学生信息修改成功")
break
else:
print("该学生不存在,请检查姓名是否输入正确")
print(student_list)三科成绩修改完成后,需要重新计算 total,否则总分会和单科成绩对不上。
案例:完整运行流程
需求: 将菜单、学生数据结构和四项记录操作组合成一个可以连续运行的基础版系统。
功能分析: 按“新增 → 显示 → 查询与修改 → 删除 → 退出”的顺序验证状态变化,重点检查修改成绩后总分是否同步更新。
前面的菜单、主循环和五项操作已经分别验证,现在把它们组合成完整程序:
menu = """**************************************************
欢迎使用【学生信息管理系统】V1.0
请选择你想要进行的操作
1. 新建学生信息
2. 显示全部信息
3. 查询学生信息
4. 修改学生信息
5. 删除学生信息
0. 退出系统
**************************************************"""
students = []
row_format = "{}\t{}\t{}\t{}\t{}"
while True:
print(menu)
action = input("请选择你想要进行的操作:")
if action == "1":
print("1. 新建学生信息")
name = input("请输入学生姓名:")
chinese = int(input("请输入语文成绩:"))
math = int(input("请输入数学成绩:"))
english = int(input("请输入英语成绩:"))
total = chinese + math + english
student = {
"name": name,
"chinese": chinese,
"math": math,
"english": english,
"total": total,
}
students.append(student)
print("学生信息添加成功")
elif action == "2":
print("2. 显示全部信息")
if students:
print("姓名\t语文\t数学\t英语\t总分")
for student in students:
print(row_format.format(*student.values()))
else:
print("暂无学生信息")
elif action == "3":
print("3. 查询学生信息")
name = input("请输入要查询的学生姓名:")
for student in students:
if name == student["name"]:
print("姓名\t语文\t数学\t英语\t总分")
print(row_format.format(*student.values()))
break
else:
print("该学生不存在,请检查姓名是否输入正确")
elif action == "4":
print("4. 修改学生信息")
name = input("请输入要修改的学生姓名:")
for student in students:
if name == student["name"]:
print("直接按回车可以保留原内容")
new_name = input("请输入学生姓名:")
if new_name:
student["name"] = new_name
chinese = input("请输入语文成绩:")
if chinese:
student["chinese"] = int(chinese)
math = input("请输入数学成绩:")
if math:
student["math"] = int(math)
english = input("请输入英语成绩:")
if english:
student["english"] = int(english)
student["total"] = (
student["chinese"] + student["math"] + student["english"]
)
print("学生信息修改成功")
break
else:
print("该学生不存在,请检查姓名是否输入正确")
elif action == "5":
print("5. 删除学生信息")
name = input("请输入要删除的学生姓名:")
for student in students:
if name == student["name"]:
students.remove(student)
print("学生信息删除成功")
break
else:
print("该学生不存在,请检查姓名是否输入正确")
elif action == "0":
print("感谢使用学生信息管理系统,再见!")
break
else:
print("请输入正确的功能编号")运行程序后,按下面的顺序验证完整流程:
- 新增一名学生
- 显示全部信息,检查是否添加成功
- 查询并修改这名学生
- 再次显示全部信息,检查总分是否更新
- 删除这名学生
- 输入
0退出系统
下一节继续完善
当前学生列表只保存在内存中,程序退出后数据会消失。下一节学习文件操作后,再为系统补上加载和保存功能。
小结
这个案例需要回答四个问题:
- 如何用
while True组织持续运行的菜单? - 如何用列表保存多名学生的信息?
- 如何用字典保存一名学生的各项字段?
- 如何通过遍历列表完成显示、查询、修改和删除?
练习
- 给学生字典增加一个
phone字段 - 显示全部信息时,如果列表为空,提示“暂无学生信息”
- 删除学生前增加一次确认,输入
y才真正删除 - 思考当前程序遇到同名学生时会发生什么