- 时长: 90 分钟
- 教学目标:
- 综合运用本系列课程所学的所有核心知识点:
- 数据结构: 列表(存储多条记录)、字典(存储单条记录的属性)。
- 控制流程: 循环(遍历、菜单循环)、条件判断(选择、验证输入)。
- 函数: 封装功能(添加、查看、查找、删除)。
- 文件操作: 读取和写入数据到文本文件,实现数据持久化。
- 错误处理:
try-except
捕获用户输入和文件操作可能出现的错误。
- 学习如何设计一个小型系统:规划功能模块、数据存储格式。
- 提升将复杂需求分解为可执行代码的能力。
- 培养程序开发中的模块化思维(用函数组织代码)。
- 体验从零开始构建一个“小型应用”的完整过程和成就感。
- 综合运用本系列课程所学的所有核心知识点:
课程内容
1. 复习与引入 (10 分钟)
- 复习: 快速回顾之前学过的所有核心概念:变量、数据类型、列表、字典、元组、集合、函数、循环、条件判断、文件操作、错误处理、
random
和os
模块。 - 提出问题: 老师提问:“我们现在掌握了很多编程‘积木块’了。列表可以存多个数据,字典可以存有标签的数据,函数可以把代码打包,文件可以把数据保存下来。那我们能不能把这些‘积木块’组合起来,做一个能管理一些数据的小程序呢?比如,管理一个简单的学生通讯录,或者一个待办事项列表,或者一个小小的图书馆藏书记录?”
- 引出综合项目: 今天,我们将挑战一个稍微复杂一点的综合项目:一个简单的学生信息管理系统。这个系统能把学生的名字、学号、年龄等信息保存到文件里,下次打开程序还能继续用,并且能实现添加、查看、查找和删除学生信息的功能。
2. 项目需求分析与系统设计 (15 分钟)
- 功能需求:
- 添加学生信息: 每次添加一个学生(姓名、学号、年龄)。
- 查看所有学生信息: 列出所有已保存的学生。
- 查找学生信息: 根据学生姓名查找并显示信息。
- 删除学生信息: 根据学生姓名删除学生记录。
- 保存/加载数据: 所有学生信息要能保存到文件,程序启动时能从文件加载。
- 友好交互: 提供菜单让用户选择功能,处理可能的错误输入。
- 数据存储设计:
- 每个学生的信息(姓名、学号、年龄)是一组关联数据 → 用字典来表示一个学生。例如:
{"name": "小明", "id": "S001", "age": 12}
。 - 所有学生的信息 → 用一个列表来存储多个学生字典。例如:
[{"name": "小明", ...}, {"name": "小红", ...}]
。 - 数据保存到文件 → 使用文本文件。每行可以存储一个学生的信息,但如何将字典转换为字符串保存?简单起见,可以把字典的关键信息(如姓名,学号,年龄)用逗号分隔成一行字符串(例如
"小明,S001,12"
),保存到文件。读取时再拆分(用.split(',')
)。
- 每个学生的信息(姓名、学号、年龄)是一组关联数据 → 用字典来表示一个学生。例如:
- 功能模块分解 (函数设计):
load_students(filename)
: 从文件加载学生数据到列表。save_students(students_list, filename)
: 将学生列表保存到文件。add_student(students_list)
: 接收用户输入,添加新学生到列表。view_students(students_list)
: 打印所有学生信息。find_student(students_list, name)
: 根据姓名查找学生,返回学生字典或 None。delete_student(students_list, name)
: 根据姓名删除学生。display_menu()
: 打印操作菜单。main_loop()
: 主程序循环,处理用户选择和调用相应函数。
3. Step by Step 实现项目代码 (40 分钟)
老师带领学生一步一步编写代码。每写一部分,都运行测试一下。
- 准备工作:
- 定义文件路径常量:
DATA_FILE = "students.txt"
- 初始化学生列表:
students = []
- 定义文件路径常量:
- 第一步:数据加载和保存函数 (
load_students
,save_students
)- 讲解文件格式:每行
姓名,学号,年龄
load_students
: 用with open(..., 'r')
逐行读取,.strip()
去除换行符,.split(',')
分割,转换为字典,添加到列表。注意try-except FileNotFoundError
。DATA_FILE = "students.txt" # 数据文件路径 def load_students(filename): students_list = [] try: with open(filename, 'r', encoding='utf-8') as f: # 指定编码防止乱码 for line in f: parts = line.strip().split(',') if len(parts) == 3: # 确保数据完整 try: student = { "name": parts[0], "id": parts[1], "age": int(parts[2]) # 年龄转换为整数 } students_list.append(student) except ValueError: print(f"警告:跳过无效行数据: {line.strip()}") except FileNotFoundError: print(f"数据文件 '{filename}' 不存在,将创建新的文件。") return students_list def save_students(students_list, filename): with open(filename, 'w', encoding='utf-8') as f: for student in students_list: # 将学生字典转换为字符串 "姓名,学号,年龄\n" f.write(f"{student['name']},{student['id']},{student['age']}\n") print("学生信息已保存到文件。") # 主程序开始时加载数据 students_data = load_students(DATA_FILE) print(f"加载了 {len(students_data)} 条学生信息。")
save_students
: 用with open(..., 'w')
遍历列表,将每个字典转换为字符串(用 f-string 格式化),写入文件。
- 讲解文件格式:每行
- 第二步:菜单显示函数 (
display_menu
)def display_menu(): print("\n--- 学生信息管理系统 ---") print("1. 添加学生") print("2. 查看所有学生") print("3. 查找学生") print("4. 删除学生") print("0. 退出系统") print("--------------------")
- 第三步:添加学生函数 (
add_student
)- 获取用户输入,进行简单验证(年龄是否是数字)。
- 创建学生字典,添加到列表中。
def add_student(students_list): print("\n--- 添加新学生 ---") name = input("请输入学生姓名:") student_id = input("请输入学生学号:") age_str = input("请输入学生年龄:") try: age = int(age_str) if age <= 0: print("年龄必须是正整数。") return # 提前结束函数 except ValueError: print("年龄输入无效,请输入数字。") return # 检查学号是否重复 (简单查找) for student in students_list: if student['id'] == student_id: print("错误:该学号已存在!") return new_student = {"name": name, "id": student_id, "age": age} students_list.append(new_student) print(f"学生 {name} 已添加成功!")
- 第四步:查看所有学生函数 (
view_students
)- 遍历列表,打印每个学生的信息。
def view_students(students_list): print("\n--- 所有学生信息 ---") if not students_list: # 判断列表是否为空 print("目前没有学生信息。") return print(f"{'姓名':<10}{'学号':<10}{'年龄':<5}") # 格式化表头 print("-" * 25) for student in students_list: print(f"{student['name']:<10}{student['id']:<10}{student['age']:<5}") print("--------------------")
- 第五步:查找学生函数 (
find_student
)- 根据姓名遍历列表,查找匹配的字典。
def find_student(students_list, name_to_find): for student in students_list: if student['name'] == name_to_find: print(f"\n--- 找到学生信息 ---") print(f"姓名: {student['name']}") print(f"学号: {student['id']}") print(f"年龄: {student['age']}") print("--------------------") return student # 找到后返回学生字典 print(f"未找到学生 '{name_to_find}'。") return None # 未找到返回 None
- 第六步:删除学生函数 (
delete_student
)- 根据姓名查找,如果找到则从列表中移除。
def delete_student(students_list, name_to_delete): found_index = -1 for i, student in enumerate(students_list): # 使用 enumerate 获取索引 if student['name'] == name_to_delete: found_index = i break # 找到第一个就停止 if found_index != -1: del students_list[found_index] # 删除对应索引的元素 print(f"学生 '{name_to_delete}' 已删除成功。") return True else: print(f"未找到学生 '{name_to_delete}'。") return False
- 第七步:主程序循环 (
main_loop
)while True
循环显示菜单,获取用户选择,调用对应函数。- 使用
if-elif-else
处理用户选择。 - 退出时保存数据。
def main_loop(): # 确保 students_data 变量能被函数内部使用 (在函数外面定义了) global students_data # 声明使用全局变量,以便在函数内部修改它 while True: display_menu() choice = input("请选择操作 (输入数字): ") if choice == '1': add_student(students_data) elif choice == '2': view_students(students_data) elif choice == '3': name = input("请输入要查找的学生姓名:") find_student(students_data, name) elif choice == '4': name = input("请输入要删除的学生姓名:") delete_student(students_data, name) elif choice == '0': print("正在保存数据并退出系统...") save_students(students_data, DATA_FILE) print("感谢使用!") break # 退出循环 else: print("无效的选择,请重新输入。")
- 最后:启动主程序
if __name__ == "__main__": # 确保这段代码只在直接运行文件时执行 main_loop()
(讲解
if __name__ == "__main__":
的作用,确保主程序代码在文件被作为模块导入时不运行)。
4. 课堂巩固练习与扩展 (15 分钟)
- 练习 1: 在
add_student
函数中,添加一个功能,检查新添加学生的学号是否重复。如果学号已经存在,就提示用户“该学号已存在,请重新输入”并取消添加。 - 练习 2: 修改
find_student
函数,让它返回找到的学生字典(如果找到),这样在main_loop
中调用它时,可以对返回的学生信息做进一步处理(例如,找到后询问用户是否要修改这个学生的信息)。 - 练习 3: (选做) 增加一个新功能:修改学生信息。
- 让用户输入要修改的学生的姓名。
- 如果找到该学生,询问用户要修改哪个信息(姓名、学号、年龄)。
- 获取新值,更新学生字典中的对应信息。
- 提示用户修改成功。
5. 总结与提问 (5 分钟)
- 回顾: 总结本节课通过一个学生信息管理系统项目,综合运用了所有核心知识点:列表存储多个学生,字典存储单个学生属性,函数封装各个功能,文件读写实现数据保存,循环构建菜单,条件判断处理选择和验证,错误处理增强健壮性。
- 提问:
- 在这个项目中,我们用列表存了什么?用字典存了什么?
- 为什么需要
load_students
和save_students
函数? - 为什么
main_loop
里要用while True
? - 你在哪些地方用到了错误处理
try-except
? - 这个项目用了哪些之前学过的“编程积木块”?
- 答疑: 回答学生问题。
6. 布置课后作业 (5 分钟)
- 作业 1: 完善课堂上练习 1、2、3 的功能(学号重复检查、
find_student
返回值、增加修改功能)。 - 作业 2: 增加一个功能:统计。
- 添加一个菜单选项 5. 统计。
- 编写一个函数
count_students_by_age(students_list, min_age, max_age)
,统计某个年龄范围内的学生数量。 - 在统计功能中,调用此函数,例如统计 10-12 岁(包含两端)的学生人数。
- 作业 3: 尝试优化数据文件格式,让每行保存的数据更清晰,例如使用 JSON 格式(可选,可能需要简单介绍
json
模块)。或者,让学生思考如何更健壮地处理文件读取时的无效数据行。 - 作业 4: (选做) 将这个系统扩展为一个简单的商品管理系统:
- 存储商品名称、价格、库存。
- 实现添加、查看、查找、删除、修改商品的功能。
- 所有数据也要能保存到文件。
- 本网站名称:系统驰云
- 本站永久网址:https://blog.xxyyo.com
- 本网站的内容均来源于网络,仅供大家学习与交流,如有侵权,请联系站长365919529@qq.com删除处理。
- 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
- 本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
- 本站资源大多存储在云盘,如发现链接失效,请联系我们我们会第一时间更新。365919529@qq.com
评论(0)