[Python语言程序设计]课程选课系统
三人自由组合完成一个课程系统:系统包括学校、学员、课程、讲师和管理员等角色,详细要求如下描述所示:1. 创建武汉、长沙 2 所学校 (管理员创建学校)。2. 创建 Linux、Python、C 语言 3 门课程 , Linux、Python 在武汉开课, C 语言在长沙开课。3. 课程包含周期和价格(通过学校创建课程)。4. 提供两个角色接口:创建讲师、创建学员时需选择学校,并关联班级。5. 提供
文章目录
开发时间 | 开发环境 | 工程文件 |
---|---|---|
22/02/28 - 22/04/30 | PyCharm 2021.1.1 | course-selection |
一、快速开始
-
项目下载:点击下载 course-selection 工程压缩包到您的计算机来获取源代码。
-
打开工程:使用 PyCharm 开发工具打开解压的工程文件。
-
运行 main.py 系统入口文件即可启动项目。
二、任务描述
三人自由组合完成一个课程系统:系统包括学校、学员、课程、讲师和管理员等角色,详细要求如下描述所示:
- 创建武汉、长沙 2 所学校 (管理员创建学校)。
- 创建 Linux、Python、C 语言 3 门课程 , Linux、Python 在武汉开课, C 语言在长沙开课。
- 课程包含周期和价格(通过学校创建课程)。
- 提供两个角色接口:创建讲师、创建学员时需选择学校,并关联班级。
- 提供三个视图操作:
- 学员视图:可以注册,选择课程(等同于选择班级)。
- 讲师视图:讲师可管理自己的课程,上课时选择班级,查看班级学员列表 , 修改所管理的学员的成绩。
- 管理视图:创建讲师, 创建班级,创建课程。
- 上面的操作产生的数据都通过 pickle 序列化保存到文件里(pickle 可以帮我们保存对象)。
二、需求分析
2.1 管理视图
- 注册:
- 用户在视图层输入用户名与密码交给接口层。
- 接口层调用数据层的 models.select 进行校验。
- 若不存在,则创建,并将注册成功返回给用户视图层。
- 登录:
- 用户在视图层输入用户名与密码交给接口层。
- 接口层调用数据层的 models.select 进行校验。
- 若存在则校验密码,并将登录成功返回给用户视图层。
- 创建学校:
- 让用户输入学校名与学校地址。
- 调用管理员创建学校接口。
- 判断学校是否存在,若存在,不让创建。
- 若不存在,则调用接口层创建学校,获取对象的创建学校方法,保存学校。
- 将结果返回给视图层。
- 创建课程(先选择学校):
- 获取所有学校并打印,让用户选择。
- 获取用户选择的学校与创建的课程交给接口层。
- 接口层调用管理员对象中的创建课程方法,保存课程对象。
- 课程需要绑定给学校对象,最终将创建成功的结果返回给视图层。
- 创建讲师:
- 让用户输入老师的名称。
- 调用接口层,接口层中设置默认密码 123,调用数据层。
- 判断老师是否存在,不存在则调用管理员对象中的创建老师方法。
- 保存老师对象并将结果返回给视图层
2.2 学员视图
- 注册:
- 用户在视图层输入用户名与密码交给接口层。
- 接口层调用数据层的 models.select 进行校验。
- 若不存在,则创建,并将注册成功返回给用户视图层。
- 登录:
- 用户在视图层输入用户名与密码交给接口层。
- 接口层调用数据层的 models.select 进行校验。
- 若存在则校验密码,并将登录成功返回给用户视图层。
- 选择校区:
- 获取所有学校让学生选择,将选择的学校传给接口层。
- 接口层判断当前学生是否选择学校。
- 若没有选择,则调用学生对象中的添加学校方法。
- 将添加后的消息返回给视图层。
- 选择课程(先选择校区,再选择校区中的某一门课程),学生与课程互相选择:
- 先获取当前学生所在学校的所有课程并选择。
- 接口层将选择后的学生课程,调用数据层的添加课程方法,保存。
- 学生对象中的课程列表添加该课程,设置课程分数默认为 0。
- 最终将结果返回给视图层。
- 查看分数:
- 直接调用接口层。
- 接口层调用数据层的查看成绩方法。
- 返回成绩给视图层并打印。
2.3 讲师视图
- 登录:
- 用户在视图层输入用户名与密码交给接口层。
- 接口层调用数据层的 models.select 进行校验。
- 若存在则校验密码,并将登录成功返回给用户视图层。
- 查看授课课程:
- 直接调用接口层,获取老师对象下课程列表数据。
- 若有则打印,没有则退出。
- 选择教授课程:
- 调用接口层中的选择教授课程接口,调用数据层中该课程下所有的学生返回给视图层。
- 打印所有的课程让老师选择,若老师课程中有该课程则不让添加。
- 没有则调用老师中的添加课程方法进行添加。
- 查看课程下的学生名单:
- 直接获取老师对象下所有的课程,选择课程。
- 从老师对象中,调用查看课程下学生方法,获取课程对象下所有的学生,返回给视图层。
- 视图层打印,该课程下所有的学生。
- 修改学生分数:
- 直接获取老师对象下所有的课程,选择课程。
- 从老师对象中,调用查看课程下学生方法,获取课程对象下所有的学生,返回给视图层。
- 视图层打印,该课程下所有的学生,并让用户选择需要修改分数的学生。
- 调用老师修改分数接口,获取老师对象,调用对象中的修改分数方法。
- 获取学生对象中的 score_dict 分数字典进行修改。
三、模块设计
项目采用三层架构设计,基于面向对象封装角色数据和功能。面向过程和面向对象搭配使用。程序开始,用户选择角色,进入不同的视图层,展示每个角色的功能,供用户选择。进入具体角色视图后,调用功能,对接逻辑接口层获取数据并展示给用户视图层。逻辑接口层需要调用数据处理层的类,获取类实例化对象,进而实现数据的增删改查。
3.1 视图层
将视图层封装成视图类,之所以想要将视图层封装成视图类,主要是为了简化代码和避免手动编写用户的功能函数字典。
采用视图类之后,可以将功能函数做成视图类的对象的绑定方法,采用反射,可以自动获取并调用。
但这里需要做一个处理:用户选择角色后,如何获取并显示这个角色的功能函数函数列表?
这里需要在视图类里面做一个显示功能的方法 start(),这个方法要在用户选择先显示所有的功能,在此之前,还需要一个收集角色功能的方法 auto_get_func_menu(),这个函数必须在对象使用时就立即工作,最后,还要配合一个装饰器 my_func(),让收集函数知道搜集那些功能,保存下来 func_list(),让显示函数获取。
上述这个过程涉及的方法是每个视图类都要有的,因此抽象出来一个基础视图类 BaseViewer。最后,视图类需要用到一些公用工具 (lib/tool.py),将它封装成一个 ToolsMixin() 类,视图类继承之,方便传参。
3.2 逻辑接口层
3.3 数据处理层
- models.py:存放所有的类,包括学校类、学院类、课程类、讲师类和管理员类等。
- db_handler.py:用户保存对象与获取对象,存放 json 格式的数据。
3.4 角色类
从管理员、学生、老师角色中抽象出 Human 类,有用户基本数据属性和密码相关的公共属性。
为了方便角色数据的读取和保存,定义了一个接口类 FileMixin,用于对象数据的读取和保存。FileMixin 类中设置一个绑定类的方法,这样每个继承 FileMixin 的类都可以通过对象名判断这个对象的存在与否(多继承时遵循 Mixins 规范)。
对象初始化后立即保存数据,每个功能操作后,也跟一个 save_obj() 方法,这样类的调用起来较为方便。
在用户类中设置角色的方法属性,这样直接在逻辑接口层中在获取对象后,直接调用对象的方法即可。这样做是为了保证面向对象的完整性,每个对象都对应其现实意义。
3.5 登录
每个角色都有登录需求,因此应抽取一个公用的登录逻辑接口层。不过因为数据存放格式的限制,这里妥协一下。
每个登录视图层还是直接调用各自的登录逻辑接口,然后从各自的逻辑接口层中调用公用逻辑接口层的核心登录逻辑判断。
这里在角色的登录接口中做一个中转的目的是为了给登录用户设置一个登录角色。并且这个角色的字符串名字和类的名字保持一致,为了方便在公共登录接口中使用反射判断。
3.6 数据格式
将一个类实例化对象按照类型保存在不同的文件夹中,文件夹名与类名相同,文件名为对象的 name 属性的名字。
这样做的好处是方便对象数据的读取和保存,并且对象间没有使用组合的方式,避免数据的重复保存。但这样做也有着不足:每个类下面的对象不能重名。这个问题需要重新组织数据管理方式,让其更实际化。
# json 格式数据存放格式
{school:{course:{'teacher': teacher, 'grade': grade}}}
四、系统测试
4.1 管理员功能
-
管理员注册:
-
管理员登录:
-
管理员创建学校:
-
管理员创建课程:
-
管理员创建讲师:
4.2 教师功能
-
教师登录:
-
教师查看并添加授课课程:
-
教师查看课程学生名单(学生选择课程后操作有效):
-
教师修改学生课程分数(学生选择课程后操作有效):
4.3 学生功能
-
学生注册:
-
学生登录:
-
学生选择校区:
-
学生选择课程:
-
学生查看课程分数(教师修改学生课程分数后操作有效):
五、总结
对于刚学习 Python,拿到需求,首先要经过自己分析,确实搞不定了,可以查看一些优秀的代码学习总结归纳,从而转化为自己的能力。
对于写程序,实现逻辑思路是很重要的,写项目前一定要先分析需求,再构思设计,最后开始编码。
角色设计时,需要全面考虑角色之间的关系方便接口设计。基于反射可以做很多动态判断,避免使用 if-elif-else 多级判断。
三层架构的设计,明确每层职责,系统耦合度低,方便易开发。
六、参考文献
[1] 张艳,顾晨.实践课程网上选课系统的设计与实现[J].实验室研究与探索,2003(03):75-77.
[2] 韩春英. 高校选课系统的设计与实现[D].华东师范大学,2010.
[3] 盛蒙蒙. Python 程序设计课程综合实验案例设计[J]. 现代计算机, 2020, (20):70-73,95.
更多推荐
所有评论(0)