【Python实现】学员管理系统(详细解析)

article/2025/11/11 13:30:36

目录

  • 1、总体要求
  • 2、需求分析
  • 3、框架设计
  • 4、细节设计
    • 4.1 程序入口
    • 4.2 学员管理类
      • 4.2.1 初始化
      • 4.2.2 登录认证
      • 4.2.3 功能菜单
      • 4.2.4 文件操作
      • 4.2.5 新增学员
      • 4.2.6 删除学员
      • 4.2.7 修改学员
      • 4.2.8 查找学员
      • 4.2.9 显示全部学员
      • 4.2.10 学员数据统计
      • 4.2.11 清空系统数据
  • 5、总结

1、总体要求

  • 学员信息管理系统
    ------ 用于管理学员的相关信息,其中,学号为学员的唯一识别信息,不能重复,姓名和其他的信息可以重复。

    以下为基本功能要求:
    (1)登录认证:要求先通过用户名和密码验证,通过之后才能进入系统进行相应的功能使用,如果可以有管理员和普通用户的区分会更好,不同的用户分配不同的操作权限。
    (2)新增学员信息:可以连续增加多个学员信息,增加完成后提示是否继续、保存、退出等。
    (3)删除学员信息:先显示学员列表给用户看,然后再删除对应学员,删除完成后提示是否继续、保存、退出等。
    (4)修改学员信息:若添加信息时输入错误可进行修改,同样先把学员列表显示出来,再让用户选择相应信息进行修改,修改完成后提示是否继续、保存、退出等。
    (5)查找学员信息:根据学员姓名,查询该学员的相关信息。
    (6)显示全部学员:直接展示所有学员的全部信息,可以选择按添加时间顺序或者按学号的顺序来显示。
    (7)学员统计分析:对所有学员的相关信息进行统计,显示男女性别分布和年龄分布等情况。
    (8)文件操作:进行新增、删除和修改操作的时候,可以自动将学员的信息写入文件,进行永久存储,下次使用管理系统的时候,先读取文件里面的信息,然后进行新的操作。


2、需求分析

  • 基本思路

    (1)按照以上要求,可以成设计一个学员管理的类,相关的各个功能以类方法的形式来处理实现;
    (2)学员管理系统,由若干个学员的信息组成,每个学员的信息包括:学号、姓名、性别、年龄、爱好,可以以字典来存放;
    (3)先设置程序入口,并用学员管理类创建一个学员管理的对象,用此对象来调用类的各种方法:首先调用登录认证,验证通过之后再调用主要的逻辑实现方法,在主方法中去调用增、删、改、查等各个功能实现方法;
    (4)类的主方法中显示功能菜单,供用户选择操作。每选择一个功能,都会进入新的页面,每次操作完成后返回主页,依旧显示功能菜单,直至用户退出系统。


3、框架设计

# 定义学员管理类
class Student_Manager(object):# 初始化...(可以把各个功能实现需要用到的临时变量在此处创建并初始化)def __init__(self):pass# 登录认证--不同用户实现不同的功能权限def login_auth(self):pass# 显示功能选项def login_welcome(self):pass# 主功能页面--前提是通过了登录认证def main(self):pass# 新增学员信息--可以连续添加多个学员信息def add_student_data(self)pass# 删除学员信息def remove_student_data(self):pass# 修改学员信息def mod_student_data(self):pass# 查找学员信息--根据姓名查找,重名的需要全部显示出来def srh_student_data(self):pass# 显示全部学员--可选显示顺序def display_student_data(self):pass# 数据统计--统计男女学员人数、年龄段分布等def data_statistics(self):pass# 清空系统数据def clear_student_data(self):pass# 保存数据--将临时变量self.student_list里面的学生信息遍历出来,保存到txt文件def save_student_data(self):pass# 读取数据--读取过去存储数据的txt文件,将里面数据存到临时变量self.student_list中def read_student_data(self):pass# 程序入口
if __name__ == "__main__":# 创建对象manager = Student_Manager()# 先进行登录验证manager.login_auth()# 通过验证后再调用主方法manager.main()

4、细节设计


4.1 程序入口

if __name__ == "__main__":manager = Student_Manager()var1 = manager.login_auth()# 通过了认证即可执行main()方法if var1 == "已取得全部权限" or var1 == "已取得只读权限":manager.main(var1)# 没通过认证,啥也别谈else:print(var1)

4.2 学员管理类

4.2.1 初始化

首先在创建类时,需要将后续要用的临时变量进行初始化。功能选项可以打包成字典,让功能函数与键之间建立映射关系。允许登录的用户的用户名、密码以及他们的不同权限,都可以在此处先声明好。

class Student_Manager(object):def __init__(self):self.student_list = []    # 用于存放学员信息,单个学员的信息以字典的形式存在self.id_list = []         # 用于存放学员的学号,便于判断后续新增或者修改时候会不会重号# 选项功能字典self.option_func_dict = {'1': self.add_student_data,'2': self.remove_student_data,'3': self.mod_student_data,'4': self.srh_student_data,'5': self.display_student_data,'6': self.data_statistics,'7': self.clear_student_data}# 已授权的用户列表self.user_list = [{'username': 'admin', 'password': '1234', 'permission': '全部权限'},{'username': 'guest', 'password': '0000', 'permission': '只读权限'}]

4.2.2 登录认证

