功能代码实现源地址:https://www.cnblogs.com/lianzhilei/p/5832691.html    如有侵权,立即删除

本文主要是分析 选课系统 实现思路及上面代码的实现过程,感谢python前辈分享出源码。

首先,写出自己的实现思路:

python初学者,自学到面向对象,有以下作业要求需要实现:

角色:学校、学员、课程、讲师
要求:
1. 创建北京、上海 2 所学校
2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上海开
3. 课程包含,周期,价格,通过学校创建课程
4. 通过学校创建班级, 班级关联课程、讲师
5. 创建学员时,选择学校,关联班级
6. 创建讲师角色时要关联学校,
7. 提供两个角色接口
8. 学员视图, 可以注册, 交学费, 选择班级,
9. 讲师视图, 讲师可管理自己的班级, 上课时选择班级, 查看班级学员列表 , 修改所管理的学员的成绩
10. 管理视图,创建讲师, 创建班级,创建课程11. 上面的操作产生的数据都通过pickle序列化保存到文件里

最初拿到这个作业真的是无从下手,只能通过一句一句的返回斟酌,因为是学过了python的面向对象,首先分析上面那些可以作为类:

学校类、课程类、讲师类、学生类class School:passclass Course:passclass Teacher:passclass Student:pass

1. 创建北京、上海 2 所学校

通过实例化可以创建这两所学校sh = School(xxx)
bj = School(xxx)

2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上海开

三个课程,我们可以通过实例化课程类实现
linux = Course(xxx)
python = Course(xxx)
go = Course(xxx)

linux\py 在北京开, go 在上海开  这就说明 School 类下有course这个属性,因此 School 修改为:

class School:def __init__(name, addr, course):self.name = name # 学校名self.addr = addr  # 学校地址self.course = course # 学校里的课程class Course:def __init__(name, price, time):self.name = nameself.price = priceself.time = timecourse = Course(name, price, time)   # 实例化课程类school = School('上海', '上海市', course)   # 类的组合

3. 课程包含,周期,价格,通过学校创建课程

到第三点要求的时候,上面的代码得改写了,如下:class School:def __init__(name, addr, course):self.name = name   # 学校名self.addr = addr  # 学校地址def create_course(self):  # 通过学校创建课程passclass Course:def __init__(name, price, time):self.name = nameself.price = priceself.time = time

4. 通过学校创建班级, 班级关联课程、讲师

到第四点又多了一个班级的类,这个类里包含哪些属性呢?班级名、班级上课的讲师、班级要上的课程、班级里的学生class School:def __init__(name, addr, course):self.name = name   # 学校名self.addr = addr  # 学校地址def create_course(self):  # 通过学校创建课程passclass Course:def __init__(name, price, time):self.name = nameself.price = priceself.time = timeclass Grade:def __init__(name, teacher, course, student):self.name = nameself.teacher = teacherself.course = courseself.student = student

作为一个初学者,后面的需求就不知道怎么去实现了。于是去参考了下python前辈的代码:

源码地址:功能代码实现源地址:https://www.cnblogs.com/lianzhilei/p/5832691.html    如有侵权,立即删除

撸了N边代码,整理下思路,数据关系结构如下:

{school:{course:{'teacher': teacher, 'grade': grade}}}

{teacher:{'grade':grade}}

有了这个数据关系,基本就能明白作者的实现思路。

举个栗子:

main_db = {school:{course:{'teacher': teacher, 'grade': grade}}}
school = School('上海')上海学院下面的课程信息:course = main_db[school]上海学院python课程下面的老师和班级信息:python = Course('python')info = main_db[school][python]

不知道通过上面的栗子能不能稍微领悟一点,通读作者代码和上面的作业要求,可以分为三大部分。

学校中心

接下来,不用看代码,试试自己来实现下:

作业要求是通过 pickle 序列化到本地文件

首先有三个视图:

main_list = ['学校中心', '讲师中心', '学生中心', '退出']

先来实现第一个视图:学校中心

第一步,实现三大视图的循环选择

import pickledef options(li):for i, k in enumerate(li):print(i+1, k)choice = input('>>>').strip()return choicedef start():while True:choice = options(main_list)if not choice: continueif choice == '1':print('\033[33;1m【学校中心】\033[0m')elif choice == '2':print('\033[33;1m【讲师中心】\033[0m')elif choice == '3':print('\033[33;1m【学生中心】\033[0m')elif choice == '4':print('退出')breakif __name__ == '__main__':main_list = ['学校中心', '讲师中心', '学生中心', '退出']start()

根据流程图, 第二步我们需要选择学校名,而我们并没有任何数据信息,这里就需要先初始化学校信息:

import os, pickleBASE_DIR = os.path.dirname(os.path.abspath(__file__))
__db_main = os.path.join(BASE_DIR, 'main_dict')  # 学校内容文件
__db_teacher = os.path.join(BASE_DIR, 'teacher_dict')  # 讲师课程内容文件class School(object):'''学校类'''def __init__(self, name, addr):self.name = nameself.addr = addrdef options(li):'''序号和标题循环打印,返回选择序号'''for i, k in enumerate(li):print(i + 1, k)choice = input('>>>').strip()return choicedef start():'''开始程序,根据选择的序号进入不同的视图'''while True:choice = options(main_list)if not choice: continueif choice == '1':print('\033[33;1m【学校中心】\033[0m')elif choice == '2':print('\033[33;1m【讲师中心】\033[0m')elif choice == '3':print('\033[33;1m【学生中心】\033[0m')elif choice == '4':print('退出')breakdef file_oper(file, mode, *args):'''根据文件的读或者写,做不同的操作,读返回文件内容信息'''if mode == 'wb':data = args[0]with open(file, mode) as f:pickle.dump(data, f)elif mode == 'rb':with open(file, mode) as f:data = pickle.load(f)return datadef init_database():'''初始化学校信息'''sh = School('上海', '上海市')bj = School('北京', '北京市')if not os.path.exists(__db_main):data = {sh: {}, bj: {}}file_oper(__db_main, 'wb', data)if not os.path.exists(__db_teacher):data = {}file_oper(__db_teacher, 'wb', data)if __name__ == '__main__':init_database()main_list = ['学校中心', '讲师中心', '学生中心', '退出']start()

通过初始化,已经将数据结构确定下来了。

__db_main = {sh: {}, bj: {}}
__db_teacher = {}

可以查看当前程序的目录下,已经生成两个pickle序列化的文件,下一步,我们就可以通过读取本地的文件,将初始化的数据读取出来,进行学校的选择:

import os, pickleBASE_DIR = os.path.dirname(os.path.abspath(__file__))
__db_main = os.path.join(BASE_DIR, 'main_dict')  # 学校内容文件
__db_teacher = os.path.join(BASE_DIR, 'teacher_dict')  # 讲师课程内容文件class School(object):'''学校类'''def __init__(self, name, addr):self.name = nameself.addr = addrdef cat_school(self):print('\033[32;1m学校【%s】\t地址【%s】\033[0m' % (self.name, self.addr))def options(li):'''序号和标题循环打印,返回选择序号'''for i, k in enumerate(li):print(i + 1, k)choice = input('>>>').strip()return choicedef information(db, mode):dict_info = {}if db:for key in db:if mode == 'main':key.cat_school()if not isinstance(key, str):dict_info[key.name] = keyreturn dict_infodef school_center():Flag = Truewhile Flag:main_db = file_oper(__db_main, 'rb')res_school = information(main_db, 'main')school_name = input('\033[34;1m选择学校名:\033[0m')def start():'''开始程序,根据选择的序号进入不同的视图'''while True:choice = options(main_list)if not choice: continueif choice == '1':print('\033[33;1m【学校中心】\033[0m')school_center()elif choice == '2':print('\033[33;1m【讲师中心】\033[0m')elif choice == '3':print('\033[33;1m【学生中心】\033[0m')elif choice == '4':print('退出')breakdef file_oper(file, mode, *args):'''根据文件的读或者写,做不同的操作,读返回文件内容信息'''if mode == 'wb':data = args[0]with open(file, mode) as f:pickle.dump(data, f)elif mode == 'rb':with open(file, mode) as f:data = pickle.load(f)return datadef init_database():'''初始化学校信息'''sh = School('上海', '上海市')bj = School('北京', '北京市')if not os.path.exists(__db_main):data = {sh: {}, bj: {}}file_oper(__db_main, 'wb', data)if not os.path.exists(__db_teacher):data = {}file_oper(__db_teacher, 'wb', data)if __name__ == '__main__':init_database()main_list = ['学校中心', '讲师中心', '学生中心', '退出']start()

