c1785 2 months ago
parent e822f01cfc
commit d12c277689

@ -1,7 +1,8 @@
import json import json
import os, sys import os, sys,csv
from datetime import date from datetime import date
from typing import List, Optional from typing import List, Optional
from model.Student import Student
import csv import csv
current_dir = os.path.dirname(os.path.abspath(__file__)) current_dir = os.path.dirname(os.path.abspath(__file__))
@ -10,6 +11,107 @@ sys.path.append(parent_dir)
from model.Student import Student from model.Student import Student
class StudentDALJSON:
def __init__(self, file_path="students.json"):
self.file_path = file_path
def get_all_students(self):
try:
with open(self.file_path, 'r', encoding='utf-8') as file:
student_dicts = json.load(file)
return [Student.from_dict(s) for s in student_dicts]
except (FileNotFoundError, json.JSONDecodeError):
return []
def save_students(self, students):
student_dicts = [student.to_dict() for student in students]
with open(self.file_path, 'w', encoding='utf-8') as file:
json.dump(student_dicts, file, ensure_ascii=False, indent=4)
# 新增导出为JSON
def export_to_json(self, file_path=None):
if not file_path:
file_path = self.file_path
students = self.get_all_students()
if not students:
print("没有数据可导出")
return
try:
with open(file_path, 'w', encoding='utf-8') as f:
json.dump([s.to_dict() for s in students], f, ensure_ascii=False, indent=4)
print(f"数据已导出到 {file_path}")
except Exception as e:
print(f"导出失败: {e}")
# 新增导出为CSV
def export_to_csv(self, file_path="students.csv"):
students = self.get_all_students()
if not students:
print("没有数据可导出")
return
try:
with open(file_path, 'w', encoding='utf-8-sig', newline='') as f:
writer = csv.DictWriter(
f,
fieldnames=[
'student_id', 'name', 'gender', 'age', 'class_name',
'major', 'phone', 'email', 'id_number',
'height', 'weight', 'birth_date', 'enrollment_date'
]
)
writer.writeheader()
for student in students:
data = student.to_dict()
# 将日期对象转换为字符串
data['birth_date'] = data['birth_date'].isoformat()
data['enrollment_date'] = data['enrollment_date'].isoformat()
writer.writerow(data)
print(f"数据已导出到 {file_path}")
except Exception as e:
print(f"导出失败: {e}")
# 新增从JSON导入
def import_from_json(self, file_path):
try:
with open(file_path, 'r', encoding='utf-8') as f:
student_dicts = json.load(f)
students = []
for data in student_dicts:
# 转换日期字符串为日期对象
data['birth_date'] = date.fromisoformat(data['birth_date'])
data['enrollment_date'] = date.fromisoformat(data['enrollment_date'])
students.append(Student.from_dict(data))
self.save_students(students)
print(f"{file_path} 导入成功")
except FileNotFoundError:
print(f"文件不存在: {file_path}")
except json.JSONDecodeError:
print(f"JSON格式错误: {file_path}")
except Exception as e:
print(f"导入失败: {e}")
# 新增从CSV导入
def import_from_csv(self, file_path):
try:
with open(file_path, 'r', encoding='utf-8-sig') as f:
reader = csv.DictReader(f)
student_dicts = list(reader)
students = []
for data in student_dicts:
# 转换数值类型
data['age'] = int(data['age'])
data['height'] = float(data['height'])
data['weight'] = float(data['weight'])
# 转换日期类型
data['birth_date'] = date.fromisoformat(data['birth_date'])
data['enrollment_date'] = date.fromisoformat(data['enrollment_date'])
students.append(Student.from_dict(data))
self.save_students(students)
print(f"{file_path} 导入成功")
except FileNotFoundError:
print(f"文件不存在: {file_path}")
except Exception as e:
print(f"导入失败: {e}")
class StudentDAL: class StudentDAL:
def __init__(self, file_path: str): def __init__(self, file_path: str):
self.file_path = file_path self.file_path = file_path
@ -109,10 +211,17 @@ class StudentDAL:
json.dump(student_dicts, file, ensure_ascii=False, indent=4) json.dump(student_dicts, file, ensure_ascii=False, indent=4)
def import_from_json(self, file_path): def import_from_json(self, file_path):
with open(file_path, mode='r', encoding='utf-8') as file: try:
student_dicts = json.load(file) with open(file_path, mode='r', encoding='utf-8') as file:
students = [Student.from_dict(student_dict) for student_dict in student_dicts] student_dicts = json.load(file)
self.save_students(students) students = [Student.from_dict(student_dict) for student_dict in student_dicts]
self.save_students(students)
except FileNotFoundError:
print(f"文件 {file_path} 未找到。")
except json.JSONDecodeError:
print(f"文件 {file_path} 不是有效的 JSON 文件。")
except ValueError as e:
print(f"数据转换错误: {e}")
def export_to_csv(self, file_path): def export_to_csv(self, file_path):
students = self.load_students() students = self.load_students()
@ -124,15 +233,20 @@ class StudentDAL:
writer.writerow(student.to_dict()) writer.writerow(student.to_dict())
def import_from_csv(self, file_path): def import_from_csv(self, file_path):
students = [] try:
with open(file_path, mode='r', encoding='utf-8') as file: students = []
reader = csv.DictReader(file) with open(file_path, mode='r', encoding='utf-8') as file:
for row in reader: reader = csv.DictReader(file)
row['birth_date'] = date.fromisoformat(row['birth_date']) for row in reader:
row['enrollment_date'] = date.fromisoformat(row['enrollment_date']) row['birth_date'] = date.fromisoformat(row['birth_date'])
student = Student.from_dict(row) row['enrollment_date'] = date.fromisoformat(row['enrollment_date'])
students.append(student) student = Student.from_dict(row)
self.save_students(students) students.append(student)
self.save_students(students)
except FileNotFoundError:
print(f"文件 {file_path} 未找到。")
except ValueError as e:
print(f"日期格式错误: {e}")
def get_average_height(self): def get_average_height(self):
students = self.load_students() students = self.load_students()
@ -152,4 +266,24 @@ class StudentDAL:
def count_students_by_age_range(self, min_age, max_age): def count_students_by_age_range(self, min_age, max_age):
today = date.today() today = date.today()
students = self.load_students() students = self.load_students()
return len([student for student in students if min_age <= today.year - student.birth_date.year <= max_age]) return len([student for student in students if min_age <= today.year - student.birth_date.year <= max_age])
def backup_data(self, backup_path):
try:
with open(self.file_path, mode='r', encoding='utf-8') as src_file, \
open(backup_path, mode='w', encoding='utf-8') as dst_file:
dst_file.write(src_file.read())
print(f"数据备份到 {backup_path} 成功。")
except Exception as e:
print(f"数据备份失败: {e}")
def restore_data(self, backup_path):
try:
with open(backup_path, mode='r', encoding='utf-8') as src_file, \
open(self.file_path, mode='w', encoding='utf-8') as dst_file:
dst_file.write(src_file.read())
print(f"数据从 {backup_path} 恢复成功。")
except FileNotFoundError:
print(f"备份文件 {backup_path} 未找到。")
except Exception as e:
print(f"数据恢复失败: {e}")

