import csv import json import os import sqlite3 from abc import ABC, abstractmethod from datetime import date from typing import List, Optional, Union # 学生类定义 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: str = None): self.name = name self.id_card = id_card self.stu_id = stu_id self.gender = gender self.height = height self.weight = weight if isinstance(enrollment_date, str): self.enrollment_date = date.fromisoformat(enrollment_date) else: self.enrollment_date = enrollment_date self.class_name = class_name self.major = major self.age, self.birthday = self._calculate_age_and_birthday() self._validation_errors = [] self._validate_all() def _calculate_age_and_birthday(self): birth_year = int(self.id_card[6:10]) birth_month = int(self.id_card[10:12]) birth_day = int(self.id_card[12:14]) birthday = date(birth_year, birth_month, birth_day) today = date.today() age = today.year - birth_year if (today.month, today.day) < (birth_month, birth_day): age -= 1 return age, birthday def _validate_all(self): self._validate_id_card() self._validate_stu_id() self._validate_name() self._validate_enrollment_date() self._validate_height() self._validate_weight() def _validate_id_card(self): if len(self.id_card) != 18: self._validation_errors.append("身份证号必须为18位") # 简单的校验位验证,可根据国家标准完善 try: int(self.id_card[:17]) except ValueError: self._validation_errors.append("身份证号前17位必须为数字") def _validate_stu_id(self): if not self.stu_id: self._validation_errors.append("学号不能为空") def _validate_name(self): if not (2 <= len(self.name) <= 20): self._validation_errors.append("姓名长度需在2-20个字符之间") if any(char.isdigit() or not char.isalpha() for char in self.name): self._validation_errors.append("姓名不能包含数字和特殊符号") def _validate_enrollment_date(self): if self.enrollment_date and self.enrollment_date < self.birthday: self._validation_errors.append("入学日期不能早于出生日期") def _validate_height(self): if self.height is not None and not (50 <= self.height <= 250): self._validation_errors.append("身高需在50-250cm之间") def _validate_weight(self): if self.weight is not None and not (5 <= self.weight <= 300): self._validation_errors.append("体重需在5-300kg之间") @property def is_valid(self): return len(self._validation_errors) == 0 def get_errors(self): return self._validation_errors.copy() def to_dict(self): return { 'name': self.name, 'id_card': self.id_card, 'stu_id': self.stu_id, 'gender': self.gender, 'height': self.height, 'weight': self.weight, 'enrollment_date': self.enrollment_date.isoformat() if self.enrollment_date else None, 'class_name': self.class_name, 'major': self.major, 'age': self.age, 'birthday': self.birthday.isoformat() } @classmethod def from_dict(cls, data): return cls( name=data['name'], id_card=data['id_card'], stu_id=data['stu_id'], gender=data['gender'], height=data['height'], weight=data['weight'], enrollment_date=data['enrollment_date'], class_name=data['class_name'], major=data['major'] )