# 登录认证--不同用户实现不同的功能权限def login_auth(self):print("=" * 12, "欢迎登录学员管理系统", "=" * 12)for i in range(5):    # 设置登录认证次数为5次username = input("用户名:").strip()password = input("密码:").strip()for user in self.user_list:if username == user['username'] and password == user['password']:# 判断用户权限,执行相应权限的功能if user['permission'] == '全部权限':return "已取得全部权限"elif user['permission'] == '只读权限':return "已取得只读权限"else:if i < (5 - 1):print(f"用户名或密码错误,剩余验证次数{4 - i}次,请重新输入。")else:print(f"用户名或密码错误,今日验证次数已用完,请明天再尝试登录。")input("按任意键关闭程序...")return "---大宝天天见!---"

让用户名和密码的验证只能循环固定次数,即相当于限制登录验证次数,这样可以提高系统的安全性,效果如下:

在这里插入图片描述

全部权限和只读权限的选项功能界面一样,但是只读权限的用户无法使用添加、删除和修改这样一些需要写入的权限的功能,效果如下:

在这里插入图片描述

4.2.3 功能菜单

# 显示功能选项def login_welcome(self):print("=" * 12, "欢迎进入学员管理系统", "=" * 12)print('\t', "*" * 5, "1、添加学员信息", "*" * 5)print('\t', "*" * 5, "2、删除学员信息", "*" * 5)print('\t', "*" * 5, "3、修改学员信息", "*" * 5)print('\t', "*" * 5, "4、查找学员信息", "*" * 5)print('\t', "*" * 5, "5、显示全部学员", "*" * 5)print('\t', "*" * 5, "6、学员统计信息", "*" * 5)print('\t', "*" * 5, "7、清空系统数据", "*" * 5)print('\t', "*" * 5, "0、退出管理系统", "*" * 5)print("=" * 46)# 主功能页面--前提是通过了登录认证def main(self, temp):while True:self.login_welcome()       # 显示欢迎界面,给出功能选项self.student_list.clear()  # 清空学员列表self.id_list.clear()       # 清空学员学号列表self.read_student_data()   # 读取已经存储到txt内的数据,重新赋值给student_listoption = input("请输入数字,选择对应的功能:").strip()if option == "0":print("~~~欢迎下次使用~~~")input("按任意键关闭程序...")breakelif option in self.option_func_dict:if temp == "已取得全部权限":self.option_func_dict[option]()  # 根据键值直接调用对应功能函数elif temp == "已取得只读权限":if option == "1" or option == "2" or option == "3" or option == "7":print("当前用户权限不足!你仅可以选择4、5、6对应功能,或者退出系统。")input("按任意键返回主页...")elif option == "4":self.srh_student_data()elif option == "5":self.display_student_data()elif option == "6":self.data_statistics()else:print("~~~输入错误,请输入正确的数字!~~~")input("按任意键返回主页...")

效果如下(后面效果皆展示使用具有全部权限的账号登录认证成功后的效果):

在这里插入图片描述

4.2.4 文件操作

  • 读取文件
    ------ 每次返回主页功能选项界面后,需要重新读取文件内数据,因为有些操作会更新文件内数据。
 # 读取数据--读取过去存储数据的txt文件,将里面数据存到临时变量self.student_list中def read_student_data(self):try:with open("./student_data.txt", "r", encoding="utf-8") as f:# 避开第一行的标题,从第二行开始遍历,将数据存储到临时变量self.student_listfor line in f.readlines()[1:]:stu_id, stu_name, stu_sex, stu_age, stu_hobby = line.strip().split("\t")student = {'学号': stu_id, '姓名': stu_name, '性别': stu_sex, '年龄': stu_age, '爱好': stu_hobby}self.student_list.append(student)self.id_list.append(stu_id)except (FileNotFoundError, ValueError):   # 避免初次启动时,因为txt文件还没创建或者为空而报错print("当前学员系统暂无数据,请先添加学员信息!")

首次使用的时候,因为文件为空,所以用 try…except…来捕捉异常,避免读取文件时报错导致程序无法运行。

初次运行时,文件为空

初次进入管理系统后,读取效果如下:

在这里插入图片描述

  • 写入文件
    ------ 每次用户进行新增、删除、修改、清空等操作时,提示用户保存,如果保存,就将数据写入txt文件。
# 保存数据--将临时变量self.student_list里面的学生信息遍历出来,保存到txt文件def save_student_data(self):if self.student_list:    # 判断学员列表是否为空,只有列表不为空才执行写入with open("./student_data.txt", "w", encoding="utf-8") as f:f.write("学号\t姓名\t性别\t年龄\t爱好\n")    # 首行写入标题,便于用户查看文件for student in self.student_list:f.write(f"{student['学号']}\t{student['姓名']}\t{student['性别']}\t{student['年龄']}\t{student['爱好']}\n")print("---保存成功---")else:print("---暂无数据需要保存---")

4.2.5 新增学员

# 新增学员信息--可以连续添加多个学员信息def add_student_data(self):print("=" * 12, "欢迎进入新增学员系统", "=" * 12)while True:stu_id = input("请输入学员学号:").strip()if stu_id in self.id_list:print(f"学号{stu_id}---已存在,请重新输入!")continuestudent = {'学号': stu_id,'姓名': input("请输入学员姓名:").strip(),'性别': input("请输入学员性别:").strip(),'年龄': input("请输入学员年龄:").strip(),'爱好': input("请输入学员爱好:").strip()}for value in student.values():if not value:print(f"信息不能为空---添加失败,请重新输入!")breakelse:self.student_list.append(student)self.id_list.append(stu_id)print(f"{student['学号']}号学员:{student['姓名']}---添加成功!")num = input("是否继续添加(1:继续,2:保存并退出,3:不保存并退出):").strip()if num == '2':self.save_student_data()breakif num == '3':break

