[Python学习日记-74] 面向对象实战2——选课系统

[Python学习日记-74] 面向对象实战2——选课系统

简介

开发要求

实现:选课系统

简介

        在前面的《年会答题系统》当中我们介绍了面向对象软件开发的一些流程,当然这一流程只是涵括了大部分的,目前在业界也没有一个统一的标准,每个企业自己都有一套软件开发流程,但是在学习阶段对于借鉴一些标准化的开发流程还是非常有意义的。本篇将会来做一个选课系统,同样也会参照前面《年会答题系统》的模式来进行开发。

开发要求

角色:学校、学员、课程、讲师、管理员


要求:
1.管理员创建北京、上海2所学校
2.创建 linux、python、go 3个课程,linux 和 py 在北京开展授课,go 在上海开展
3.课程包含:周期和价格,通过学校创建课程
4.创建讲师
5.创建学员时,选择学校,并关联课程
6.提供三个角色接口
    6.1 学员视图:可以注册、交学费(可选)、选择课程(等同于选择班级)、去上课
    6.2 讲师视图:讲师可管理自己的课程,上课时选择课程,还可以查看班级学员列表,修改所管理的学员的成绩
    6.3 管理视图:创建讲师、创建学校、创建课程
7.上面的操作产生的数据都通过 pickle 序列化保存到文件里

实现:选课系统

一、需求分析

1、用例名称

        选课系统

2、场景

        when:课程上线后,任意时间使用

        where:某学校

        who:学生、老师、管理员

3、用例描述

        - 管理试图

                1.管理员注册登录

                2.管理员创建学校:北京和上海两个校区

                3.管理员创建课程(先选择校区):python 周末班1期,go 脱产班2期,linux 架构班3期

                4.创建讲师:Jove、Kerry、Lucy、Amy

        - 讲师视图

                1.讲师登录

                2.讲师查看教授课程

                3.讲师选择教授课程

                4.讲师查看课程下的学员

                5.修改分数:讲师为 python 周末班1期第7次课的所有学生批改作业,为每个学生打上分数

        - 学员视图

                1.学员注册登录:波多野结衣,花野真衣,川岛芳子

                2.学员选择校区

                3.学员选择课程(先选择校区,再选择校区中的某一门课程,即学生选择课程,课程也选择学生)

                4.学员上课,产生上课记录

                5.查看分数

                6.学员为课程交学费(可选)

4、用例价值

        为某学校解决了课程管理问题

5、约束和限制

        无

二、领域模型

找名词: 

管理员、学校、课程、班级、学员、讲师、上课记录、作业、分数、成绩
筛选:去掉与行业或者说领域无关的名词

加属性:

名词属性备注
管理员-具备所有权限,对于选课系统来说,并不需要管理员的属性,因此在领域模型中,管理员是没有属性的
学校学校名,地址,课程列表
课程课程名,周期,价钱,大纲
学员学员名,年龄,学校,课程
讲师讲师名
上课记录课程节次,日期
学习记录学员名、上课记录、签到状态、签到日期、成绩

画图连关系:

三、设计模型

        设计模型的实现较为复杂,具体步骤可查看年会答题系统中的设计模型小节,本次我们将用到 MVC 模型(感兴趣的可以先自行百度一下,该模型框架将会在 Web 框架中学习到)来进行架构的设计

三层架构(MVC):

        - 用户视图层

                - 用于与用户进行交互的

                - 小的逻辑判断,比如注册功能中两次密码是否一致的校验
                - core
                    - src.py  主视图
                    - admin.py  管理员视图
                    - student.py  学员视图
                    - teacher.py  讲师视图

        - 逻辑接口层

                - 核心业务逻辑的处理

                - interface
                    - admin_interface.py
                    - student_interface.py
                    - teacher_interface.py

        - 数据处理层

                - 做数据的处理,比如数据的 增、删、查、改

                - db

                    - models.py

                        - 用于存放所有类,管理所有的类
                        - Base:
                            # 保存数据
                            - save(self):
                                db_handler.save_data()

                              @classmethod
                            - select(cls, username):
                                obj = db_handler.select_data(cls, username)
                               return obj

                       - Admin(Base)
                           - __init__(self, admin_name, pwd):
                               self.user = admin_name
                               self.pwd = pwd

                            # 管理员的创建学校方法
                            - create_school():
                                school_obj = School()
                                school_obj.save()

                           # 管理员的创建课程方法
                            - create_course(school_obj, course_name):
                               course_obj = Course()
                               course_obj.save()
                               school_obj.course_list.append(course_name)

                            # 管理员的创建老师方法
                           - create_teacher(self, teacher_name, teacher_pwd):
                               tea_obj = Teacher(teacher_name, teacher_pwd)
                               tea_obj.save()


                       - School(Base):
                           __init__(self, school_name, school_addr)
                                self.user = school_name
                                self.addr = school_addr
                                self.course_list = []


                        - Course(Base):
                            __init__(self, course_name):
                                self.user = course_name
                                self.student_list = []

                        - Teacher(Base):
                            __init__(self, teacher_name, teacher_pwd):
                               self.user = teacher_name
                               self.pwd = teacher_pwd
                               self.course_list_from_teacher = []


                   - db_handler.py
                        - save_data(obj)  保存 对象
                           - 拼接文件夹,以类名当做文件夹管理文件
                           class_name = obj.__class__.__name__
                           - 再拼接文件,然后把对象通过pickle序列化到pickle文件中


                        - select_data(cls, username):
                           - 拼接文件夹,以类名当做文件夹管理文件
                           class_name = cls.__name__
                           - 再拼接文件,然后把通过pickle反序列化得到pickle文件中的对象


                       - ATM + 购物车(可选实现)
                            - 存放 json格式的数据
                            - dict --> json

                       - 选课系统(可选实现)
                            - pickle 保存对象
                            - object ——> pickle