上面的代码中,School 类中增加了一个cat_school 查看学校属性的方法,最主要的是增加了一个 information 函数,这个函数一定要理解:

我们在初始化时:

sh = School('上海', '上海市')
bj = School('北京', '北京市')

通过pickle读取出来的类型如下:

main_db = {sh: {}, bj: {}}

sh、bj 都是School实例化后的对象,这里就需要通过 information 来做转换

def information(db, mode):dict_info = {}if db:for key in db:if mode == 'main':key.cat_school()if not isinstance(key, str):dict_info[key.name] = keyreturn dict_info

当我们执行:

information(main_db, 'main')

1. 首先 key 就是school对象,通过对象.方法查看school类的方法cat_school()
2. if not isinstance(key, str):    当 key 不是字符串类型,这里 key 是实例化后的类型,并不是字符串类型,因此返回的是 {'北京':bj, '上海':sh}

通过上面的步骤,我们已经可以进行选择学校,来到了学校内部,可以 ['创建课程', '招聘讲师', '创建班级']

import os, pickleBASE_DIR = os.path.dirname(os.path.abspath(__file__))
__db_main = os.path.join(BASE_DIR, 'main_dict')  # 学校内容文件
__db_teacher = os.path.join(BASE_DIR, 'teacher_dict')  # 讲师课程内容文件class School(object):'''学校类'''def __init__(self, name, addr):self.name = nameself.addr = addrdef cat_school(self):print('\033[32;1m学校【%s】\t地址【%s】\033[0m' % (self.name, self.addr))def options(li):'''序号和标题循环打印,返回选择序号'''for i, k in enumerate(li):print(i + 1, k)choice = input('>>>').strip()return choicedef information(db, mode):dict_info = {}if db:for key in db:if mode == 'main':key.cat_school()if not isinstance(key, str):dict_info[key.name] = keyreturn dict_infodef school_center():Flag = Truewhile Flag:main_db = file_oper(__db_main, 'rb')res_school = information(main_db, 'main')school_name = input('\033[34;1m选择学校名:\033[0m')if school_name in res_school:school = res_school[school_name]  # 通过学校名获取到了该学校名的类while Flag:choice = options(school_list)  # 循环打印学校中心下的功能点if choice == '1':  # 创建课程passelif choice == '2':  # 招聘讲师passelif choice == '3':  # 创建班级passelif choice == '4':  # 返回Flag = False                # 退出到主界面else:print('\033[31;1m输入错误,请重新输入.\033[0m')def start():'''开始程序,根据选择的序号进入不同的视图'''while True:choice = options(main_list)if not choice: continueif choice == '1':print('\033[33;1m【学校中心】\033[0m')school_center()elif choice == '2':print('\033[33;1m【讲师中心】\033[0m')elif choice == '3':print('\033[33;1m【学生中心】\033[0m')elif choice == '4':print('退出')breakdef file_oper(file, mode, *args):'''根据文件的读或者写,做不同的操作,读返回文件内容信息'''if mode == 'wb':data = args[0]with open(file, mode) as f:pickle.dump(data, f)elif mode == 'rb':with open(file, mode) as f:data = pickle.load(f)return datadef init_database():'''初始化学校信息'''sh = School('上海', '上海市')bj = School('北京', '北京市')if not os.path.exists(__db_main):data = {sh: {}, bj: {}}file_oper(__db_main, 'wb', data)if not os.path.exists(__db_teacher):data = {}file_oper(__db_teacher, 'wb', data)if __name__ == '__main__':init_database()main_list = ['学校中心', '讲师中心', '学生中心', '退出']school_list = ['创建课程', '招聘讲师', '创建班级', '返回']start()

上面的代码:
1. 通过用户选择的学校名获取到了带学校名属性的类;
2. 使用Flag = True 循环,当要退出时候,直接可以退出到主界面,这里可以揣摩下,这种用法以后肯定会遇到。

接下来,就需要实现创建课程的功能点。

import os, pickleBASE_DIR = os.path.dirname(os.path.abspath(__file__))
__db_main = os.path.join(BASE_DIR, 'main_dict')  # 学校内容文件
__db_teacher = os.path.join(BASE_DIR, 'teacher_dict')  # 讲师课程内容文件class School(object):'''学校类'''def __init__(self, name, addr):self.name = nameself.addr = addrdef cat_school(self):print('\033[32;1m学校【%s】\t地址【%s】\033[0m' % (self.name, self.addr))def create_course(self, main_db, course, main_file):main_db[self][course] = {}file_oper(main_file, 'wb', main_db)class Course(object):def __init__(self, name, price, time):self.name = nameself.price = priceself.time = timedef cat_course(self):print('\033[32;1m课程【%s】\t价格【%s元】\t周期【%s个月】\033[0m' % (self.name, self.price, self.time))def options(li):'''序号和标题循环打印,返回选择序号'''for i, k in enumerate(li):print(i + 1, k)choice = input('>>>').strip()return choicedef information(db, mode):dict_info = {}if db:for key in db:if mode == 'main':key.cat_school()elif mode == 'course':key.cat_course()if not isinstance(key, str):dict_info[key.name] = keyreturn dict_infodef school_center():Flag = Truewhile Flag:main_db = file_oper(__db_main, 'rb')res_school = information(main_db, 'main')school_name = input('\033[34;1m选择学校名:\033[0m')if school_name in res_school:school = res_school[school_name]while Flag:choice = options(school_list)if choice == '1':  # 创建课程while True:print('\033[33;1m目前学校【%s】已经存在的课程信息:\033[0m' % school_name)res_course = information(main_db[school], 'course')print(type(res_course))if not res_course:print('\033[31;1m目前没有任何课程信息.\033[0m')if_cont = input('\033[34;1m是否创建课程[y/b]:').strip()if if_cont == 'y':course_name = input('\033[34;1m输入课程名:').strip()if course_name not in res_course:course_price = input('\033[34;1m输入课程价格:').strip()course_time = input('\033[34;1m输入课程周期:').strip()course = Course(course_name, course_price, course_time)school.create_course(main_db, course, __db_main)else:print('\033[31;1m该课程名已存在.\033[0m')elif if_cont == 'b':breakelif choice == '2':  # 招聘讲师passelif choice == '3':  # 创建班级passelif choice == '4':  # 返回Flag = Falseelse:print('\033[31;1m输入错误,请重新输入.\033[0m')def start():'''开始程序,根据选择的序号进入不同的视图'''while True:choice = options(main_list)if not choice: continueif choice == '1':print('\033[33;1m【学校中心】\033[0m')school_center()elif choice == '2':print('\033[33;1m【讲师中心】\033[0m')elif choice == '3':print('\033[33;1m【学生中心】\033[0m')elif choice == '4':print('退出')breakdef file_oper(file, mode, *args):'''根据文件的读或者写,做不同的操作,读返回文件内容信息'''if mode == 'wb':data = args[0]with open(file, mode) as f:pickle.dump(data, f)elif mode == 'rb':with open(file, mode) as f:data = pickle.load(f)return datadef init_database():'''初始化学校信息'''sh = School('上海', '上海市')bj = School('北京', '北京市')if not os.path.exists(__db_main):data = {sh: {}, bj: {}}file_oper(__db_main, 'wb', data)if not os.path.exists(__db_teacher):data = {}file_oper(__db_teacher, 'wb', data)if __name__ == '__main__':init_database()main_list = ['学校中心', '讲师中心', '学生中心', '退出']school_list = ['创建课程', '招聘讲师', '创建班级', '返回']start()

