Compare commits

...

No commits in common. 'main' and 'master_lxq' have entirely different histories.

3
.idea/.gitignore vendored

@ -0,0 +1,3 @@
# 默认忽略的文件
/shelf/
/workspace.xml

@ -0,0 +1 @@
student_bll.py

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.12" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.11" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12" project-jdk-type="Python SDK" />
</project>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/PythonProject.iml" filepath="$PROJECT_DIR$/.idea/PythonProject.iml" />
</modules>
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

1081
1.py

File diff suppressed because it is too large Load Diff

@ -1,2 +0,0 @@
# xsxxglxt

@ -0,0 +1,188 @@
from datetime import date
from typing import Optional, Dict, Union, Any
# ============== 数据模型层 ==============
class Student:
"""学生实体类,封装学生基本信息及相关操作"""
def __init__(self,
name: str,
id_card: str,
stu_id: str,
gender: Optional[bool] = None,
height: Optional[int] = None,
weight: Optional[float] = None,
enrollment_date: Optional[Union[date, str]] = None,
class_name: Optional[str] = None,
major: Optional[str] = None):
"""初始化学生对象"""
self.name = name
self.id_card = id_card
self.stu_id = stu_id
self.gender = gender
self.height = height
self.weight = weight
self.enrollment_date = enrollment_date
self.class_name = class_name
self.major = major
# 从身份证号生成的属性
self._birthday = None
self._age = None
# 错误信息字典
self._errors = {}
# 初始化时进行数据校验
self.validate()
@property
def birthday(self) -> date:
"""从身份证号提取出生日期"""
if not self._birthday and self.id_card and len(self.id_card) == 18:
birth_str = self.id_card[6:14]
try:
self._birthday = date.fromisoformat(birth_str)
except:
self._birthday = date(1900, 1, 1)
return self._birthday
@property
def age(self) -> int:
"""计算年龄"""
if not self._age and self.birthday:
today = date.today()
self._age = today.year - self.birthday.year
if today < date(today.year, self.birthday.month, self.birthday.day):
self._age -= 1
return self._age
@property
def enrollment_date(self) -> Optional[date]:
"""入学日期属性"""
return self._enrollment_date
@enrollment_date.setter
def enrollment_date(self, value: Optional[Union[date, str]]):
"""入学日期设置器,支持日期对象或字符串"""
if value is None:
self._enrollment_date = None
elif isinstance(value, str):
try:
self._enrollment_date = date.fromisoformat(value)
except:
self._enrollment_date = None
else:
self._enrollment_date = value
@property
def errors(self) -> Dict[str, str]:
"""获取所有验证错误信息"""
return self._errors
@property
def is_valid(self) -> bool:
"""判断学生信息是否有效"""
return not bool(self._errors)
def validate(self) -> None:
"""验证学生信息的合法性"""
self._errors = {}
# 验证姓名
if not self.name or len(self.name) < 2 or len(self.name) > 20:
self._errors["name"] = "姓名必须在2到20个字符之间"
elif not self.name.isalpha():
self._errors["name"] = "姓名不能包含数字和特殊符号"
# 验证身份证号
if not self.__validate_id_card(self.id_card):
self._errors["id_card"] = "身份证号格式不正确"
# 验证学号
if not self.stu_id:
self._errors["stu_id"] = "学号不能为空"
# 验证身高
if self.height is not None and (self.height < 50 or self.height > 250):
self._errors["height"] = "身高必须在50到250厘米之间"
# 验证体重
if self.weight is not None and (self.weight < 5 or self.weight > 300):
self._errors["weight"] = "体重必须在5到300千克之间"
# 验证入学日期
if self.enrollment_date and self.birthday and self.enrollment_date < self.birthday:
self._errors["enrollment_date"] = "入学日期不能早于出生日期"
@staticmethod
def __validate_id_card(id_card: str) -> bool:
"""验证身份证号是否符合国家标准"""
if not id_card or len(id_card) != 18:
return False
# 检查前17位是否为数字
if not id_card[:17].isdigit():
return False
# 验证出生日期
birth_str = id_card[6:14]
try:
date.fromisoformat(birth_str)
except:
return False
# 验证校验位
factors = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2] # 加权因子
check_codes = '10X98765432' # 校验码映射
total = sum(int(id_card[i]) * factors[i] for i in range(17))
check_code = check_codes[total % 11]
return check_code == id_card[17].upper()
def to_dict(self) -> Dict[str, Any]:
"""将学生对象转换为字典"""
result = self.__dict__.copy()
# 处理日期类型
if result.get('_enrollment_date'):
result['enrollment_date'] = result['_enrollment_date'].isoformat()
# 移除内部属性
if '_birthday' in result:
del result['_birthday']
if '_age' in result:
del result['_age']
if '_errors' in result:
del result['_errors']
return result
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> 'Student':
"""从字典创建学生对象"""
if not isinstance(data, dict):
raise TypeError("数据必须是字典类型")
# 处理入学日期
enrollment_date = data.get('enrollment_date')
if enrollment_date and isinstance(enrollment_date, str):
try:
data['enrollment_date'] = date.fromisoformat(enrollment_date)
except:
data['enrollment_date'] = None
return cls(
name=data.get('name', ''),
id_card=data.get('id_card', ''),
stu_id=data.get('stu_id', ''),
gender=data.get('gender'),
height=data.get('height'),
weight=data.get('weight'),
enrollment_date=data.get('enrollment_date'),
class_name=data.get('class_name'),
major=data.get('major')
)
def __repr__(self) -> str:
"""学生对象的字符串表示"""
attrs = [f"{k}='{v}'" for k, v in self.to_dict().items() if v is not None]
return f"Student({', '.join(attrs)})"