四、实现模型

目录结构设计:

CourseSystem/

| --  conf/

|      | --  settings.py

|      |

| --  core/

|      | -- src.py

|      | -- admin.py

|      | -- student.py

|      | -- teacher.py

|

| --  db/

|      | -- Admin/

|      | -- Course/

|      | -- School/

|      | -- Student/

|      | -- Teacher/

|      | -- models.py

|      | -- db_handler.py

|

| --  interface/

|      | -- admin_interface.py

|      | -- common_interface.py

|      | -- student_interface.py

|      | -- teacher_interface.py

|

| --  lib/

|      | -- common.py

|

| --  start.py

|

| --  README

start.py:程序入口

"""
启动文件入口
"""import os, sys
sys.path.append(os.path.dirname(__file__)
)
from core import srcif __name__ == '__main__':src.run()

setting.py:程序设置

import osBASE_PATH = os.path.dirname(os.path.dirname(__file__)
)DB_PATH = os.path.join(BASE_PATH, 'db'
)

core/src.py:用户视图层的主视图

"""
用户视图层的 主视图
"""from core import admin
from core import student
from core import teacherfunc_dict = {'1': admin.admin_view,'2': student.student_view,'3': teacher.teacher_view,
}
def run():while True:print('''====== 欢迎来到选课系统 ======1.管理员功能2.学生功能3.老师功能=========== end =============''')choice = input('请输入功能编号: ').strip()if choice not in func_dict:print('输入有误,请重新输入!')continuefunc_dict.get(choice)()

core/admin.py:管理员视图

"""
管理员视图
"""
from interface import admin_interface
from interface import common_interface
from lib import commonadmin_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, password)if flag:print(msg)breakelse:print(msg)else:print('两次密码不一致,请重新输入')# 管理员登录
def login():while True:username = input('请输入用户名: ').strip()password = input('请输入密码: ').strip()# 1.调用管理员登录接口flag, msg = common_interface.login_interface(username, password, user_type='admin')if flag:print(msg)# 记录当前用户登录状态# 可变类型不需要globaladmin_info['user'] = usernamebreakelse:print(msg)# 管理员创建学校
@common.auth('admin')
def create_school():while True:# 1.让用户输入学校的名称与地址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)breakelse:print(msg)# 管理员创建课程
@common.auth('admin')
def create_course():while True:# 1.让管理员先选择学校# 1.1 调用接口,获取所有学校的名称并打印flag, school_list_or_msg = common_interface.get_all_school_interface()if not flag:print(school_list_or_msg)breakfor index, school_name in enumerate(school_list_or_msg):print(f'编号: {index}    学校名: {school_name}')choice = input('请输入学校编号: ').strip()if not choice.isdigit():print('请输入数字')continuechoice = int(choice)if choice not in range(len(school_list_or_msg)):print('请输入正确编号!')continue# 获取选择后的学校名字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'))if flag:print(msg)breakelse:print(msg)# 管理员创建老师
@common.auth('admin')
def create_teacher():while True:# 1.让管理员输入创建的老师名字teacher_name = input('请输入老师的名字: ').strip()# 2.调用接口创建老师flag, msg = admin_interface.create_teacher_interface(teacher_name, admin_info.get('user'))if flag:print(msg)breakelse:print(msg)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.创建讲师''')choice = input('请输入功能编号: ').strip()if choice == 'q':admin_info['user'] = Nonebreakif choice not in func_dict:print('输入有误,请重新输入!')continuefunc_dict.get(choice)()