1. 首先创建课程类和查看课程的方法;
2. 通过information函数执行查看课程的方法并返回{'课程名': 课程类},当没有课程的时候,一定要返回字典类型,因为后面需要做课程名是否存在的判断;
3. 在school类中添加新增课程的方法,因为通过要求得知,课程是通过学校创建的
4. 首先展示已经存在的课程信息,并得到{'课程名': 课程类},再次通过用户输入得到课程信息,通过用户输入信息实例化课程类,最后将实例化对象写入学校类的方法中

到此,新增课程已经完成。接下来是招聘讲师,其实思路和上面大同小异。

首先,通过上面分析过作者的数据类型:

main_db = {school:{course:{'讲师名': 讲师类, '班级名': 班级类}}}

当用户输入讲师名的时候,需要判断该讲师是否已经存在,因此我们需要得到 {'讲师名': 讲师类}

s1 = set()    # 这里需要定义一个set类型,因为无论数据存不存在,后续都需要进行判断
for key in main_db[school][course]:main_db[school][course][key].cat_teacher()    # 这样就能执行查看讲师的方法
    s1.add(key)return s1

通过上面的伪代码,我们执行了查看讲师的方法,并返回了已经存在讲师的名字。

1. 创建讲师类和查看讲师的方法;
2. 通过information函数执行查看讲师的方法并返回,当没有讲师的时候,一定要返回set()类型,因为后面需要做讲师名是否存在的判断;
3. 在school类中添加招聘讲师的方法;

import os, pickleBASE_DIR = os.path.dirname(os.path.abspath(__file__))
__db_main = os.path.join(BASE_DIR, 'main_dict')  # 学校内容文件
__db_teacher = os.path.join(BASE_DIR, 'teacher_dict')  # 讲师课程内容文件class School(object):'''学校类'''def __init__(self, name, addr):self.name = nameself.addr = addrdef cat_school(self):print('\033[32;1m学校【%s】\t地址【%s】\033[0m' % (self.name, self.addr))def create_course(self, main_db, course, main_file):main_db[self][course] = {}file_oper(main_file, 'wb', main_db)def hire_teacher(self, main_db, course, teacher, main_file):main_db[self][course] = {'teacher': teacher}file_oper(main_file, 'wb', main_db)class Course(object):def __init__(self, name, price, time):self.name = nameself.price = priceself.time = timedef cat_course(self):print('\033[32;1m课程【%s】\t价格【%s元】\t周期【%s个月】\033[0m' % (self.name, self.price, self.time))class Teacher(object):def __init__(self, name, age, school, course):self.name = nameself.age = ageself.school = schoolself.course = coursedef cat_teacher(self):print('\033[32;1m课程【%s】\t讲师【%s】\033[0m' % (self.course, self.name))def options(li):'''序号和标题循环打印,返回选择序号'''for i, k in enumerate(li):print(i + 1, k)choice = input('>>>').strip()return choicedef information(db, mode):set_info = set()dict_info = {}if db:for key in db:if mode == 'main':key.cat_school()elif mode == 'course':key.cat_course()elif mode == 'teacher':db[key].cat_teacher()set_info.add(key)if not isinstance(key, str):dict_info[key.name] = keyreturn dict_info, set_infodef school_center():Flag = Truewhile Flag:main_db = file_oper(__db_main, 'rb')res_school = information(main_db, 'main')[0]school_name = input('\033[34;1m选择学校名:\033[0m')if school_name in res_school:school = res_school[school_name]while Flag:choice = options(school_list)if choice == '1':  # 创建课程while True:print('\033[33;1m目前学校【%s】已经存在的课程信息:\033[0m' % school_name)res_course = information(main_db[school], 'course')[0]print(type(res_course))if not res_course:print('\033[31;1m目前没有任何课程信息.\033[0m')if_cont = input('\033[34;1m是否创建课程[y/b]:\033[0m').strip()if if_cont == 'y':course_name = input('\033[34;1m输入课程名:').strip()if course_name not in res_course:course_price = input('\033[34;1m输入课程价格:').strip()course_time = input('\033[34;1m输入课程周期:').strip()course = Course(course_name, course_price, course_time)school.create_course(main_db, course, __db_main)else:print('\033[31;1m该课程名已存在.\033[0m')elif if_cont == 'b':breakelse:print('\033[31;1m输入错误,请重新输入.\033[0m')elif choice == '2':  # 招聘讲师while True:print('\033[33;1m目前学校【%s】已经存在的讲师信息:\033[0m' % school_name)res_course = information(main_db[school], 'None')[0]if res_course:for i in res_course:k = res_course[i]res_teacher = information(main_db[school][k], 'teacher')[1]if not res_teacher:print('\033[31;1m课程【%s】\t讲师【None】\033[0m' % k.name)if_cont = input('\033[34;1m是否招聘讲师[y/b]:\033[0m').strip()if if_cont == 'y':teacher_name = input('\033[34;1m输入讲师名:').strip()teacher_age = input('\033[34;1m输入讲师年龄:').strip()course_name = input('\033[34;1m输入课程名:').strip()if course_name in res_course:course = res_course[course_name]if teacher_name not in res_teacher:teacher = Teacher(teacher_name, teacher_age, school_name, course_name)school.hire_teacher(main_db, course, teacher, __db_main)else:print('\033[31;1m该讲师名已存在.\033[0m')else:print('\033[31;1m该课程名不存在.\033[0m')elif if_cont == 'b':breakelse:print('\033[31;1m输入错误,请重新输入.\033[0m')elif choice == '3':  # 创建班级passelif choice == '4':  # 返回Flag = Falseelse:print('\033[31;1m输入错误,请重新输入.\033[0m')def start():'''开始程序,根据选择的序号进入不同的视图'''while True:choice = options(main_list)if not choice: continueif choice == '1':print('\033[33;1m【学校中心】\033[0m')school_center()elif choice == '2':print('\033[33;1m【讲师中心】\033[0m')elif choice == '3':print('\033[33;1m【学生中心】\033[0m')elif choice == '4':print('退出')breakdef file_oper(file, mode, *args):'''根据文件的读或者写,做不同的操作,读返回文件内容信息'''if mode == 'wb':data = args[0]with open(file, mode) as f:pickle.dump(data, f)elif mode == 'rb':with open(file, mode) as f:data = pickle.load(f)return datadef init_database():'''初始化学校信息'''sh = School('上海', '上海市')bj = School('北京', '北京市')if not os.path.exists(__db_main):data = {sh: {}, bj: {}}file_oper(__db_main, 'wb', data)if not os.path.exists(__db_teacher):data = {}file_oper(__db_teacher, 'wb', data)if __name__ == '__main__':init_database()main_list = ['学校中心', '讲师中心', '学生中心', '退出']school_list = ['创建课程', '招聘讲师', '创建班级', '返回']start()

创建班级功能,和招聘讲师实现思路完全一致。

1. 创建班级类和查看班级的方法;
2. 通过information函数执行查看班级的方法并返回,当没有班级的时候,一定要返回set()类型,因为后面需要做班级名是否存在的判断;
3. 在school类中添加班级的方法;

