[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…

5. C语言 常量与宏定义

本章目录: 前言一、什么是常量?1. 整型常量2. 浮点型常量3. 字符常量4. 字符串常量 二、如何定义常量?1. 使用 #define 宏定义2. 使用 const 关键字 三、#define 和 const 的区别四、使用建议1. 使用场景区分2. 避免宏定义的潜在问题 五、特殊用法与小技…

随机置矩阵列为0[矩阵乘法pytorch版]

文章目录 1. 举例:2. python 代码 1. 举例: A [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 ] , r a n d [ 0 , 5 , 2 ] → A [ 0 1 0 3 4 0 6 7 0 9…

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

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

uniapp实现后端数据i18n国际化

1.在main.js配置请求获取到数据再设置到i18n中, 我这里是通过后端接口先获取到一个多个数据的的json链接,通过链接再获取数据,拿到数据后通过遍历的方式设置i18n //接口数据示例:{"vi": "http://localhost:8899/…

关于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)

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

26.Java Lock 接口(synchronized 关键字回顾、可重入锁快速入门、Lock 对比 synchronized)

一、synchronized 关键字 1、synchronized 关键字回顾 synchronized 是 Java 中的关键字,是一种同步锁,它修饰的对象有以下几种 修饰一个类:其作用的范围是 synchronized 后面括号括起来的部分,作用的对象是这个类的所有对象 修…

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

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

云手机 —— 手机矩阵的 “超级外挂

如何打造手机矩阵 打造手机矩阵主要包括以下几个步骤: 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…

NLP 技术的突破与未来:从词嵌入到 Transformer

在过去的十年中,自然语言处理(NLP)经历了深刻的技术变革。从早期的统计方法到深度学习的应用,再到如今Transformer架构的普及,NLP 的发展不仅提高了模型的性能,还扩展了其在不同领域中的应用边界。 1. 词嵌…

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

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

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

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