core/student.py:学员视图

"""
学生视图
"""
from docutils.nodes import attentionfrom lib import common
from interface import student_interface
from interface import common_interfacestudent_info = {'user': None}# 学生注册
def register():while True:username = input('请输入用户名: ').strip()password = input('请输入密码: ').strip()re_password = input('请确认密码: ').strip()# 小的逻辑判断if password == re_password:# 调用接口层,学生注册接口flag, msg = student_interface.student_register_interface(username, password)if flag:print(msg)breakelse:print(msg)else:print('两次密码不一致,请重新输入')# 学生登录
def login():while True:username = input('请输入用户名: ').strip()password = input('请输入密码: ').strip()# 1.调用管理员登录接口flag, msg = common_interface.login_interface(username, password, user_type='student')if flag:print(msg)# 记录当前用户登录状态# 可变类型不需要globalstudent_info['user'] = usernamebreakelse:print(msg)# 学生选择学校
@common.auth('student')
def choice_school():while True:# 1、获取所有学校,让学生选择flag, school_list = common_interface.get_all_school_interface()if not flag:print(school_list)breakfor index, school_name in enumerate(school_list):print(f'编号: {index}   学校名: {school_name}')# 2、让学生输入学校编号choice = input('请输入选择的学校编号: ').strip()if not choice.isdigit():print('输入有误')continuechoice = int(choice)if choice not in range(len(school_list)):print('输入编号有误!')continueschool_name = school_list[choice]# 3、开始调用学生选择学校接口flag, msg = student_interface.add_school_interface(school_name, student_info.get('user'))if flag:print(msg)breakelse:print(msg)break# 学生选择课程
@common.auth('student')
def choice_course():while True:# 1、先获取 "当前学生" 所在学校的课程列表flag, course_list = student_interface.get_course_list_interface(student_info.get('user'))if not flag:print(course_list)break# 2、打印课程列表,并让用户选择课程for index, course_name in enumerate(course_list):print(f'编号: {index}   课程名: {course_name}')# 2、让学生输入学校编号choice = input('请输入选择的学校编号: ').strip()if not choice.isdigit():print('输入有误')continuechoice = int(choice)if choice not in range(len(course_list)):print('输入编号有误!')continue# 3、获取选择的课程名称course_name = course_list[choice]# 4、调用学生选择课程接口flag, msg = student_interface.add_course_interface(course_name, student_info.get('user'))if flag:print(msg)breakelse:print(msg)# 上课
@common.auth('student')
def attend_course():while True:# 1、先获取 "当前学生" 已选的课程列表flag, course_list = student_interface.get_course_list_for_student_interface(student_info.get('user'))if not flag:print(course_list)break# 2、打印课程列表,并让用户选择课程for index, course_name in enumerate(course_list):print(f'编号: {index}   课程名: {course_name}')# 3、让学生输入课程编号choice = input('请输入选择的课程编号: ').strip()if not choice.isdigit():print('输入有误')continuechoice = int(choice)if choice not in range(len(course_list)):print('输入编号有误!')continue# 3、获取选择的课程名称course_name = course_list[choice]# 4、调用学生上课接口,并留下上课记录flag, msg = student_interface.attend_course_for_student_interface(course_name, student_info.get('user'))if flag:print(msg)break# 学生查看课程分数
@common.auth('student')
def check_score():# 1、直接调用查看分数接口score_dict = student_interface.check_score_interface(student_info.get('user'))if not score_dict:print('没有选择课程!')print(score_dict)func_dict = {'1': register,'2': login,'3': choice_school,'4': choice_course,'5': attend_course,'6': check_score,
}def student_view():while True:print('''- 1.注册- 2.登录功能- 3.选择校区- 4.选择课程- 5.上课- 6.查看分数''')choice = input('请输入功能编号: ').strip()if choice == 'q':breakif choice not in func_dict:print('输入有误,请重新输入!')continuefunc_dict.get(choice)()

core/teacher.py:讲师视图