@ -0,0 +1,308 @@
import csv
import json
import os
from abc import ABC, abstractmethod
from datetime import date
from typing import List, Optional, Dict, Any
class Student:
pass
class IStudentDAL(ABC):
"""学生信息数据访问层接口"""
@abstractmethod
def get_by_id(self, id_card: str) -> Optional[Student]:
"""根据身份证号获取学生信息"""
pass
@abstractmethod
def get_by_stu_id(self, stu_id: str) -> Optional[Student]:
"""根据学号获取学生信息"""
pass
@abstractmethod
def get_all(self) -> List[Student]:
"""获取所有学生信息"""
pass
@abstractmethod
def add(self, student: Student) -> bool:
"""添加学生信息"""
pass
@abstractmethod
def delete(self, id_card: str) -> bool:
"""根据身份证号删除学生信息"""
pass
@abstractmethod
def delete_by_stu_id(self, stu_id: str) -> bool:
"""根据学号删除学生信息"""
pass
@abstractmethod
def update(self, student: Student) -> bool:
"""更新学生信息"""
pass
@abstractmethod
def is_exist(self, id_card: str) -> bool:
"""检查学生是否存在"""
pass
@abstractmethod
def is_exist_stu_id(self, stu_id: str) -> bool:
"""检查学号是否存在"""
pass
class JsonStudentDAL(IStudentDAL):
"""JSON文件数据访问实现"""
def __init__(self, file_path: str):
"""初始化JSON数据访问层"""
self.file_path = file_path
self._ensure_file_exists()
def _ensure_file_exists(self) -> None:
"""确保数据文件存在"""
if not os.path.exists(self.file_path):
with open(self.file_path, 'w', encoding='utf-8') as f:
json.dump([], f, ensure_ascii=False, indent=4)
def _load(self) -> List[Dict[str, Any]]:
"""从文件加载学生数据"""
try:
with open(self.file_path, 'r', encoding='utf-8') as f:
return json.load(f)
except (json.JSONDecodeError, FileNotFoundError):
return []
def _save(self, students: List[Dict[str, Any]]) -> None:
"""保存学生数据到文件"""
with open(self.file_path, 'w', encoding='utf-8') as f:
json.dump(students, f, ensure_ascii=False, indent=4)
def get_by_id(self, id_card: str) -> Optional[Student]:
"""根据身份证号获取学生信息"""
students = self._load()
for data in students:
if data.get('id_card') == id_card:
return Student.from_dict(data)
return None
def get_by_stu_id(self, stu_id: str) -> Optional[Student]:
"""根据学号获取学生信息"""
students = self._load()
for data in students:
if data.get('stu_id') == stu_id:
return Student.from_dict(data)
return None
def get_all(self) -> List[Student]:
"""获取所有学生信息"""
students_data = self._load()
return [Student.from_dict(data) for data in students_data]
def add(self, student: Student) -> bool:
"""添加学生信息"""
if self.is_exist(student.id_card) or self.is_exist_stu_id(student.stu_id):
return False
students = self._load()
students.append(student.to_dict())
self._save(students)
return True
def delete(self, id_card: str) -> bool:
"""根据身份证号删除学生信息"""
students = self._load()
original_length = len(students)
students = [s for s in students if s.get('id_card') != id_card]
if len(students) < original_length:
self._save(students)
return True
return False
def delete_by_stu_id(self, stu_id: str) -> bool:
"""根据学号删除学生信息"""
students = self._load()
original_length = len(students)
students = [s for s in students if s.get('stu_id') != stu_id]
if len(students) < original_length:
self._save(students)
return True
return False
def update(self, student: Student) -> bool:
"""更新学生信息"""
students = self._load()
updated = False
for i, data in enumerate(students):
if data.get('id_card') == student.id_card:
students[i] = student.to_dict()
updated = True
break
if updated:
self._save(students)
return updated
def is_exist(self, id_card: str) -> bool:
"""检查学生是否存在"""
return self.get_by_id(id_card) is not None
def is_exist_stu_id(self, stu_id: str) -> bool:
"""检查学号是否存在"""
return self.get_by_stu_id(stu_id) is not None
class CsvStudentDAL(IStudentDAL):
"""CSV文件数据访问实现"""
FIELD_TYPES = {
'height': int,
'weight': float,
'gender': lambda x: True if x == 'True' else False if x == 'False' else None,
}
def __init__(self, file_path: str):
"""初始化CSV数据访问层"""
self.file_path = file_path
self._ensure_file_exists()
def _ensure_file_exists(self) -> None:
"""确保数据文件存在"""
if not os.path.exists(self.file_path):
with open(self.file_path, 'w', encoding='utf-8-sig', newline='') as f:
writer = csv.DictWriter(f, fieldnames=self._get_fieldnames())
writer.writeheader()
def _get_fieldnames(self) -> List[str]:
"""获取CSV文件字段名"""
return [
'name', 'id_card', 'stu_id', 'gender', 'height',
'weight', 'enrollment_date', 'class_name', 'major'
]
def _convert_row(self, row: Dict[str, str]) -> Dict[str, Any]:
"""转换CSV行数据为字典"""
result = {}
for key, value in row.items():
if not value:
result[key] = None
else:
converter = self.FIELD_TYPES.get(key)
if converter:
result[key] = converter(value)
elif key == 'enrollment_date':
try:
result[key] = date.fromisoformat(value)
except:
result[key] = value
else:
result[key] = value
return result
def _load(self) -> List[Dict[str, Any]]:
"""从文件加载学生数据"""
try:
with open(self.file_path, 'r', encoding='utf-8-sig', newline='') as f:
reader = csv.DictReader(f)
return [self._convert_row(row) for row in reader]
except FileNotFoundError:
return []
def _save(self, students: List[Dict[str, Any]]) -> None:
"""保存学生数据到文件"""
with open(self.file_path, 'w', encoding='utf-8-sig', newline='') as f:
writer = csv.DictWriter(f, fieldnames=self._get_fieldnames())
writer.writeheader()
for student in students:
# 转换日期为字符串
if student.get('enrollment_date') and isinstance(student['enrollment_date'], date):
student['enrollment_date'] = student['enrollment_date'].isoformat()
writer.writerow(student)
def get_by_id(self, id_card: str) -> Optional[Student]:
"""根据身份证号获取学生信息"""
students = self._load()
for data in students:
if data.get('id_card') == id_card:
return Student.from_dict(data)
return None
def get_by_stu_id(self, stu_id: str) -> Optional[Student]:
"""根据学号获取学生信息"""
students = self._load()
for data in students:
if data.get('stu_id') == stu_id:
return Student.from_dict(data)
return None
def get_all(self) -> List[Student]:
"""获取所有学生信息"""
students_data = self._load()
return [Student.from_dict(data) for data in students_data]
def add(self, student: Student) -> bool:
"""添加学生信息"""
if self.is_exist(student.id_card) or self.is_exist_stu_id(student.stu_id):
return False
students = self._load()
students.append(student.to_dict())
self._save(students)
return True
def delete(self, id_card: str) -> bool:
"""根据身份证号删除学生信息"""
students = self._load()
original_length = len(students)
students = [s for s in students if s.get('id_card') != id_card]
if len(students) < original_length:
self._save(students)
return True
return False
def delete_by_stu_id(self, stu_id: str) -> bool:
"""根据学号删除学生信息"""
students = self._load()
original_length = len(students)
students = [s for s in students if s.get('stu_id') != stu_id]
if len(students) < original_length:
self._save(students)
return True
return False
def update(self, student: Student) -> bool:
"""更新学生信息"""
students = self._load()
updated = False
for i, data in enumerate(students):
if data.get('id_card') == student.id_card:
students[i] = student.to_dict()
updated = True
break
if updated:
self._save(students)
return updated
def is_exist(self, id_card: str) -> bool:
"""检查学生是否存在"""
return self.get_by_id(id_card) is not None
def is_exist_stu_id(self, stu_id: str) -> bool:
"""检查学号是否存在"""
return self.get_by_stu_id(stu_id) is not None

