一、项目开发功能模块划分
1.功能划分
包/文件 | 功能 |
---|---|
interface | 登录、注册、选课等接口 |
core | 注册、登录、选课核心功能 |
db | 存放注册的用户数据 |
lib | 存放编写的公共方法文件 |
conf | 存放配置文件 |
readme.txt | 项目文档 |
requirements.txt | 开发文件说明 |
start.py | 启动文件 |
2.对象功能分析
管理员:
- 注册
- 登录
- 创建课程
- 创建讲师
- 创建学校
讲师:
- 登录
- 查看教授课程
- 选择教授课程
- 讲师查看课程的学生
- 讲师课程评分
学生:
- 登录
- 注册
- 选择课程
- 查看成绩
- 选择学校
二、开发环境及其版本
没有写版本的对应是python3.7的
开发环境 | 版本 |
---|---|
python | 3.7 |
json | |
sys | |
os | |
hashlib | |
pickle |
三、db包
db_handler.py
from conf import settings
import os
import pickle
def save_obj(obj):
# 1.先获取当前对象所载的文件夹路径
file_path = os.path.join(
settings.DB_DIR, obj.__class__.__name__
)
# 2.判断当前路径是否存在 不存在自动创建
if not os.path.exists(file_path):
os.mkdir(file_path)
# 3.存在则拼接对象文件路径
obj_file_path = os.path.join(file_path, obj.name)
with open(obj_file_path, 'wb') as f:
pickle.dump(obj, f)
def get_obj(cls, name):
# 直接拼接对象的完整路径
obj_file_path = os.path.join(
settings.DB_DIR, cls.__name__, name
)
if os.path.exists(obj_file_path):
with open(obj_file_path,'rb') as f:
obj = pickle.load(f)
return obj
def get_objs(cls):
obj_file_path = os.path.join(
settings.DB_DIR, cls.__name__
)
dirs = os.listdir(obj_file_path)
if len(dirs) > 0:
res = []
for dir in dirs:
file = os.path.join(obj_file_path, dir)
with open(file, 'rb') as f:
obj = pickle.load(f)
res.append(obj)
return res
return []
if __name__ == '__main__':
pass
models.py
from db import db_handler
class fa:
def save(self):
db_handler.save_obj(self)
@classmethod
def get_obj(cls, name):
return db_handler.get_obj(cls, name) # 这个方法将来不止一种角色使用
class Admin(fa):
def __init__(self, name, pwd):
self.name = name
self.pwd = pwd
self.is_identity = "superuser"
# 只要代码能运行到对象实例化 那么肯定要保存
self.save() # 直接自动保存
class Course(fa):
def __init__(self, name, classTeacher, school):
self.name = name
self.classTeacher = classTeacher
self.school = school
self.save()
# 查找学生是否已加入学校
def get_no_teacher(self):
if self.classTeacher == "":
return True
return False
@classmethod
def get_courses(self):
return db_handler.get_objs(self)
class Teacher(fa):
def __init__(self, name, tPassWord, tUserName):
self.tUserName = tUserName
self.tPassWord = tPassWord
self.name = name
self.is_identity = "teacher"
self.save()
class School(fa):
def __init__(self, name, address, superuser):
self.name = name
self.address = address
self.superuser = superuser
self.courses = []
self.save()
@classmethod
def get_schools(self):
return db_handler.get_objs(self)
# 为学校开设课程
def insert_course(self, course):
self.courses.append(course)
self.save()
class Student(fa):
def __init__(self, username, password, sname):
self.name = username
self.sname = sname
self.password = password
self.choose_courses = {}
self.school = ""
self.is_identity = "student"
self.save()
# 修改学生对应课程分数
def update_course_score(self, course, score):
self.choose_courses[course] = score
self.save()
# 查看该学生是否有对应课程
def is_course_student(self, course):
if course in self.choose_courses:
return True
return False
# 查看学生是否加入学校
def has_school(self):
if self.school == "":
return True
return False
# 为学生添加学校
def insert_school(self, school):
self.school = school
self.save()
@classmethod
def get_students(self):
return db_handler.get_objs(self)
四、core包
src.py
from core import admin_view, teacher_view, student_view
module_dict = {
'1': admin_view,
'2': teacher_view,
'3': student_view
}
def run():
while True:
print("""
==============选课系统=================
1.管理员视图
2.讲师视图
3.学员视图
======================================
""")
choice = input('请输入您想要执行的视图编号>>>:').strip()
if choice in module_dict:
module_name = module_dict.get(choice)
module_name.run()
else:
print('暂无该视图')
admin_view.py
from interface import admin_interface
from lib.common import is_login,public_login
def register():
# 1.获取用户数据
name = input('请输入您的用户名>>>:').strip()
pwd = input('请输入您的密码>>>:').strip()
confirm_pwd = input('请确认密码>>>:').strip()
# 2.判断密码是否一致(逻辑太简单 直接在展示层做即可)
if not pwd == confirm_pwd:
print('两次密码不一致')
return
# 3.直接调用注册接口
flag, msg = admin_interface.register_interface(name, pwd)
print(msg)
def login():
public_login("admin")
@is_login("admin")
def create_course():
print('管理员创建课程')
className = input("请输入课程名:").strip()
classTeacher = input("请输入授课讲师(可为空):").strip()
school = input("请输入所属学校:").strip()
flag, msg = admin_interface.create_course_interface(className, classTeacher, school)
print(msg)
@is_login("admin")
def create_teacher():
print('管理员创建讲师')
tUserName = input("请输入讲师账号用户名:").strip()
tPassWord = input("请输入讲师账号密码:").strip()
tName = input("请输入讲师名字:").strip()
flag, msg = admin_interface.create_teacher_interface(tUserName, tPassWord, tName)
print(msg)
@is_login("admin")
def create_school():
print('管理员创建学校')
schoolName = input("请输入学校名字:").strip()
schoolAddress = input("请输入学校地址").strip()
flag, msg = admin_interface.create_school_interface(schoolName, schoolAddress)
print(msg)
func_dict = {
'1': register,
'2': login,
'3': create_course,
'4': create_teacher,
'5': create_school,
}
def run():
while True:
print("""
==============管理员视图=================
1.注册
2.登录
3.创建课程
4.创建讲师
5.创建学校
======================================
""")
choice = input('请输入您想要执行的视图编号>>>:').strip()
if choice == 'q': return # 返回上一层功能选择
if choice in func_dict:
func_name = func_dict.get(choice)
func_name()
else:
print('暂无该功能编号')
student_view.py
from interface import student_interface
from lib.common import is_login,public_login
from db import models
from lib import common
def register():
print('学员注册功能')
username = input("请输入用户名:").strip()
password = input("请输入密码:").strip()
password1 = input("请再次输入密码:").strip()
sname = input("请输入姓名:").strip()
if not password == password1:
print('两次密码不一致')
return
flag, msg = student_interface.register_interface(username, password, sname)
print(msg)
def login():
public_login("student")
@is_login("student")
def select_school():
print('学员选择学校')
scobjs = models.School.get_schools()
print("可加入学校:")
for scobj in scobjs:
print(scobj.name)
school = input("请输入要加入的学校:").strip()
flag, msg = student_interface.select_school_interface(school)
print(msg)
@is_login("student")
def select_course():
print('学员选择课程')
stobj = models.Student.get_obj(common.get_cookie_username())
flag = stobj.has_school()
if flag:
print("请先加入学校再选课")
else:
scobj = models.School.get_obj(stobj.school)
print(f"{scobj.name}可申请学习的课程:")
for i in scobj.courses:
print(i)
course_name = input("请输入申请的课程:").strip()
flag1, msg1 = student_interface.select_course_interface(course_name)
print(msg1)
@is_login("student")
def check_score():
print('学员查看分数')
flag, msg = student_interface.check_score_interface()
if flag:
for i in msg.items():
print("课程:%s,成绩:%s"%(i[0], i[1]))
else:
print(msg)
func_dict = {
'1': register,
'2': login,
'3': select_school,
'4': select_course,
'5': check_score
}
def run():
while True:
print("""
==============学员视图=================
1.注册
2.登录
3.学员选择学校
4.学员选择课程
5.学员查看分数
======================================
""")
choice = input('请输入您想要执行的视图编号>>>:').strip()
if choice == 'q': return # 返回上一层功能选择
if choice in func_dict:
func_name = func_dict.get(choice)
func_name()
else:
print('暂无该功能编号')
teacher_view.py
from interface import teacher_interface
from lib.common import is_login,public_login
from db import models
def login():
public_login("teacher")
@is_login("teacher")
def check_teach_course():
print('讲师查看课程')
flag, msg = teacher_interface.check_teach_course_interface()
print(msg)
@is_login("teacher")
def select_teach_course():
print('讲师选择课程')
courses = models.Course.get_courses()
print("所有可申请教授的课程(为空说明没有):")
for course in courses:
if course.get_no_teacher():
print(course.school + "开设的" + course.name)
course_name = input("请输入申请教授的课程名:").strip()
flag, msg = teacher_interface.select_teach_course_interface(course_name)
print(msg)
@is_login("teacher")
def check_course_student():
print('讲师查看课程的学生')
print("可查看的课程:")
f, m = teacher_interface.check_teach_course_interface()
print(m)
course_name = input("请输入要查看的课程名字:").strip()
flag, msg = teacher_interface.check_course_student_interface(course_name)
print(msg)
@is_login("teacher")
def update_student_score():
print('讲师设置分数')
flag, msg = teacher_interface.check_teach_course_interface()
if not flag:
print("没有你教授的课,无法给学生打分")
else:
print(msg)
course_name = input("请输入你要打分的课程:").strip()
flag1, msg1 = teacher_interface.check_course_student_interface(course_name)
if not flag1:
print("该课程还没选课学生")
else:
print(msg1)
student = input("请输入要打分的学生:").strip()
score = input("请输入分数:").strip()
flag2, msg2 = teacher_interface.update_student_score_interface(student, course_name, score)
print(msg2)
func_dict = {
'1': login,
'2': check_teach_course,
'3': select_teach_course,
'4': check_course_student,
'5': update_student_score
}
def run():
while True:
print("""
==============讲师视图=================
1.登录
2.查看课程
3.选择课程
4.讲师查看课程的学生
5.设置分数
======================================
""")
choice = input('请输入您想要执行的视图编号>>>:').strip()
if choice == 'q': return # 返回上一层功能选择
if choice in func_dict:
func_name = func_dict.get(choice)
func_name()
else:
print('暂无该功能编号')
六、lib包
common.py
import hashlib
cookie = {}
def password_md5(password):
md5 = hashlib.md5()
md5.update(password.encode("utf8"))
return md5.hexdigest()
def password_md5_super(password):
md5 = hashlib.md5("super".encode("utf8"))
md5.update(password.encode("utf8"))
return md5.hexdigest()
def add_cookie(name, identity):
cookie["username"] = name
cookie["is_identity"] = identity
def get_cookie_username():
return cookie["username"]
def get_cookie_is_identity():
return cookie["is_identity"]
def is_has_cookie():
if len(cookie) == 0:
return False
return True
def is_login(user_type):
def outer(func):
def inner(*args, **kwargs):
from core import admin_view,student_view,teacher_view
l = {
"admin":admin_view,
"student":student_view,
"teacher":teacher_view
}
if not is_has_cookie():
print(f"你需要登录才能使用,{user_type}的功能")
l[user_type].login()
else:
res = func(*args, **kwargs)
return res
return inner
return outer
def public_login(type):
from interface import student_interface,teacher_interface,admin_interface
l = {
"admin":admin_interface,
"teacher":teacher_interface,
"student":student_interface
}
print(f'{type}登录功能')
username = input("请输入账号:").strip()
password = input("请输入密码:").strip()
flag, msg = l[type].login_interface(username, password)
print(msg)
七、interface包
admin_interface.py
from db import models
from lib import common
def register_interface(name, pwd):
# 1.校验用户名是否已存在
obj = models.Admin.get_obj(name)
if obj:
return False, f'用户名{name}已存在'
# 2.调用接口保存数据 创建管理员对象并保存
models.Admin(name, common.password_md5_super(pwd))
return True, f'{name}注册成功'
def login_interface(name, pwd):
# 1.获取用户数据
user_obj = models.Admin.get_obj(name)
if not user_obj:
return False, '用户名不存在'
# 2.校验用户数据
if user_obj.pwd == common.password_md5_super(pwd):
common.add_cookie(name, user_obj.is_identity)
return True, f'{name}登录成功'
return False, '密码错误'
def create_course_interface(className, classTeacher, school):
obj = models.Course.get_obj(className)
if obj:
return False, f'{className}课程已存在'
if classTeacher != '':
teacher = models.Teacher.get_obj(classTeacher)
if not teacher:
return False, f'{classTeacher}讲师不存在'
if not models.School.get_obj(school):
return False, f"{school}不存在"
models.Course(className, classTeacher, school)
sobj = models.School.get_obj(school)
sobj.insert_course(className)
return True, f'{school}下的{className}课程创建成功'
def create_teacher_interface(tUserName, tPassWord, tName):
obj = models.Teacher.get_obj(tUserName)
if obj:
return False, f'用户名:{tUserName},{tName}讲师已存在'
models.Teacher(tUserName, common.password_md5(tPassWord), tName)
return True, f'用户名:{tUserName},讲师名字:{tName}创建成功'
def create_school_interface(schoolName, schoolAddress):
obj = models.School.get_obj(schoolName)
if obj:
return False, f'{schoolName}学校已存在'
models.School(schoolName, schoolAddress, common.get_cookie_username())
return True, f'{schoolName}学校创建成功'
student_interface.py
from db import models
from lib import common
def register_interface(username, password, sname):
obj = models.Student.get_obj(username)
if obj:
return False, f'用户名{username}已存在'
models.Student(username, common.password_md5(password), sname)
return True, f'{username}注册成功'
def login_interface(username, password):
obj = models.Student.get_obj(username)
if not obj:
return False, "用户名或密码错误"
if obj.password != common.password_md5(password):
return False, "用户名或密码错误"
common.add_cookie(obj.name, obj.is_identity)
return True, f'{obj.sname}学生登陆成功'
def select_school_interface(school):
sobj = models.School.get_obj(school)
stname = common.get_cookie_username()
stobj = models.Student.get_obj(stname)
if not sobj:
return False, f"{school}不存在"
if not stobj.has_school():
return False, f"已选择{stobj.school},不可再次选择"
stobj.insert_school(school)
return True, f"成功加入{school}"
def select_course_interface(course_name):
cobj = models.Course.get_obj(course_name)
stobj = models.Student.get_obj(common.get_cookie_username())
choose_course = stobj.choose_courses
if not cobj:
return False, f"{course_name}课程不存在"
if len(choose_course) == 0:
stobj.choose_courses[course_name] = 0
stobj.save()
return True, f"{course_name}课程学习申请成功"
else:
if course_name in choose_course :
return False, f"{course_name}已经申请学习,请勿重复"
else:
stobj.choose_courses[course_name] = 0
stobj.save()
return True, f"{course_name}课程学习申请成功"
def check_score_interface():
choose_course = models.Student.get_obj(common.get_cookie_username()).choose_courses
if len(choose_course) == 0:
return False, "你还没有课程,请先申请学习课程"
return True, choose_course
teacher_interface.py
from db import models
from lib import common
def login_interface(tUserName, tPassWord):
obj = models.Teacher.get_obj(tUserName)
if not obj:
return False, "用户名或密码错误"
if obj.tPassWord != common.password_md5(tPassWord):
return False, "用户名或密码错误"
common.add_cookie(obj.name, obj.is_identity)
return True, f'{obj.name}讲师登陆成功'
def check_teach_course_interface():
courses = models.Course.get_courses()
obj = common.cookie["username"]
res = f"{obj}讲师的课程:"
for course in courses:
if course.classTeacher == obj:
res += course.name + "\n"
return True, res
def select_teach_course_interface(course_name):
courses = models.Course.get_courses()
obj = common.cookie["username"]
for course in courses:
if course.name == course_name:
if course.classTeacher == '':
course.classTeacher = obj
models.Course.save(course)
return True, f"你教授课程{course.name}成功"
return False, f'你教授课程{course.name}不存在或已有授课讲师'
def check_course_student_interface(course_name):
cobj = models.Course.get_obj(course_name)
students = models.Student.get_students()
if not cobj:
return False, f"没有{course_name}课程"
if not cobj.classTeacher == common.get_cookie_username():
return False, f"不是{course_name}课任老师,无法查看"
i = 0
res = ""
for student in students:
if student.is_course_student(course_name):
res += student.name + "\n"
return True, f"{course_name}学生: \n" + res
def update_student_score_interface(student, course, score):
if not models.Student.get_obj(student):
return False, f"{student}学生不存在"
if not models.Course.get_obj(course):
return False, f"{course}课程不存在"
if not score.isdigit():
return False, "分数必须是整数"
obj = models.Student.get_obj(student)
obj.update_course_score(course, score)
return True, f"{student}的{course}课程分数为:{score}分,评分成功"
七、conf包
setting.py
import os
# 路径信息一般都不会改变 所以建议放在配置文件中
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
DB_DIR = os.path.join(BASE_DIR, 'db')
八、start
start.py
import os
import sys
# 添加sys.path
sys.path.append(os.path.dirname(__file__))
from core import src
if __name__ == '__main__':
src.run()
总结
目前项目划分比较合理,将整个项目分为了三个部分表现层、业务逻辑层、数据持久层,由于没有使用前端和数据库只能大致模拟这样的效果,项目分割后方便协作开发、产生异常时也不会项目影响,开发项目时使用了单例设计模式,用以节省项目资源,本项目在于练习面向对象的使用。