"""
老师视图
"""
from lib import common
from interface import common_interface
from interface import teacher_interfaceteacher_info = {'user': None}# 老师登录
def login():while True:username = input('请输入用户名: ').strip()password = input('请输入密码: ').strip()# 1.调用管理员登录接口flag, msg = common_interface.login_interface(username, password, user_type='teacher')if flag:print(msg)# 记录当前用户登录状态# 可变类型不需要globalteacher_info['user'] = usernamebreakelse:print(msg)# 查看教授课程
@common.auth('teacher')
def check_course():flag, course_list = teacher_interface.check_course_interface(teacher_info.get('user'))if flag:print(course_list)else:print(course_list)# 选择教授课程
@common.auth('teacher')
def choose_course():while True:# 1、先打印所有学校,并选择flag, school_list = common_interface.get_all_school_interface()if not flag:print(school_list)breakfor index, school_name in enumerate(school_list):print(f'编号: {index}   学校名: {school_name}')choice = input('请输入选择的学校编号: ').strip()if not choice.isdigit():print('输入有误')continuechoice = int(choice)if choice not in range(len(school_list)):print('输入编号有误!')continue# 获取选择的学校名称school_name = school_list[choice]# 2、从选择的学校中获取所有的课程flag2, course_list = common_interface.get_course_in_school_interface(school_name)if not flag2:print(course_list)breakfor index2, course_name in enumerate(course_list):print(f'编号: {index2}   课程名: {course_name}')choice2 = input('请输入选择的课程编号: ').strip()if not choice2.isdigit():print('输入有误')continuechoice2 = int(choice2)if choice2 not in range(len(course_list)):print('输入编号有误!')continue# 获取选择的课程名称course_name = course_list[choice2]# 3、调用选择教授课程接口,将该课程添加到老师课程列表中flag3, msg = teacher_interface.add_course_interface(course_name, teacher_info.get('user'))if flag3:print(msg)breakelse:print(msg)# 查看课程下学生
@common.auth('teacher')
def check_stu_from_course():while True:# 1、调用获取当前老师下所有的课程接口flag, course_list = teacher_interface.check_course_interface(teacher_info.get('user'))if not flag:print(course_list)break# 2、打印所有课程,并让老师选择for index, course_name in enumerate(course_list):print(f'编号: {index}   课程名: {course_name}')choice = input('请输入选择的课程编号: ').strip()if not choice.isdigit():print('输入有误')continuechoice = int(choice)if choice not in range(len(course_list)):print('输入编号有误!')continue# 3、获取选择的课程名称course_name = course_list[choice]# 4、利用当前课程名称获取所有学生flag2, student_list = teacher_interface.get_student_interface(course_name, teacher_info.get('user'))if flag2:print(student_list)breakelse:print(student_list)break# 修改学生分数
@common.auth('teacher')
def change_score_from_student():'''# 1、先获取老师下所有的课程,并选择# 2、获取选择的课程下所有的学生,并选择修改的学生# 3、调用修改学生分数接口修改分数'''while True:# 1、调用获取当前老师下所有的课程接口flag, course_list = teacher_interface.check_course_interface(teacher_info.get('user'))if not flag:print(course_list)break# 2、打印所有课程,并让老师选择for index, course_name in enumerate(course_list):print(f'编号: {index}   课程名: {course_name}')choice = input('请输入选择的课程编号: ').strip()if not choice.isdigit():print('输入有误')continuechoice = int(choice)if choice not in range(len(course_list)):print('输入编号有误!')continue# 3、获取选择的课程名称course_name = course_list[choice]# 4、利用当前课程名称获取所有学生flag2, student_list = teacher_interface.get_student_interface(course_name, teacher_info.get('user'))if not flag2:print(student_list)break# 5、打印所有学生让老师选择for index2, student_name in enumerate(student_list):print(f'编号:{index2}   学生名: {student_name}')choice2 = input('请输入学生编号: ').strip()choice2 = int(choice2)if choice2 not in range(len(student_list)):print('输入编号有误!')continue# 获取选择的课程名称student_name = student_list[choice2]# 老师输入需要修改的分数score = input('请输入需要修改的成绩:').strip()if not score.isdigit():continuescore = int(score)# 6、调用修改学生分数接口修改分数flag3, msg = teacher_interface.change_score_interface(course_name, student_name,score, teacher_info.get('user'))if flag3:print(msg)breakfunc_dict = {'1': login,'2': check_course,'3': choose_course,'4': check_stu_from_course,'5': change_score_from_student,
}def teacher_view():while True:print('''- 1.登录- 2.查看教授课程- 3.选择教授课程- 4.查看课程下学生- 5.修改学生分数''')choice = input('请输入功能编号: ').strip()if choice == 'q':breakif choice not in func_dict:print('输入有误,请重新输入!')continuefunc_dict.get(choice)()

db/models.py:用于存放所有类,管理所有的类,即接口相关功能具体实现都是这里的代码来实现的