@ -0,0 +1,9 @@
from 面向对象方法三层.ui.student_ui import StudentUI
if __name__ == "__main__":
# 默认为JSON文件存储
default_file = "students.json"
print(f"使用默认数据文件: {default_file}")
ui = StudentUI(default_file)
ui.run()

@ -0,0 +1,201 @@
import csv
import json
from typing import List, Optional, Dict
from 面向对象方法三层.dal.json_student_dal import IStudentDAL, JsonStudentDAL, CsvStudentDAL, Student
class StudentBLL:
"""学生信息业务逻辑层"""
def __init__(self, file_path: str):
"""初始化业务逻辑层"""
self.file_path = file_path
self.dal = self._get_dal()
def _get_dal(self) -> IStudentDAL:
"""获取数据访问层实例"""
if self.file_path.endswith('.json'):
return JsonStudentDAL(self.file_path)
elif self.file_path.endswith('.csv'):
return CsvStudentDAL(self.file_path)
else:
raise ValueError("不支持的文件格式仅支持JSON和CSV")
def add_student(self, student: Student) -> bool:
"""添加学生信息"""
# 校验学生信息
if not student.is_valid:
raise ValueError(f"学生信息无效: {student.errors}")
# 检查唯一性
if self.dal.is_exist(student.id_card):
raise ValueError("该身份证号已存在")
if self.dal.is_exist_stu_id(student.stu_id):
raise ValueError("该学号已存在")
return self.dal.add(student)
def delete_student(self, id_card: str) -> bool:
"""根据身份证号删除学生"""
if not self.dal.is_exist(id_card):
raise ValueError("学生不存在")
return self.dal.delete(id_card)
def delete_student_by_stu_id(self, stu_id: str) -> bool:
"""根据学号删除学生"""
if not self.dal.is_exist_stu_id(stu_id):
raise ValueError("学生不存在")
return self.dal.delete_by_stu_id(stu_id)
def update_student(self, student: Student) -> bool:
"""更新学生信息"""
if not student.is_valid:
raise ValueError(f"学生信息无效: {student.errors}")
if not self.dal.is_exist(student.id_card):
raise ValueError("学生不存在")
return self.dal.update(student)
def update_student_partial(self, id_card: str, **kwargs) -> bool:
"""部分更新学生信息"""
student = self.dal.get_by_id(id_card)
if not student:
raise ValueError("学生不存在")
# 更新提供的字段
for key, value in kwargs.items():
if hasattr(student, key) and key not in ['id_card', 'stu_id']:
setattr(student, key, value)
# 校验更新后的信息
student.validate()
if student.errors:
raise ValueError(f"更新后学生信息无效: {student.errors}")
return self.dal.update(student)
def get_student_by_id(self, id_card: str) -> Optional[Student]:
"""根据身份证号查询学生"""
return self.dal.get_by_id(id_card)
def get_student_by_stu_id(self, stu_id: str) -> Optional[Student]:
"""根据学号查询学生"""
return self.dal.get_by_stu_id(stu_id)
def get_all_students(self) -> List[Student]:
"""获取所有学生"""
return self.dal.get_all()
def search_by_name(self, name: str, fuzzy: bool = True) -> List[Student]:
"""按姓名查询学生"""
all_students = self.get_all_students()
if fuzzy:
return [s for s in all_students if name.lower() in s.name.lower()]
return [s for s in all_students if s.name == name]
def search_by_class(self, class_name: str, fuzzy: bool = True) -> List[Student]:
"""按班级查询学生"""
all_students = self.get_all_students()
if fuzzy:
return [s for s in all_students if class_name.lower() in (s.class_name or '').lower()]
return [s for s in all_students if s.class_name == class_name]
def search_by_major(self, major: str, fuzzy: bool = True) -> List[Student]:
"""按专业查询学生"""
all_students = self.get_all_students()
if fuzzy:
return [s for s in all_students if major.lower() in (s.major or '').lower()]
return [s for s in all_students if s.major == major]
def count_students(self) -> int:
"""统计学生总数"""
return len(self.get_all_students())
def count_by_major(self) -> Dict[str, int]:
"""按专业统计学生人数"""
result = {}
for student in self.get_all_students():
if student.major:
result[student.major] = result.get(student.major, 0) + 1
return result
def average_height(self) -> float:
"""计算平均身高"""
students = [s for s in self.get_all_students() if s.height is not None]
if not students:
return 0
return sum(s.height for s in students) / len(students)
def average_weight(self) -> float:
"""计算平均体重"""
students = [s for s in self.get_all_students() if s.weight is not None]
if not students:
return 0
return sum(s.weight for s in students) / len(students)
def export_to_json(self, file_path: str) -> bool:
"""导出数据到JSON文件"""
students = [s.to_dict() for s in self.get_all_students()]
try:
with open(file_path, 'w', encoding='utf-8') as f:
json.dump(students, f, ensure_ascii=False, indent=4)
return True
except:
return False
def export_to_csv(self, file_path: str) -> bool:
"""导出数据到CSV文件"""
students = self.get_all_students()
if not students:
return False
fieldnames = list(students[0].to_dict().keys())
try:
with open(file_path, 'w', encoding='utf-8-sig', newline='') as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
for student in students:
writer.writerow(student.to_dict())
return True
except:
return False
def import_from_json(self, file_path: str) -> int:
"""从JSON文件导入数据"""
try:
with open(file_path, 'r', encoding='utf-8') as f:
students_data = json.load(f)
count = 0
for data in students_data:
try:
student = Student.from_dict(data)
if self.add_student(student):
count += 1
except:
continue
return count
except:
return 0
def import_from_csv(self, file_path: str) -> int:
"""从CSV文件导入数据"""
try:
with open(file_path, 'r', encoding='utf-8-sig', newline='') as f:
reader = csv.DictReader(f)
students_data = [row for row in reader]
count = 0
for data in students_data:
try:
student = Student.from_dict(data)
if self.add_student(student):
count += 1
except:
continue
return count
except:
return 0