在这里插入图片描述

选择新增功能后,进入新界面,效果如下:

在这里插入图片描述

因为学号是唯一的,所以在后面继续添加学员的时候,如果重号了,会提示用户重新输入。

在这里插入图片描述

最后添加完成选择保存后,我们可以看下txt文件已经被成功写入数据:

在这里插入图片描述

4.2.6 删除学员

# 删除学员信息def remove_student_data(self):print("=" * 12, "欢迎进入删减学员系统", "=" * 12)if self.student_list:  # 先判断数据是否为空,避免进入死循环print("学员列表如下:")  # 先打印下学员列表,避免输入不存在的学员信息,优化用户体验for index, student in enumerate(self.student_list):print(f"索引值:{index}-- 学号:{student['学号']},姓名:{student['姓名']},性别:{student['性别']},年龄:{student['年龄']},爱好:{student['爱好']}")while True:try:index = int(input("请选择要删除的学员信息(输入对应索引值):").strip())student = self.student_list[index]self.student_list.remove(student)self.id_list.remove(student['学号'])print(f"{student['学号']}号学员:{student['姓名']}---删除成功!")except (IndexError, ValueError):   # 防止输入非整数类型或者超出索引而发生报错print("索引值错误,请重新输入!")continuenum = input("是否继续删除(1:继续,2:保存并退出,3:不保存并退出):").strip()if num == '2':self.save_student_data()breakif num == '3':breakelse:print("当前学员系统暂无数据!")input("按任意键返回主页...")

选择保存后,效果如下:(如果不保存退出,则txt文件内的数据不会发生改变)

在这里插入图片描述
在这里插入图片描述

4.2.7 修改学员

# 修改学员信息def mod_student_data(self):print("=" * 12, "欢迎进入修改学员系统", "=" * 12)if self.student_list:  # 先判断数据是否为空,避免进入死循环print("学员列表如下:")  # 先打印下学员列表,避免输入不存在的学员信息,优化用户体验for index, student in enumerate(self.student_list):print(f"索引值:{index}-- 学号:{student['学号']},姓名:{student['姓名']},性别:{student['性别']},年龄:{student['年龄']},爱好:{student['爱好']}")while True:try:index = int(input("请选择要修改的学员信息(输入对应索引值):").strip())student = self.student_list[index]self.mod_choice(student)  # 直接传递所选学员字典except (IndexError, ValueError):       # 防止输入非整数类型或者超出索引而发生报错print("索引值错误,请重新输入!")continuenum = input("是否继续修改(1:继续,2:保存并退出,3:不保存并退出):").strip()if num == '2':self.save_student_data()breakif num == '3':breakelse:print("当前学员系统暂无数据!")input("按任意键返回主页...")

为了优化用户体验,我们允许用户选择具体修改某一项信息或者全部信息,具体代码实现如下:

# 具体修改选项--优化用户体验,让用户可以选择需要修改的具体信息def mod_choice(self, student):print("该学员信息如下:")print(f"学号:{student['学号']},姓名:{student['姓名']},性别:{student['性别']},年龄:{student['年龄']},爱好:{student['爱好']}")print("请选择要修改的信息:")print("1:全部修改  2:仅学号  3:仅姓名  4:仅性别  5:仅年龄  6:仅爱好")num = input("请输入数字选择要修改的信息:").strip()if num == '1':while True:new_id = input("请输入修改后的学号:").strip()if new_id not in self.id_list or new_id == student['学号']:self.id_list.remove(student['学号'])student['学号'] = new_idstudent['姓名'] = input("请输入修改后的姓名:").strip()student['性别'] = input("请输入修改后的性别:").strip()student['年龄'] = input("请输入修改后的年龄:").strip()student['爱好'] = input("请输入修改后的爱好:").strip()self.id_list.append(student['学号'])breakelse:print(f"学号{new_id}---已存在,请重新输入!")elif num == '2':while True:new_id = input("请输入修改后的学号:").strip()if new_id not in self.id_list:self.id_list.remove(student['学号'])student['学号'] = new_idself.id_list.append(student['学号'])breakelse:print(f"学号{new_id}---已存在,请重新输入!")elif num == '3':student['姓名'] = input("请输入修改后的姓名:").strip()elif num == '4':student['性别'] = input("请输入修改后的性别:").strip()elif num == '5':student['年龄'] = input("请输入修改后的年龄:").strip()elif num == '6':student['爱好'] = input("请输入修改后的爱好:").strip()else:print("~~~输入错误,请输入正确的数字!~~~")return self.mod_choice(student)print(f"{student['学号']}号学员:{student['姓名']}---修改成功!")print("修改后信息为:")print(f"学号:{student['学号']},姓名:{student['姓名']},性别:{student['性别']},年龄:{student['年龄']},爱好:{student['爱好']}")

可以选择修改某一项信息,也可以选择修改全部信息,实现效果如下:

在这里插入图片描述
在这里插入图片描述

更多效果,大家可以自行尝试,如遇到bug,欢迎大家与我分享交流~

4.2.8 查找学员