"""
用于存放所有类(学校类、学员类、课程类、讲师类、管理员类)的管理功能
"""
from db import db_handler# 父类,让所有子类都继承 select 与 save方法
class Base:# 查看数据  ----> 登录、查看数据库@classmethoddef select(cls, username):  # School, school_name# obj: 对象   or   Noneobj = db_handler.select_data(cls, username)return obj# 保存数据 ---> 注册、保存、更新数据def save(self):# 让db_handler中的save_data帮我保存对象数据db_handler.save_data(self)# 管理员类
class Admin(Base):# 调用类的时候触发# username, passworddef __init__(self, user, pwd):# 给当前对象赋值self.user = userself.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)course_obj.save()# 2.获取当前学校对象,并将课程添加到课程列表中school_obj.course_list.append(course_name)# 3.更新学校数据school_obj.save()# 创建讲师def create_teacher(self, teacher_name, teacher_pwd):# 1.调用老师类,实例化的到老师对象,并保存teacher_obj = Teacher(teacher_name, teacher_pwd)teacher_obj.save()# 学校类
class School(Base):def __init__(self, name, addr):# 必须写: self.user,# 因为db_handler里面的select_data统一规范self.user = nameself.addr = addr# 课程列表: 每所学校都应该有相应的课程self.course_list = []# 学生类
class Student(Base):def __init__(self, user, pwd):self.user = userself.pwd = pwd# 每个学生只能有一个校区self.school = None# 一个学生可以选择多门课程self.course_list = []# 学生课程分数self.score_dict = {}  # {"course_name": 0}# 学生上课记录self.course_log_dict = {}# 学生添加学校方法def add_school(self, school_name):self.school = school_nameself.save()# 学生添加课程方法def add_course(self, course_name):# 1、学生课程列表添加课程self.course_list.append(course_name)# 2、给学生选择的课程设置默认分数self.score_dict[course_name] = 0self.save()# 3、学生选择的课程对象,添加学生course_obj = Course.select(course_name)course_obj.student_list.append(self.user)course_obj.save()# 学生上课def add_attend_course_log(self, course_name, time):# 1、学生上课记录if course_name in self.course_log_dict:time_log = self.course_log_dict[course_name]# 每上一次课追加一次time_log.append(time)else:time_log = [time]self.course_log_dict[course_name] = time_logself.save()# 课程类
class Course(Base):def __init__(self, course_name):self.user = course_nameself.student_list = []# 老师类
class Teacher(Base):def __init__(self, teacher_name, teacher_pwd):self.user = teacher_name# self.pwd需要统一self.pwd = teacher_pwdself.course_list_from_tea = []# 老师查看教授课程方法def show_course(self):return self.course_list_from_tea# 老师添加课程方法def add_course(self, course_name):self.course_list_from_tea.append(course_name)self.save()# 老师获取课程下学生方法def get_student(self, course_name):course_obj = Course.select(course_name)return course_obj.student_list# 老师修改学生分数方法def change_score(self, course_name, student_name, score):# 1、获取学生对象student_obj = Student.select(student_name)# 2、再给学生对象中的课程修改分数student_obj.score_dict[course_name] = scorestudent_obj.save()

db/db_handler.py:用于数据操作,保存之类的

