You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

350 lines
13 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

from datetime import date, datetime
from typing import List, Optional
from ..bll.student_bll import StudentBLL
from ..model.student import Student
class StudentConsoleUI:
"""学生信息管理系统的控制台用户界面"""
def __init__(self, bll: StudentBLL):
self.bll = bll
def display_menu(self):
"""显示主菜单"""
print("\n" + "=" * 50)
print("学生信息管理系统".center(50))
print("=" * 50)
print("1. 添加学生")
print("2. 删除学生")
print("3. 修改学生信息")
print("4. 查看学生详细信息")
print("5. 查询学生")
print("6. 统计功能")
print("7. 数据导入导出")
print("8. 退出系统")
print("=" * 50)
def run(self):
"""运行系统"""
while True:
self.display_menu()
choice = input("请输入您的选择: ")
if choice == '1':
self.add_student()
elif choice == '2':
self.delete_student()
elif choice == '3':
self.update_student()
elif choice == '4':
self.view_student_details()
elif choice == '5':
self.search_students()
elif choice == '6':
self.statistics_menu()
elif choice == '7':
self.import_export_menu()
elif choice == '8':
print("感谢使用学生信息管理系统,再见!")
break
else:
print("无效的选择,请重新输入!")
def add_student(self):
"""添加学生界面"""
print("\n添加学生")
print("-" * 50)
name = input("姓名: ")
id_card = input("身份证号: ")
stu_id = input("学号: ")
gender_input = input("性别 (男/女,可选): ")
gender = None
if gender_input:
gender = gender_input.lower() == ''
height = input("身高 (cm可选): ")
height = int(height) if height else None
weight = input("体重 (kg可选): ")
weight = float(weight) if weight else None
enrollment_date = input("入学日期 (YYYY-MM-DD可选): ")
enrollment_date = datetime.strptime(enrollment_date, '%Y-%m-%d').date() if enrollment_date else None
class_name = input("班级名称 (可选): ")
major = input("专业名称 (可选): ")
email = input("电子邮箱 (可选): ")
phone = input("联系电话 (可选): ")
student = Student(
name=name,
id_card=id_card,
stu_id=stu_id,
gender=gender,
height=height,
weight=weight,
enrollment_date=enrollment_date,
class_name=class_name,
major=major,
email=email,
phone=phone
)
success, message = self.bll.add_student(student)
if success:
print("添加成功!")
else:
print(f"添加失败: {message}")
def delete_student(self):
"""删除学生界面"""
print("\n删除学生")
print("-" * 50)
print("1. 根据身份证号删除")
print("2. 根据学号删除")
choice = input("请选择删除方式: ")
if choice == '1':
id_card = input("请输入要删除的学生身份证号: ")
if self.bll.delete_student_by_id(id_card):
print("删除成功!")
else:
print("删除失败,未找到该学生!")
elif choice == '2':
stu_id = input("请输入要删除的学生学号: ")
if self.bll.delete_student_by_stu_id(stu_id):
print("删除成功!")
else:
print("删除失败,未找到该学生!")
else:
print("无效的选择!")
def update_student(self):
"""修改学生信息界面"""
print("\n修改学生信息")
print("-" * 50)
id_card = input("请输入要修改的学生身份证号: ")
student = self.bll.get_student_by_id(id_card)
if not student:
print("未找到该学生!")
return
print(f"当前学生信息 - 姓名: {student.name}, 学号: {student.stu_id}")
name = input(f"姓名 ({student.name}): ") or student.name
stu_id = input(f"学号 ({student.stu_id}): ") or student.stu_id
gender_input = input(f"性别 ({'' if student.gender else '' if student.gender is not None else '未设置'}): ")
gender = student.gender
if gender_input:
gender = gender_input.lower() == ''
height = input(f"身高 ({student.height} cm): ")
height = int(height) if height else student.height
weight = input(f"体重 ({student.weight} kg): ")
weight = float(weight) if weight else student.weight
enrollment_date = input(f"入学日期 ({student.enrollment_date}): ")
enrollment_date = datetime.strptime(enrollment_date,
'%Y-%m-%d').date() if enrollment_date else student.enrollment_date
class_name = input(f"班级名称 ({student.class_name}): ") or student.class_name
major = input(f"专业名称 ({student.major}): ") or student.major
email = input(f"电子邮箱 ({student.email}): ") or student.email
phone = input(f"联系电话 ({student.phone}): ") or student.phone
student.name = name
student.stu_id = stu_id
student.gender = gender
student.height = height
student.weight = weight
student.enrollment_date = enrollment_date
student.class_name = class_name
student.major = major
student.email = email
student.phone = phone
success, message = self.bll.update_student(student)
if success:
print("修改成功!")
else:
print(f"修改失败: {message}")
def view_student_details(self):
"""查看学生详细信息界面"""
print("\n查看学生详细信息")
print("-" * 50)
print("1. 根据身份证号查询")
print("2. 根据学号查询")
choice = input("请选择查询方式: ")
if choice == '1':
id_card = input("请输入学生身份证号: ")
student = self.bll.get_student_by_id(id_card)
elif choice == '2':
stu_id = input("请输入学生学号: ")
student = self.bll.get_student_by_stu_id(stu_id)
else:
print("无效的选择!")
return
if not student:
print("未找到该学生!")
return
self._print_student_details(student)
def _print_student_details(self, student: Student):
"""打印学生详细信息"""
print("\n" + "-" * 50)
print(f"姓名: {student.name}")
print(f"身份证号: {student.id_card}")
print(f"学号: {student.stu_id}")
print(f"性别: {'' if student.gender else '' if student.gender is not None else '未设置'}")
print(f"年龄: {student.age if student.age is not None else '未知'}")
print(f"出生日期: {student.birthday if student.birthday else '未知'}")
print(f"身高: {student.height} cm" if student.height else "身高: 未设置")
print(f"体重: {student.weight} kg" if student.weight else "体重: 未设置")
print(f"入学日期: {student.enrollment_date}" if student.enrollment_date else "入学日期: 未设置")
print(f"班级: {student.class_name if student.class_name else '未设置'}")
print(f"专业: {student.major if student.major else '未设置'}")
print(f"电子邮箱: {student.email if student.email else '未设置'}")
print(f"联系电话: {student.phone if student.phone else '未设置'}")
print("-" * 50)
def search_students(self):
"""查询学生界面"""
print("\n查询学生")
print("-" * 50)
print("1. 按姓名查询")
print("2. 按班级查询")
print("3. 按专业查询")
choice = input("请选择查询方式: ")
if choice == '1':
keyword = input("请输入姓名关键词: ")
students = self.bll.search_students_by_name(keyword)
elif choice == '2':
keyword = input("请输入班级关键词: ")
students = self.bll.search_students_by_class(keyword)
elif choice == '3':
keyword = input("请输入专业关键词: ")
students = self.bll.search_students_by_major(keyword)
else:
print("无效的选择!")
return
if not students:
print("未找到匹配的学生!")
return
print(f"\n共找到 {len(students)} 名学生:")
for i, student in enumerate(students, 1):
print(
f"{i}. {student.name} - {student.stu_id} - {student.class_name if student.class_name else '未知班级'}")
view_choice = input("是否查看详情?(y/n): ")
if view_choice.lower() == 'y':
detail_index = input("请输入要查看的学生序号: ")
try:
index = int(detail_index) - 1
if 0 <= index < len(students):
self._print_student_details(students[index])
else:
print("无效的序号!")
except ValueError:
print("请输入有效的数字!")
def statistics_menu(self):
"""统计功能菜单"""
print("\n统计功能")
print("-" * 50)
print("1. 学生总数")
print("2. 各专业学生人数")
print("3. 计算平均身高")
print("4. 计算平均体重")
print("5. 统计性别比例")
choice = input("请选择统计功能: ")
if choice == '1':
total = self.bll.get_total_students()
print(f"学生总数: {total}")
elif choice == '2':
major_count = self.bll.get_students_by_major()
print("\n各专业学生人数:")
for major, count in major_count.items():
print(f"{major}: {count}")
elif choice == '3':
print("1. 全部学生平均身高")
print("2. 按班级计算平均身高")
print("3. 按专业计算平均身高")
sub_choice = input("请选择计算方式: ")
if sub_choice == '1':
avg_height = self.bll.calculate_average_height()
print(f"全部学生平均身高: {avg_height:.2f} cm")
elif sub_choice == '2':
class_name = input("请输入班级名称: ")
avg_height = self.bll.calculate_average_height('class', class_name)
print(f"{class_name} 班级平均身高: {avg_height:.2f} cm")
elif sub_choice == '3':
major = input("请输入专业名称: ")
avg_height = self.bll.calculate_average_height('major', major)
print(f"{major} 专业平均身高: {avg_height:.2f} cm")
else:
print("无效的选择!")
elif choice == '4':
print("1. 全部学生平均体重")
print("2. 按班级计算平均体重")
print("3. 按专业计算平均体重")
sub_choice = input("请选择计算方式: ")
if sub_choice == '1':
avg_weight = self.bll.calculate_average_weight()
print(f"全部学生平均体重: {avg_weight:.2f} kg")
elif sub_choice == '2':
class_name = input("请输入班级名称: ")
avg_weight = self.bll.calculate_average_weight('class', class_name)
print(f"{class_name} 班级平均体重: {avg_weight:.2f} kg")
elif sub_choice == '3':
major = input("请输入专业名称: ")
avg_weight = self.bll.calculate_average_weight('major', major)
print(f"{major} 专业平均体重: {avg_weight:.2f} kg")
else:
print("无效的选择!")
elif choice == '5':
ratio = self.bll.get_gender_ratio()
print("\n性别比例统计:")
print(f"总人数: {ratio['total']}")
print(f"男生人数: {ratio['male']} ({ratio['male_ratio']:.2%})")
print(f"女生人数: {ratio['female']} ({ratio['female_ratio']:.2%})")
else:
print("无效的选择!")
def import_export_menu(self):
"""数据导入导出菜单"""
print("\n数据导入导出")
print("-" * 50)
print("1. 导出学生数据到CSV")
print("2. 导出学生数据到JSON")
print("3. 从CSV导入学生数据")
print("4. 从JSON导入学生数据")
choice = input("请选择操作: ")
# 这里只是示例,实际实现需要根据具体的数据存储方式编写
if choice in ['1', '2', '3', '4']:
print("功能开发中,暂未实现...")
else:
print("无效的选择!")
def _get_age(self, birthday: Optional[date]) -> Optional[int]:
"""计算学生年龄"""
if not birthday:
return None
today = date.today()
age = today.year - birthday.year - ((today.month, today.day) < (birthday.month, birthday.day))
return age