@ -1 +1,10 @@
[] [
{
"sid": "110309230907041",
"name": "cgt",
"height": 180,
"birth_date": "2023-09-01",
"enrollment_date": "2023-09-01",
"class_name": "cls2"
}
]

@ -126,4 +126,3 @@ def main():
if __name__ == '__main__': if __name__ == '__main__':
main() main()
print(123)

@ -18,8 +18,8 @@ class Student:
self._validation_errors.append(f"身高{self.height}cm超出合理范围") self._validation_errors.append(f"身高{self.height}cm超出合理范围")
def _validate_name(self) -> None: def _validate_name(self) -> None:
if not (2 <= len(self.name) <=20): if not (2 <= len(self.name) <= 20) or not self.name.isprintable():
self._validation_errors.append("姓名长度需在2-20个字符之间") self._validation_errors.append("姓名长度需在2-20个字符之间且为可打印字符")
if not self.name.isprintable(): if not self.name.isprintable():
self._validation_errors.append("姓名长度需在2-20个字符之间") self._validation_errors.append("姓名长度需在2-20个字符之间")
def _validate_date(self) -> None: def _validate_date(self) -> None:

@ -1,8 +1,9 @@
import os import os,re
from datetime import date from datetime import date
from bll.student_bll import StudentBLL from bll.student_bll import StudentBLL
from dal.student_dal_json import StudentDAL from dal.student_dal_json import StudentDAL
from model.Student import Student from model.Student import Student
from dal.student_dal_json import StudentDALJSON # 确保导入
class StudentUI: class StudentUI:
def __init__(self): def __init__(self):
@ -87,7 +88,18 @@ class StudentUI:
name = self.get_input("请输入姓名: ") name = self.get_input("请输入姓名: ")
id_number = self.get_input("请输入身份证号: ") id_number = self.get_input("请输入身份证号: ")
student_id = self.get_input("请输入学号: ") # 验证学号格式(新增)
id_number = self.get_input("请输入身份证号: ")
while not re.match(r'^\d{17}[\dXx]$', id_number):
print("身份证号格式不正确,请输入 18 位身份证号。")
id_number = self.get_input("请输入身份证号: ")
while True:
student_id = self.get_input("请输入学号: ")
if re.match(r'^\d{10,15}$', student_id): # 假设学号是8-12位数字
break
print("学号格式不正确请输入8-12位数字")
gender = self.get_input("请输入性别(男/女): ") gender = self.get_input("请输入性别(男/女): ")
while True: while True:
@ -108,37 +120,34 @@ class StudentUI:
except ValueError: except ValueError:
print("体重必须为0到500之间的有效数值请重新输入") print("体重必须为0到500之间的有效数值请重新输入")
enrollment_date = self.get_input("请输入入学日期(YYYY-MM-DD): ") # 修改后的日期输入验证
while True:
enrollment_date = self.get_input("请输入入学日期(YYYY-MM-DD): ")
try:
date_obj = date.fromisoformat(enrollment_date)
break
except ValueError:
print("日期格式错误,请使用 YYYY-MM-DD 格式例如2023-09-01")
class_name = self.get_input("请输入班级: ") class_name = self.get_input("请输入班级: ")
major = self.get_input("请输入专业: ") major = self.get_input("请输入专业: ")
student = Student( # 创建 Student 对象
name=name,
id_number=id_number,
student_id=student_id,
gender=gender,
height=height,
weight=weight,
enrollment_date=enrollment_date,
class_name=class_name,
major=major
)
student = Student(
sid=student_id, # 注意这里添加了 sid
name=name,
height=height,
birth_date=date.fromisoformat(enrollment_date), # 假设入学日期作为示例,可根据实际情况修改
enrollment_date=date.fromisoformat(enrollment_date),
class_name=class_name
)
try: try:
student = Student(
sid=student_id,
name=name,
height=height,
birth_date=date_obj, # 使用验证后的日期对象
enrollment_date=date_obj, # 使用验证后的日期对象
class_name=class_name
)
if self.bll.add_student(student): if self.bll.add_student(student):
print("学生信息添加成功!") print("学生信息添加成功!")
else: else:
print("学生信息添加失败。") print("学生信息添加失败。")
except ValueError as e: except ValueError as e:
print(e) print(f"添加学生失败: {e}")
def handle_import_export(self, choice): def handle_import_export(self, choice):
if choice == '1': if choice == '1':

Loading…
Cancel
Save