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.

132 lines
5.3 KiB

from datetime import date
import re
class Student:
def __init__(self, sid: str, name: str, gender: str, height: int, weight: float, birth_date: date | str,
enrollment_date: date | str, class_name: str, id_number: str, phone: str, email: str, major: str):
self.sid = sid
self.name = name.strip()
self.gender = gender
self.height = height
self.weight = weight
self.birth_date = birth_date if isinstance(birth_date, date) else date.fromisoformat(birth_date)
self.enrollment_date = enrollment_date if isinstance(enrollment_date, date) else date.fromisoformat(enrollment_date)
self.class_name = class_name
self.id_number = id_number
self.phone = phone
self.email = email
self.major = major
self._validation_errors = []
self._validate_height()
self._validate_weight()
self._validate_date()
self._validate_name()
self._validate_id_number()
self._validate_gender()
def _validate_height(self) -> None:
if not (50 <= self.height <= 250):
self._validation_errors.append(f"身高{self.height}cm超出合理范围")
def _validate_weight(self) -> None:
if not (5 <= self.weight <= 300):
self._validation_errors.append(f"体重{self.weight}kg超出合理范围")
def _validate_name(self) -> None:
if not (2 <= len(self.name) <= 20):
self._validation_errors.append("姓名长度需在2-20个字符之间")
if not all('\u4e00' <= char <= '\u9fff' or char.isascii() for char in self.name):
self._validation_errors.append("姓名只能包含中文、英文或数字")
def _validate_id_number(self) -> None:
if not re.match(r'^\d{17}[\dXx]$', self.id_number):
self._validation_errors.append("身份证号格式不正确")
def _validate_date(self) -> None:
today = date.today()
if self.birth_date > today:
self._validation_errors.append('出生日期不能在未来')
if self.enrollment_date > today:
self._validation_errors.append('入学日期不能在未来')
if (self.enrollment_date.year - self.birth_date.year) < 15:
self._validation_errors.append('入学年龄应至少15岁')
def _validate_gender(self) -> None:
if self.gender not in ['', '']:
self._validation_errors.append('性别只能是""""')
@property
def is_valid(self) -> bool:
return len(self._validation_errors) == 0
def get_errors(self) -> list[str]:
return self._validation_errors.copy()
def __eq__(self, other) -> bool:
if not isinstance(other, Student):
return NotImplemented
return (self.sid == other.sid and
self.name == other.name and
self.gender == other.gender and
self.height == other.height and
self.weight == other.weight and
self.birth_date == other.birth_date and
self.enrollment_date == other.enrollment_date and
self.class_name == other.class_name and
self.id_number == other.id_number and
self.phone == other.phone and
self.email == other.email and
self.major == other.major)
@classmethod
def from_dict(cls, data: dict) -> 'Student':
birth_date = data['birth_date'] if isinstance(data['birth_date'], date) else date.fromisoformat(data['birth_date'])
enrollment_date = data['enrollment_date'] if isinstance(data['enrollment_date'], date) else date.fromisoformat(data['enrollment_date'])
return cls(
sid=data['sid'],
name=data['name'],
gender=data['gender'],
height=data['height'],
weight=data['weight'],
birth_date=birth_date,
enrollment_date=enrollment_date,
class_name=data['class_name'],
id_number=data['id_number'],
phone=data['phone'],
email=data['email'],
major=data['major']
)
def to_dict(self) -> dict:
return {
'sid': self.sid,
'name': self.name,
'gender': self.gender,
'height': self.height,
'weight': self.weight,
'birth_date': self.birth_date.isoformat(),
'enrollment_date': self.enrollment_date.isoformat(),
'class_name': self.class_name,
'id_number': self.id_number,
'phone': self.phone,
'email': self.email,
'major': self.major
}
def __repr__(self) -> str:
return (
f"{self.__class__.__name__}("
f"sid='{self.sid}', "
f"name='{self.name}', "
f"gender='{self.gender}', "
f"height={self.height}, "
f"weight={self.weight}, "
f"birth_date=date({self.birth_date.year}, {self.birth_date.month}, {self.birth_date.day}), "
f"enrollment_date=date({self.enrollment_date.year}, {self.enrollment_date.month}, {self.enrollment_date.day}), "
f"class_name='{self.class_name}', "
f"id_number='{self.id_number}', "
f"phone='{self.phone}', "
f"email='{self.email}', "
f"major='{self.major}'"
f")"
)