@ -0,0 +1,9 @@
[
{
"name": "李宇哲",
"id_card": "362425200605012231",
"stu_id": "123456",
"gender": true,
"height": 156,
"weight": 56.0,
"_enrollment_date":

@ -0,0 +1,387 @@
from datetime import date
from 面向对象方法三层.bll.student_bll import Student
from 面向对象方法三层.model.student import StudentBLL
class StudentUI:
"""学生信息管理系统用户界面"""
def __init__(self, file_path: str):
"""初始化用户界面"""
self.bll = StudentBLL(file_path)
self.running = True
def display_main_menu(self) -> None:
"""显示主菜单"""
print("\n===== 学生信息管理系统 =====")
print("1. 添加学生信息")
print("2. 删除学生信息")
print("3. 更新学生信息")
print("4. 查询学生信息")
print("5. 统计分析")
print("6. 数据导入导出")
print("7. 清空所有学生信息")
print("0. 退出系统")
print("==========================")
def display_query_menu(self) -> None:
"""显示查询菜单"""
print("\n===== 查询学生信息 =====")
print("1. 查询所有学生")
print("2. 按身份证号查询")
print("3. 按学号查询")
print("4. 按姓名查询")
print("5. 按班级查询")
print("6. 按专业查询")
print("0. 返回上一级")
print("======================")
def display_stats_menu(self) -> None:
"""显示统计菜单"""
print("\n===== 统计分析 =====")
print("1. 学生总数")
print("2. 各专业学生人数")
print("3. 平均身高")
print("4. 平均体重")
print("0. 返回上一级")
print("====================")
def display_import_export_menu(self) -> None:
"""显示数据导入导出菜单"""
print("\n===== 数据导入导出 =====")
print("1. 导出到JSON")
print("2. 从JSON导入")
print("3. 导出到CSV")
print("4. 从CSV导入")
print("0. 返回上一级")
print("========================")
def get_input(self, prompt: str) -> str:
"""获取用户输入"""
return input(prompt).strip()
def add_student(self) -> None:
"""添加学生信息"""
print("\n--- 添加学生信息 ---")
name = self.get_input("姓名: ")
id_card = self.get_input("身份证号: ")
stu_id = self.get_input("学号: ")
gender = self.get_input("性别(1-男, 0-女, 直接回车-未知): ")
if gender == '1':
gender = True
elif gender == '0':
gender = False
else:
gender = None
height_str = self.get_input("身高(cm, 直接回车-未知): ")
height = int(height_str) if height_str else None
weight_str = self.get_input("体重(kg, 保留一位小数, 直接回车-未知): ")
weight = float(weight_str) if weight_str else None
enrollment_date = self.get_input("入学日期(YYYY-MM-DD, 直接回车-未知): ")
enrollment_date = date.fromisoformat(enrollment_date) if enrollment_date else None
class_name = self.get_input("班级名称(直接回车-未知): ")
major = self.get_input("专业(直接回车-未知): ")
try:
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
)
if self.bll.add_student(student):
print("学生添加成功!")
else:
print("学生添加失败,身份证号或学号已存在!")
except ValueError as e:
print(f"操作失败: {e}")
def delete_student(self) -> None:
"""删除学生信息"""
print("\n--- 删除学生信息 ---")
print("1. 按身份证号删除")
print("2. 按学号删除")
choice = self.get_input("请选择: ")
try:
if choice == '1':
id_card = self.get_input("请输入身份证号: ")
if self.bll.delete_student(id_card):
print("学生删除成功!")
else:
print("学生不存在!")
elif choice == '2':
stu_id = self.get_input("请输入学号: ")
if self.bll.delete_student_by_stu_id(stu_id):
print("学生删除成功!")
else:
print("学生不存在!")
else:
print("无效选择!")
except ValueError as e:
print(f"操作失败: {e}")
def update_student(self) -> None:
"""更新学生信息"""
print("\n--- 更新学生信息 ---")
id_card = self.get_input("请输入要更新的学生身份证号: ")
student = self.bll.get_student_by_id(id_card)
if not student:
print("学生不存在!")
return
print(f"\n当前学生信息: {student}")
name = self.get_input(f"姓名[{student.name}]: ") or student.name
gender = self.get_input(f"性别(1-男, 0-女, 直接回车[{student.gender}]): ")
if gender:
gender = True if gender == '1' else False
else:
gender = student.gender
height_str = self.get_input(f"身高(cm, 直接回车[{student.height}]): ")
height = int(height_str) if height_str else student.height
weight_str = self.get_input(f"体重(kg, 直接回车[{student.weight}]): ")
weight = float(weight_str) if weight_str else student.weight
enrollment_date = self.get_input(f"入学日期(YYYY-MM-DD, 直接回车[{student.enrollment_date}]): ")
enrollment_date = date.fromisoformat(enrollment_date) if enrollment_date else student.enrollment_date
class_name = self.get_input(f"班级名称[{student.class_name}]: ") or student.class_name
major = self.get_input(f"专业[{student.major}]: ") or student.major
try:
updated_student = Student(
name=name,
id_card=id_card,
stu_id=student.stu_id,
gender=gender,
height=height,
weight=weight,
enrollment_date=enrollment_date,
class_name=class_name,
major=major
)
if self.bll.update_student(updated_student):
print("学生信息更新成功!")
else:
print("学生信息更新失败!")
except ValueError as e:
print(f"操作失败: {e}")
def query_student(self) -> None:
"""查询学生信息"""
while True:
self.display_query_menu()
choice = self.get_input("请选择操作: ")
if choice == '0':
break
try:
if choice == '1':
# 查询所有学生
students = self.bll.get_all_students()
if not students:
print("没有学生信息!")
else:
print("\n--- 所有学生信息 ---")
for i, student in enumerate(students, 1):
print(f"{i}. {student}")
elif choice == '2':
# 按身份证号查询
id_card = self.get_input("请输入身份证号: ")
student = self.bll.get_student_by_id(id_card)
if student:
print(f"\n--- 学生信息 ---: {student}")
else:
print("未找到该学生!")
elif choice == '3':
# 按学号查询
stu_id = self.get_input("请输入学号: ")
student = self.bll.get_student_by_stu_id(stu_id)
if student:
print(f"\n--- 学生信息 ---: {student}")
else:
print("未找到该学生!")
elif choice == '4':
# 按姓名查询
name = self.get_input("请输入姓名(支持模糊查询): ")
students = self.bll.search_by_name(name)
if not students:
print("未找到该学生!")
else:
print(f"\n--- 查找结果({len(students)}人) ---")
for i, student in enumerate(students, 1):
print(f"{i}. {student}")
elif choice == '5':
# 按班级查询
class_name = self.get_input("请输入班级名称(支持模糊查询): ")
students = self.bll.search_by_class(class_name)
if not students:
print("未找到该班级的学生!")
else:
print(f"\n--- 查找结果({len(students)}人) ---")
for i, student in enumerate(students, 1):
print(f"{i}. {student}")
elif choice == '6':
# 按专业查询
major = self.get_input("请输入专业名称(支持模糊查询): ")
students = self.bll.search_by_major(major)
if not students:
print("未找到该专业的学生!")
else:
print(f"\n--- 查找结果({len(students)}人) ---")
for i, student in enumerate(students, 1):
print(f"{i}. {student}")
else:
print("无效选择!")
except Exception as e:
print(f"查询出错: {e}")
def show_stats(self) -> None:
"""显示统计信息"""
while True:
self.display_stats_menu()
choice = self.get_input("请选择操作: ")
if choice == '0':
break
try:
if choice == '1':
# 学生总数
count = self.bll.count_students()
print(f"\n学生总数: {count}")
elif choice == '2':
# 各专业学生人数
major_counts = self.bll.count_by_major()
if not major_counts:
print("没有学生信息!")
else:
print("\n各专业学生人数:")
for major, count in major_counts.items():
print(f"{major}: {count}")
elif choice == '3':
# 平均身高
avg_height = self.bll.average_height()
print(f"\n平均身高: {avg_height:.2f}cm")
elif choice == '4':
# 平均体重
avg_weight = self.bll.average_weight()
print(f"\n平均体重: {avg_weight:.2f}kg")
else:
print("无效选择!")
except Exception as e:
print(f"统计出错: {e}")
def import_export_data(self) -> None:
"""数据导入导出"""
while True:
self.display_import_export_menu()
choice = self.get_input("请选择操作: ")
if choice == '0':
break
try:
if choice == '1':
# 导出到JSON
file_path = self.get_input("请输入导出文件路径: ")
if self.bll.export_to_json(file_path):
print(f"数据已成功导出到 {file_path}")
else:
print("导出失败!")
elif choice == '2':
# 从JSON导入
file_path = self.get_input("请输入导入文件路径: ")
count = self.bll.import_from_json(file_path)
print(f"成功导入 {count} 条学生记录")
elif choice == '3':
# 导出到CSV
file_path = self.get_input("请输入导出文件路径: ")
if self.bll.export_to_csv(file_path):
print(f"数据已成功导出到 {file_path}")
else:
print("导出失败!")
elif choice == '4':
# 从CSV导入
file_path = self.get_input("请输入导入文件路径: ")
count = self.bll.import_from_csv(file_path)
print(f"成功导入 {count} 条学生记录")
else:
print("无效选择!")
except Exception as e:
print(f"操作出错: {e}")
def clear_students(self) -> None:
"""清空所有学生信息"""
print("\n--- 清空所有学生信息 ---")
confirm = self.get_input("确定要清空所有学生信息吗?(y/n): ")
if confirm.lower() == 'y':
# 这里简单实现,实际应更安全
open(self.bll.file_path, 'w', encoding='utf-8').close()
print("所有学生信息已清空!")
else:
print("已取消清空操作。")
def run(self) -> None:
"""运行系统"""
print("学生信息管理系统启动中...")
while self.running:
self.display_main_menu()
choice = self.get_input("请选择操作: ")
try:
if choice == '1':
self.add_student()
elif choice == '2':
self.delete_student()
elif choice == '3':
self.update_student()
elif choice == '4':
self.query_student()
elif choice == '5':
self.show_stats()
elif choice == '6':
self.import_export_data()
elif choice == '7':
self.clear_students()
elif choice == '0':
self.running = False
print("感谢使用学生信息管理系统,再见!")
else:
print("无效选择,请重新输入!")
except Exception as e:
print(f"操作出错: {e}")
Loading…
Cancel
Save