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.

124 lines
4.2 KiB

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']
)