学校选课
下列操作产生的数据都通过pickle序列化保存到文件里
pickle可以帮我们保存对象
1、需求分析
一、管理员视图
1.注册
2登录
3.创建学校
4创建课程(先选择学校)
5.创建讲师
二、学员视图
1.注册
2.登录
3.选择校区
4.选择课程
先选择校区再选择校区中某一门课程,学生选课 课程也选择学生
5.查看分数
三、讲师视图
1.登录
2.查看教授课程
3.选择教授课程
4.查看课程学生
5.给学生打分
2、程序的架构设计
三层架构)(MVC)
用户视图层
用于与用户的交互
小的逻辑判断,比如注册功能中两次密码是否一致的校验
core(用户视图层再这个包下面,在src.py这个文件中)
src.py主视图
admin.py分别给三个视图三个模块
admin_view再分为三个视图
student.py
student_view
teacher.py
teacher_view
逻辑接口层
核心业务逻辑的处理
逻辑接口层在interface包下面
admin_interface.py
student_interface.py
teacher_interfac.py
数据处理层
做数据的处理,比如数据的增、删、查、改
数据处理层在db这个包下面 下面还有一个db_handler.py的模块和model.py
db
models.py
db_handler.py
pickle 保存对象
在ATM+购物车中 是存放json格式的数据,将字典dict---->json
在选课系统中 pickle保存对象 将object------>pickle
先在interface里面创建接口:admin_interface(管理员接口) student_interface(学生接口) teacher_interfac(讲师接口)
1.先从db--->start.py开始写 导入os 模块、 sys模块 先添加到解释器 环境变量中
import os,sys
sys.path addend(
os.path.dirname(__file__) #在start中要拿到Coursesystem这个项目的根目录 添加到解释器的环境变量中
)
from core import src #把core里面的主视图导入过来 #到src里面来先写 用户视图层的主视图 src.py:
if __name__=='__main__':
src.run()
#到src.py里面来先写 用户视图层的主视图 src.py:
from core import admin #回到src里面来就可以导入刚刚写的管理员、学生、讲师三个视图模块
from core import student
from core import teacher
func_dict={
'1':admin.admin_view, #因为子视图还没有写 这里123会对应子视图 所以先去core写子视图(管理员、学生、讲师三个) admin.py 管理员视图在下面
'2':student.student_view, #子视图写完导入刚刚写的管理员、学生、讲师三个视图模块后 将管理员视图的函数对象拿过来(admin.admin_view)
'3':teacher.teacher_view, 不加括号
}
def run:
while True:
print('''
===========欢迎来到选课系统==========
1.管理员功能
2.学生功能
3.老师功能
================end================
''')
choice=input('请输入功能编号:').strip()
if choice not in func_dict:
print('输入有误,请重新输入!')
contiue
func_dict.get(choice)() ??
core------》写子视图 admin.py 管理员视图
from interface import admin_interface
from interface import common_interface
from lib imprort common
admin_info={
'user':None
}
def register():#管理员注册
while True:
username=input('请输入用户名:').strip()
password=input('请输入密码:').strip()
re_password=input('请输入密码:').strip()
if password==re_password: #小的逻辑判断
flag,msg=admin_interface.admin_register_interface(
username,passmrod) #调用接口层,管理员注册接口
if flag:
print(msg)
break
else:
print('两次密码不一致,请重新输入密码')
def login():#管理员登录
while True:
username=input('请输入用户名:').strip()
password=input('请输入密码:').strip()
1.调用管理员登录接口
flag,msg=admin_interface.damin_login_interface(
username,password
)
if flag:
print(msg)
#记录当前用户登录状态 可变类型不需要global
admin_info['user']=username
break
else:
print(msg)
#管理员创建学校
@common.auth('admin')
def create_school():
while True:
#让用户输入学校的名称和地址
school_name=input('请输入学校名称:').strip()
school_addr=input('请输入学校地址:').strip()
2.调用接口保存学校
flag.msg=admin_interface.create_school_interface(
#学校名、学校地址、创建学校的管理员
school_name,school_addr,admin_info.get('user')
)
if flag:
print(msg)
break
else:
print(msg)
#管理员创建课程
@common.auth('admin')
def create_course():
while True: 先另外创建一个公共的接口
#1.让管理员先选择学校
1.1调用接口 获取所有学校的名称并打印
flag,school_list_or_msg=common_interface.get_all_achool_interface()
if not flag:
print(school_list_or_msg)
break
for index,school_name in enumerate(school_list_or_msg):
print(f'编号:(index) 学校名:(school_name)')
choice=input('请输入学校编号:').strip()
if not choice.isdigit():
print('请输入学校编号:')
continue
choice=int(choice)
if choice not in range(len(school_list_or_msg)):
print('请输入正确编号')
contime
#获取选择后的学校名字
school_name=school_list_or_msg[choice]
#2.选择学校后再输入课程名称
course_name=input('请输入需要创建的课程名称:').strip()
3.调用创建课程接口 让管理员去创建课程
flag,msg=admin_interface.create_course_interface(
#传递学校的目的 是为了关联课程
school_name,course_name,admin_info.get('user')
)
interface---->commom_interface
#公共接口
import os
from conf import settings
#获取所有学校名称接口
def get_all_school_interface():
1.获取学校文件夹路径
school_dir=os.path.join(
ettings.DB_PATH,'School'
)
2.判断文件夹是否存在
if not os.path.exists(school_dir):
return False,'没有学校,请先联系管理员'
3.文件夹如果存在 则获取文件夹中所有的名字
school_list=os.listdir(school_dir)
return True,school_list
#管理员创建老师
@common.auth('admin')
def create_teacher():
func_dict={
'1':register,
'2':login,
'3':create_school,
'4':create_course,
'5':create_teacher
}
def admin_view(): #管理员视图函数
while True:
print('''
1.注册
2.登录
3.创建学校
4.创建课程(先选择学校)
5.创建讲师
''') #管理员视图完毕 回到src.py
choice=input('请输入功能编号:').strip()
if choice=='q': #q是退出
break
if choice not in func_dict:
print('输入有误,请重新输入!')
contiue
func_dict.get(choice)()
core------》写子视图 student.py 学生视图
from lib import common
student_info=['user':None]
def register(): #学生注册
def login(): #学生登录
#学生选择学校:
@common.auth('student')
def choice_school():
#学生选择课程:
@common.auth('student')
def choice_course():
#学生查看课程分数:
@common.auth('student')
def check_score():
func_dict={
'1':register,
'2':login,
'3':choice_school,
'4':choice_course,
'5':check_score
}
def student_view():
while True:
print('''
1.注册
2.登录
3.选择校区
4.选择课程
先选择校区再选择校区中某一门课程,学生选课 课程也选择学生
5.查看分数
'''} #写完三个子视图分别导入用户视图层的主视图 src.py:
choice=input('请输入功能编号:').strip()
if choice=='q': #q是退出
break
if choice not in func_dict:
print('输入有误,请重新输入!')
contiue
func_dict.get(choice)()
core------》写子视图 teacher.py 讲师视图
from lib import common
teacher_info=['user':None]
def login(): #老师登录
#查看教授课程:
@common.auth('teacher')
def check_course():
#选择教授课程
@common.auth('teacher')
def choice_school():
#查看课程下学生 :
@common.auth('teacher')
def check_stu_from_course():
#修改学生分数
@common.auth('teacher')
def check_stu_from_course():
func_dict={
'1':login,
'2':check_course,
'3':choose_course,
'4':check_stu_from_course,
'5':check_stu_from_course
}
def teacher_view():
while True:
print('''
1.登录
2.查看教授课程
3.选择教授课程
4.查看课程学生
5.修改学生分数
' ''} #写完三个子视图分别导入用户视图层的主视图 src.py:
choice=input('请输入功能编号:').strip()
if choice=='q': #q是退出
break
if choice not in func_dict:
print('输入有误,请重新输入!')
contiue
func_dict.get(choice)()
#调用接口层,管理员注册接口
管理员接口
#管理员注册接口-------> admin inyerface
from db import models #创建对象
def admin_register_interface(username,passmrod):
1.判断用户是否存在
admin_obj=models.Admin.select(username)
1.1若存在不允许注册返回用户已存在给视图层
if admin_obj:
return False,'用户已经存在'
1.2若用户不存在则允许注册,调用类实例化得到对象并且保存
admin_obj=models.Admin(username,passwrod) #调用类,再传入username,password 得到类的对象
admin_obj.save() #对象调用save 会将admin_obj传给save方法 由该方法去调用db_handler中的select_data功能获取对象
return True,'注册成功'
管理员登录接口
def admin_login_interface(username,password):
#1.判断用户是否存在
admin_obj=models.Admin.select(username)
2.若不存在则证明用户不存在并返回给视图层
if not admin_obj:
RETURN fALSE,'用户不存在'
3.若用户存在,则校验密码
if password==admin_obj.pwd:
return Turn,'登录成功'
else:
return False,'密码错误!'
#管理员创建学校接口
def create_school_interface(school_name,school_addr,admin_name):
1.查看当前学校是否已经存在
#school_obj---->对象or None
school_obj=models.School.select(school_name)
2.若学校存在则返回False 告诉用户学校已经存在
if school_obj:
return False,'学校已存在'
3.若不存在,则创建学校 注意:由管理员对象来创建
admin_obj=models.Admin.select(admin_name)
#由管理员来调用创建学校方法,并传入学校的名字与地址
admin_obj.create_school(
school_name,school_addr
)
4.返回创建学校成功给视图层
return True,f'[(shool_name)]学校创建成功!'
#管理员创建课程接口
def create_course_interface(school_name,course_name,admin_name):
#1.查看课程是否存在
1.1先获取学校对象中的课程列表
school_obj=models.School.select(school_name)
1.2判断当前课程是否存在课程列表中
if course_name in scholl_obj.course_list:
return False,'当前课程已存在'
2。若课程不存在 则创建课程 有管理员来创建
admin_obj=models.Admin.select(admin_name)
admin_obj.create_course(
school_name,course_name
)
#管理员创建老师接口
def create_teacher_interface(teacher_name,admin_name,teacher_pwd='123')
1.判断老师是否存在
teacher_obj=models.Teacher.select(teacher_name)
2.若存在 则返回不能创建
if teacher_obj:
return False,'老师已存在!'
3.若不存在 则创建老师 让管理员来创建
admin-obj=models.Admin.select(admin_name) #因为需要管理员来创建 所以要先获取管理员这个对象
admin_obj.crete_teacher((teacher_name,teacher_pwd) #调用管理员里面的功能来创建老师
return True,f'[(teacher_name)]老师创建成功!'
用于存放类 db--->mode.py models.py
有学校类、学员类、课程类、课程类、管理员类
from db improt db_handler #导入 db_handler里面的save来保存数据
#父类:让所有子类都继承select与save方法
class Base:
@classmethod #查看数据------>查看登录查看数据库
def select(cls,username): #接受到admin和用户的名字
#obj有可能是对象或者none
obj=db_handler.select_data(cls,username)
return obj
#保存数据-------》注册保存、更新数据
def save(self)让类来保存
#让db_handler中的save__data帮我保存数据
db_handler.save__data(self) #需要手动传入self
class Admin(Base): #管理员类 调用类的时候触发init 其实就是他的内置方法
def _ _init_ _(self,user,pwd): #username,passmrod相当于把这个传过来
self.user=user#再赋值给对象的这两个
self.pwd=pwd #给当前赋值
#创建学校
def create_school(self,school_name,school_addr):
'''该方法内部来调用学校类实例化的得到对象,并保存'''
school_obj=school(school_name,school_addr):
school_obj.save()
#创建课程
def create_course(self,school_obj,course_name):
1.调用课程类 创建实例化课程
course_obj=Course(course_name)
2.获取当前学校对象,并将课程添加到课程列表中
course_obj.course_list.append(course_name)
3.更新学校数据
school_obj.save()
return True,f'[(course_name)] 课程创建成功,绑定给[(school_name)]校区!'
school_obj.course_list.append(course_name)
#创建讲师
@common.auth('admin')
def create_teacher():
while True:
#让管理员输入创建的老师名字
teacher_name=input('请输入老师的名字:').strip()
2.调用接口创建老师
flag,msg=admin_interface.create_teacher_interface(
teacher_name.admin_info.get('user'))
if flag:
print(msg)
break
else:
print(msg)
创建讲师
def create_teacher(self,taecher_name,teacher_pwd):
1.调用老师类 实例化得到老师对象 并保存
Teacher(self,taecher_name,teacher_pwd)
return True,f'[(teacher_name)]老师创建成功!'
#学校类
class School(Base):
def _ _init_ _(self,user,addr):
#必须写:self.user,因为db_handler_data统一规范
self.user=user
self.addr=addr
#课程列表:每所学校都应该有相应的课程
self.course_list=[]
#学生类
class Stuent(Base):
#课程类
class Course(Base):
def__init__(self,course_name):
self.user=course_name
self.student_list=[]
self.save()
#讲师类
classTeacher(Base):
def __init__(self,self,taecher_name,teacher_pwd):
self.user=teachername
#self.pwd需要统一
self.pwd=teacher_pwd
self.course_list_form_tea=[]
在db_handler里面创建save
用于保存对象和获取对象
improt os
import pickle
from conf import settings
def save__data(): #定义新函数 用于保存数据 1.获取对象的保存文件夹路径 以类名当作文件的文件夹名字
#obj.__class__ 获取当前对象的类
#obj.__class__ .__name__ 获取类的名字
class_name=obj.__class__ .__name__
user_dir_path= os.path.join( #用户文件夹路径
settings.DB_PATH,class_name
)
2.判断文件夹是否存在 不存在则创建文件夹
if not os.path.exists(user_dir_path):
os.mkdir(user_dir_path) 创建文件夹
3.拼接当前为用户的pickle文件路径 以用户名作为文件名
user_path=os.path.join(
user_dir_path,obj.user#当前用户名字
)
4.打开文件保存对象 通过pickle
with open(user_path,'wb')as f:
pickle.dump(obj,f)
查看数据
def select__data(cls,username): #定义新函数 查看数据 拿到类、username了
class_name=cls .__name__ 由cls类获取类名
user_dir_path= os.path.join( #用户文件夹路径
settings.DB_PATH,class_name
)
2.判断文件夹是否存在 不存在则创建文件夹
if not os.path.exists(user_dir_path):
os.mkdir(user_dir_path) 创建文件夹
3.拼接当前为用户的pickle文件路径 以用户名作为文件名
user_path=os.path.join(
user_dir_path,username#当前用户名字
)
4.打开文件获取对象
with open(user_path,'wb')as f:
pickle.dump(obj,f)
或者在查看数据中,也可以汇总成下面:
判断文件如果存在 再打开并返回 如果不存在 则代表用户不存在
if os.path.exists(user_path):
with open(user_path,'rb')as f: #打开文件获取对象
obj=pickle.load(f)
return obj
return None
conf--->settings.py 导入os模块
improt os
BASE_PATH=os.path.dirname( #固定用法 先给一个项目根目录的获取(路径)
os.path.dirname(__file__)
)
DB_PATH=os.path.join(
BASE_PATH,'db' ???????
)
lib------>common.py公共方法里 来写登录认证装饰器
#多用户登录认证装饰器
def auth(role):角色---》管理员、学生、老师
from core import admin ,student,teacher
def login_auth(func):
def inner(*args,**kwargs):
if role=='admin':如果角色是管理员
if admin.admin_info['user']:
res=func(*args,**kwargs)
return res
else:
admin.login()
elif role=='student'
if student.student_info['user']:
res=func(*args,**kwargs)
return res
else:
student.login()
elif role=='teacher'
if teache.teache_info['user']:
res=func(*args,**kwargs)
return res
else:
teache.login()
else:
print('当前视图没有权限')
return inner
return login_auth
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战