第二章 抽象数据类型和python类
2.5类定义实例: 学校人事管理系统中的类
import datetime
class PersonValueError(ValueError):
"""自定义异常类"""
pass
class PersonTypeError(TypeError):
"""自定义异常类"""
pass
class Person:
_num = 0
def __init__(self, name, sex, birthday, ident):
if not (isinstance(name, str) and
sex in ("女", "男")):
raise PersonValueError(name, sex)
try:
birth = datetime.date(*birthday)
except:
raise PersonValueError("Wrong date:", birthday)
self._name = name
self._sex = sex
self._birthday = birth
self._id = ident
Person._num += 1
def id(self): return self._id
def name(self): return self._name
def sex(self): return self._sex
def birthday(self): return self._birthday
def age(self): return (datetime.date.today().year -
self._birthday.year)
def set_name(self, name):
if not isinstance(name, str):
raise PersonValueError("set_name", name)
self._name = name
def __lt__(self, another):
if not isinstance(another, Person):
raise PersonTypeError(another)
return self._id < another._id
@classmethod
def num(cls): return Person._num
def __str__(self):
return " ".join((self._id, self._name,
self._sex, str(self._birthday)))
def details(self):
return ", ".join(("编号:" + self._id,
"姓名:" + self._name,
"性别:" + self._sex,
"出生日期:" + str(self._birthday)))
# 30人数据(包含你指定的p1)
p1 = Person("谢雨洁", "女", (2005, 7, 30), "25015101111")
p2 = Person("张伟", "男", (2002, 3, 15), "25015101112")
p3 = Person("李娜", "女", (2003, 9, 22), "25015101113")
p4 = Person("王芳", "女", (2004, 5, 18), "25015101114")
p5 = Person("刘强", "男", (2001, 11, 8), "25015101115")
p6 = Person("陈静", "女", (2005, 2, 14), "25015101116")
p7 = Person("杨光", "男", (2003, 7, 30), "25015101117")
p8 = Person("赵敏", "女", (2002, 12, 5), "25015101118")
p9 = Person("黄磊", "男", (2004, 8, 19), "25015101119")
p10 = Person("周涛", "男", (2001, 6, 25), "25015101120")
p11 = Person("吴秀英", "女", (2005, 4, 12), "25015101121")
p12 = Person("郑丽", "女", (2003, 10, 3), "25015101122")
p13 = Person("孙洋", "男", (2002, 1, 17), "25015101123")
p14 = Person("朱艳", "女", (2004, 7, 9), "25015101124")
p15 = Person("胡勇", "男", (2001, 9, 28), "25015101125")
p16 = Person("林军", "男", (2005, 3, 6), "25015101126")
p17 = Person("徐杰", "男", (2003, 11, 15), "25015101127")
p18 = Person("马兰", "女", (2002, 8, 22), "25015101128")
p19 = Person("高敏", "女", (2004, 2, 11), "25015101129")
p20 = Person("罗伟", "男", (2001, 5, 30), "25015101130")
p21 = Person("宋芳", "女", (2005, 10, 8), "25015101131")
p22 = Person("唐静", "女", (2003, 4, 19), "25015101132")
p23 = Person("董强", "男", (2002, 7, 3), "25015101133")
p24 = Person("袁丽", "女", (2004, 12, 25), "25015101134")
p25 = Person("邓洋", "男", (2001, 2, 14), "25015101135")
p26 = Person("曹艳", "女", (2005, 9, 7), "25015101136")
p27 = Person("彭勇", "男", (2003, 1, 20), "25015101137")
p28 = Person("潘军", "男", (2002, 6, 12), "25015101138")
p29 = Person("钟杰", "男", (2004, 11, 28), "25015101139")
p30 = Person("田兰", "女", (2001, 8, 15), "25015101140")
# 人员列表
plist2 = [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10,
p11, p12, p13, p14, p15, p16, p17, p18, p19, p20,
p21, p22, p23, p24, p25, p26, p27, p28, p29, p30]
# 打印所有人员信息
for i, p in enumerate(plist2, 1):
print(f"{i:2d}. {p}")
print("\nAfter sorting:")
plist2.sort()
for p in plist2:
print(p.details())
print("People created:", Person.num(), "\n")
#=================================================
# 30人数据(包含你指定的p1)
p1 = Person("谢雨洁", "女", (2005, 7, 30), "25015101111")
p2 = Person("张伟", "男", (2002, 3, 15), "25015101112")
p3 = Person("李娜", "女", (2003, 9, 22), "25015101113")
p4 = Person("王芳", "女", (2004, 5, 18), "25015101114")
p5 = Person("刘强", "男", (2001, 11, 8), "25015101115")
p6 = Person("陈静", "女", (2005, 2, 14), "25015101116")
p7 = Person("杨光", "男", (2003, 7, 30), "25015101117")
p8 = Person("赵敏", "女", (2002, 12, 5), "25015101118")
p9 = Person("黄磊", "男", (2004, 8, 19), "25015101119")
p10 = Person("周涛", "男", (2001, 6, 25), "25015101120")
p11 = Person("吴秀英", "女", (2005, 4, 12), "25015101121")
p12 = Person("郑丽", "女", (2003, 10, 3), "25015101122")
p13 = Person("孙洋", "男", (2002, 1, 17), "25015101123")
p14 = Person("朱艳", "女", (2004, 7, 9), "25015101124")
p15 = Person("胡勇", "男", (2001, 9, 28), "25015101125")
p16 = Person("林军", "男", (2005, 3, 6), "25015101126")
p17 = Person("徐杰", "男", (2003, 11, 15), "25015101127")
p18 = Person("马兰", "女", (2002, 8, 22), "25015101128")
p19 = Person("高敏", "女", (2004, 2, 11), "25015101129")
p20 = Person("罗伟", "男", (2001, 5, 30), "25015101130")
p21 = Person("宋芳", "女", (2005, 10, 8), "25015101131")
p22 = Person("唐静", "女", (2003, 4, 19), "25015101132")
p23 = Person("董强", "男", (2002, 7, 3), "25015101133")
p24 = Person("袁丽", "女", (2004, 12, 25), "25015101134")
p25 = Person("邓洋", "男", (2001, 2, 14), "25015101135")
p26 = Person("曹艳", "女", (2005, 9, 7), "25015101136")
p27 = Person("彭勇", "男", (2003, 1, 20), "25015101137")
p28 = Person("潘军", "男", (2002, 6, 12), "25015101138")
p29 = Person("钟杰", "男", (2004, 11, 28), "25015101139")
p30 = Person("田兰", "女", (2001, 8, 15), "25015101140")
# 人员列表
plist2 = [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10,
p11, p12, p13, p14, p15, p16, p17, p18, p19, p20,
p21, p22, p23, p24, p25, p26, p27, p28, p29, p30]
# 打印所有人员信息
for i, p in enumerate(plist2, 1):
print(f"{i:2d}. {p}")
print("\nAfter sorting:")
plist2.sort()
for p in plist2:
print(p.details())
print("People created:", Person.num(), "\n")
#=============================================
import datetime
from random import choice, randint
class Staff(Person):
_id_num = 0
# 部门分类
teaching_depts = ["中文学院", "外文学院", "数学学院", "马克思学院"]
support_depts = ["教务处", "学工处", "后勤处", "财务处", "保卫处"]
departments = teaching_depts + support_depts
# 职位和职称定义
teaching_positions = ["教师", "班主任", "系主任", "教研室主任"]
teaching_titles = ["助理教师", "讲师", "副教授", "教授", "政府津贴"]
support_positions = ["科员", "主任", "处长", "院长"]
admin_positions = ["专员", "主管", "经理", "总监"]
all_positions = teaching_positions + support_positions + admin_positions
@classmethod
def _id_gen(cls, birthday):
"""生成员工ID: 类型码+年份后两位+部门代码+序号"""
cls._id_num += 1
birth_date = datetime.date(*birthday)
year_code = str(birth_date.year)[-2:]
# 部门代码取前两字的首字母
dept_code = "".join([d[0] for d in cls.departments])[:2]
# 类型码:T-教学单位,S-后勤单位
dept = choice(cls.departments)
type_code = "T" if dept in cls.teaching_depts else "S"
return f"{type_code}{year_code}{dept_code}{cls._id_num:04d}"
def __init__(self, name, sex, birthday, entry_date=None):
# 生成员工ID
staff_id = self._id_gen(birthday)
# 调用父类初始化
super().__init__(name, sex, birthday, staff_id)
# 设置入职日期(默认为今天)
self._entry_date = entry_date if entry_date else datetime.date.today()
self._salary = 0
self._department = None
self._position = None
self._title = None
self._type = None
def set_salary(self, amount):
if not isinstance(amount, (int, float)) or amount < 0:
raise ValueError("薪资必须为正数")
self._salary = amount
def set_department(self, department):
if department not in self.departments:
raise ValueError(f"部门必须是以下之一: {self.departments}")
self._department = department
# 根据部门自动设置类型
self._type = "教学单位" if department in self.teaching_depts else "后勤保障单位"
def set_position(self, position):
if position not in self.all_positions:
raise ValueError(f"职位必须是以下之一: {self.all_positions}")
self._position = position
def set_title(self, title):
"""设置职称(仅教学单位有效)"""
if self._department in self.teaching_depts:
if title not in self.teaching_titles:
raise ValueError(f"教学职称必须是以下之一: {self.teaching_titles}")
self._title = title
else:
self._title = "无"
def details(self):
base_info = super().details()
return (f"{base_info}\n"
f"单位类型: {self._type}\n"
f"部门: {self._department}\n"
f"职务: {self._position}\n"
f"职称: {self._title}\n"
f"薪资: {self._salary}\n"
f"入职日期: {self._entry_date}")
# 生成20个员工数据
def generate_staff(num=20):
staff_list = []
first_names = ["王", "李", "张", "刘", "陈", "杨", "赵", "黄", "周", "吴"]
last_names = ["伟", "芳", "娜", "敏", "静", "丽", "强", "磊", "洋", "勇"]
for _ in range(num):
# 随机生成基本信息
sex = choice(["男", "女"])
name = choice(first_names) + choice(last_names)
birth_year = randint(1980, 2000)
birthday = (birth_year, randint(1, 12), randint(1, 28))
# 创建员工实例
staff = Staff(name, sex, birthday)
# 设置部门(自动确定单位类型)
dept = choice(Staff.departments)
staff.set_department(dept)
# 设置职务和职称
if dept in Staff.teaching_depts:
staff.set_position(choice(Staff.teaching_positions))
staff.set_title(choice(Staff.teaching_titles))
else:
staff.set_position(choice(Staff.support_positions + Staff.admin_positions))
staff.set_title("无")
# 设置薪资
if dept in Staff.teaching_depts:
staff.set_salary(randint(8000, 50000))
else:
staff.set_salary(randint(3000, 30000))
# 随机生成入职日期
entry_date = datetime.date.today() - datetime.timedelta(days=randint(1, 1825))
staff._entry_date = entry_date
staff_list.append(staff)
return staff_list
# 创建20名员工
staff_list = generate_staff(20)
# 打印前5名员工信息
for i, staff in enumerate(staff_list[:5], 1):
print(f"\n=== 员工{i} ===")
print(staff.details())
print(f"\n总员工数: {Staff._id_num}")
=== 员工1 ===
编号:S81中外0001, 姓名:黄强, 性别:男, 出生日期:1981-02-05
单位类型: 教学单位
部门: 数学学院
职务: 教研室主任
职称: 副教授
薪资: 32012
入职日期: 2024-01-14
=== 员工2 ===
编号:T90中外0002, 姓名:李敏, 性别:女, 出生日期:1990-10-03
单位类型: 后勤保障单位
部门: 教务处
职务: 院长
职称: 无
薪资: 17288
入职日期: 2022-08-27
=== 员工3 ===
编号:S99中外0003, 姓名:陈静, 性别:男, 出生日期:1999-07-22
单位类型: 后勤保障单位
部门: 教务处
职务: 总监
职称: 无
薪资: 20508
入职日期: 2024-12-04
=== 员工4 ===
编号:T91中外0004, 姓名:陈勇, 性别:男, 出生日期:1991-10-22
单位类型: 教学单位
部门: 中文学院
职务: 系主任
职称: 讲师
薪资: 31820
入职日期: 2023-11-03
=== 员工5 ===
编号:T96中外0005, 姓名:李敏, 性别:女, 出生日期:1996-03-16
单位类型: 教学单位
部门: 数学学院
职务: 教师
职称: 讲师
薪资: 34577
入职日期: 2025-02-26
总员工数: 20
class DepartmentCourses:
"""各学院课程目录"""
@staticmethod
def chinese_department():
return {
"学院名称": "中文学院",
"主修课程": [
("现代汉语", "研究现代汉语的语音、词汇、语法等"),
("古代汉语", "学习古代汉语的语法、文字、音韵及经典文献阅读"),
("中国现代文学史", "探讨中国现代文学的发展历程和重要作品"),
("中国当代文学史", "分析中国当代文学的现象、流派和代表作品"),
("中国文学史", "全面介绍中国文学从古至今的发展脉络"),
("语言学概论", "概述语言学的基本概念、理论和研究方法"),
("文艺理论", "研究文学艺术的基本原理和批评方法"),
("美学", "探讨美的本质、审美经验和艺术的价值"),
("外国文学史", "了解世界文学的主要流派、作品及其影响")
],
"选修课程": [
("写作", "提高文字表达能力和创作技巧"),
("秘书学", "学习秘书工作的知识和技能,包括文书处理、档案管理等"),
("英文常用写作", "提升英文写作能力和跨文化交流技巧"),
("对外汉语教学概论", "了解对外汉语教学的基本原理和方法"),
("中文办公自动化", "掌握中文环境下办公自动化软件的应用")
]
}
@staticmethod
def math_department():
return {
"学院名称": "数学学院",
"主修课程": [
("数学分析", "研究极限、微积分、级数等基本概念和方法"),
("高等代数", "学习线性代数、矩阵论和抽象代数基础"),
("解析几何", "研究几何图形的坐标表示和代数方法"),
("概率论与数理统计", "掌握随机现象和数据分析的基本理论"),
("常微分方程", "学习常微分方程的基本解法及应用"),
("复变函数", "研究复数域上的函数理论"),
("实变函数", "深入理解实数集和可测函数理论"),
("抽象代数", "学习群、环、域等代数结构"),
("拓扑学", "研究空间在连续变换下的不变性质")
],
"选修课程": [
("数学建模", "学习用数学方法解决实际问题"),
("数值分析", "掌握数值计算的基本算法"),
("运筹学", "研究优化问题的数学方法"),
("数学史", "了解数学发展历史和重要思想"),
("计算机数学", "学习计算机科学中的数学基础")
]
}
@staticmethod
def foreign_lang_department():
return {
"学院名称": "外文学院",
"主修课程": [
("综合英语", "系统训练英语听、说、读、写能力"),
("英语语言学", "研究英语语言的结构和规律"),
("英美文学史", "学习英美文学发展历程和经典作品"),
("翻译理论与实践", "掌握翻译的基本技巧和方法"),
("跨文化交际", "研究不同文化背景下的交流策略"),
("第二外语", "学习法语/德语/日语等第二外语基础"),
("英语写作", "培养英语学术和实用写作能力"),
("英语国家概况", "了解主要英语国家的文化和社会"),
("学术英语", "掌握学术研究和论文写作的英语表达")
],
"选修课程": [
("商务英语", "学习商务环境中的英语应用"),
("英语演讲与辩论", "培养英语口头表达能力"),
("影视英语", "通过影视作品学习地道英语"),
("英语教学法", "了解英语作为外语的教学方法"),
("同声传译基础", "初步掌握同声传译技巧")
]
}
@staticmethod
def marxism_department():
return {
"学院名称": "马克思学院",
"主修课程": [
("马克思主义基本原理", "系统学习马克思主义哲学、政治经济学和科学社会主义"),
("中国近现代史纲要", "研究中国近现代历史发展脉络"),
("毛泽东思想和中国特色社会主义理论体系概论", "学习党的理论创新成果"),
("思想政治教育学原理", "研究思想政治教育的基本理论"),
("马克思主义发展史", "了解马克思主义理论发展历程"),
("科学社会主义理论与实践", "研究社会主义运动的历史和现实"),
("马克思主义经典著作选读", "精读马克思主义经典文献"),
("中国共产党历史", "学习党的奋斗历程和基本经验"),
("当代世界经济与政治", "分析国际格局和热点问题")
],
"选修课程": [
("中国特色社会主义理论与实践研究", "深入研究中国特色社会主义理论"),
("马克思主义与社会科学方法论", "学习马克思主义研究方法"),
("中国传统文化概论", "了解中国传统文化精髓"),
("国际共产主义运动史", "研究国际共运的历史经验"),
("当代社会思潮评析", "分析和评价当代主要社会思潮")
]
}
@classmethod
def get_all_courses(cls):
return {
"中文学院": cls.chinese_department(),
"数学学院": cls.math_department(),
"外文学院": cls.foreign_lang_department(),
"马克思学院": cls.marxism_department()
}
# 使用示例
if __name__ == "__main__":
courses = DepartmentCourses.get_all_courses()
# 打印中文学院课程
print(f"=== {courses['中文学院']['学院名称']}课程 ===")
print("\n主修课程:")
for course, desc in courses['中文学院']['主修课程']:
print(f"- {course}:{desc}")
print("\n选修课程:")
for course, desc in courses['中文学院']['选修课程']:
print(f"- {course}:{desc}")
#================================================
import datetime
from random import choice, randint, random
from collections import defaultdict
# ================== 基础类定义 ==================
class Person:
def __init__(self, name, sex, birthday, ident):
self.name = name
self.sex = sex
self.birthday = datetime.date(*birthday)
self.id = ident
class Staff(Person):
departments = ["中文学院", "外文学院", "数学学院", "马克思学院"]
positions = ["讲师", "副教授", "教授", "研究员"]
def __init__(self, name, sex, birthday, ident=None):
ident = ident if ident else f"25015101{randint(100,999)}"
super().__init__(name, sex, birthday, ident)
self.department = choice(self.departments)
self.position = choice(self.positions)
self._type = "教学单位" if self.department.endswith("学院") else "行政单位"
# ================== 课程管理系统 ==================
class Course:
def __init__(self, name, description, credit, dept, category="主修"):
self.name = name
self.description = description
self.credit = credit
self.department = dept
self.category = category
self.popularity = 0
self.students = set()
self.assessments = {
'平时作业': {'weight': 20, 'score': 0},
'课堂表现': {'weight': 10, 'score': 0},
'期中考试': {'weight': 20, 'score': 0},
'实验报告': {'weight': 15, 'score': 0},
'期末考试': {'weight': 35, 'score': 0}
}
def enroll(self, student_id):
if student_id not in self.students:
self.students.add(student_id)
self.popularity = min(100, self.popularity + 5)
return True
return False
def record_scores(self):
"""为所有选课学生生成随机成绩"""
for student_id in self.students:
for item in self.assessments:
self.assessments[item]['score'] = randint(60, 95)
def calculate_final(self):
"""计算最终成绩"""
return sum(self.assessments[item]['score'] * self.assessments[item]['weight'] / 100
for item in self.assessments)
# ================== 学院课程目录 ==================
department_courses = {
"中文学院": {
"主修": [
("现代汉语", "语音、词汇、语法研究", 4),
("古代汉语", "语法、文字、音韵研究", 4),
("中国文学史", "文学发展脉络", 3)
],
"选修": [
("创意写作", "文学创作技巧", 2),
("古典文献学", "古籍整理与研究", 3)
]
},
"数学学院": {
"主修": [
("高等数学", "微积分基础", 5),
("线性代数", "矩阵与向量空间", 4),
("概率统计", "随机现象分析", 3)
],
"选修": [
("数学建模", "实际问题数学解决", 3),
("数值分析", "数值计算方法", 3)
]
}
}
# ================== 生成教职工数据 ==================
def generate_staff(num=30):
first_names = ["王", "李", "张", "刘", "陈"]
last_names = ["伟", "芳", "娜", "敏", "杰"]
staff_list = []
for i in range(num):
name = choice(first_names) + choice(last_names)
sex = choice(["男", "女"])
birthday = (randint(1975, 1995), randint(1,12), randint(1,28))
staff_list.append(Staff(name, sex, birthday, f"25015101{100+i}"))
return staff_list
# ================== 主系统 ==================
class AcademicSystem:
def __init__(self):
self.staff_list = generate_staff()
self.courses = self.init_courses()
self.student_records = {s.id: s for s in self.staff_list}
self.course_records = defaultdict(dict) # {student_id: {course: grade}}
def init_courses(self):
"""初始化所有课程"""
courses = []
for dept, categories in department_courses.items():
for category, course_list in categories.items():
for name, desc, credit in course_list:
courses.append(Course(name, desc, credit, dept, category))
return courses
def enroll(self, student_id, course_name):
"""学生选课"""
student = self.student_records.get(student_id)
course = next((c for c in self.courses if c.name == course_name), None)
if student and course:
if course.enroll(student_id):
self.course_records[student_id][course] = None
return True
return False
def generate_grades(self):
"""为所有课程生成成绩"""
for course in self.courses:
course.record_scores()
final_grade = course.calculate_final()
for student_id in course.students:
self.course_records[student_id][course] = {
'grade': final_grade,
'passed': final_grade >= 60,
'credits': course.credit if final_grade >= 60 else 0
}
def get_transcript(self, student_id):
"""生成成绩单"""
if student_id not in self.student_records:
return None
student = self.student_records[student_id]
records = self.course_records.get(student_id, {})
transcript = {
"学号": student_id,
"姓名": student.name,
"部门": student.department,
"职位": student.position,
"总学分": sum(cr['credits'] for cr in records.values() if cr),
"课程成绩": [
{
"课程": course.name,
"类型": course.category,
"学分": course.credit,
"成绩": record['grade'],
"结果": "通过" if record['passed'] else "不通过"
}
for course, record in records.items()
]
}
return transcript
# ================== 使用示例 ==================
if __name__ == "__main__":
system = AcademicSystem()
# 选课示例
system.enroll("25015101101", "现代汉语")
system.enroll("25015101101", "高等数学")
system.enroll("25015101102", "线性代数")
# 生成成绩
system.generate_grades()
# 打印成绩单
print("=== 学生成绩单示例 ===")
print(system.get_transcript("25015101101"))
# 打印热门课程
print("\n=== 热门课程Top3 ===")
popular = sorted(system.courses, key=lambda x: x.popularity, reverse=True)[:3]
for i, course in enumerate(popular, 1):
print(f"{i}. {course.name} ({course.department}, 热度: {course.popularity})")
=== 学生成绩单示例 ===
{‘学号’: ‘25015101101’, ‘姓名’: ‘刘敏’, ‘部门’: ‘数学学院’, ‘职位’: ‘教授’, ‘总学分’: 9, ‘课程成绩’: [{‘课程’: ‘现代汉语’, ‘类型’: ‘主修’, ‘学分’: 4, ‘成绩’: 74.3, ‘结果’: ‘通过’}, {‘课程’: ‘高等数学’, ‘类型’: ‘主修’, ‘学分’: 5, ‘成绩’: 86.15, ‘结果’: ‘通过’}]}
=== 热门课程Top3 ===
- 现代汉语 (中文学院, 热度: 5)
- 高等数学 (数学学院, 热度: 5)
- 线性代数 (数学学院, 热度: 5)
import datetime
from random import choice, randint, random
from collections import defaultdict
# ================== 基础类定义 ==================
class Person:
def __init__(self, name, sex, birthday, ident):
self.name = name
self.sex = sex
self.birthday = datetime.date(*birthday)
self.id = ident
class Student(Person):
def __init__(self, name, sex, birthday, ident, degree_type):
super().__init__(name, sex, birthday, ident)
self.degree_type = degree_type
self.enrollment_date = datetime.date.today()
self.courses = {}
self.total_credits = 0
self.gpa = 0.0
def enroll_course(self, course):
if course not in self.courses:
self.courses[course] = None
course.enroll(self.id)
return True
return False
def update_grade(self, course, score):
if course in self.courses:
self.courses[course] = score
self._update_academic_record()
return True
return False
def _update_academic_record(self):
"""更新学分和GPA"""
total_points = 0
total_credits = 0
for course, score in self.courses.items():
if score is not None and score >= 60:
total_credits += course.credit
total_points += score * course.credit
self.total_credits = total_credits
self.gpa = round(total_points / (total_credits * 25), 2) if total_credits > 0 else 0.0
# ================== 派生学生类 ==================
class Undergraduate(Student):
def __init__(self, name, sex, birthday, ident, major):
super().__init__(name, sex, birthday, ident, "本科生")
self.major = major
self.required_credits = 160 # 本科毕业要求学分
def can_graduate(self):
return self.total_credits >= self.required_credits
class Master(Student):
def __init__(self, name, sex, birthday, ident, research_field):
super().__init__(name, sex, birthday, ident, "硕士生")
self.research_field = research_field
self.required_credits = 32
self.thesis_progress = 0 # 论文进度(0-100)
def update_thesis(self, progress):
self.thesis_progress = min(100, self.thesis_progress + progress)
def can_graduate(self):
return (self.total_credits >= self.required_credits
and self.thesis_progress >= 100)
class PhD(Student):
def __init__(self, name, sex, birthday, ident, research_topic):
super().__init__(name, sex, birthday, ident, "博士生")
self.research_topic = research_topic
self.required_credits = 20
self.papers_published = 0
self.thesis_defended = False
def publish_paper(self):
self.papers_published += 1
def defend_thesis(self):
self.thesis_defended = True
def can_graduate(self):
return (self.total_credits >= self.required_credits
and self.papers_published >= 3
and self.thesis_defended)
class InternationalStudent(Student):
def __init__(self, name, sex, birthday, ident, degree_type, country):
super().__init__(name, sex, birthday, ident, f"留学生({degree_type})")
self.country = country
self.chinese_level = "HSK" + str(randint(3, 6)) # 随机汉语水平
# 根据学位类型设置毕业要求
if "本科" in degree_type:
self.required_credits = 140
elif "硕士" in degree_type:
self.required_credits = 30
else:
self.required_credits = 18
def can_graduate(self):
return (self.total_credits >= self.required_credits
and self.chinese_level >= "HSK4")
# ================== 课程类 ==================
class Course:
def __init__(self, name, credit, dept):
self.name = name
self.credit = credit
self.department = dept
self.students = set()
def enroll(self, student_id):
self.students.add(student_id)
return True
# ================== 学院系统 ==================
```python
class AcademicSystem:
def __init__(self):
self.students = {}
self.courses = [
Course("高等数学", 5, "数学学院"),
Course("现代汉语", 4, "中文学院"),
Course("机器学习", 3, "计算机学院")
]
def add_student(self, student_type, *args, **kwargs):
"""添加学生"""
if student_type == "本科":
student = Undergraduate(*args, **kwargs)
elif student_type == "硕士":
student = Master(*args, **kwargs)
elif student_type == "博士":
student = PhD(*args, **kwargs)
elif student_type == "留学":
student = InternationalStudent(*args, **kwargs)
else:
raise ValueError("未知学生类型")
self.students[student.id] = student
return student
def enroll(self, student_id, course_name):
"""学生选课"""
student = self.students.get(student_id)
course = next((c for c in self.courses if c.name == course_name), None)
if student and course:
return student.enroll_course(course)
return False
def generate_grades(self):
"""为所有学生生成随机成绩"""
for student in self.students.values():
for course in student.courses:
if student.courses[course] is None:
score = randint(50, 100) if random() > 0.1 else randint(30, 59) # 10%不及格率
student.update_grade(course, score)
def check_graduation(self, student_id):
"""检查毕业资格"""
student = self.students.get(student_id)
if student:
return student.can_graduate()
return False
================== 使用示例 ==================
if __name__ == "__main__":
system = AcademicSystem()
# 添加各类学生
undergrad = system.add_student(
"本科", "张三", "男", (1999,5,12), "S2021001", "计算机科学"
)
master = system.add_student(
"硕士", "李四", "女", (1995,8,23), "S2021002", "人工智能"
)
phd = system.add_student(
"博士", "王五", "男", (1990,3,15), "S2021003", "量子计算"
)
international = system.add_student(
"留学", "John Smith", "男", (1998,7,30), "S2021004", "本科", "美国"
)
# 学生选课
system.enroll(undergrad.id, "高等数学")
system.enroll(undergrad.id, "机器学习")
system.enroll(master.id, "机器学习")
system.enroll(international.id, "现代汉语")
# 生成成绩
system.generate_grades()
# 博士生发表论文
phd.publish_paper()
phd.publish_paper()
phd.publish_paper()
phd.defend_thesis()
# 硕士生更新论文进度
master.update_thesis(80)
# 打印学生状态
print("=== 学生状态 ===")
for sid, student in system.students.items():
status = "可毕业" if system.check_graduation(sid) else "在读"
print(f"{student.name}({student.degree_type}): GPA={student.gpa}, 学分={student.total_credits}, 状态={status}")
=== 学生状态 ===
张三(本科生): GPA=3.31, 学分=8, 状态=在读
李四(硕士生): GPA=0.0, 学分=0, 状态=在读
王五(博士生): GPA=0.0, 学分=0, 状态=在读
John Smith(留学生(本科)): GPA=3.12, 学分=4, 状态=在读
一、系统框架设计
1. 核心模块
2. 技术架构
┌─────────────────┐
│ 前端展示层 │ # Vue/React + Element UI
├─────────────────┤
│ 业务逻辑层 │ # Python(Django/Flask)
├─────────────────┤
│ 数据访问层 │ # ORM(SQLAlchemy)
├─────────────────┤
│ 数据存储层 │ # MySQL/PostgreSQL + Redis缓存
二、系统分析
1. 角色分析
角色 权限说明 典型用例
教职工 查看个人信息/课表/薪资 请假申请/课表查询
院系管理员 管理本院系师生信息 教师考核/学生分班
人事专员 全系统人事数据管理 入职办理/离职处理
校级管理员 系统配置/权限分配 院系合并/权限调整
2. 关键业务流程
入职流程
简历筛选 → 面试安排 → 录用审批 → 信息录入 → 账号开通
职称评审流程
个人申请 → 教研室初审 → 学院评审 → 学校终审 → 结果公示
学生培养流程
培养方案制定 → 选课管理 → 中期考核 → 论文答辩 → 毕业审核
三、系统配置方案
1. 基础配置
yaml
# config.yaml
database:
host: mysql.university.edu
port: 3306
user: hr_system
password: secure_password
storage:
document_path: /var/www/hr_docs
max_upload_size: 100MB
security:
password_policy:
min_length: 8
require_mixed_case: true
expire_days: 90
2. 业务参数配置
python
# 职称晋升规则
PROMOTION_RULES = {
"讲师→副教授": {
"min_years": 5,
"required_papers": 3,
"teaching_hours": 320
},
"副教授→教授": {
"min_years": 6,
"required_projects": 2,
"international_papers": 1
}
}
# 学分计算规则
CREDIT_POLICY = {
"本科生": {
"required": 160,
"public_course_ratio": 0.3
},
"硕士生": {
"core_course_min": 12,
"thesis_credit": 8
}
}
3. 集成配置
json
{
"integrations": {
"financial_system": {
"api_endpoint": "https://finance.university.edu/api",
"sync_schedule": "daily 02:00"
},
"library_system": {
"book_quota": {
"professor": 20,
"student": 10
}
}
}
}
四、扩展设计
1. 数据模型设计
python
class Staff(models.Model):
id = UUIDField(primary_key=True)
name = CharField(max_length=50)
type = ChoiceField(choices=[
('TEACH', '教师'),
('ADMIN', '行政'),
('LAB', '实验员')
])
department = ForeignKey(Department)
positions = ArrayField( # 支持双肩挑人员
EmbeddedField(PositionInfo)
)
class Course(models.Model):
code = CharField(max_length=10) # 如"MATH-201"
credits = DecimalField(max_digits=3, decimal_places=1)
assessment_schema = JSONField() # 存储考核权重
2. 安全设计
四层防护:
网络层:IP白名单+VPN
应用层:JWT认证+接口签名
数据层:字段级加密(身份证/薪资)
审计层:所有敏感操作留痕
3. 高可用方案
plaintext
┌───────────────┐
│ 负载均衡器 │
└──────┬───────┘
│
┌──────────────┼──────────────┐
▼ ▼ ▼
┌─────────────────────┐ ┌───────────────┐
│ 主数据库(MySQL集群) │ │ 只读副本 │
└─────────────────────┘ └───────────────┘
▲
│
┌──────────┴──────────┐
│ 定时备份系统 │
│ (每日全量+binlog) │
└─────────────────────┘
数据结构 与算法 裘宗燕 p65