import os, pickleBASE_DIR = os.path.dirname(os.path.abspath(__file__))
__db_main = os.path.join(BASE_DIR, 'main_dict')  # 学校内容文件
__db_teacher = os.path.join(BASE_DIR, 'teacher_dict')  # 讲师课程内容文件class School(object):'''学校类'''def __init__(self, name, addr):self.name = nameself.addr = addrdef cat_school(self):print('\033[32;1m学校【%s】\t地址【%s】\033[0m' % (self.name, self.addr))def create_course(self, main_db, course, main_file):main_db[self][course] = {}file_oper(main_file, 'wb', main_db)def hire_teacher(self, main_db, course, teacher, main_file):main_db[self][course] = {'teacher': teacher}file_oper(main_file, 'wb', main_db)def create_grade(self, main_db, teacher_db, course, grade, teacher, main_file, teacher_file):main_db[self][course]['grade'] = gradefile_oper(main_file, 'wb', main_db)teacher_db[teacher] = {'grade': grade}file_oper(teacher_file, 'wb', teacher_db)class Course(object):def __init__(self, name, price, time):self.name = nameself.price = priceself.time = timedef cat_course(self):print('\033[32;1m课程【%s】\t价格【%s元】\t周期【%s个月】\033[0m' % (self.name, self.price, self.time))class Teacher(object):def __init__(self, name, age, school, course):self.name = nameself.age = ageself.school = schoolself.course = coursedef cat_teacher(self):print('\033[32;1m课程【%s】\t讲师【%s】\033[0m' % (self.course, self.name))class Grade(object):def __init__(self, name, course, teacher):self.name = nameself.course = courseself.teacher = teacherdef cat_grade(self):print('\033[32;1m课程【%s】\t班级【%s】\033[0m' % (self.course, self.name))def options(li):'''序号和标题循环打印,返回选择序号'''for i, k in enumerate(li):print(i + 1, k)choice = input('>>>').strip()return choicedef information(db, mode):set_info = set()dict_info = {}if db:for key in db:if mode == 'main':key.cat_school()elif mode == 'course':key.cat_course()elif mode == 'teacher' and key == 'teacher':db[key].cat_teacher()set_info.add(key)elif mode == 'grade' and key == 'grade':db[key].cat_grade()set_info.add(key)if not isinstance(key, str):dict_info[key.name] = keyreturn dict_info, set_infodef school_center():Flag = Truewhile Flag:main_db = file_oper(__db_main, 'rb')res_school = information(main_db, 'main')[0]school_name = input('\033[34;1m选择学校名:\033[0m')if school_name in res_school:school = res_school[school_name]while Flag:choice = options(school_list)if choice == '1':  # 创建课程while True:print('\033[33;1m目前学校【%s】已经存在的课程信息:\033[0m' % school_name)res_course = information(main_db[school], 'course')[0]print(type(res_course))if not res_course:print('\033[31;1m目前没有任何课程信息.\033[0m')if_cont = input('\033[34;1m是否创建课程[y/b]:\033[0m').strip()if if_cont == 'y':course_name = input('\033[34;1m输入课程名:').strip()if course_name not in res_course:course_price = input('\033[34;1m输入课程价格:').strip()course_time = input('\033[34;1m输入课程周期:').strip()course = Course(course_name, course_price, course_time)school.create_course(main_db, course, __db_main)else:print('\033[31;1m该课程名已存在.\033[0m')elif if_cont == 'b':breakelse:print('\033[31;1m输入错误,请重新输入.\033[0m')elif choice == '2':  # 招聘讲师while True:print('\033[33;1m目前学校【%s】已经存在的讲师信息:\033[0m' % school_name)res_course = information(main_db[school], 'None')[0]if res_course:for i in res_course:k = res_course[i]res_teacher = information(main_db[school][k], 'teacher')[1]print(main_db)if not res_teacher:print('\033[31;1m课程【%s】\t讲师【None】\033[0m' % k.name)if_cont = input('\033[34;1m是否招聘讲师[y/b]:\033[0m').strip()if if_cont == 'y':teacher_name = input('\033[34;1m输入讲师名:').strip()teacher_age = input('\033[34;1m输入讲师年龄:').strip()course_name = input('\033[34;1m输入课程名:').strip()if course_name in res_course:course = res_course[course_name]if teacher_name not in res_teacher:teacher = Teacher(teacher_name, teacher_age, school_name, course_name)school.hire_teacher(main_db, course, teacher, __db_main)else:print('\033[31;1m该讲师名已存在.\033[0m')else:print('\033[31;1m该课程名不存在.\033[0m')elif if_cont == 'b':breakelse:print('\033[31;1m输入错误,请重新输入.\033[0m')elif choice == '3':  # 创建班级while True:teacher_db = file_oper(__db_teacher, 'rb')print('\033[33;1m目前学校【%s】已经存在的班级信息:\033[0m' % school_name)res_course = information(main_db[school], 'None')[0]if res_course:for i in res_course:k = res_course[i]print('k:', k)print(main_db[school][k])print('--------------------------')res_grade = information(main_db[school][k], 'grade')[1]if not res_grade:print('\033[31;1m目前没有任何班级信息.\033[0m')else:print('\033[31;1m目前没有任何课程信息, 请先创建课程.\033[0m')if_cont = input('\033[34;1m是否创建班级[y/b]:\033[0m').strip()if if_cont == 'y':grade_name = input('\033[34;1m输入班级名:\033[0m').strip()course_name = input('\033[34;1m输入班级要上的课程:\033[0m').strip()if course_name in res_course:course = res_course[course_name]if main_db[school][course]:teacher = main_db[school][course]['teacher']if grade_name not in res_grade:grade = Grade(grade_name, course_name, teacher.name)print('grade:', grade)school.create_grade(main_db, teacher_db, course, grade, teacher,__db_main, __db_teacher)else:print('\033[31;1m讲师不存在,请先招聘讲师.\033[0m')else:print('\033[31;1m课程名不存在,请重新输入.\033[0m')elif if_cont == 'b':breakelse:print('\033[31;1m输入错误,请重新输入.\033[0m')elif choice == '4':  # 返回Flag = Falseelse:print('\033[31;1m输入错误,请重新输入.\033[0m')def start():'''开始程序,根据选择的序号进入不同的视图'''while True:choice = options(main_list)if not choice: continueif choice == '1':print('\033[33;1m【学校中心】\033[0m')school_center()elif choice == '2':print('\033[33;1m【讲师中心】\033[0m')elif choice == '3':print('\033[33;1m【学生中心】\033[0m')elif choice == '4':print('退出')breakdef file_oper(file, mode, *args):'''根据文件的读或者写,做不同的操作,读返回文件内容信息'''if mode == 'wb':data = args[0]with open(file, mode) as f:pickle.dump(data, f)elif mode == 'rb':with open(file, mode) as f:data = pickle.load(f)return datadef init_database():'''初始化学校信息'''sh = School('上海', '上海市')bj = School('北京', '北京市')if not os.path.exists(__db_main):data = {sh: {}, bj: {}}file_oper(__db_main, 'wb', data)if not os.path.exists(__db_teacher):data = {}file_oper(__db_teacher, 'wb', data)if __name__ == '__main__':init_database()main_list = ['学校中心', '讲师中心', '学生中心', '退出']school_list = ['创建课程', '招聘讲师', '创建班级', '返回']start()

招聘讲师和创建班级思路是一样的,只是多了下面的步骤:

1. 班级类包含:班级、课程、讲师 信息

2. 这里就引入了第二个存储文件 __db_teacher 一定要知道数据类型的存储格式:
{讲师类:{'班级名':班级类}}

3. 必须取得讲师类才能进行第2步的操作

获取讲师信息

res_course = information(main_db[school], 'None')[0]
if res_course:for i in res_course:k = res_course[i]    # 这里就拿到了课程类res_grade = information(main_db[school][k], 'grade')[1]    # 这里就可以拿到已经存在或者为空的班级信息

当该班级的课程名被接收后

course_name = input('\033[34;1m输入班级要上的课程:\033[0m').strip()if course_name in res_course:course = res_course[course_name]if main_db[school][course]:teacher = main_db[school][course]['teacher']

上面的代码就能拿到讲师类,数据结构定义下来,代码就很好写了。

到目前为止,根据要求,学校中心的所有功能都已经实现了。

学校中心功能所有代码:

