作业要求:
角色:学校、学员、课程、讲师
要求:
1. 创建北京、上海 2 所学校
2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上海开
3. 课程包含,周期,价格,通过学校创建课程
4. 通过学校创建班级, 班级关联课程、讲师
5. 创建学员时,选择学校,关联班级
5. 创建讲师角色时要关联学校,
6. 提供两个角色接口
6.1 学员视图, 可以注册, 交学费, 选择班级,
6.2 讲师视图, 讲师可管理自己的班级, 上课时选择班级, 查看班级学员列表 , 修改所管理的学员的成绩
6.3 管理视图,创建讲师, 创建班级,创建课程
7. 上面的操作产生的数据都通过pickle序列化保存到文件里
思路分析
-
模型或者角色:学校, 课程, 学生, 讲师, 班级。 创建类的先后次序上,从属性最简单的课程开始
-
角色的成员属性
- 课程Course: 名称,价格,周期
- 班级ClassRoom:名称,课程详情(1:1),学生(1:n)
- 讲师Tutor: 姓名,性别,工资,年龄,所教授的班级(1:n)
- 学生Student: 姓名,性别,年龄,分数
- 学校School: 校区名称,地址,课程(1:n), 班级(1:n), 讲师(1:n), 学生(1:n)
- 关联关系
班级:课程 = 1:1
班级:学生 = 1:n
讲师:班级 = 1:n
学校:课程 = 1:n
学校:班级 = 1:n
学校:讲师 = 1:n
学校:学生 = 1:n
核心点:信息存储在文件时,需要做到一个文件修改另个文件也修改,类似一个“伪”数据库,这里类和类的一对多关系全部由字典完成。 牵涉到使用shelves。
有待扩展: 学生:班级 = 1:n 学生能够选多个课程班级。
- 视图功能
- 学校视图(admin):创建课程,创建班级,招聘讲师,查看课程,查看班级,查看讲师
- 学生视图(student):(一个功能点)注册,付学费, 选择班级
- 讲师视图(Tutor):查看不同班级的学生, 修改学生成绩
- 通过视图,勾勒类的方法
- Student: 修改分数modify_score(逻辑:分数是学士的属性,修改属性提供接口)
- Tutor: 挂钩班级attach_class(逻辑:所教授班级是tutor属性,修改属性提供接口)
- School: 实例课程new_course, 实例班级new_class, 实例学生new_student, 显示班级|课程|学生 show_info
- main.py, 把故事串起来。
知识点
1. OPP编程基础, 实例绑定及调用
2. shevel函数:创建的文件 .db
3. 伪数据库的建立:文件, 关系链用字典链接
代码结构
作业代码:
\bin\course_sys.py
import os, sys BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR) from core import main if __name__ == '__main__': main.sys_run()
\conf\settings.py
import os BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) DB_FILE = os.path.join(BASE_DIR, "db") school_db_file = os.path.join(DB_FILE, "school") #print(school_db_file)
\conf\templats.py
MAIN_MENU = ''' |----------------------------------------- 选课系统 -------------------------------------------| | | | 1. 学生 Student | | 2. 讲师 Tutor | | 3. 管理员 Admin | | | |---------------------------------------------------------------------------------------------| ''' STUDENT_MENU = ''' |-------------------------------------- 选课系统 学生版 ---------------------------------------| | | | 1. 课程注册 | | | |---------------------------------------------------------------------------------------------| ''' TUTOR_MENU = ''' |-------------------------------------- 选课系统 讲师版 ---------------------------------------| | | | 1. 查看班级 | | 2. 更新成绩 | |---------------------------------------------------------------------------------------------| ''' ADMIN_MENU = ''' |-------------------------------------- 选课系统 学校版 ---------------------------------------| | | | 1. 新建课程 2. 新建班级 3. 招聘讲师 | | 4. 查看课程 5. 查看班级 6. 查看讲师 | | 7. 查看学生 | |---------------------------------------------------------------------------------------------| '''
\core\main.py
import os, sys, shelve from lib.school import School from conf import settings from conf import templates def sys_run(): """ 主页面 :return: """ print(templates.MAIN_MENU) main_menu = { "1": StudentPortal, "2": TutorPortal, "3": AdminPortal } while True: main_opt = input("请选择相应视图 【q键 退出】>>> ").strip() if main_opt == "q": sys.exit("感谢使用【选课系统】") elif main_opt in main_menu: main_menu[main_opt]() else: print("输入有误,请重新选择") continue class AdminPortal(object): """ 学校管理员视图 """ def __init__(self): if os.path.exists(settings.school_db_file + ".db"): self.db = shelve.open(settings.school_db_file) self.admin_center() self.db.close() else: self.init_sch() self.admin_center() self.db.close() def init_sch(self): # 初始化校区 self.db = shelve.open(settings.school_db_file) self.db["BJ"] = School("北京总校", "北京朝阳") # shelve的用法,key 必须为字符串 self.db["SH"] = School("上海分校", "上海浦东") def admin_center(self): # 管理员视图: print("|-------------------------------------- 选课系统 学校版 ---------------------------------------|") for sch in self.db: print(sch) sch_opt = input("请选择校区 >>> ").strip() sch_obj = self.db[sch_opt] print(sch_obj) while True: print(templates.ADMIN_MENU) admin_menu = { "1": self.add_course, "2": self.add_class, "3": self.hire_tutor, "4": self.check_course, "5": self.check_class, "6": self.check_teacher, "7": self.check_student, } admin_opt = input("请选择功能 【q键 退出】 >>> ").strip() if admin_opt in admin_menu: admin_menu[admin_opt](sch_opt) self.admin_center() break elif admin_opt == "q": sys.exit("欢迎使用系统") else: print("输入有误,请重新选择") continue def add_course(self, sch_opt): # 新建课程接口,呼应 school/new_course while True: course_name = input("请输入【课程名称】") course_price = input("请输入【课程价格】") course_cycle = input("请输入 【课程周期】") print("课程名称:%s | 课程价格:%s | 课程周期:%s |" % (course_name,course_price,course_cycle)) confirmation = input("请确认 Y/N").strip() if confirmation == "Y": sch_obj = self.db[sch_opt] sch_obj.new_course(course_name, course_price, course_cycle) self.db[sch_opt] = sch_obj print("%s 校区 新建课程 %s" %(sch_obj.name, course_name)) break else: continue def add_class(self,sch_opt): # 新建班级接口 while True: class_name = input("请输入 【班级名称】") sch_obj = self.db[sch_opt] course_list = sch_obj.sch_course.keys() print("现有课程:%s" % course_list) course_name = input("请输入 【关联课程】") if course_name in sch_obj.sch_course: print("班级名称:%s | 关联课程:%s |" % (class_name, course_name)) confirmation = input("请确认 Y/N").strip() if confirmation == "Y": course_obj = sch_obj.sch_course[course_name] sch_obj.new_class(class_name, course_obj) self.db[sch_opt] = sch_obj print("%s 校区 新建班级 %s" % (sch_obj.name, class_name)) break else: continue else: print("无该课程,请先创建") continue def hire_tutor(self, sch_opt): # 招聘新讲师 while True: tutor_name = input("请输入 【讲师名字】") tutor_sex = input("请输入 【性别】") tutor_salary = input("请输入 【工资】") class_name = input("请输入 【班级】") print("讲师:%s | 性别:%s | 工资:%s | 班级:%s |" % (tutor_name, tutor_sex, tutor_salary, class_name)) confirmation = input("请确认 Y/N").strip() if confirmation == "Y": sch_obj = self.db[sch_opt] class_obj = sch_obj.sch_class sch_obj.new_tutor(tutor_name, tutor_sex, tutor_salary, class_name, class_obj) self.db[sch_opt] = sch_obj print("%s 校区 新聘讲师 %s" % (sch_obj.name, tutor_name)) break else: continue def check_course(self, sch_opt): # 查询课程 self.db[sch_opt].show_course() print("|---------------------------------------- THE END -----------------------------------------|") def check_class(self, sch_opt): # 查询班级 self.db[sch_opt].show_class() print("|---------------------------------------- THE END -----------------------------------------|") def check_teacher(self, sch_opt): # 查询讲师 self.db[sch_opt].show_tutor() print("|---------------------------------------- THE END -----------------------------------------|") def search_tutor(self, sch_opt): # 查询讲师 tutor_name = input("请输入 【讲师名字】") self.db[sch_opt].search_tutor(tutor_name) print("|---------------------------------------- THE END -----------------------------------------|") def check_student(self, sch_opt): # 查询学生 self.db[sch_opt].show_student() print("|---------------------------------------- THE END -----------------------------------------|") class StudentPortal(object): # 学生视图:注册学籍,选课缴费 def __init__(self): if os.path.exists(settings.school_db_file + ".db"): self.db = shelve.open(settings.school_db_file) self.stu_center() self.db.close() else: sys.exit("请联系学校管理员") def stu_center(self): """ 学生中心 :return: """ print("|-------------------------------------- 选课系统 学生版 ---------------------------------------|") for sch in self.db: print(sch) sch_opt = input("请选择校区 >>> ").strip() while True: print(templates.STUDENT_MENU) stu_menu = { "1": self.stu_enroll} # "2": self.sel_class} while True: stu_opt = input("请选择功能 【q键 退出】 >>> ").strip() if stu_opt in stu_menu: stu_menu[stu_opt](sch_opt) elif stu_opt == "q": sys.exit("欢迎使用系统") else: print("输入有误,请重新选择") continue def stu_enroll(self, sch_opt): # 新生注册 sch_obj = self.db[sch_opt] while True: stu_name = input("请输入 【学生姓名】") stu_sex = input("请输入 【性别】") stu_age = input("请输入 【年龄】") print("学生姓名:%s | 性别:%s | 年龄:%s |" % (stu_name, stu_sex, stu_age)) confirmation = input("请确认 Y/N").strip() if confirmation == "Y": while True: class_name = input("请输入 【班级】") if class_name in sch_obj.sch_class: class_obj = sch_obj.sch_class[class_name] course_obj = class_obj.class_course while True: pay_opt = input("您选择 【%s】, 价格为 【%s】。请付款" %(class_name, course_obj.price)).strip() if pay_opt == course_obj.price: sch_obj.new_student(stu_name, stu_sex, stu_age, class_name) # 实例学生 self.db[sch_opt] = sch_obj # 非常关键,实例化好后需要存储到db里 print("选课成功,少年。快学习去吧") break else: print("哥儿,多付少付都不行") continue break else: print("没开课,滚出") continue break else: continue class TutorPortal(object): # 讲师视图:查询班级,更新成绩 def __init__(self): if os.path.exists(settings.school_db_file + ".db"): self.db = shelve.open(settings.school_db_file) self.tutor_center() self.db.close() else: sys.exit("请联系学校管理员") def tutor_center(self): # 讲师中心 print("|-------------------------------------- 选课系统 讲师版 ---------------------------------------|") for sch in self.db: print(sch) sch_opt = input("请选择校区 >>> ").strip() while True: print(templates.TUTOR_MENU) tutor_menu = { "1": self.check_class, "2": self.update_score} while True: tutor_opt = input("请选择功能 【q键 退出】 >>> ").strip() if tutor_opt in tutor_menu: tutor_menu[tutor_opt](sch_opt) elif tutor_opt == "q": sys.exit("欢迎使用系统") else: print("输入有误,请重新选择") continue def check_class(self, sch_opt): sch_obj = self.db[sch_opt] tutor_name = input("请输入 【讲师姓名】 >>>").strip() if tutor_name in sch_obj.sch_tutor: sch_obj.search_tutor(tutor_name) else: print("无该讲师") def update_score(self, sch_opt): sch_obj = self.db[sch_opt] stu_name = input("请输入 【学生名字】 >>>").strip() new_score = input("请输入 【考试分数】 >>>").strip() sch_obj.modify_score(stu_name, new_score) self.db[sch_opt] = sch_obj
\lib\classroom.py
class ClassRoom(object): """ 类,班级 """ def __init__(self, classroom_name, course_obj): """ 描述班级 :param classroom_name: 班级名称,如[s1,s2, b1,b2] :param course_obj: 班级所对应课程的实例对象 """ self.name = classroom_name self.class_course = course_obj self.class_student = {}
\lib\course.py
class Course(object): """ 类,课程 """ def __init__(self, course_name, course_price, course_cycle): """ 课程 :param course_name: 课程名称 :param course_price: 课程价格 :param course_cycle: 课程周期 """ self.name = course_name self.price = course_price self.cycle = course_cycle
\lib\student.py
class Student(object): ''' 类,学生 ''' def __init__(self, stu_name, stu_sex, stu_age): ''' 学生 :param stu_name: 学生名字 :param stu_sex: 学生性别 :param stu_age: 学生年龄 ''' self.name = stu_name self.sex = stu_sex self.age = stu_age self.score = 0
\lib\tutor.py
class Tutor(object): """ 类,讲师 """ def __init__(self, tutor_name, tutor_sex, tutor_salary): """ 讲师 :param tutor_name: 讲师名字 :param tutor_sex: 讲师性别 :param tutor_salary: 讲师工资 """ self.name = tutor_name self.sex = tutor_sex self.salary = tutor_salary self.tutor_class = {} def attach_classroom(self, class_name, class_obj): self.tutor_class[class_name] = class_obj
\lib\school.py
rom lib.classroom import ClassRoom from lib.course import Course from lib.student import Student from lib.tutor import Tutor class School(object): def __init__(self, sch_name, sch_addr): """ 学校 :param sch_name: 校区名字,如“北京总校”,“上海分校” :param sch_addr:校区地址 """ self.name = sch_name self.address = sch_addr self.sch_course = {} self.sch_class = {} self.sch_tutor = {} self.sch_student = {} def new_course(self,course_name, course_price, course_cycle): """ 创建新课程 :param course_name: 课程名称 :param course_price: 价格 :param course_cycle: 周期 :return: """ course_obj = Course(course_name,course_price,course_cycle) self.sch_course[course_name] = course_obj def new_class(self, class_name, course_obj): """ 创建新班级 :param classroom_name: 班级名称 :param course_obj: 课程实例 :return: """ if course_obj.name in self.sch_course and class_name not in self.sch_class: class_obj = ClassRoom(class_name, course_obj) self.sch_class[class_name] = class_obj else: print("信息错误") def new_tutor(self, tutor_name, tutor_sex, tutor_salary, class_name, class_obj): """ 创建新讲师, 并关联一个课程 :param tutor_name: 讲师名字 :param tutor_sex: 讲师性别 :param tutor_salary: 讲师收入 :param class_name: 班级名称 :param class_obj: 班级实例 :return: """ tutor_obj = Tutor(tutor_name, tutor_sex, tutor_salary) tutor_obj.attach_classroom(class_name, class_obj) self.sch_tutor[tutor_name] = tutor_obj def new_student(self, stu_name, stu_sex, stu_age, class_name): """ 创建新学生,包括实例化学生,加入班级 :param stu_name: :param stu_sex: :param stu_age: :param class_name: :return: """ stu_obj = Student(stu_name, stu_sex, stu_age) self.sch_student[stu_name] = stu_obj class_obj = self.sch_class[class_name] class_obj.class_student[stu_name] = stu_obj self.sch_class[class_name] = class_obj def show_course(self): """ 课程信息显示,结果:【课程名称:xx 课程价格:xxxx 周期:xx】 :return: """ for course_name in self.sch_course: course_obj = self.sch_course[course_name] print("课程名称:%s 价格:%s 周期:%s" % (course_obj.name, course_obj.price, course_obj.cycle)) def show_class(self): """ 班级信息显示,数据显示:【班级名称:xx 课程名称:xx 价格:xxxx 周期:xx 】 :return: """ for class_name in self.sch_class: class_obj = self.sch_class[class_name] course_obj = class_obj.class_course print("班级:%s 课程:%s 周期:%s" % (class_obj.name, course_obj.name, course_obj.cycle)) def show_student(self): """学生信息""" for class_name in self.sch_class: class_obj = self.sch_class[class_name] for stu_name in class_obj.class_student: stu_obj = class_obj.class_student[stu_name] print("班级:%s 学生:%s 性别:%s 分数:%s" % (class_obj.name, stu_obj.name, stu_obj.sex, stu_obj.score)) def show_tutor(self): """ 老师信息显示,数据显示:【讲师:xx 课程名称:xx 班级:xx 学员:xx】 :return: """ for tutor_name in self.sch_tutor: tutor_obj = self.sch_tutor[tutor_name] class_list = [] for class_name in tutor_obj.tutor_class: class_list.append(class_name) print("讲师:%s 薪酬:%s 班级:%s" % (tutor_obj.name, tutor_obj.salary, class_list)) def search_tutor(self, tutor_name): """ 查询某讲师信息 :param tutor_name: :return: """ tutor_obj = self.sch_tutor[tutor_name] for class_name in tutor_obj.tutor_class: class_obj = self.sch_class[class_name] stu_list = [] for stu in class_obj.class_student: stu_list.append(stu) print("======== 讲师【%s】的信息如下 ========" % tutor_name) print("班级:%s | 课程:%s | 周期:%s | 学生:%s" % (class_name, class_obj.class_course.name, class_obj.class_course.cycle, stu_list)) def modify_score(self, stu_name, new_score): stu_obj = self.sch_student[stu_name] stu_obj.score = new_score self.sch_student[stu_name] = stu_obj
作业评语:
1.
这类这种代码可用 字符串格式化 和 字符串乘以一个数字 来替代
2. 有部分 无法退出 的情况,可进一步改进