# 查找学员信息--根据姓名查找,重名的需要全部显示出来def srh_student_data(self):print("=" * 12, "欢迎进入学员查询系统", "=" * 12)if self.student_list:  # 先判断数据是否为空,避免进入死循环while True:# 将所有学员的姓名暂时存储到一个列表中,用于判断name_list = [student["姓名"] for student in self.student_list]stu_name = input("请输入要查找的学员姓名:").strip()if name_list.count(stu_name) == 0:print(f"姓名为{stu_name}的学员---不存在!")else:for student in self.student_list:if student["姓名"] == stu_name:print(f"学号:{student['学号']},姓名:{student['姓名']},性别:{student['性别']},年龄:{student['年龄']},爱好:{student['爱好']}")num = input("是否继续查找(1:继续,2:退出):").strip()if num == '2':breakelse:print("当前学员系统暂无数据!")input("按任意键返回主页...")

不管要查找的学员是否存在,或者有同名的多个学员,都给出对应的提示和结果,效果如下:

在这里插入图片描述

4.2.9 显示全部学员

# 显示全部学员--可选显示顺序def display_student_data(self):print("=" * 12, "欢迎进入学员展示系统", "=" * 12)if self.student_list:  # 判断数据是否为空,避免报错num = input("请选择显示方式(1:按学员添加时间顺序,2:按学号排序):").strip()if num == '2':self.student_list.sort(key=lambda x: x['学号'])print("学员列表如下:")for index, student in enumerate(self.student_list):print(f"索引值:{index}-- 学号:{student['学号']},姓名:{student['姓名']},性别:{student['性别']},年龄:{student['年龄']},爱好:{student['爱好']}")else:print("当前学员系统暂无数据!")input("按任意键返回主页...")

效果如下:

在这里插入图片描述

4.2.10 学员数据统计

# 数据统计--统计男女学员人数、年龄段分布等def data_statistics(self):print("=" * 12, "欢迎进入学员统计系统", "=" * 12)if self.student_list:  # 先判断数据是否为空,避免报错print(f"当前学员总人数:{len(self.student_list)}人")male_num = female_num = 0yong_num = middle_num = large_num = old_num = older_num = grandpa_num = 0age_list = []for student in self.student_list:if student["性别"] == "男":male_num += 1if student["性别"] == "女":female_num += 1if int(student["年龄"]) <= 20:yong_num += 1if 20 < int(student["年龄"]) <= 30:middle_num += 1if 30 < int(student["年龄"]) <= 40:large_num += 1if 40 < int(student["年龄"]) <= 50:old_num += 1if 50 < int(student["年龄"]) <= 60:older_num += 1if int(student["年龄"]) > 60:grandpa_num += 1age_list.append(int(student["年龄"]))other_num = len(self.student_list) - male_num - female_numprint("男女性别分布如下:")print(f"男性学员数量:{male_num}人,占比:{male_num / len(self.student_list):.1%}")print(f"女性学员数量:{female_num}人,占比:{female_num / len(self.student_list):.1%}")print(f"无性别学员数量:{other_num}人,占比:{other_num / len(self.student_list):.1%}\n")print("各年龄段分布:")print(f"20岁(含20)以下学员数量:{yong_num}人,占比:{yong_num / len(self.student_list):.1%}")print(f"20-30岁(含30)学员数量:{middle_num}人,占比:{middle_num / len(self.student_list):.1%}")print(f"30-40岁(含40)学员数量:{large_num}人, 占比:{large_num / len(self.student_list):.1%}")print(f"40-50岁(含50)学员数量:{old_num}人, 占比:{old_num / len(self.student_list):.1%}")print(f"50-60岁(含60)学员数量:{older_num}人, 占比:{older_num / len(self.student_list):.1%}")print(f"60岁以上学员数量:{grandpa_num}人,占比:{grandpa_num / len(self.student_list):.1%}")print(f"平均年龄水平:{sum(age_list)/len(age_list):.1f}岁")else:print("当前学员系统暂无数据!")input("按任意键返回主页...")

学员数据统计效果如下:

在这里插入图片描述

4.2.11 清空系统数据

------ 为了优化体验,增加一个清空系统数据的功能。

# 清空系统数据def clear_student_data(self):print("=" * 12, "欢迎进入学员清空系统", "=" * 12)if self.student_list:  # 先判断数据是否为空print("重要提示:数据清空后,无法恢复,请谨慎操作!!!")num = input("请确认是否清空(1:确认,2:取消):").strip()if num == "1":self.student_list = [{'学号': "", '姓名': "", '性别': "", '年龄': "", '爱好': ""}]  # 放入空值字典,防止save的时候判断为空而不执行保存self.id_list.clear()self.save_student_data()print("---系统数据已全部清空---")else:print("---已取消清空---")else:print("当前学员系统暂无数据!")input("按任意键返回主页...")

因为清空操作比较敏感,选择进入该功能页面后第一时间给出用户“重要提醒”,然后再让用户确认清空操作,如果取消,保存数据的文件就不会发生任何变动;如果确认清空,则将学员列表清空后,存入一个空值的字典数据到文件中,效果如下:

在这里插入图片描述

可以打开txt文件检查,里面的学员数据已经被清空,只保留了标题信息,效果如下:

在这里插入图片描述