import os, pickleBASE_DIR = os.path.dirname(os.path.abspath(__file__))
__db_main = os.path.join(BASE_DIR, 'main_dict')  # 学校内容文件
__db_teacher = os.path.join(BASE_DIR, 'teacher_dict')  # 讲师课程内容文件class School(object):'''学校类'''def __init__(self, name, addr):self.name = nameself.addr = addrdef cat_school(self):print('\033[32;1m学校【%s】\t地址【%s】\033[0m' % (self.name, self.addr))def create_course(self, main_db, course, main_file):main_db[self][course] = {}file_oper(main_file, 'wb', main_db)def hire_teacher(self, main_db, course, teacher, main_file):main_db[self][course] = {'teacher': teacher}file_oper(main_file, 'wb', main_db)def create_grade(self, main_db, teacher_db, course, grade, teacher, main_file, teacher_file):main_db[self][course]['grade'] = gradefile_oper(main_file, 'wb', main_db)teacher_db[teacher] = {'grade': grade}file_oper(teacher_file, 'wb', teacher_db)class Course(object):def __init__(self, name, price, time):self.name = nameself.price = priceself.time = timedef cat_course(self):print('\033[32;1m课程【%s】\t价格【%s元】\t周期【%s个月】\033[0m' % (self.name, self.price, self.time))class Teacher(object):def __init__(self, name, age, school, course):self.name = nameself.age = ageself.school = schoolself.course = coursedef cat_teacher(self):print('\033[32;1m课程【%s】\t讲师【%s】\033[0m' % (self.course, self.name))class Grade(object):def __init__(self, name, course, teacher):self.name = nameself.course = courseself.teacher = teacherdef cat_grade(self):print('\033[32;1m课程【%s】\t班级【%s】\033[0m' % (self.course, self.name))def options(li):'''序号和标题循环打印,返回选择序号'''for i, k in enumerate(li):print(i + 1, k)choice = input('>>>').strip()return choicedef information(db, mode):set_info = set()dict_info = {}if db:for key in db:if mode == 'main':key.cat_school()elif mode == 'course':key.cat_course()elif mode == 'teacher' and key == 'teacher':db[key].cat_teacher()set_info.add(key)elif mode == 'grade' and key == 'grade':db[key].cat_grade()set_info.add(key)if not isinstance(key, str):dict_info[key.name] = keyreturn dict_info, set_infodef school_center():Flag = Truewhile Flag:main_db = file_oper(__db_main, 'rb')res_school = information(main_db, 'main')[0]school_name = input('\033[34;1m选择学校名:\033[0m')if school_name in res_school:school = res_school[school_name]while Flag:choice = options(school_list)if choice == '1':  # 创建课程while True:print('\033[33;1m目前学校【%s】已经存在的课程信息:\033[0m' % school_name)res_course = information(main_db[school], 'course')[0]print(type(res_course))if not res_course:print('\033[31;1m目前没有任何课程信息.\033[0m')if_cont = input('\033[34;1m是否创建课程[y/b]:\033[0m').strip()if if_cont == 'y':course_name = input('\033[34;1m输入课程名:').strip()if course_name not in res_course:course_price = input('\033[34;1m输入课程价格:').strip()course_time = input('\033[34;1m输入课程周期:').strip()course = Course(course_name, course_price, course_time)school.create_course(main_db, course, __db_main)else:print('\033[31;1m该课程名已存在.\033[0m')elif if_cont == 'b':breakelse:print('\033[31;1m输入错误,请重新输入.\033[0m')elif choice == '2':  # 招聘讲师while True:print('\033[33;1m目前学校【%s】已经存在的讲师信息:\033[0m' % school_name)res_course = information(main_db[school], 'None')[0]if res_course:for i in res_course:k = res_course[i]res_teacher = information(main_db[school][k], 'teacher')[1]print(main_db)if not res_teacher:print('\033[31;1m课程【%s】\t讲师【None】\033[0m' % k.name)if_cont = input('\033[34;1m是否招聘讲师[y/b]:\033[0m').strip()if if_cont == 'y':teacher_name = input('\033[34;1m输入讲师名:').strip()teacher_age = input('\033[34;1m输入讲师年龄:').strip()course_name = input('\033[34;1m输入课程名:').strip()if course_name in res_course:course = res_course[course_name]if teacher_name not in res_teacher:teacher = Teacher(teacher_name, teacher_age, school_name, course_name)school.hire_teacher(main_db, course, teacher, __db_main)else:print('\033[31;1m该讲师名已存在.\033[0m')else:print('\033[31;1m该课程名不存在.\033[0m')elif if_cont == 'b':breakelse:print('\033[31;1m输入错误,请重新输入.\033[0m')elif choice == '3':  # 创建班级while True:teacher_db = file_oper(__db_teacher, 'rb')print('\033[33;1m目前学校【%s】已经存在的班级信息:\033[0m' % school_name)res_course = information(main_db[school], 'None')[0]if res_course:for i in res_course:k = res_course[i]print('k:', k)print(main_db[school][k])print('--------------------------')res_grade = information(main_db[school][k], 'grade')[1]if not res_grade:print('\033[31;1m目前没有任何班级信息.\033[0m')else:print('\033[31;1m目前没有任何课程信息, 请先创建课程.\033[0m')if_cont = input('\033[34;1m是否创建班级[y/b]:\033[0m').strip()if if_cont == 'y':grade_name = input('\033[34;1m输入班级名:\033[0m').strip()course_name = input('\033[34;1m输入班级要上的课程:\033[0m').strip()if course_name in res_course:course = res_course[course_name]if main_db[school][course]:teacher = main_db[school][course]['teacher']if grade_name not in res_grade:grade = Grade(grade_name, course_name, teacher.name)print('grade:', grade)school.create_grade(main_db, teacher_db, course, grade, teacher,__db_main, __db_teacher)else:print('\033[31;1m讲师不存在,请先招聘讲师.\033[0m')else:print('\033[31;1m课程名不存在,请重新输入.\033[0m')elif if_cont == 'b':breakelse:print('\033[31;1m输入错误,请重新输入.\033[0m')elif choice == '4':  # 返回Flag = Falseelse:print('\033[31;1m输入错误,请重新输入.\033[0m')def start():'''开始程序,根据选择的序号进入不同的视图'''while True:choice = options(main_list)if not choice: continueif choice == '1':print('\033[33;1m【学校中心】\033[0m')school_center()elif choice == '2':print('\033[33;1m【讲师中心】\033[0m')elif choice == '3':print('\033[33;1m【学生中心】\033[0m')elif choice == '4':print('退出')breakdef file_oper(file, mode, *args):'''根据文件的读或者写,做不同的操作,读返回文件内容信息'''if mode == 'wb':data = args[0]with open(file, mode) as f:pickle.dump(data, f)elif mode == 'rb':with open(file, mode) as f:data = pickle.load(f)return datadef init_database():'''初始化学校信息'''sh = School('上海', '上海市')bj = School('北京', '北京市')if not os.path.exists(__db_main):data = {sh: {}, bj: {}}file_oper(__db_main, 'wb', data)if not os.path.exists(__db_teacher):data = {}file_oper(__db_teacher, 'wb', data)if __name__ == '__main__':init_database()main_list = ['学校中心', '讲师中心', '学生中心', '退出']school_list = ['创建课程', '招聘讲师', '创建班级', '返回']start()

学生中心

功能点:学员注册,返回

学员注册这里,是使用了一个Grade类中的student属性来保存的。

self.student = set([])    # 该属性是一个set集合

在Grade类中实现一个新增学员的方法:

def add_student(self, teacher_db, teacher, student_name, teacher_file):self.student.add(student_name)    # 将学员名添加到 self.student属性中teacher_db[teacher] = {'grade': self}    # 重新给讲师赋值,所以这里必须要拿到讲师类file_oper(teacher_file, 'wb', teacher_db)    # 写入文件

以上的操作,就能添加一个新的学员到班级。

新增学员的操作流程:

输入用户名 --> 选择已有学校 --> 选择已有课程 --> 写入文件