"""
用于保存对象与获取对象
"""
import os
import pickle
from conf import settings# 保存数据
def save_data(obj):"""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.打开文件,保存对象, 通过picklewith open(user_path, 'wb') as f:pickle.dump(obj, f)# 查看数据
def select_data(cls, username):  # 类, username# 由cls类获取类名class_name = cls.__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, username  # 当前用户名字)# 4.判断文件如果存在,再打开,并返回,若不存在,则代表用户不存在if os.path.exists(user_path):# 5.打开文件,获取对象with open(user_path, 'rb') as f:obj = pickle.load(f)return obj

interface/admin_interface.py:管理员接口

"""
管理员接口
"""
from db import models# 管理员注册接口
def admin_register_interface(username, password):# 1.判断用户是否存在# 调用Admin类中的,select方法,# 由该方法去调用db_handler中的select_data功能获取对象admin_obj = models.Admin.select(username)# 1.1) 若存在不允许注册,返回用户已存在给视图层if admin_obj:return False, '用户已存在!'# 1.2) 若不存在则允许注册,调用类实例化得到对象并保存admin_obj = models.Admin(username, password)# 对象调用save() 会将 admin_obj传给save方法admin_obj.save()return True, '注册成功!'# 管理员登录接口(被lib/common中的公共登录接口所替代)
"""
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 True, '登录成功! 'else:return False, '密码错误!'
"""# 管理员创建学校接口
def create_school_interface(school_name, school_addr, admin_name):# 1.查看当前学校是否已存在# school_obj ---> 对象  or   Noneschool_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'[{school_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 school_obj.course_list:return False, '当前课程已存在!'# 1.2 若课程不存在,则创建课程, 由管理员来创建admin_obj = models.Admin.select(admin_name)admin_obj.create_course(school_obj, course_name)return True, f'[{course_name}] 课程创建成功, 绑定给[{school_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.create_teacher(teacher_name, teacher_pwd)return True, f'[{teacher_name}]老师创建成功!初始密码为[{teacher_pwd}]'

interface/common_interface.py:公共接口

"""
公共接口
"""
import os
from conf import settings
from db import models# 获取所有学校名称接口
def get_all_school_interface():# 1.获取学校文件夹路径school_dir = os.path.join(settings.DB_PATH, 'School')# 2.判断文件夹是否存在if not os.path.exists(school_dir):return False, '没有学校,请先联系管理员'# 3.文件夹若存在,则获取文件夹中所有文件的名字school_list = os.listdir(school_dir)return True, school_list# 公共登录接口
def login_interface(user, pwd, user_type):if user_type == 'admin':obj = models.Admin.select(user)elif user_type == 'student':obj = models.Student.select(user)elif user_type == 'teacher':obj = models.Teacher.select(user)else:return False, '登录角色不对,请输入角色'# 1.判断用户是否存在if obj:# 2.若用户存在,则校验密码if pwd == obj.pwd:return True, '登录成功! 'else:return False, '密码错误!'else:# 3.若不存在,则证明用户不存在并返回给视图层return False, '用户名不存在!'# 获取学校下所有课程接口
def get_course_in_school_interface(school_name):# 1、获取学校对象school_obj = models.School.select(school_name)# 2、获取学校对象下所有课程course_list = school_obj.course_listif not course_list:return False, '该学校没有课程'return True, course_list

interface/student_interface.py:学员接口

"""
学生接口层
"""
from db import models
import datetime# 学生注册接口
def student_register_interface(user, pwd):# 1.判断用户是否存在# 调用Student类中的,select方法,# 由该方法去调用db_handler中的select_data功能获取对象student_obj = models.Student.select(user)# 1.1) 若存在不允许注册,返回用户已存在给视图层if student_obj:return False, '学生用户已存在!'# 1.2) 若不存在则允许注册,调用类实例化得到对象并保存student_obj = models.Student(user, pwd)# 对象调用save() 会将 admin_obj传给save方法student_obj.save()return True, '注册成功!'# 学生登录接口(被lib/common中的公共登录接口所替代)
"""
def student_login_interface(user, pwd):# 1.判断用户是否存在student_obj = models.Student.select(user)# 2.若不存在,则证明用户不存在并返回给视图层if not student_obj:return False, '用户名不存在!'# 3.若用户存在,则校验密码if pwd == student_obj.pwd:return True, '登录成功! 'else:return False, '密码错误!'
"""# 学生选择学校接口
def add_school_interface(school_name, student_name):# 1、判断当前学生是否存在学校student_obj = models.Student.select(student_name)if student_obj.school:return False, '当前学生已经选择过学校了!'# 2、若不存在学校,则给调用学生对象中选择学校的方法,实现学生添加学校student_obj.add_school(school_name)return True, '选择学校成功!'# 获取学生所在学校所有课程接口
def get_course_list_interface(student_name):# 1、获取当前学生对象student_obj = models.Student.select(student_name)school_name = student_obj.school# 2、判断当前学生是有学校,若没有则返回Falseif not school_name:return False, '没有学校,请先选择学校'# 3、开始获取学校对象中的课程列表school_obj = models.School.select(school_name)# 3.1、判断当前学校中是否有课程,若没有,则联系管理员course_list = school_obj.course_listif not course_list:return False, '没有课程,请先联系管理员创建'# 3.2、若有则,返回课程列表return True, course_list# 学生选择学校接口
def add_course_interface(course_name, student_name):# 1、先判断当前课程是否已经存在学生课程列表中student_obj = models.Student.select(student_name)if course_name in student_obj.course_list:return False, '该课程已经选择过了!'# 2、调用学生对象中添加课程的方法student_obj.add_course(course_name)return True, f'[{course_name}] -- 课程添加成功!'# 学生查看已选课程接口
def get_course_list_for_student_interface(student_name):# 1、获取当前学生对象student_obj = models.Student.select(student_name)# 2、开始获取学生对象中的课程列表course_list = student_obj.course_list# 3、没有课程让学生选择课程if not course_list:return False, '没有课程,请先选择课程'# 4、若有则,返回课程列表return True, course_list# 学生上课接口
def attend_course_for_student_interface(course_name, student_name):# 1、获取当前学生对象student_obj = models.Student.select(student_name)# 2、进入课堂,产生上课记录time = datetime.datetime.now()student_obj.add_attend_course_log(course_name, time)return True, '上完课了!'# 学生会查看分数接口
def check_score_interface(student_name):student_obj = models.Student.select(student_name)if student_obj.score_dict:return student_obj.score_dict

interface/teacher_interface.py:讲师接口

"""
老师接口层
"""
from db import models# 老师查看课程接口
def check_course_interface(teacher_name):# 1、获取当前老师对象teacher_obj = models.Teacher.select(teacher_name)# 2、判断老师对象中课程列表是否有值# 让老师对象,调用查看教授课程方法,返回课程# course_list = teacher_obj.course_list_from_teacourse_list = teacher_obj.show_course()# 3、若有则返回True, 无则返回Falseif not course_list:return False, '老师没有选择课程'return True, course_list# 老师添加课程接口
def add_course_interface(course_name, teacher_name):# 1、获取当前老师对象teacher_obj = models.Teacher.select(teacher_name)# 2、判断当前课程是否在老师的课程列表中course_list = teacher_obj.course_list_from_teaif course_name in course_list:return False, '该课程已存在!'# 3、若不存在,则添加该课程到老师课程列表中teacher_obj.add_course(course_name)return True, '添加课程成功!'# 老师获取课程下学生接口
def get_student_interface(course_name, teacher_name):# 1、获取当前老师对象teacher_obj = models.Teacher.select(teacher_name)# 2、让当前老师对象,调用获取课程下所有学生功能student_list = teacher_obj.get_student(course_name)# 3、判断课程下是否有学生if not student_list:return False, '学生没有选择该课程'return True, student_list# 老师修改分数接口
def change_score_interface(course_name, student_name, score, teacher_name):# 1、获取老师对象teacher_obj = models.Teacher.select(teacher_name)# 2、让老师对象调用修改分数方法teacher_obj.change_score(course_name, student_name, score)return True, '修改分数成功!'

lib/common.py:公共方法

"""
公共方法
"""# 多用户登录认证装饰器
def auth(role):""":param role: 角色 ---》 管理员、学生、老师:return:"""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 reselse:admin.login()elif role == 'student':if student.student_info['user']:res = func(*args, **kwargs)return reselse:student.login()elif role == 'teacher':if teacher.teacher_info['user']:res = func(*args, **kwargs)return reselse:teacher.login()else:print('当前视图没有权限')return innerreturn login_auth

代码链接:https://gitcode.com/zjw529507929/CourseSystem 

效果如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/66110.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用户注册模块(芒果头条项目进度4)

1 创建⽤户模块⼦应⽤ 1.1 在项⽬包⽬录下 创建apps的python包。 1.2 在apps包下 创建应⽤userapp $ cd 项⽬包⽬录/apps $ python ../../manage.py startapp userapp 1.3 配置导包路径 默认情况下导包路径指向项⽬根⽬录 # 通过下⾯语句可以打印当前导包路径 print(sys.pa…

Elasticsearch:利用 AutoOps 检测长时间运行的搜索查询

作者:来自 Elastic Valentin Crettaz 了解 AutoOps 如何帮助你调查困扰集群的长期搜索查询以提高搜索性能。 AutoOps 于 11 月初在 Elastic Cloud Hosted 上发布,它通过性能建议、资源利用率和成本洞察、实时问题检测和解决路径显著简化了集群管理。 Au…

关于Flutter应用国际化语言的设置

目录 1. Locale配置 2. 用户切换/启动自动加载缓存里面的locale 由于最近在开发app国际化设置的时候遇到一些问题,所以做出一些总结。 1. Locale配置 具体的初始化配置可以参考文档:i18n | Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 值得…

基层医联体医院患者历史检验检查数据的快速Python编程分析

​​​​​​​ 一、引言 1.1 研究背景与意义 在当今数字化医疗时代,医疗数据呈爆炸式增长,涵盖患者的基本信息、病史、检验检查结果、治疗方案等各个维度。这些海量且复杂的数据蕴含着巨大价值,为精准医疗决策提供了关键依据。通过对患者历史检验检查数据的深入对比分析…

如何使用OpenCV进行抓图-多线程

前言 需求: 1、如何使用OpenCV捕抓Windows电脑上USB摄像头的流、 2、采用多线程 3、获知当前摄像头的帧率。 这个需求,之前就有做了,但是由于出现了一个问题,人家摄像头的帧率目前都可以达到60帧/s 了,而我的程序…

数势科技:解锁数据分析 Agent 的智能密码(14/30)

一、数势科技引领数据分析变革 在当今数字化浪潮中,数据已然成为企业的核心资产,而数据分析则是挖掘这一资产价值的关键钥匙。数势科技,作为数据智能领域的领军者,以其前沿的技术与创新的产品,为企业开启了高效数据分析…

C++11编译器优化以及引用折叠

1.左值与右值的意义 1.左值引用和右值引用最终目的是减少拷贝,提高效率 2.左值引用还可以修改参数/返回值 左值引用不足: 部分函数放回场景,只能传值返回,不能引用左值返回 当前函数局部对象,出了当前函数作用域生…

小程序学习06——uniapp组件常规引入和easycom引入语法

目录 一 组件注册 1.1 组件全局注册 1.2 组件全局引入 1.3 组件局部引入 页面引入组件方式 1.3.1 传统vue规范: 1.3.2 通过uni-app的easycom 二 组件的类型 2.1 基础组件列表 一 组件注册 1.1 组件全局注册 (a)新建compoents文件…

【时时三省】(C语言基础)常见的动态内存错误2

山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省 对非动态开辟空间内存使用free释放 示例: 这个arr数组是在栈上的 *p指向的就是arr 对非动态空间也用了free ferr只能在动态开辟空间使用 使用free释放一块动态开辟空间的一部分…

3D高斯点云CUDA版本数据制作与demo运行

0. 简介 关于UCloud(优刻得)旗下的compshare算力共享平台 UCloud(优刻得)是中国知名的中立云计算服务商,科创板上市,中国云计算第一股。 Compshare GPU算力平台隶属于UCloud,专注于提供高性价4090算力资源,配备独立IP,…

【游戏设计原理】46 - 魔杖

幻想,人们可以通过多种形式来引发,比如文字,图片,绘画,语言等,但游戏与以上这些形式的区别,正如游戏与其他艺术形式的区别一样,游戏作为一种艺术和娱乐形式,其独特之处在…

基于Java的敬老院管理系统的设计和实现【源码+文档+部署讲解】

基于Java的敬老院管理系统设计和实现 摘 要 新世纪以来,互联网与计算机技术的快速发展,我国也迈进网络化、集成化的信息大数据时代。对于大众而言,单机应用早已成为过去,传统模式早已满足不了当下办公生活等多种领域的需求,在一台电脑上不联网的软件少之又少&#x…

Git快速入门(一)·Git软件的安装以及GitHubDesktop客户端的安装

目录 1. 概述 1.1 版本控制介绍 1.1.1 集中式版本控制 1.1.2 分布式版本控制 1.1.3 多人协作开发 2. 安装Git 3. 安装GitHubDesktop客户端 1. 概述 Git 是一个免费的、开源的分布式版本控制系统。它能够快速高效地处理从小型到大型的各种项目。Git 具有易于学习…

数据挖掘——神经网络分类

神经网络分类 神经网络分类人工神经网络多层人工神经网络 误差反向传播(BP)网络后向传播算法 神经网络分类 人工神经网络 人工神经网络主要由大量的神经元以及它们之间的有向连接构成。包含三个方面: 神经元的激活规则 主要是指神经元输入…

PDF文件提示-文档无法打印-的解决办法

背景信息 下载了几个签名的PDF文件,想要打印纸质版,结果打印时 Adobe Acrobat Reader 提示【文档无法打印】: 解决办法 网上的方案是使用老版本的PDF阅读器, 因为无法打印只是一个标识而已。 PDF文件不能打印的五种解决方案-zhihu 这些方…

docker容器间基于bridge双向通信

前面介绍了通过link实现容器间的单向通信: docker容器间基于Link单向通信-CSDN博客 情景概述 通过前面已经知道了设置link来达到容器间通过容器名称双向通信,那是不是可以通过每个容器都设置link来达到双向通信,这种方式实现起来太麻烦&…

前端如何判断多个请求完毕

在前端开发中,经常会遇到需要同时发起多个异步请求,并在所有请求都完成后再进行下一步操作的情况。 这里有几个常用的方法来实现这一需求: 使用 Promise.all() Promise.all() 方法接收一个 Promise 对象的数组作为参数,当所有的…

云备份项目--服务端编写

文章目录 7. 数据管理模块7.1 如何设计7.2 完整的类 8. 热点管理8.1 如何设计8.2 完整的类 9. 业务处理模块9.1 如何设计9.2 完整的类9.3 测试9.3.1 测试展示功能 完整的代码–gitee链接 7. 数据管理模块 TODO: 读写锁?普通锁? 7.1 如何设计 需要管理…

exam0-试卷整理

exam0-试卷整理 2010,2013是梦开始的地方,大概率会出原题的 2010 2013 2015 大题 manchester RIP更新 说出ISO与TCP/IP模型的相同点和不同点(8分) 相似: 两者都有层次,网络专业人员都需要知道二者&a…

ACL---访问控制列表---策略

在路由器流量流入或者流出的接口上匹配流量,之后执行设定好的动作---permit(允许)deny(拒绝) 1.访问控制: 在路由器流量流入或者流出的接口上匹配流量,之后执行设定好的动作---permit&#xf…