5、总结

  • 代码结构:代码结构比较清晰,注释充足且易于理解,但是还存在很大优化空间。
  • 功能实现:代码实现的学员管理系统的主要功能比较完整,包括增删改查统计等,这些功能的实现基本上符合需求。
  • 异常处理:代码实现中考虑到了各种异常情况,具备了一定的异常处理能力。比如,在删除和修改功能中,如果输入的索引值不存在,会给出提示而不是直接报错。还有初次启动程序时,文件不存在或者为空,也会给出提示而不是报错。
  • 性能优化: 代码在性能方面没有太大问题,对于这种较小的系统来说效率是可以接受的。但如果要处理的数据量较大,可能需要更高效的数据结构,或者更优的设计思路。
  • 用户体验:在功能实现上,代码可读性较高,变量命名规范。但是print语句较多,如果学员数量较大,打印内容会过多,影响用户体验。
  • 其他:以上代码中数据存储是列表形式,如果学员数量较大,索引查询效率会变低,可以改为字典形式存储。(此条为小伙伴的建议,暂时还未完成测试是否有助提高效率)

完整代码如下:
------ 欢迎大家提出宝贵意见,我们相互交流学习,共同进步。

class Student_Manager(object):# 初始化...def __init__(self):self.student_list = []self.id_list = []# 选项功能字典self.option_func_dict = {'1': self.add_student_data,'2': self.remove_student_data,'3': self.mod_student_data,'4': self.srh_student_data,'5': self.display_student_data,'6': self.data_statistics,'7': self.clear_student_data}# 已授权的用户列表self.user_list = [{'username': 'admin', 'password': '1234', 'permission': '全部权限'},{'username': 'guest', 'password': '0000', 'permission': '只读权限'}]# 新增学员信息--可以连续添加多个学员信息def add_student_data(self):print("=" * 12, "欢迎进入新增学员系统", "=" * 12)while True:stu_id = input("请输入学员学号:").strip()if stu_id in self.id_list:print(f"学号{stu_id}---已存在,请重新输入!")continuestudent = {'学号': stu_id,'姓名': input("请输入学员姓名:").strip(),'性别': input("请输入学员性别:").strip(),'年龄': input("请输入学员年龄:").strip(),'爱好': input("请输入学员爱好:").strip()}for value in student.values():if not value:print(f"信息不能为空---添加失败,请重新输入!")breakelse:self.student_list.append(student)self.id_list.append(stu_id)print(f"{student['学号']}号学员:{student['姓名']}---添加成功!")num = input("是否继续添加(1:继续,2:保存并退出,3:不保存并退出):").strip()if num == '2':self.save_student_data()breakif num == '3':break# 删除学员信息def remove_student_data(self):print("=" * 12, "欢迎进入删减学员系统", "=" * 12)if self.student_list:  # 先判断数据是否为空,避免进入死循环print("学员列表如下:")  # 先打印下学员列表,避免输入不存在的学员信息,优化用户体验for index, student in enumerate(self.student_list):print(f"索引值:{index}-- 学号:{student['学号']},姓名:{student['姓名']},性别:{student['性别']},年龄:{student['年龄']},爱好:{student['爱好']}")while True:try:index = int(input("请选择要删除的学员信息(输入对应索引值):").strip())student = self.student_list[index]self.student_list.remove(student)self.id_list.remove(student['学号'])print(f"{student['学号']}号学员:{student['姓名']}---删除成功!")except (IndexError, ValueError):   # 防止输入非整数类型或者超出索引而发生报错print("索引值错误,请重新输入!")continuenum = input("是否继续删除(1:继续,2:保存并退出,3:不保存并退出):").strip()if num == '2':self.save_student_data()breakif num == '3':breakelse:print("当前学员系统暂无数据!")input("按任意键返回主页...")# 修改学员信息def mod_student_data(self):print("=" * 12, "欢迎进入修改学员系统", "=" * 12)if self.student_list:  # 先判断数据是否为空,避免进入死循环print("学员列表如下:")  # 先打印下学员列表,避免输入不存在的学员信息,优化用户体验for index, student in enumerate(self.student_list):print(f"索引值:{index}-- 学号:{student['学号']},姓名:{student['姓名']},性别:{student['性别']},年龄:{student['年龄']},爱好:{student['爱好']}")while True:try:index = int(input("请选择要修改的学员信息(输入对应索引值):").strip())student = self.student_list[index]self.mod_choice(student)  # 直接传递所选学员字典except (IndexError, ValueError):       # 防止输入非整数类型或者超出索引而发生报错print("索引值错误,请重新输入!")continuenum = input("是否继续修改(1:继续,2:保存并退出,3:不保存并退出):").strip()if num == '2':self.save_student_data()breakif num == '3':breakelse:print("当前学员系统暂无数据!")input("按任意键返回主页...")# 具体修改选项--优化用户体验,让用户可以选择需要修改的具体信息def mod_choice(self, student):print("该学员信息如下:")print(f"学号:{student['学号']},姓名:{student['姓名']},性别:{student['性别']},年龄:{student['年龄']},爱好:{student['爱好']}")print("请选择要修改的信息:")print("1:全部修改  2:仅学号  3:仅姓名  4:仅性别  5:仅年龄  6:仅爱好")num = input("请输入数字选择要修改的信息:").strip()if num == '1':while True:new_id = input("请输入修改后的学号:").strip()if new_id not in self.id_list or new_id == student['学号']:self.id_list.remove(student['学号'])student['学号'] = new_idstudent['姓名'] = input("请输入修改后的姓名:").strip()student['性别'] = input("请输入修改后的性别:").strip()student['年龄'] = input("请输入修改后的年龄:").strip()student['爱好'] = input("请输入修改后的爱好:").strip()self.id_list.append(student['学号'])breakelse:print(f"学号{new_id}---已存在,请重新输入!")elif num == '2':while True:new_id = input("请输入修改后的学号:").strip()if new_id not in self.id_list:self.id_list.remove(student['学号'])student['学号'] = new_idself.id_list.append(student['学号'])breakelse:print(f"学号{new_id}---已存在,请重新输入!")elif num == '3':student['姓名'] = input("请输入修改后的姓名:").strip()elif num == '4':student['性别'] = input("请输入修改后的性别:").strip()elif num == '5':student['年龄'] = input("请输入修改后的年龄:").strip()elif num == '6':student['爱好'] = input("请输入修改后的爱好:").strip()else:print("~~~输入错误,请输入正确的数字!~~~")return self.mod_choice(student)print(f"{student['学号']}号学员:{student['姓名']}---修改成功!")print("修改后信息为:")print(f"学号:{student['学号']},姓名:{student['姓名']},性别:{student['性别']},年龄:{student['年龄']},爱好:{student['爱好']}")# 查找学员信息--根据姓名查找,重名的需要全部显示出来def srh_student_data(self):print("=" * 12, "欢迎进入学员查询系统", "=" * 12)if self.student_list:  # 先判断数据是否为空,避免进入死循环while True:# 将所有学员的姓名暂时存储到一个列表中,用于判断name_list = [student["姓名"] for student in self.student_list]stu_name = input("请输入要查找的学员姓名:").strip()if name_list.count(stu_name) == 0:print(f"姓名为{stu_name}的学员---不存在!")else:for student in self.student_list:if student["姓名"] == stu_name:print(f"学号:{student['学号']},姓名:{student['姓名']},性别:{student['性别']},年龄:{student['年龄']},爱好:{student['爱好']}")num = input("是否继续查找(1:继续,2:退出):").strip()if num == '2':breakelse:print("当前学员系统暂无数据!")input("按任意键返回主页...")# 显示全部学员--可选显示顺序def display_student_data(self):print("=" * 12, "欢迎进入学员展示系统", "=" * 12)if self.student_list:  # 判断数据是否为空,避免报错num = input("请选择显示方式(1:按学员添加时间顺序,2:按学号排序):").strip()if num == '2':self.student_list.sort(key=lambda x: x['学号'])print("学员列表如下:")for index, student in enumerate(self.student_list):print(f"索引值:{index}-- 学号:{student['学号']},姓名:{student['姓名']},性别:{student['性别']},年龄:{student['年龄']},爱好:{student['爱好']}")else:print("当前学员系统暂无数据!")input("按任意键返回主页...")# 数据统计--统计男女学员人数、年龄段分布等def data_statistics(self):print("=" * 12, "欢迎进入学员统计系统", "=" * 12)if self.student_list:  # 先判断数据是否为空,避免报错print(f"当前学员总人数:{len(self.student_list)}人")male_num = female_num = 0yong_num = middle_num = large_num = old_num = older_num = grandpa_num = 0age_list = []for student in self.student_list:if student["性别"] == "男":male_num += 1if student["性别"] == "女":female_num += 1if int(student["年龄"]) <= 20:yong_num += 1if 20 < int(student["年龄"]) <= 30:middle_num += 1if 30 < int(student["年龄"]) <= 40:large_num += 1if 40 < int(student["年龄"]) <= 50:old_num += 1if 50 < int(student["年龄"]) <= 60:older_num += 1if int(student["年龄"]) > 60:grandpa_num += 1age_list.append(int(student["年龄"]))other_num = len(self.student_list) - male_num - female_numprint("男女性别分布如下:")print(f"男性学员数量:{male_num}人,占比:{male_num / len(self.student_list):.1%}")print(f"女性学员数量:{female_num}人,占比:{female_num / len(self.student_list):.1%}")print(f"无性别学员数量:{other_num}人,占比:{other_num / len(self.student_list):.1%}\n")print("各年龄段分布:")print(f"20岁(含20)以下学员数量:{yong_num}人,占比:{yong_num / len(self.student_list):.1%}")print(f"20-30岁(含30)学员数量:{middle_num}人,占比:{middle_num / len(self.student_list):.1%}")print(f"30-40岁(含40)学员数量:{large_num}人, 占比:{large_num / len(self.student_list):.1%}")print(f"40-50岁(含50)学员数量:{old_num}人, 占比:{old_num / len(self.student_list):.1%}")print(f"50-60岁(含60)学员数量:{older_num}人, 占比:{older_num / len(self.student_list):.1%}")print(f"60岁以上学员数量:{grandpa_num}人,占比:{grandpa_num / len(self.student_list):.1%}")print(f"平均年龄水平:{sum(age_list)/len(age_list):.1f}岁")else:print("当前学员系统暂无数据!")input("按任意键返回主页...")# 清空系统数据def clear_student_data(self):print("=" * 12, "欢迎进入学员清空系统", "=" * 12)if self.student_list:  # 先判断数据是否为空print("重要提示:数据清空后,无法恢复,请谨慎操作!!!")num = input("请确认是否清空(1:确认,2:取消):").strip()if num == "1":self.student_list = [{'学号': "", '姓名': "", '性别': "", '年龄': "", '爱好': ""}]  # 放入空值字典,防止save的时候判断为空而不执行保存self.id_list.clear()self.save_student_data()print("---系统数据已全部清空---")else:print("---已取消清空---")else:print("当前学员系统暂无数据!")input("按任意键返回主页...")# 保存数据--将临时变量self.student_list里面的学生信息遍历出来,保存到txt文件def save_student_data(self):if self.student_list:  # 判断学员列表是否为空,只有列表不为空才执行写入with open("./student_data.txt", "w", encoding="utf-8") as f:f.write("学号\t姓名\t性别\t年龄\t爱好\n")   # 首行写入标题,便于用户查看文件for student in self.student_list:f.write(f"{student['学号']}\t{student['姓名']}\t{student['性别']}\t{student['年龄']}\t{student['爱好']}\n")print("---保存成功---")else:print("---暂无数据需要保存---")# 读取数据--读取过去存储数据的txt文件,将里面数据存到临时变量self.student_list中def read_student_data(self):try:with open("./student_data.txt", "r", encoding="utf-8") as f:# 避开第一行的标题,从第二行开始遍历,将数据存储到临时变量self.student_listfor line in f.readlines()[1:]:stu_id, stu_name, stu_sex, stu_age, stu_hobby = line.strip().split("\t")student = {'学号': stu_id, '姓名': stu_name, '性别': stu_sex, '年龄': stu_age, '爱好': stu_hobby}self.student_list.append(student)self.id_list.append(stu_id)except (FileNotFoundError, ValueError):  # 避免初次启动时,因为txt文件还没创建或为空而报错print("当前学员系统暂无数据,请先添加学员信息!")# 登录认证--不同用户实现不同的功能权限def login_auth(self):print("=" * 12, "欢迎登录学员管理系统", "=" * 12)for i in range(5):  # 设置登录认证次数为5次username = input("用户名:").strip()password = input("密码:").strip()for user in self.user_list:if username == user['username'] and password == user['password']:# 判断用户权限,执行相应权限的功能if user['permission'] == '全部权限':return "已取得全部权限"elif user['permission'] == '只读权限':return "已取得只读权限"else:if i < (5 - 1):print(f"用户名或密码错误,剩余验证次数{4 - i}次,请重新输入。")else:print(f"用户名或密码错误,今日验证次数已用完,请明天再尝试登录。")input("按任意键关闭程序...")return "---大宝天天见!---"# 显示功能选项def login_welcome(self):print("=" * 12, "欢迎进入学员管理系统", "=" * 12)print('\t', "*" * 5, "1、添加学员信息", "*" * 5)print('\t', "*" * 5, "2、删除学员信息", "*" * 5)print('\t', "*" * 5, "3、修改学员信息", "*" * 5)print('\t', "*" * 5, "4、查找学员信息", "*" * 5)print('\t', "*" * 5, "5、显示全部学员", "*" * 5)print('\t', "*" * 5, "6、学员统计信息", "*" * 5)print('\t', "*" * 5, "7、清空系统数据", "*" * 5)print('\t', "*" * 5, "0、退出管理系统", "*" * 5)print("=" * 46)# 主功能页面--前提是通过了登录认证def main(self, temp):while True:self.login_welcome()  # 打印欢迎界面self.student_list.clear()  # 清空学员列表self.id_list.clear()  # 清空学员学号列表self.read_student_data()  # 读取已经存储到txt内的数据,重新赋值给student_listoption = input("请输入数字,选择对应的功能:").strip()if option == "0":print("~~~欢迎下次使用~~~")input("按任意键关闭程序...")breakelif option in self.option_func_dict:if temp == "已取得全部权限":self.option_func_dict[option]()  # 根据键值直接调用对应功能函数elif temp == "已取得只读权限":if option == "1" or option == "2" or option == "3" or option == "7":print("当前用户权限不足!你仅可以选择4、5、6对应功能,或者退出系统。")input("按任意键返回主页...")elif option == "4":self.srh_student_data()elif option == "5":self.display_student_data()elif option == "6":self.data_statistics()else:print("~~~输入错误,请输入正确的数字!~~~")input("按任意键返回主页...")# 程序入口
if __name__ == "__main__":manager = Student_Manager()var1 = manager.login_auth()# 通过了认证即可执行main()方法if var1 == "已取得全部权限" or var1 == "已取得只读权限":manager.main(var1)# 没通过认证,啥也别谈else:print(var1)