import os, pickleBASE_DIR = os.path.dirname(os.path.abspath(__file__))
__db_main = os.path.join(BASE_DIR, 'main_dict')  # 学校内容文件
__db_teacher = os.path.join(BASE_DIR, 'teacher_dict')  # 讲师课程内容文件class School(object):'''学校类'''def __init__(self, name, addr):self.name = nameself.addr = addrdef cat_school(self):print('\033[32;1m学校【%s】\t地址【%s】\033[0m' % (self.name, self.addr))def create_course(self, main_db, course, main_file):main_db[self][course] = {}file_oper(main_file, 'wb', main_db)def hire_teacher(self, main_db, course, teacher, main_file):main_db[self][course] = {'teacher': teacher}file_oper(main_file, 'wb', main_db)def create_grade(self, main_db, teacher_db, course, grade, teacher, main_file, teacher_file):main_db[self][course]['grade'] = gradefile_oper(main_file, 'wb', main_db)teacher_db[teacher] = {'grade': grade}file_oper(teacher_file, 'wb', teacher_db)class Course(object):def __init__(self, name, price, time):self.name = nameself.price = priceself.time = timedef cat_course(self):print('\033[32;1m课程【%s】\t价格【%s元】\t周期【%s个月】\033[0m' % (self.name, self.price, self.time))class Teacher(object):def __init__(self, name, age, school, course):self.name = nameself.age = ageself.school = schoolself.course = coursedef cat_teacher(self):print('\033[32;1m课程【%s】\t讲师【%s】\033[0m' % (self.course, self.name))class Grade(object):def __init__(self, name, course, teacher):self.name = nameself.course = courseself.teacher = teacherself.student = set([])def cat_grade(self):print('\033[32;1m课程【%s】\t班级【%s】\033[0m' % (self.course, self.name))def add_student(self, teacher_db, teacher, student_name, teacher_file):self.student.add(student_name)teacher_db[teacher] = {'grade': self}file_oper(teacher_file, 'wb', teacher_db)def options(li):'''序号和标题循环打印,返回选择序号'''for i, k in enumerate(li):print(i + 1, k)choice = input('>>>').strip()return choicedef information(db, mode):set_info = set()dict_info = {}if db:for key in db:if mode == 'main':key.cat_school()elif mode == 'course':key.cat_course()elif mode == 'teacher' and key == 'teacher':db[key].cat_teacher()set_info.add(key)elif mode == 'grade' and key == 'grade':db[key].cat_grade()set_info.add(key)if not isinstance(key, str):dict_info[key.name] = keyreturn dict_info, set_infodef school_center():Flag = Truewhile Flag:main_db = file_oper(__db_main, 'rb')res_school = information(main_db, 'main')[0]school_name = input('\033[34;1m选择学校名:\033[0m')if school_name in res_school:school = res_school[school_name]while Flag:choice = options(school_list)if choice == '1':  # 创建课程while True:print('\033[33;1m目前学校【%s】已经存在的课程信息:\033[0m' % school_name)res_course = information(main_db[school], 'course')[0]print(type(res_course))if not res_course:print('\033[31;1m目前没有任何课程信息.\033[0m')if_cont = input('\033[34;1m是否创建课程[y/b]:\033[0m').strip()if if_cont == 'y':course_name = input('\033[34;1m输入课程名:').strip()if course_name not in res_course:course_price = input('\033[34;1m输入课程价格:').strip()course_time = input('\033[34;1m输入课程周期:').strip()course = Course(course_name, course_price, course_time)school.create_course(main_db, course, __db_main)else:print('\033[31;1m该课程名已存在.\033[0m')elif if_cont == 'b':breakelse:print('\033[31;1m输入错误,请重新输入.\033[0m')elif choice == '2':  # 招聘讲师while True:print('\033[33;1m目前学校【%s】已经存在的讲师信息:\033[0m' % school_name)res_course = information(main_db[school], 'None')[0]if res_course:for i in res_course:k = res_course[i]res_teacher = information(main_db[school][k], 'teacher')[1]print(main_db)if not res_teacher:print('\033[31;1m课程【%s】\t讲师【None】\033[0m' % k.name)if_cont = input('\033[34;1m是否招聘讲师[y/b]:\033[0m').strip()if if_cont == 'y':teacher_name = input('\033[34;1m输入讲师名:').strip()teacher_age = input('\033[34;1m输入讲师年龄:').strip()course_name = input('\033[34;1m输入课程名:').strip()if course_name in res_course:course = res_course[course_name]if teacher_name not in res_teacher:teacher = Teacher(teacher_name, teacher_age, school_name, course_name)school.hire_teacher(main_db, course, teacher, __db_main)else:print('\033[31;1m该讲师名已存在.\033[0m')else:print('\033[31;1m该课程名不存在.\033[0m')elif if_cont == 'b':breakelse:print('\033[31;1m输入错误,请重新输入.\033[0m')elif choice == '3':  # 创建班级while True:teacher_db = file_oper(__db_teacher, 'rb')print('\033[33;1m目前学校【%s】已经存在的班级信息:\033[0m' % school_name)res_course = information(main_db[school], 'None')[0]if res_course:for i in res_course:k = res_course[i]print('k:', k)print(main_db[school][k])print('--------------------------')res_grade = information(main_db[school][k], 'grade')[1]if not res_grade:print('\033[31;1m目前没有任何班级信息.\033[0m')else:print('\033[31;1m目前没有任何课程信息, 请先创建课程.\033[0m')if_cont = input('\033[34;1m是否创建班级[y/b]:\033[0m').strip()if if_cont == 'y':grade_name = input('\033[34;1m输入班级名:\033[0m').strip()course_name = input('\033[34;1m输入班级要上的课程:\033[0m').strip()if course_name in res_course:course = res_course[course_name]if main_db[school][course]:teacher = main_db[school][course]['teacher']if grade_name not in res_grade:grade = Grade(grade_name, course_name, teacher.name)print('grade:', grade)school.create_grade(main_db, teacher_db, course, grade, teacher,__db_main, __db_teacher)else:print('\033[31;1m讲师不存在,请先招聘讲师.\033[0m')else:print('\033[31;1m课程名不存在,请重新输入.\033[0m')elif if_cont == 'b':breakelse:print('\033[31;1m输入错误,请重新输入.\033[0m')elif choice == '4':  # 返回Flag = Falseelse:print('\033[31;1m输入错误,请重新输入.\033[0m')def student_center():while True:choice = options(student_list)main_db = file_oper(__db_main, 'rb')teacher_db = file_oper(__db_teacher, 'rb')if choice == '1':student_name = input('\033[34;1m输入学生名:\033[0m').strip()res_school = information(main_db, 'main')[0]school_name = input('\033[34;1m输入学校名:\033[0m').strip()if school_name in res_school:school = res_school[school_name]res_course = information(main_db[school], 'course')[0]course_name = input('\033[34;1m输入课程名:\033[0m').strip()if course_name in res_course:course = res_course[course_name]if main_db[school][course].get('grade'):for i in teacher_db:i.name = course.nameteacher = igrade = teacher_db[teacher].get('grade')print('\033[33;1m课程【%s】的费用为【%s元】\033[0m' % (course_name, course.price))if_pay = input('\033[34;1m是否支付当前费用(y支付):\033[0m').strip()if if_pay == 'y':grade.student.add(student_name)grade.add_student(teacher_db, teacher, student_name, __db_teacher)print('\033[32;1m选课成功!\033[0m')any = input('输入任意键退出当前:')else:print('\033[31;1m讲师不存在,请先招聘讲师.\033[0m')else:print('\033[31;1m课程不存在,请重新选择.\033[0m')else:print('\033[31;1m学校不存在,请重新选择.\033[0m')elif choice == '2':breakelse:print('\033[31;1m输入错误,请重新输入.\033[0m')def start():'''开始程序,根据选择的序号进入不同的视图'''while True:choice = options(main_list)if not choice: continueif choice == '1':print('\033[33;1m【学校中心】\033[0m')school_center()elif choice == '2':print('\033[33;1m【讲师中心】\033[0m')elif choice == '3':print('\033[33;1m【学生中心】\033[0m')student_center()elif choice == '4':print('退出')breakdef file_oper(file, mode, *args):'''根据文件的读或者写,做不同的操作,读返回文件内容信息'''if mode == 'wb':data = args[0]with open(file, mode) as f:pickle.dump(data, f)elif mode == 'rb':with open(file, mode) as f:data = pickle.load(f)return datadef init_database():'''初始化学校信息'''sh = School('上海', '上海市')bj = School('北京', '北京市')if not os.path.exists(__db_main):data = {sh: {}, bj: {}}file_oper(__db_main, 'wb', data)if not os.path.exists(__db_teacher):data = {}file_oper(__db_teacher, 'wb', data)if __name__ == '__main__':init_database()main_list = ['学校中心', '讲师中心', '学生中心', '退出']school_list = ['创建课程', '招聘讲师', '创建班级', '返回']student_list = ['学员注册', '返回']start()

上面代码的难点在通过讲师把两个字典联系起来取值:

main_db = {学校类:{课程类:{'讲师名': 讲师类, '班级名': 班级类}}}
teacher_db = {讲师类:{'班级名': 班级类}}if main_db[school][course].get('grade'):    # 使用get判断班级是否存在,不存在返回None不会报错for i in teacher_db:    # 这里循环取讲师类i.course = course.name    # 当teacher_db中讲师类课程的名字和main_db中课程的名字一致时,讲师和课程就关联起来了teacher = i        # 直接获取讲师类

上面这里是整篇代码最难理解地方,需要从全面代码数据结构去理解。
简单来说,通过学员选择的课程确定课程类,在从课程类确定讲师类,就是这样的关联关系。

目前,学校中心和学员中心都已经实现了,学校中心和学员中心都有查询和写入的操作,所以提前完成,接下就是讲师中心,只有查询的功能

讲师中心

功能点:查看班级信息,查看学员列表信息

实现思路:

每个讲师都有自己的班级信息和学员列表,因此在实现功能点之前需要进行确认讲师身份
查看班级信息中需要:学校和班级
学员列表是保存在Grade类student属性中

import os, pickleBASE_DIR = os.path.dirname(os.path.abspath(__file__))
__db_main = os.path.join(BASE_DIR, 'main_dict')  # 学校内容文件
__db_teacher = os.path.join(BASE_DIR, 'teacher_dict')  # 讲师课程内容文件class School(object):'''学校类'''def __init__(self, name, addr):self.name = nameself.addr = addrdef cat_school(self):print('\033[32;1m学校【%s】\t地址【%s】\033[0m' % (self.name, self.addr))def create_course(self, main_db, course, main_file):main_db[self][course] = {}file_oper(main_file, 'wb', main_db)def hire_teacher(self, main_db, course, teacher, main_file):main_db[self][course] = {'teacher': teacher}file_oper(main_file, 'wb', main_db)def create_grade(self, main_db, teacher_db, course, grade, teacher, main_file, teacher_file):main_db[self][course]['grade'] = gradefile_oper(main_file, 'wb', main_db)teacher_db[teacher] = {'grade': grade}file_oper(teacher_file, 'wb', teacher_db)class Course(object):def __init__(self, name, price, time):self.name = nameself.price = priceself.time = timedef cat_course(self):print('\033[32;1m课程【%s】\t价格【%s元】\t周期【%s个月】\033[0m' % (self.name, self.price, self.time))class Teacher(object):def __init__(self, name, age, school, course):self.name = nameself.age = ageself.school = schoolself.course = coursedef cat_teacher(self):print('\033[32;1m课程【%s】\t讲师【%s】\033[0m' % (self.course, self.name))class Grade(object):def __init__(self, name, course, teacher):self.name = nameself.course = courseself.teacher = teacherself.student = set([])def cat_grade(self):print('\033[32;1m课程【%s】\t班级【%s】\033[0m' % (self.course, self.name))def add_student(self, teacher_db, teacher, student_name, teacher_file):self.student.add(student_name)teacher_db[teacher] = {'grade': self}file_oper(teacher_file, 'wb', teacher_db)def options(li):'''序号和标题循环打印,返回选择序号'''for i, k in enumerate(li):print(i + 1, k)choice = input('>>>').strip()return choicedef information(db, mode):set_info = set()dict_info = {}if db:for key in db:if mode == 'main':key.cat_school()elif mode == 'course':key.cat_course()elif mode == 'teacher' and key == 'teacher':db[key].cat_teacher()set_info.add(key)elif mode == 'grade' and key == 'grade':db[key].cat_grade()set_info.add(key)if not isinstance(key, str):dict_info[key.name] = keyreturn dict_info, set_infodef school_center():Flag = Truewhile Flag:main_db = file_oper(__db_main, 'rb')res_school = information(main_db, 'main')[0]school_name = input('\033[34;1m选择学校名:\033[0m')if school_name in res_school:school = res_school[school_name]while Flag:choice = options(school_list)if choice == '1':  # 创建课程while True:print('\033[33;1m目前学校【%s】已经存在的课程信息:\033[0m' % school_name)res_course = information(main_db[school], 'course')[0]print(type(res_course))if not res_course:print('\033[31;1m目前没有任何课程信息.\033[0m')if_cont = input('\033[34;1m是否创建课程[y/b]:\033[0m').strip()if if_cont == 'y':course_name = input('\033[34;1m输入课程名:').strip()if course_name not in res_course:course_price = input('\033[34;1m输入课程价格:').strip()course_time = input('\033[34;1m输入课程周期:').strip()course = Course(course_name, course_price, course_time)school.create_course(main_db, course, __db_main)else:print('\033[31;1m该课程名已存在.\033[0m')elif if_cont == 'b':breakelse:print('\033[31;1m输入错误,请重新输入.\033[0m')elif choice == '2':  # 招聘讲师while True:print('\033[33;1m目前学校【%s】已经存在的讲师信息:\033[0m' % school_name)res_course = information(main_db[school], 'None')[0]if res_course:for i in res_course:k = res_course[i]res_teacher = information(main_db[school][k], 'teacher')[1]print(main_db)if not res_teacher:print('\033[31;1m课程【%s】\t讲师【None】\033[0m' % k.name)if_cont = input('\033[34;1m是否招聘讲师[y/b]:\033[0m').strip()if if_cont == 'y':teacher_name = input('\033[34;1m输入讲师名:').strip()teacher_age = input('\033[34;1m输入讲师年龄:').strip()course_name = input('\033[34;1m输入课程名:').strip()if course_name in res_course:course = res_course[course_name]if teacher_name not in res_teacher:teacher = Teacher(teacher_name, teacher_age, school_name, course_name)school.hire_teacher(main_db, course, teacher, __db_main)else:print('\033[31;1m该讲师名已存在.\033[0m')else:print('\033[31;1m该课程名不存在.\033[0m')elif if_cont == 'b':breakelse:print('\033[31;1m输入错误,请重新输入.\033[0m')elif choice == '3':  # 创建班级while True:teacher_db = file_oper(__db_teacher, 'rb')print('\033[33;1m目前学校【%s】已经存在的班级信息:\033[0m' % school_name)res_course = information(main_db[school], 'None')[0]if res_course:for i in res_course:k = res_course[i]print('k:', k)print(main_db[school][k])print('--------------------------')res_grade = information(main_db[school][k], 'grade')[1]if not res_grade:print('\033[31;1m目前没有任何班级信息.\033[0m')else:print('\033[31;1m目前没有任何课程信息, 请先创建课程.\033[0m')if_cont = input('\033[34;1m是否创建班级[y/b]:\033[0m').strip()if if_cont == 'y':grade_name = input('\033[34;1m输入班级名:\033[0m').strip()course_name = input('\033[34;1m输入班级要上的课程:\033[0m').strip()if course_name in res_course:course = res_course[course_name]if main_db[school][course]:teacher = main_db[school][course]['teacher']if grade_name not in res_grade:grade = Grade(grade_name, course_name, teacher.name)print('grade:', grade)school.create_grade(main_db, teacher_db, course, grade, teacher,__db_main, __db_teacher)else:print('\033[31;1m讲师不存在,请先招聘讲师.\033[0m')else:print('\033[31;1m课程名不存在,请重新输入.\033[0m')elif if_cont == 'b':breakelse:print('\033[31;1m输入错误,请重新输入.\033[0m')elif choice == '4':  # 返回Flag = Falseelse:print('\033[31;1m输入错误,请重新输入.\033[0m')def student_center():while True:choice = options(student_list)main_db = file_oper(__db_main, 'rb')teacher_db = file_oper(__db_teacher, 'rb')if choice == '1':student_name = input('\033[34;1m输入学生名:\033[0m').strip()res_school = information(main_db, 'main')[0]school_name = input('\033[34;1m输入学校名:\033[0m').strip()if school_name in res_school:school = res_school[school_name]res_course = information(main_db[school], 'course')[0]course_name = input('\033[34;1m输入课程名:\033[0m').strip()if course_name in res_course:course = res_course[course_name]if main_db[school][course].get('grade'):for i in teacher_db:i.course = course.nameteacher = igrade = teacher_db[teacher].get('grade')print('\033[33;1m课程【%s】的费用为【%s元】\033[0m' % (course_name, course.price))if_pay = input('\033[34;1m是否支付当前费用(y支付):\033[0m').strip()if if_pay == 'y':grade.student.add(student_name)grade.add_student(teacher_db, teacher, student_name, __db_teacher)print('\033[32;1m选课成功!\033[0m')any = input('输入任意键退出当前:')else:print('\033[31;1m讲师不存在,请先招聘讲师.\033[0m')else:print('\033[31;1m课程不存在,请重新选择.\033[0m')else:print('\033[31;1m学校不存在,请重新选择.\033[0m')elif choice == '2':breakelse:print('\033[31;1m输入错误,请重新输入.\033[0m')def teacher_center():teacher_db = file_oper(__db_teacher, 'rb')teacher_name = input('\033[34;1m输入讲师名:\033[0m').strip()res_teacher = information(teacher_db, 'None')[0]if res_teacher:if teacher_name in res_teacher:teacher = res_teacher[teacher_name]grade = teacher_db[teacher].get('grade')print('\033[33;1m欢迎进入讲师【%s】的管理中心\033[0m' % teacher_name)while True:choice = options(teacher_list)if choice == '1':print('\033[32;1m学校【%s】\t班级【%s】\033[0m' % (teacher.school, grade.name))any = input('输入任意键退出当前:')elif choice == '2':print('\033[32;1m班级【%s】\t学员【%s】\033[0m' % (grade.name, grade.student))any = input('输入任意键退出当前:')elif choice == '3':breakelse:print('\033[31;1m输入错误,请重新输入.\033[0m')else:print('\033[31;1m讲师信息不存在,请重新输入.\033[0m')def start():'''开始程序,根据选择的序号进入不同的视图'''while True:choice = options(main_list)if not choice: continueif choice == '1':print('\033[33;1m【学校中心】\033[0m')school_center()elif choice == '2':print('\033[33;1m【讲师中心】\033[0m')teacher_center()elif choice == '3':print('\033[33;1m【学生中心】\033[0m')student_center()elif choice == '4':print('退出')breakdef file_oper(file, mode, *args):'''根据文件的读或者写,做不同的操作,读返回文件内容信息'''if mode == 'wb':data = args[0]with open(file, mode) as f:pickle.dump(data, f)elif mode == 'rb':with open(file, mode) as f:data = pickle.load(f)return datadef init_database():'''初始化学校信息'''sh = School('上海', '上海市')bj = School('北京', '北京市')if not os.path.exists(__db_main):data = {sh: {}, bj: {}}file_oper(__db_main, 'wb', data)if not os.path.exists(__db_teacher):data = {}file_oper(__db_teacher, 'wb', data)if __name__ == '__main__':init_database()main_list = ['学校中心', '讲师中心', '学生中心', '退出']school_list = ['创建课程', '招聘讲师', '创建班级', '返回']student_list = ['学员注册', '返回']teacher_list = ['查看班级信息', '查看学员列表信息', '返回']start()

