Day7作业:选课系统
Posted ccorz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Day7作业:选课系统相关的知识,希望对你有一定的参考价值。
这周的作业有点糙,迁就看吧,给大家点思路:
readme:
需要安装模块: prettytable 测试帐号: 1.后台管理:admin/admin 只设定了这个后台管理帐号,没有写到数据库中 2.学生选课系统需要先注册才可登录操作,测试帐号cc/123,也可注册新帐号使用 设计思路: 1.使用pickle存储数据,数据类型为老师,学生,课程的对象 2.使用流程为:创建老师-->创建课程,并关联老师-->学生注册并登录-->学生选课,上课等操作 3.老师资产的变化是由学生选择上课或者课程事故触发的,管理员没有权限操作 4.教师名是唯一的,作为数据标识ID 本课难点: 1.整体比较简单,难点在于上个数据库中的数据关联性. 2.由于同一对象存到不同数据库中后,反序列化取出的值是不一样的,简要说明就是对象保存后不是引用关系 3.所以在保存对象时,对象属性中标记了教师名称,课程名称作为引用ID来做相关数据的匹配
流程图:
目录介绍:
目录说明: |____bin 执行目录,程序入口 | |____init_all_data.py 初始化数据库 | |____manage.py 管理员入口 | |____student.py 学生入口 |____conf 配置文件目录 | |____setting.py 配置文件 |____core 主程序目录 | |____manage_sys.py 管理主程序 | |____student.py 学生主程序 |____data 数据库目录 | |____manage.pickle 教师对象数据 | |____student.pickle 学生对象数据 | |____subject.pickle 课程对象数据
代码:
bin/init_all_data:
#!/usr/bin/env python # -*-coding=utf-8-*- # Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/ # GitHub:https://github.com/ccorzorz import sys,os,pickle BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR) # print(BASE_DIR) from conf.setting import * from core import manage_sys from core import student """ 系统数据初始化程序,慎重使用!!!!! """ #将所有pickle数据库中的数据写入空列表 manage_sys.data_flush([]) manage_sys.subject_data_flush([]) student.student_data_flush([])
bin/manage.py
#!/usr/bin/env python # -*-coding=utf-8-*- # Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/ # GitHub:https://github.com/ccorzorz import sys,os BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR) import core.manage_sys """ 管理员后台入口,测试帐号admin/admin """ if __name__ == \'__main__\': core.manage_sys.login() core.manage_sys.main()
bin/student.py
#!/usr/bin/env python # -*-coding=utf-8-*- # Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/ # GitHub:https://github.com/ccorzorz import sys,os BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR) import core.student """ 学生系统入口,可注册登录,或者测试帐号cc/123 """ if __name__ == \'__main__\': core.student.main()
conf/setting.py:
#!/usr/bin/env python # -*-coding=utf-8-*- # Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/ # GitHub:https://github.com/ccorzorz import os,sys,time BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR) """ 配置文件 """ #存储老师信息的数据文件 manage_data_file=\'%s/data/manage.pickle\'%BASE_DIR #存储课程信息的数据文件 subject_data_file=\'%s/data/subject.pickle\'%BASE_DIR #存储学生信息的数据文件 student_data_file=\'%s/data/student.pickle\'%BASE_DIR #定义教师类 class Teacher: def __init__(self,name,age,favor): self.favor=favor self.name=name self.age=age self.asset=0 def gain(self,value): """ 上课时老师资产增加 :param value: 课程的课时费 :return: """ self.asset=int(self.asset)+int(value) def teach_accidents(self): """ 课程事故时老师资产减少 :return: """ self.asset-=1 from core import manage_sys #定义课程类 class Subject: def __init__(self,classes,value,teacher_name):#构造方法 self.classes=classes self.value=int(value) self.teacher_name=teacher_name def attend_class(self): """ 课程上课,并对相应老师的资产做相应调整 :return: """ print(\'来上课,今天我们学%s\'%self.classes) print(5*(\'%s...\'%self.classes)) time.sleep(1) print(\'齐活!下课下课!!!\') teacher_obj,index=manage_sys.sub_match_teacher(self.classes) #执行老师对象的资产增加方法 teacher_obj.gain(self.value) teacher_data=manage_sys.data_read() teacher_data[index]=teacher_obj manage_sys.data_flush(teacher_data) def accidents(self): """ 课堂事故,并对相应老师的资产做相应调整, :return: """ print(\'卧槽,今天上不了课了,%s老师去做大保健了\'%self.teacher_name) print(5*\'大保健...\') time.sleep(1) print(\'退钱退钱退钱!!!\') teacher_obj,index=manage_sys.sub_match_teacher(self.classes) #执行老师对象的资产减少方法 teacher_obj.teach_accidents() teacher_data=manage_sys.data_read() teacher_data[index]=teacher_obj manage_sys.data_flush(teacher_data) #定义学生的类 class Student: def __init__(self,name,pwd): self.name=name self.pwd=pwd self.subject_classes=[]
core/manage_sys.py
#!/usr/bin/env python # -*-coding=utf-8-*- # Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/ # GitHub:https://github.com/ccorzorz import sys,os,pickle,prettytable,time BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR) from conf.setting import * #定义登录状态的常量 LOGIN_STATE=False def check_login(func): """ 装饰器,判断管理员权限 :param func: :return: """ def inner(*args,**kwargs): if LOGIN_STATE: #判断是否已登录 res=func(*args,**kwargs) return res else:print(\'程序需要登录后才可执行!\') return inner def data_read(): """ 老师DB读取函数 :return: 读取结果 """ data=pickle.load(open(manage_data_file,\'rb\')) return data def data_flush(args): """ 写入修改后的新教师类数据 :param args: 修改后的老师数据 :return: """ pickle.dump(args,open(manage_data_file,\'wb\')) def subject_data_read(): """ 读取课程类的数据 :return: 读取结果 """ subject_data=pickle.load(open(subject_data_file,\'rb\')) return subject_data def subject_data_flush(args): """ 写入修改后的课程类数据 :param args: 修改后的数据 :return: """ pickle.dump(args,open(subject_data_file,\'wb\')) def sub_match_teacher(sub_classes): """ 匹配课程类中的老师名称与老师类数据中的老师对象 :param sub_classes:课程名称 :return:匹配到的老师对象以及对应的索引 """ #读取课程数据 subject_data=subject_data_read() #遍历课程数据,查找到课堂的名称 for item in subject_data: if sub_classes==item.classes: teac_name=item.teacher_name #遍历教师数据,查找到对应老师的对象以及下标值 teacher_data=data_read() for item in teacher_data: if item.name==teac_name: teacher_ob=item index=teacher_data.index(item) return teacher_ob,index def teacher_name(): """ 生成教师名字列表函数 :return: 返回名字列表 """ manage_data=data_read() teacher_list=[] for teacher in manage_data: teacher_list.append(teacher.name) # print(teacher_list) return teacher_list def subject_name(): """ 生成课程名称列表函数 :return: 课程名称列表 """ subject_data=subject_data_read() subject_list=[] for subject in subject_data: subject_list.append(subject.classes) # print(subject_list) return subject_list @check_login def creat_teacher(): """ 创建教师函数 :return: """ #读取教书数据 manage_data=data_read() teacher_list=teacher_name() name=input(\'输入教师姓名:\') if name in teacher_list: #判断是否已存在此教师 print(\'已有教师:%s的数据\'%name) else: while True: age=input(\'请输入教师年龄:\') if age.isdigit(): age=int(age) break else:print(\'输入有误,请重新输入\') favor=input(\'请输入教师爱好和擅长,可多选,使用逗号隔开:\') #调用教师类创建教师,并赋予相应属性 docor_name=Teacher(name,age,favor) manage_data.append(docor_name) data_flush(manage_data) print(\'教师%s已创建成功!\'%name) @check_login def creat_subject(): """ 创建课程函数 :return: """ #读取课程数据 subject_data=subject_data_read() subject_list=subject_name() classes=input(\'请输入课程名称:\') #判断是否有此课程 if classes in subject_list: print(\'已经有%s课程\'%classes) else: while True: value=input(\'请输入课时费:\') if value.isdigit(): value=int(value) break else:print(\'输入有误,请重新输入.\') while True: print(\'请选择授课老师\'.center(50,\'*\')) manage_data=show_teachers() num=input(\'请选择老师对应的序列号\') if num.isdigit(): num=int(num) if num < len(manage_data): teacher_name=manage_data[num].name #调用课程类创建课程,并赋予相应属性 subject_obj=Subject(classes,value,teacher_name) subject_data.append(subject_obj) subject_data_flush(subject_data) break else:print(\'输入有误,请重新输入.\') else:print(\'输入有误,请重新输入.\') # @check_login def show_teachers(): """ 显示所有教师信息函数 :return: """ #遍历教师数据文件,并打印对应信息 manage_data=data_read() row=prettytable.PrettyTable() row.field_names=[\'序列号\',\'教师姓名\',\'年龄\',\'爱好\',\'目前资产\'] for teach in manage_data: row.add_row([manage_data.index(teach), teach.name, teach.age, teach.favor, teach.asset]) print(row) return manage_data def show_subject(): """ 显示所有课程信息 :return: """ #遍历课程数据,并显示相应信息 subject_data=subject_data_read() row=prettytable.PrettyTable() row.field_names=[\'序列号\',\'学科名\',\'课时费\',\'授课老师\',] for subject in subject_data: row.add_row([subject_data.index(subject), subject.classes, subject.value, subject.teacher_name]) print(row) return subject_data def logout(): """ 退出系统函数 :return: """ exit(\'程序退出!\') def menu(): """ 打印菜单函数 :return: """ row=prettytable.PrettyTable() row.field_names=[\'创建老师\',\'创建课程\',\'查看所有老师\',\'查看所有课程\',\'退出程序\'] row.add_row([0,1,2,3,\'q&quit\']) print(row) def login(): """ 登录函数 :return: """ user=input(\'请输入管理员用户名:\') pwd=input(\'请输入密码:\') if (user and pwd) == \'admin\': #登录成功后修改全局变量 global LOGIN_STATE LOGIN_STATE=True print(\'登录成功!\') return LOGIN_STATE else: print(\'用户名或者密码错误!\') return False @check_login def main(): """ 主函数,系统入口 :return: """ while True: menu() #打印菜单后,将函数名形成列表让用户选择,选择后执行对应的函数 menu_list=[creat_teacher,creat_subject,show_teachers,show_subject,logout] inp=input(\'请选择操作对应的序列号:\') if inp.isdigit(): inp=int(inp) if inp < len(menu_list): menu_list[inp]() time.sleep(1) elif inp == \'q\' or inp ==\'quit\': logout() else:print(\'输入错误,请重新输入.\')
core/student.py:
#!/usr/bin/env python # -*-coding=utf-8-*- # Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/ # GitHub:https://github.com/ccorzorz import sys,os,pickle,prettytable BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR) from conf.setting import * from core import manage_sys # USER=None def student_data_read(): """ 读取学生数据 :return: 读取到的学生数据 """ student_data=pickle.load(open(student_data_file,\'rb\')) return student_data def student_data_flush(args): """ 刷新学生数据 :param args: 新的学生数据 :return: """ pickle.dump(args,open(student_data_file,\'wb\')) def student_name(): """ 生成学生登录用户名列表 :return: """ student_data=student_data_read() student_name_list=[] for item in student_data: student_name_list.append(item.name) return student_name_list def regist(): """ 注册函数 :return: """ student_data=student_data_read() student_name_list=student_name() name=input(\'请输入您的用户名:\') if name in student_name_list: #判断是否存在用户名 print(\'已有用户:%s\'%name) else: pwd=input(\'请输入您的密码:\') for i in range(3): pwd_again=input(\'确认注册密码:\') if pwd_again == pwd: print(\'%s注册成功!\'%name) #调用学生类生成学生对象,并写入学生类数据库中 student_obj=Student(name,pwd) student_data.append(student_obj) student_data_flush(student_data) break else: print(\'密码不正确,请重新输入,还剩尝试次数%s\'%(2-i)) def s_login(): """ 学生登录函数 :return: """ #读取学生类数据库和学生姓名列表,两个列表的下标相匹配 student_data=student_data_read() student_name_list=student_name() name=input(\'请输入您的用户名:\') if name not in student_name_list: print(\'无%s用户名.\'%name) else: for i in range(3): pwd=input(\'请输入用户%s的密码:\'%name) #如果输入的密码与学生类中的密码匹配 if pwd==student_data[student_name_list.index(name)].pwd: global USER USER=name print(\'登录成功!!!\') return True else:print(\'密码校验失败,剩余尝试次数:%s\'%(2-i)) def choice_subject(): """ 选择课程函数 :return: """ #读取学生类数据库和学生姓名列表,两个列表的下标相匹配 student_data=student_data_read() student_name_list=student_name() #读取课程类数据库 subject_data=manage_sys.show_subject() inp = input(\'请选择学科名对应的序列号\') if inp.isdigit(): inp=int(inp) if inp < len(subject_data): #如果输入序列符合条件,课程数据库中取到相应课程对象 subject=subject_data[inp] #学生类对象中取到课程列表,如果已有课程提示,如果无相同课程,添加入课程列表,并写入数据 student_subject_list=student_data[student_name_list.index(USER)].subject_classes if subject.classes in student_subject_list: print(\'您的课表中已有%s学科!\'%subject.classes) else: student_subject_list.append(subject.classes) student_data_flush(student_data) print(\'课程关联成功\') else:print(\'选择有误,请重新输入\') else:print(\'选择有误,请重新输入\') def has_subject(): """ 显示已选课程函数 :return: """ #读取学生类数据库和学生姓名列表,两个列表的下标相匹配 student_data=student_data_read() student_name_list=student_name() #读取学生对象中的对应课程列表信息,打印所有课程信息 student_subject_list=student_data[student_name_list.index(USER)].subject_classes row=prettytable.PrettyTable() row.field_names=[\'序列号\',\'课程名\'] for item in student_subject_list: row.add_row([student_subject_list.index(item),item]) print(row) return student_subject_list def s_logout(): sys.exit(\'程序退出!\') def show_menu(): """ 登录后的菜单信息函数 :return: """ row=prettytable.PrettyTable() row.field_names=[\'选择课程\',\'查看已选课程\',\'上课\',\'教学事故\',\'退出程序\'] row.add_row([0,1,2,3,\'3&q&quit\']) print(row) def attend(): """ 上课函数 :return: """ #读取学生类数据库和学生姓名列表,两个列表的下标相匹配 student_data=student_data_read() student_name_list=student_name() student_subject_list=student_data[student_name_list.index(USER)].subject_classes for index,item in enumerate(student_subject_list): print(index,item) inp=input(\'请选择课程对应的序列号:\') #选择上课的目标课程 if inp.isdigit(): inp=int(inp) if inp < len(student_subject_list): #如果符合序列号标准 #确认课程名称 subject_classes=student_subject_list[inp] #读取课程对象数据 subject_data=manage_sys.subject_data_read() #确认相应的课程对象 for item in subject_data: if item.classes==subject_classes: subject_obj=item #调用课程对象的上课方法 subject_obj.attend_class() else:print(\'选择有误\') else:print(\'选择有误!\') def s_accidents(): """ 教学事故函数,与上课函数相同 :return: """ student_data=student_data_read() student_name_list=student_name() student_subject_list=student_data[student_name_list.index(USER)].subject_classes for index,item in enumerate(student_subject_list): print(index,item) inp=input(\'请选择课程对应的序列号:\') if inp.isdigit(): inp=int(inp) if inp < len(student_subject_list): subject_classes=student_subject_list[inp] subject_data=manage_sys.subject_data_read() for item in subject_data: if item.classes==subject_classes: subject_obj=item #调用课程对象的教学事故方法 subject_obj.accidents() else:print(\'选择有误\') else:print(\'选择有误!\') def main2(): """ 登录后的菜单选择界面 :return: """ #将函数名形成列表,选择后执行函数 menu=[choice_subject,has_subject,attend,s_accidents,s_logout] while True: show_menu() inp=input(\'请选择操作对应的序列号:\') if inp == \'q\' or inp == \'quit\': s_logout() elif inp.isdigit(): inp=int(inp) if inp < len(menu): menu[inp]() else:print(\'输入有误,请重新输入\') else:print(\'输入有误,请重新输入~\') def main(): """ 主函数入口 :return: """ print(\'\'\'1.登录 2.注册\'\'\') inp=input(\'请选择相应操作序列号:\') if inp == \'1\': res=s_login() if res: main2() elif inp==\'2\': regist() else:print(\'选择有误!系统退出\') # if __name__ == \'__main__\': # main()
data目录都是数据库文件,直接手动创建即可.收工!
以上是关于Day7作业:选课系统的主要内容,如果未能解决你的问题,请参考以下文章