http://chatgpt.dhexx.cn/article/mpNUJ2oL.shtml

相关文章

[Java] 学员管理系统(服务器—客户端模式)

目录 学员管理系统&#xff08;服务器—客户端模式&#xff09;1. 项目演示a. 打开项目b. 运行项目 2. 项目说明a. 所采用的知识点b. 业务交互模式图示 3. 案例代码a. 客户端i. 创建实体类 Studentii. 创建主类 MainApp b. 服务器端i. 创建实体类 Studentii. 创建服务器端线程类…

java 中 Scanner 输入

因为涉及到 io 流输入问题&#xff0c;如果不关闭会一直占用资源。所以使用过后要及时关闭&#xff0c;防止资源一直被占用。 Scanner在使用前要导入 java.util.Scanner 包 1.整数 描述: 输入一个整数&#xff0c;输出这个整数。 输入描述&#xff1a; 输入一个整数&#xff0c…

Java之键盘输入语句Scanner

文章目录 键盘输入语句1. 介绍2. 步骤3. 案例演示 键盘输入语句 1. 介绍 在编程中&#xff0c;需要接收用户输入的数据&#xff0c;就可以使用键盘输入语句来获取。Input.java , 需要一个 扫描器(对象), 就是 Scanner 2. 步骤 导入该类的所在包, java.util.*创建该类对象&a…