完整代码

以上代码实现了讲师中心的两个查询功能,流程:

1. 认证讲师名信息
2. 通过讲师名获取讲师类,通过讲师类得到班级类

到此,程序代码完成,需要注意的是,在学员注册的时候,为 Grade类新增了student属性,需要删除本地 main_dict, teacher_dict 再次执行,否则报错。

总结:
    成长就是一个不断模仿和学习的过程,对于刚学习python,拿到需求,首先要经过自己分析,确实搞不定了,可以查看一些优秀的代码过来学习总结,
    从而转化为自己的能力。对于写程序,实现逻辑思路是很重要的。

转载于:https://www.cnblogs.com/hukey/p/9871330.html

[ python ] 作业:选课系统相关推荐

  1. python3自学之路作业 选课系统

    本节作业:选课系统 角色:学校.学员.课程.讲师 要求: 1. 创建北京.上海 2 所学校 2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上海开 ...

  2. python网上选课系统django-PyCharm

    学生选课信息管理系统,可以有效的对学生选课信息.学生个人信息.教师个人信息等等进行管理. 开发语言:Python 框架:django Python版本:python3.7.7 数据库:mysql   ...

  3. java/php/net/python作业批改系统的设计

    本系统带文档lw万字以上+答辩PPT+查重 如果这个题目不合适,可以去我上传的资源里面找题目,找不到的话,评论留下题目,或者站内私信我, 有时间看到机会给您发 系统体系结构 作业批改系统开发系统的结构 ...

  4. python最简单选课系统作业_python之路——作业:学生选课系统

    一.作业要求: 选课系统: 角色:学校.学员.课程.讲师 要求: 1. 创建北京.上海 2 所学校 2. 创建linux , python , go 3个课程 , linux\py 在北京开, go ...

  5. python选课管理系统_Python开发程序:选课系统

    程序名称: 选课系统 角色:学校.学员.课程.讲师 要求: 1. 创建北京.上海 2 所学校 2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上海 ...

  6. 基于Python的学生在线选课系统的设计和实现

    <基于Python的学生在线选课系统的设计和实现>该项目采用技术Python的django框架.mysql数据库 ,项目含有源码.论文.PPT.配套开发软件.软件安装教程.项目发布教程.核 ...

  7. 【原创】面向对象作业:选课系统中用pickle储存多个对象间组合引用关系的那些坑...

    转载请注明出处:https://www.cnblogs.com/oceanicstar/p/9030121.html 想直接看结论先提前列出: 1.存储一个对象,文件不是真的给你存储的了对象这种东西, ...

  8. [附源码]计算机毕业设计Python+uniapp作业批改系统APP4238p(程序+lw+APP+远程部署)

    [附源码]计算机毕业设计Python+uniapp作业批改系统APP4238p(程序+lw+APP+远程部署) 该项目含有源码.文档.程序.数据库.配套开发软件.软件安装教程 项目运行环境配置: Py ...

  9. python毕业设计作品基于django框架校园排课选课系统毕设成品(3)后台管理功能

    整个项目包含了:开题报告 + 开题报告PPT + 任务书 + 中期报告 + 论文模板 + 答辩PPT等 + 项目源码 主要安介绍了系统在开发过程中所应用到的一些关键的技术 主要python技术介绍:框 ...

最新文章

  1. HTML5时代的Web缓存机制
  2. numpy库中ndarray切片操作的参数意义
  3. python3随笔-特征值,特征向量,逆矩阵
  4. Hibernate 4.2.8,javassist 3.18.1和ClassCastExceptions –注意您的类路径
  5. 搜狗高速浏览器打开网页没有声音怎么办
  6. python fun函数、求4x4整型数组的主对角线元素的和_python中多维数组中列major的numpy整形...
  7. 【jQuery学习】—jQuery操作元素位置
  8. 优秀ASP.NET程序员的修炼之路(转)
  9. 假如我是一个项目总监/经理 From CSDN
  10. 你不能忽视的HTML语言
  11. mysql的学生信息建表语句_SQL语句创建学生信息数据库表的示例
  12. html调用xfplugin,傻瓜式网页里嵌入先锋web万能播放控件
  13. 楼下邻居是事逼怎么办
  14. UE4材质(四):自发光颜色Emissive——灯
  15. java平方根函数_java程序中怎么调用平方根函数
  16. 什么是交换机?跟服务器之间有什么联系吗?
  17. word如何将选择题按首字母拼音排序
  18. python3识别简单验证码
  19. BIOS设置通电开机?请问高手怎么设置?
  20. 有什么文字转语音软件?这几个软件你不能不知道

热门文章

  1. 【无人机】【2015.03】用于自然地形测绘的无人机多角度立体视觉
  2. O2O的盈利模式是怎么样的 零售O2O如何做?
  3. Asterisk 服务器 Linux平台安装教程
  4. 任何一台计算机都可以安装win 7系统,任何电脑都能用U盘装64位win7么?
  5. 批量修改文件名中的一部分,操作步骤
  6. 男粉适合去哪个贴吧引流?其中有什么套路?
  7. Python文件和数据格式化学习笔记
  8. 说说区块链,说说初链
  9. proxy_cache_purge 清除nginx缓存返回404
  10. 电影里的超级计算机,宇宙终极答案“42”到底是什么意思?超级计算机为我们揭晓答案...