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作业:选课系统的更多相关文章
- Python作业-选课系统
目录 Python作业-选课系统 days6作业-选课系统: 1. 程序说明 2. 思路和程序限制 3. 选课系统程序目录结构 4. 测试帐户说明 5. 程序测试过程 title: Python作业- ...
- Python作业选课系统(第六周)
作业需求: 角色:学校.学员.课程.讲师.完成下面的要求 1. 创建北京.上海 2 所学校 2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上海开 ...
- day6作业--选课系统
角色:学校.学员.课程.讲师 要求: 1.创建北京.上海2所学校: 2.创建Linux,Python,go 3个课程,Linux\python在北京开,go在上海开: 3.课程包含,周期.价格,通过学 ...
- Python开发程序:选课系统
本节作业: 选课系统 角色:学校.学员.课程.讲师要求:1. 创建北京.上海 2 所学校2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上海开3. ...
- python编辑选课系统
一.需求分析 1. 创建北京.上海 2 所学校 2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上海开 3. 课程包含,周期,价格,通过学校创建课 ...
- 老男孩Day7作业:选课系统
1.作业需求:角色:学校.学员.课程.讲师 1. 创建北京.上海 2 所学校 2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上海开 3. 课程包 ...
- 从零开始学Python06作业思路:学生选课系统
一,作业要求 选课系统: 管理员: 创建老师:姓名.性别.年龄.资产 创建课程:课程名称.上课时间.课时费.关联老师 学生:用户名.密码.性别.年龄.选课列表[].上课记录{课程1:[di,a,]} ...
- [ python ] 作业:选课系统
功能代码实现源地址:https://www.cnblogs.com/lianzhilei/p/5832691.html 如有侵权,立即删除 本文主要是分析 选课系统 实现思路及上面代码的实现过程 ...
- python第三十五天-----作业完成--学校选课系统
选课系统:角色:学校.学员.课程.讲师要求:1. 创建北京.上海 2 所学校2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上海开3. 课程包含, ...
随机推荐
- WebService在ssm框架中的简单应用
WebService的概念 Web service是一个平台独立的,低耦合的,自包含的.基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述.发布.发现.协调和配 ...
- vue 对象更改检测注意事项
- 46、[源码]-Spring容器创建-注册BeanPostProcessors
46.[源码]-Spring容器创建-注册BeanPostProcessors 6.registerBeanPostProcessors(beanFactory);注册BeanPostProcesso ...
- Soda Theme sublime 自定义编辑器主题
1.Soda ThemeSublime Text 3中较为常用的一款自定义编辑器主题,用过的人都说好.Soda Theme包含代码着色.标签.图标,拥有light和dark两种颜色主题便于用户在不同时 ...
- 肤浅的聊聊关联子查询,数据集连接,TiDB代码,关系代数,等等
本章涉及的内容是TiDB的计算层代码,就是我们编译完 TiDB 后在bin目录下生成的 tidb-server 的可执行文件,它是用 go 实现的,里面对 TiPD 和 TiKV实现了Mock,可以单 ...
- 51nod 1577 异或凑数 线性基的妙用
\(OTZgengyf\)..当场被吊打\(QwQ\) 思路:线性基 提交:\(3\)次 错因:往里面加数时\(tmp.p\)与\(i\)区分不清(还是我太菜了) 题解: 我们对每个位置的线性基如此操 ...
- 安利一个IDA插件diaphora,可以将函数名、注释、结构体等的先前版本移植到新版本
插件代码地址 https://github.com/joxeankoret/diaphora 使用方法: 启动IDA并首先打开包含完整符号的二进制文件1.让我们的IDA完成初始的自动分析,之后,通过运 ...
- 模拟I2C协议学习点滴之程序相关定义
由于主机和从机都会给数据线SDA发信号,比如主机先给SDA发送数据后,从机收到数据后发送应答信号将SDA拉低,故SDA类型设定为inout.而DATA设定为inout类型,是起到校验通信的作用(后续的 ...
- 10月清北学堂培训 Day 3
今天是钟皓曦老师的讲授~ zhx:题很简单,就是恶心一些qwq~ T1 别人只删去一个字符都能AC,我双哈希+并查集只有40?我太菜了啊qwq 考虑到越短的字符串越难压缩,越长的字符串越好压缩,所以我 ...
- [线性代数] 线性代数入门A Gentle Introduction
An Overview: System of Linear Equations Basically, linear algebra solves system of linear equations ...