Java的常用输入输出语句

一、概述 输入输出可以说是计算机的基本功能。作为一种语言体系,java中主要按照流(stream)的模式来实现。其中数据的流向是按照计算机的方向确定的,流入计算机的数据流叫做输入流(inputStream),由计算机发出的数据流叫做输出流(outputStream)。 Java语言体系中,对数据流…

java中输入语句是怎么写的

java中用户输入语句的写法是&#xff1a; 1、【Scanner sc new Scanner(System.in); 】&#xff1b; 2、【String input sc.next();】。 (视频教程推荐&#xff1a;java视频) 具体代码如下&#xff1a;import java.util.Scanner; public class Number { /** * param a…

java基础之java输入输出语句

1、使用Scanner 使用时需要引入包importjava.util.Scanner;首先定义Scanner对象 Java基础学习&#xff1a;java输入输出语句 比如&#xff1a; Java基础学习&#xff1a;java输入输出语句 2、使用BufferedReader 用前需要引入importjava.io.Reader; Java基础学习&#xff1…

java 键盘输入语句怎么写

java 键盘输入语句写法 第一种&#xff1a; public class shuRu{ public static void main(string arg[]){ system.out.println(arg[1]); } } 第二种&#xff1a; import java.util.scanner; public class shuRu{ public static void main(string arg[]){ scanner i…

