选课项目
♥♥♥选课项目前期准备
一.conf放置配置信息
setting
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
BASE_DB = os.path.join(BASE_DIR, 'db')
二.core:放置用户视图层
src.py
from core.admin import admin_view
from core.teacher import teacher_view
from core.student import student_view
func_dic={
'1':student_view,
'2':teacher_view,
'3':admin_view
}
def run():
while True:
print('''
1 学生视图
2 老师视图
3 管理员视图
''')
# 用户输入1,2,3,选择看到什么视图
choice = input('please choice(q to quit)>>')
if choice == 'q': break
if choice not in func_dic:continue
# 根据key值拿到函数,加括号执行
func_dic[choice]()
admin.py
from interface import admin_interface, common_interface
from lib.common import login_auth
admin_info = {'name': None}
def admin_register():
name = input('please input your name>>:')
password = input('please input your password>>:')
re_password = input('please confirm your password>>:')
if password == re_password:
# 调用接口,完成注册
_, msg = admin_interface.admin_register(name, password)
print(msg)
else:
print('两次密码不一致')
def admin_login():
print('管理员登录')
while True:
name = input('please input your name>>:')
password = input('please input your password>>:')
# 调用接口,登录
flag, msg = common_interface.common_login(name, password, 'admin')
if flag:
# 保存一下当前登录用户的信息
admin_info['name'] = name
print(msg)
break
else:
print(msg)
@login_auth(type_str='admin')
def create_school():
print('创建学校')
while True:
school_name = input('请输入学校名字:')
school_addr = input('请输入学校地址:')
# 调用接口,创建学校
flag, msg = admin_interface.create_school(school_name, school_addr)
if flag:
print(msg)
break
else:
print(msg)
@login_auth(type_str='admin')
def create_teacher():
print('创建老师')
while True:
name = input('请输入老师名字:')
# 调用接口,创建老师
flag, msg = admin_interface.create_teacher(name)
if flag:
print(msg)
break
else:
print(msg)
@login_auth(type_str='admin')
def create_course():
print('创建课程')
# 打印出所有学校(查询所有学校接口),选择
# 输入课程名字,周期,价格...
# 调用接口
while True:
school_list = admin_interface.check_all_school() # 返回学校名字列表(对象列表?名字列表?)
# enumerate 会生成一个从零开始的索引
for i, school in enumerate(school_list):
print('%s : %s' % (i, school))
choice = input('请选择学校(按数字):')
if choice.isdigit():
if 0 <= int(choice) < len(school_list):
# 输入课程名字....
name = input('请输入课程名字:')
# 需要传什么参数:学校名字,课程名字,课程周期。。。
school_name = school_list[int(choice)]
flag, msg = admin_interface.create_course(school_name, name)
if flag:
print(msg)
break
else:
print(msg)
func_dic = {
'1': admin_register,
'2': admin_login,
'3': create_school,
'4': create_teacher,
'5': create_course
}
def admin_view():
while True:
print('''
1、注册
2、登录
3、创建学校
4、创建老师
5、创建课程
''')
# 用户输入1,2,3,4,5,选择执行什么函数
choice = input('please choice(q to quit)>>')
if choice == 'q': break
if choice not in func_dic: continue
# 根据key值拿到函数,加括号执行
func_dic[choice]()
teacher.py
from lib.common import login_auth
from interface import common_interface, teacher_interface
teacher_info = {'name': None}
def teacher_login():
print('老师登录')
while True:
name = input('请输入用户名:')
password = input('请输入密码:')
flag, msg = common_interface.common_login(name, password, 'teacher')
if flag:
teacher_info['name'] = name
print(msg)
break
else:
print(msg)
@login_auth(type_str='teacher')
def check_course():
print('查看教授课程')
# 打印出老师对象内的课程列表属性即可
course_list = teacher_interface.get_course_list(teacher_info['name'])
for i, course in enumerate(course_list):
print('%s:%s' % (i, course))
@login_auth(type_str='teacher')
def choose_course():
# 打印所有课程
course_list = teacher_interface.get_all_course()
for i, course in enumerate(course_list):
print('%s : %s ' % (i, course))
choice = input('请选择课程(按数字):')
if choice.isdigit():
if 0 <= int(choice) < len(course_list):
course_name = course_list[int(choice)]
# 调接口(传老师名字和课程名字)
msg = teacher_interface.choose_course(teacher_info['name'], course_name)
print(msg)
@login_auth(type_str='teacher')
def check_student():
print('查看学生')
while True:
# 获取该老师教授所有课程名字,循环打印
course_list = teacher_interface.get_course_list(teacher_info['name'])
for i, course in enumerate(course_list):
print('%s:%s' % (i, course))
# 选择要查看哪门课程下的学生
choice = input('请选择要查看的课程:')
if choice.isdigit():
if 0 <= int(choice) < len(course_list):
# 根据课程名字,获取课程下所有学生
course_name = course_list[int(choice)]
student_list = teacher_interface.check_students_by_course(course_name)
for i, student in enumerate(student_list):
print('%s : %s ' % (i, student))
break
else:
print('输入有误,请重新输入')
else:
print('请输入数字')
@login_auth(type_str='teacher')
def modify_score():
'''
1 打印老师教授的所有课程
2 打印选择课程下的学生
3 修改成绩
'''
print('修改成绩')
while True:
# 获取该老师教授所有课程名字,循环打印
course_list = teacher_interface.get_course_list(teacher_info['name'])
for i, course in enumerate(course_list):
print('%s:%s' % (i, course))
# 选择要查看哪门课程下的学生
choice = input('请选择要查看的课程:')
if choice.isdigit():
if 0 <= int(choice) < len(course_list):
# 根据课程名字,获取课程下所有学生
course_name = course_list[int(choice)]
student_list = teacher_interface.check_students_by_course(course_name)
for i, student in enumerate(student_list):
print('%s : %s ' % (i, student))
choice_stu = input('请输入要修改的学生(按数字):')
if choice_stu.isdigit():
if 0 <= int(choice_stu) < len(student_list):
score = input('请输入分数:')
# 参数:学生名字,分数,课程名字,老师名字
msg = teacher_interface.change_score(student_list[int(choice_stu)], score, course_name,
teacher_info['name'])
print(msg)
break
else:
print('数字应该在范围内')
else:
print('请输入数字')
else:
print('输入有误,请重新输入')
else:
print('请输入数字')
func_dic = {
'1': teacher_login,
'2': check_course,
'3': choose_course,
'4': check_student,
'5': modify_score
}
def teacher_view():
while True:
print('''
1、登录
2、查看教授课程
3、选择教授课程
4、查看课程下学生
5、修改学生成绩
''')
# 用户输入1,2,3,4,5,选择执行什么函数
choice = input('please choice(q to quit)>>')
if choice == 'q': break
func_dic[choice]()
student.py
from interface import student_interface, common_interface,admin_interface
from lib.common import login_auth
student_info = {'name': None}
def student_register():
print('学生注册')
while True:
name = input('please input your name>>:')
password = input('please input your password>>:')
re_password = input('please confirm your password>>:')
if password == re_password:
# 调用接口,完成注册
_, msg = student_interface.student_register(name, password)
print(msg)
break
else:
print('两次密码不一致')
def student_login():
print('学生登录')
while True:
name = input('请输入用户名:')
password = input('请输入密码:')
flag, msg = common_interface.common_login(name, password, 'student')
if flag:
student_info['name'] = name
print(msg)
break
else:
print(msg)
@login_auth(type_str='student')
def choose_school():
print('选择学校')
while True:
# 打印出所有学校
school_list = admin_interface.check_all_school() # 返回学校名字列表(对象列表?名字列表?)
# enumerate 会生成一个从零开始的索引
for i, school in enumerate(school_list):
print('%s : %s' % (i, school))
choice = input('请选择学校(按数字):')
if choice.isdigit():
if 0 <= int(choice) < len(school_list):
# 参数:学生名字,学校名字
flag,msg=student_interface.choose_school(student_info['name'],school_list[int(choice)])
if flag:
print(msg)
break
else:
print(msg)
@login_auth(type_str='student')
def choose_course():
print('选择课程')
# 1 打印已经选择学校下的所有课程
# 2 选择课程(在课程对象学生列表中加入学生名字,学生的课程列表中追加课程名字)
# 不是打印所有课程,打印学生选择学校下的课程名字
flag,course_list=student_interface.get_can_choose_course(student_info['name'])
if flag:
if course_list:
for i,course in enumerate(course_list):
print('%s : %s'%(i,course))
choice=input('请选择课程:')
if choice.isdigit():
if 0<=int(choice)<len(course_list):
# 调用接口,完成选课
# 参数:学生名,课程名
msg=student_interface.choose_course(student_info['name'],course_list[int(choice)])
print(msg)
else:
# 这种情况下,course_list是一个字符串
print(course_list)
@login_auth(type_str='student')
def check_score():
print('查看成绩')
score=student_interface.get_score(student_info['name'])
print(score)
func_dic = {
'1': student_register,
'2': student_login,
'3': choose_school,
'4': choose_course,
'5': check_score
}
def student_view():
while True:
print('''
1、注册
2、登录
3、选择校区
4、选择课程
5、查看成绩
''')
# 用户输入1,2,3,4,5,选择执行什么函数
choice = input('please choice(q to quit)>>')
if choice == 'q': break
func_dic[choice]()
三.db:数据操作层py文件和以文件形式保存的数据
db_handler.py
import pickle
import os
from conf import settings
def save(obj):
# 对象.__class__ 对象的类
# 类.__name__ 类的名字
name = obj.__class__.__name__.lower()
path = os.path.join(settings.BASE_DB, name)
# 判断文件夹是否存在,如果不存在,创建一个
if not os.path.isdir(path):
os.mkdir(path)
path_obj = os.path.join(path, obj.name)
with open(path_obj, 'wb') as f:
pickle.dump(obj, f)
f.flush()
# type:是字符串:admin,student,course这种字符串
def select(name, type_str):
path = os.path.join(settings.BASE_DB, type_str)
if not os.path.isdir(path):
os.mkdir(path)
path_obj = os.path.join(path, name)
if os.path.exists(path_obj):
with open(path_obj, 'rb') as f:
# obj=pickle.load(f)
return pickle.load(f)
else:
return False
models.py
from db import db_handler
'''
保存管理员对象,老师对象,学校对象
管理员放到一个文件夹(类名作为文件夹名)
老师放到一个文件夹
学生放到一个文件夹
'''
class BaseClass():
def save(self):
db_handler.save(self)
# 把这个玩意写成对象的方法还是类的方法
# 类的绑定方法
@classmethod
def get_obj_by_name(cls, name):
type_str = cls.__name__.lower()
return db_handler.select(name, type_str)
class Admin(BaseClass):
def register(self, name, password):
self.name = name
self.password = password
self.save()
class School(BaseClass):
def __init__(self, school_name, school_addr):
self.name = school_name
self.addr = school_addr
# 后期加的(再测,需要把原理创建的学校删除,再测)
self.course_list = []
def add_course(self, course):
# course是放对象还是放名字?我选择放名字
self.course_list.append(course)
self.save()
class Teacher(BaseClass):
def __init__(self, name, password):
self.name = name
self.password = password
# 后期加的,测试需要删除老师对象,再测
self.course_list = []
def choose_course(self, course_name):
self.course_list.append(course_name)
self.save()
def change_score(self, stu_obj, course_name, score):
stu_obj.score[course_name] = score
# 一定要注意,保存的是学生,修改了学生
stu_obj.save()
class Course(BaseClass):
def __init__(self, name):
self.name = name
# 后期加的(当学生选择了这门课,就增加一个学生)
self.student_list = []
class Student(BaseClass):
def __init__(self, name, password):
self.name = name
self.password = password
# 学生成绩(使用字典存,分数对象存)
self.score = {}
# 新增学校字段
self.school = None
# 新增课程列表,选了课后,直接追加
self.course_list=[]
def choose_school(self, school_name):
self.school = school_name
self.save()
四.interface:
放置接口相关信息,有管理员接口,老师接口,学校接口,学生接口和公共接口
admin_interface.py
from db import models
from conf import settings
import os
from lib import common
def admin_register(name, password):
# 1 判断用户是否存在
# 2 创建用户并保存(类实例化)
# 3 保存(对象.save())
admin_obj = models.Admin.get_obj_by_name(name)
if admin_obj:
return False, '用户存在'
admin_obj = models.Admin()
admin_obj.register(name, password)
return True, '注册成功'
# def admin_login(name, password):
# # 根据名字查询对象是否存在
# obj = models.Admin.get_obj_by_name(name)
# if obj: # 对象存在
# # 判断密码是否正确
# if password == obj.password:
# return True, '登录成功'
# else:
# return False, '密码错误'
# else:
# return False, '账号不存在,请先注册'
def create_school(school_name, school_addr):
# 学校是否存在
# 创建学校对象,保存
obj = models.School.get_obj_by_name(school_name)
if obj:
return False, '学校已经存在'
else:
obj = models.School(school_name, school_addr)
obj.save()
return True, '创建成功'
def create_teacher(name, password='1234'):
obj = models.Teacher.get_obj_by_name(name)
if obj:
return False, '老师已经存在'
else:
obj = models.Teacher(name, password)
obj.save()
return True, '创建成功'
def create_course(school_name, course_name):
# 创建课程对象,保存
# 把课程和学校关联
obj = models.Course.get_obj_by_name(course_name)
if obj:
return False, '课程已经存在'
else:
obj = models.Course(course_name)
obj.save()
# 拿到学校对象,跟学校关联
school_obj = models.School.get_obj_by_name(school_name)
# 给学校添加课程(不把课程对象传入,而是传入课程名字:好好想想为什么?)
school_obj.add_course(course_name)
return True, '课程创建成功'
def check_all_school():
# 返回学校名字的列表(去db/school文件加下取出所有文件名字即可)
# 后期可能会用到,抽到公共方法中
path = os.path.join(settings.BASE_DB, 'school')
return common.get_all_file_name(path)
common_interface.py
from db import models
def common_login(name, password,type_str):
'''
:param name:
:param password:
:param type_str: 登录类型,可以是admin,student,teacher
:return:
'''
# 根据名字查询对象是否存在
if type_str=='admin':
obj = models.Admin.get_obj_by_name(name)
elif type_str=='student':
obj = models.Student.get_obj_by_name(name)
else:
obj = models.Teacher.get_obj_by_name(name)
if obj: # 对象存在
# 判断密码是否正确
if password == obj.password:
return True, '登录成功'
else:
return False, '密码错误'
else:
return False, '账号不存在,请先注册'
teacher_interface.py
from db import models
import os
from conf import settings
from lib import common
def get_course_list(name):
# 通过老师名字,获取老师对象
obj = models.Teacher.get_obj_by_name(name)
if obj:
return obj.course_list
else:
return []
def choose_course(teacher_name, course_name):
#获取到老师对象
obj=models.Teacher.get_obj_by_name(teacher_name)
if obj:
# obj.course_list.append(course_name)
# obj.save()
obj.choose_course(course_name)
return '选课成功'
return '老师不存在'
def get_all_course():
path = os.path.join(settings.BASE_DB, 'course')
return common.get_all_file_name(path)
def check_students_by_course(course_name):
'''
通过课程名字,获取所有学生
:param course_name:
:return:
'''
obj=models.Course.get_obj_by_name(course_name)
return obj.student_list
def change_score(stu_name,score,course_name,teacher_name):
# 参数:学生名字,分数,课程名字,老师名字
# 1 获取到老师对象
obj=models.Teacher.get_obj_by_name(teacher_name)
# 2 调用老师对象的修改成绩绑定方法,把学生对象,课程名字和分数传入即可
stu_obj=models.Student.get_obj_by_name(stu_name)
obj.change_score(stu_obj,course_name,score)
return '修改成功'
student_interface.py
from db import models
def student_register(name, password):
obj = models.Student.get_obj_by_name(name)
if obj:
return False, '用户存在'
obj = models.Student(name, password)
obj.save()
return True, '注册成功'
def choose_school(student_name, school_name):
# 拿到学生对象
obj = models.Student.get_obj_by_name(student_name)
if obj.school:
return False, '已经选择过学校了'
else:
# 方法一
# obj.school=school_name
# obj.save()
# 方法二:
obj.choose_school(school_name)
return True, '选择学校成功'
def get_score(name):
obj = models.Student.get_obj_by_name(name)
return obj.score
def get_can_choose_course(name):
# 先拿到学生对象
obj = models.Student.get_obj_by_name(name)
# 拿到学校名字,通过学校名字获取学校下所有课程
# 判断是否已经选过学校了
if obj.school:
school_obj = models.School.get_obj_by_name(obj.school)
return True, school_obj.course_list
else:
return False, '请先选择学校'
def choose_course(stu_name, course_name):
# 存两个位置
stu_obj = models.Student.get_obj_by_name(stu_name)
stu_obj.course_list.append(course_name)
stu_obj.save()
course_obj = models.Course.get_obj_by_name(course_name)
course_obj.student_list.append(stu_name)
course_obj.save()
return '选课成功'
五.lib:放置公共方法
common.py
import os
def login_auth(type_str):
'''
:param type_str: admin,student,teacher
:return:
'''
def wrapper(func):
def inner(*args, **kwargs):
# 防止循环导入,再次导入
from core import admin, student, teacher
# 判断是什么用户
if type_str == 'admin':
# 如果登录了,继续执行func,如果没有登录,提示一下
if admin.admin_info['name']: # 有值表示登录了,执行func
return func(*args, **kwargs)
else:
print('您没有登录')
admin.admin_login()
elif type_str == 'teacher':
if teacher.teacher_info['name']: # 有值表示登录了,执行func
return func(*args, **kwargs)
else:
print('您没有登录')
teacher.teacher_login()
else:
if student.student_info['name']: # 有值表示登录了,执行func
return func(*args, **kwargs)
else:
print('您没有登录')
student.student_login()
return inner
return wrapper
def get_all_file_name(path):
'''
获取当前路径下所有文件的名字,返回名字列表
:param path:
:return:
'''
return os.listdir(path)
六.启动文件
start.py
# 把项目根路径加入到环境变量
import sys, os
path = os.path.dirname(__file__)
sys.path.append(path)
from core import src
if __name__ == '__main__':
src.run()
七.readme
作业要求:选课系统
角色:学校、学生、课程、讲师
要求:
1. 创建北京、上海 2 所学校
2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上海开
3. 管理员创建学校 ,老师,课程
4. 课程包含课程名称(周期,价格等属性)
5. 学校包含学校名称,地址等属性
6. 创建老师角色要关联学校
7. 学生注册登录后,可以选择学校,选择课程,查看成绩
8. 老师登录后,可以查看教授课程,选择想要教授的课程,查看课程下的学生,修改学生成绩等
最终分为以下视图和功能:
1 学生视图
1、注册
2、登录
3、选择校区
4、选择课程
5、查看成绩
2 老师视图
1、登录
2、查看教授课程
3、选择教授课程
4、查看课程下学生
5、修改学生成绩
3 管理视图,创建讲师, 创建班级,创建课程
1、注册
2、登录
3、创建学校
4、创建老师
5、创建课程
上面的操作产生的数据都通过pickle序列化保存到文件里
总共分三个视图:
管理员视图:
def admin_register():
pass
def admin_login():
pass
def creat_school():
pass
def creat_teacher():
pass
def creat_course():
pass
老师视图:
def teacher_login():
pass
def check_course():
pass
def choose_course():
pass
def check_student():
pass
def modify_score():
pass
学生视图:
def student_register():
pass
def student_login():
pass
def choose_school():
pass
def choose_course():
pass
def check_score():
pass
conf放置配置信息setting
core:放置用户层视图
db:数据操作层py文件和以文件形式保存的数据
interface:放置接口相关信息,有管理员接口,老师接口,学校接口,学生接口和公共接口
lib:放置公共方法
用户功能层:src下:
src:主视图,
admin:管理员视图,
student:学生视图
teacher:老师视图
接口层:interface下:
admin_interface管理员的接口
common_interface公共的接口
school_interface学校的接口
student_interface学生的接口
teacher_interface老师的接口
数据层:db目录下:
db_handler,文件操作相关的方法
models:各种类及类方法的定义
其它目录:admin,course,school,student,teacher是自动生成的目录,用来存放数据信息
start.py启动文件