java语言输入语句是_java中的输入语句怎么写?

java中的输入语句怎么写&#xff1f; 发布时间&#xff1a;2020-05-20 15:19:52 来源&#xff1a;亿速云 阅读&#xff1a;206 作者&#xff1a;鸽子 java中用户输入语句的写法是&#xff1a; 1、【Scanner sc new Scanner(System.in); 】&#xff1b; 2、【String input sc.…

java 输入语句_java怎样输入语句

java输入语句的方法:1、输入单个字符【char c=(char)System.in.read()】;2、输入整数或者字符串【int a=cin.nextInt()】;3、可以用BufferedReader类输入。 java输入语句的方法: 如果你要进行输入,请一定加上两个包import java.util.*; import java.io.*; 请看下面例子用于…

java输入语句怎么写

壹哥在前面给大家讲过&#xff0c;Java中给咱们提供了有三个标准的“流”&#xff0c;他们被统称为standard streams。除了负责输出的流之外&#xff0c;还有一个负责输入的标准流&#xff0c;Java中对应的API是System.in。 与标准输出相比&#xff0c;标准输入则复杂的多。尤…

java输入语句_java输入语句是什么

Java的语句有很多&#xff0c;其中输入语句是最基本的操作之一。下面我将带大家一起了解一下要如何进行输入代码的编写。 首先当你进行输入操作前要将下面两个包给加入Java程序的包行列中。 先将java.io.*;以及java.util.*;导入Java代码中。import java.util.*; import java.io…

java输入语句

java输入语句 import java.util.Scanner;//导入 java.util 包下的 Scanner 类,用来构建Scanner对象 public class TestScanner{public static void main(String[] args){Scanner scanner new Scanner(System.in);//建立Scanner对象&#xff0c;通过System.in来读取键盘输入数…

java的四种输入方法,你会几种?

java的输入方法最常见的就是Scanner的方法&#xff0c;我经过查阅一些资料发现了输入方法原来还有那么多种&#xff0c;可以玩出不少花样&#xff0c;下面是我总结出的四种输入方式&#xff0c;有需要的可以拿去 1.Scanner相关的功能 Scanner的输入方法是最常见的一种&#x…

zzlatex制作复杂表格(跨行、跨列)

用Latex制作复杂表格&#xff0c; 需要用到\multirow宏包&#xff0c; 用\multicolumn, \multirow, \hline, \cline 四种命令来控制跨列&#xff0c;跨行&#xff0c; 横线&#xff0c; 竖线位置。 原帖请见&#xff1a; http://jhengjyun.blogspot.jp/2011/01/latexmulticolu…

HTML--table--跨行跨列

效果图 代码 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>跨行跨列</title><style type"text/css">table{border: 1px solid;width: 500px;}table td,th{border: 0.0625rem solid;text-align: c…

HTML表格标签跨行与跨列

关于行和列我们换个称呼&#xff1a;横与竖来形容&#xff0c;而<tr></tr>就是横&#xff0c;<th></th>和<td></td>代表的就是竖。rowspan的属性放置td标签中就是与下一横中td合并&#xff08;上下合并&#xff09;&#xff0c;此时要删除…

IDEA通过正则跨行搜索

idea快捷键&#xff1a;ctrlF (?is)key1.*?key2 如果想搜索同时包含key1和key2的关键词&#xff0c;同时&#xff0c;允许跨行&#xff0c;则可以这样搜索 如果没有加(?is)则是单行搜索

latex跨行跨列表格

使用revtex模板的跨行跨列表格时候不需要使用\usepackage{booktabs},否则midrule&#xff0c;toprule这些线条不能够正常显示。因此需要使用自带的线条。 下面记录一下我试用过的跨行跨列表格latex语法 \begin{table}[hb]\centering\caption{ \label{cutoff} nothing }\begin{…

Latex 跨行跨列表格

使用Latex进行论文写作时&#xff0c;常常需要制作跨行、跨列的表格。但是要制作一个美观的表格&#xff0c;还是有一点复杂的&#xff0c;这里列出一个绘制基本三线表的方法&#xff0c;以及需要注意的地方。更加复杂的表格可以此为模板修改内容。 效果&#xff1a; Latex代…

PHP数据跨行跨列处理

PS PHP数据跨行跨列处理&#xff0c;表格展示&#xff0c;Excel导出。后台是Dcat Admin,导出是"maatwebsite/excel": “^3.1” Excel效果 后台页面效果 示例代码 数据调用 可以放在Dcat对应Controller的数据仓库里面。 public function get(Grid\Model $model){// 返…