module05-2-学员管理系统
Posted jailly
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了module05-2-学员管理系统相关的知识,希望对你有一定的参考价值。
需求
主题:学员管理系统
需求:
用户角色,讲师\学员, 用户登陆后根据角色不同,能做的事情不同,分别如下
讲师视图
管理班级,可创建班级,根据学员qq号把学员加入班级
可创建指定班级的上课纪录,注意一节上课纪录对应多条学员的上课纪录, 即每节课都有整班学员上, 为了纪录每位学员的学习成绩,需在创建每节上课纪录是,同时 为这个班的每位学员创建一条上课纪录
为学员批改成绩, 一条一条的手动修改成绩
学员视图
提交作业
查看作业成绩
一个学员可以同时属于多个班级,就像报了Linux的同时也可以报名Python一样, 所以提交作业时需先选择班级,再选择具体上课的节数
附加:学员可以查看自己的班级成绩排名
实现需求
1. 实现全部需求
目录结构
学员管理系统
├ bin # 执行文件目录
| └ student_management.py # 执行程序
├ conf # 配置文件目录
| └ setting.py # 配置文件,目前主要保存mysql数据库相关信息
└ core # 程序核心代码位置
├ main.py # 主交互逻辑
├ orm_base.py # 构建映射mysql相关table的类
├ student.py # 学员接口的交互逻辑
└ teacher.py # 讲师接口的交互逻辑
代码
1 #! /usr/bin/env python3 2 # -*- coding:utf-8 -*- 3 # Author:Jailly 4 5 import os,sys 6 7 BasePath = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 8 sys.path.insert(0,BasePath) 9 10 from core import main 11 12 main.main()
1 db_user = ‘jailly‘ 2 # db_user = ‘root‘ 3 db_password = ‘123456‘ 4 db_host = ‘192.168.18.244‘ 5 # db_host = ‘localhost‘ 6 db_port = 3306 7 db_name = ‘student_management‘
1 #! /usr/bin/env python3 2 # -*- coding:utf-8 -*- 3 # Author:Jailly 4 5 import os,sys 6 7 BasePath = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 8 sys.path.insert(0,BasePath) 9 10 from core import teacher 11 from core import student 12 13 14 def main(): 15 while 1: 16 print(‘‘‘Interface: 17 1.Teacher 18 2.Student‘‘‘) 19 20 role = input(‘Please select your identity:‘).strip() 21 22 if role == ‘1‘: 23 teacher.main() 24 elif role == ‘2‘: 25 student.main() 26 else: 27 print(‘\033[1;31mThe identity that you chose does not exist,please select again\033[0m‘) 28 29 if __name__ == ‘__main__‘: 30 main()
1 #! /usr/bin/env python3 2 # -*- coding:utf-8 -*- 3 # Author:Jailly 4 5 import sqlalchemy 6 import os 7 import sys 8 from sqlalchemy import create_engine,Column,String,Integer,Enum,and_,or_,func,ForeignKey 9 from sqlalchemy.ext.declarative import declarative_base 10 from sqlalchemy.orm import sessionmaker,relationship 11 12 BasePath = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 13 sys.path.insert(0,BasePath) 14 15 from conf import setting 16 db_user = setting.db_user 17 db_password = setting.db_password 18 db_host = setting.db_host 19 db_port = setting.db_port 20 db_name = setting.db_name 21 22 engine = create_engine(‘mysql+pymysql://%s:%[email protected]%s:%s/%s?charset=utf8‘%(db_user,db_password,db_host,db_port,db_name), 23 encoding = ‘utf-8‘, 24 echo=False) 25 26 Base = declarative_base() 27 28 class Student(Base): 29 __tablename__ = ‘student‘ 30 id = Column(Integer,primary_key=True) 31 _class = Column(String(64),nullable=False) 32 qq = Column(Integer,nullable=False) 33 34 def __repr__(self): 35 return ‘%s , Class:%s , QQ:%s‘%(self.id,self._class,self.qq) 36 37 38 class StudyRecord(Base): 39 __tablename__ = ‘study_record‘ 40 id = Column(Integer,primary_key=True) 41 day = Column(Integer,nullable=False) 42 homework = Column(Enum(‘Y‘,‘N‘),nullable=False,default=‘N‘) 43 status = Column(Enum(‘Y‘,‘N‘),nullable=False,default=‘Y‘) 44 score = Column(Integer) 45 sid = Column(Integer,ForeignKey(‘student.id‘)) 46 47 student = relationship(‘Student‘,backref=‘study_record‘) 48 49 def __repr__(self): 50 return ‘%s , Day:%s , Status:%s , Score:%s , Sid:%s‘%(self.id,self.day,self.status,self.score,self.sid) 51 52 Base.metadata.create_all(bind=engine)
student.py
1 #! /usr/bin/env python3 2 # -*- coding:utf-8 -*- 3 # Author:Jailly 4 5 from sqlalchemy import and_ 6 from sqlalchemy.orm import sessionmaker 7 import os,sys 8 9 BasePath = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 10 sys.path.insert(0,BasePath) 11 12 from core import orm_base 13 14 SessionClass = sessionmaker(bind=orm_base.engine) 15 session = SessionClass() 16 17 18 def insert_student(_class): 19 ‘‘‘ 20 操作student表的函数之一,用来让讲师向班级中添加学员qq 21 :param _class: 班级名称,对应 student 表中的 _class 字段 22 :return: 23 ‘‘‘ 24 25 26 qqs = input(‘请输入您要添加的学员qq(指定多个qq,请以半角逗号分隔):‘).strip() 27 qqs = qqs.split(‘,‘) 28 for qq in qqs[:]: 29 qq = qq.strip() 30 if qq.isdigit(): 31 qq = int(qq) 32 if session.query(orm_base.Student).filter(and_(orm_base.Student._class == _class , orm_base.Student.qq == qq)) 33 .first(): 34 print(‘\033[1;31m警告:学员qq \033[1;32m%s\033[0m 在班级 \033[1;32m%s\033[0m 中已存在,请不要重复添加!\033[0m‘%(qq,_class)) 35 qqs.remove(qq) 36 else: 37 session.add(orm_base.Student(_class=_class,qq=qq)) 38 else: 39 print(‘\033[1;31m警告:%s 包含非数字字符,无法添加‘%qq) 40 qqs.remove(qq) 41 42 session.commit() 43 44 if qqs: # 只有当用户添加的学员qq中至少有一个班级中原本并不存在时,才打印以下提示信息 45 print(‘已向班级 \033[1;32m%s\033[0m 中成功添加学员qq:\033[1;32m%s\033[0m‘%(_class,‘,‘.join([qq.strip() for qq in qqs]))) 46 47 input(‘\n请输入回车键继续...‘) 48 49 def delete_student(_class): 50 ‘‘‘ 51 操作student表的函数之一,用来让讲师从班级中删除学员qq 52 :param _class: 班级名称,对应 student 表中的 _class 字段 53 :return: 54 ‘‘‘ 55 56 qqs = input(‘请输入您要删除的学员qq(指定多个qq,请以半角逗号分隔):‘).strip() 57 qqs = qqs.split(‘,‘) 58 for qq in qqs[:]: 59 qq = qq.strip() 60 61 # 虽然理论上一个班级里学员qq是唯一的,但为避免意外情况(如不是通过本程序而是直接操作mysql向同一个班级里添加了2个相同的qq),这里取能够查 62 # 询到的所有结果组成的列表 63 students = session.query(orm_base.Student).filter(and_(orm_base.Student._class == _class , orm_base.Student.qq 64 == qq)).all() 65 if students: 66 for student in students: 67 session.delete(student) 68 else: 69 print(‘\033[1;31m警告:班级 %s 中不存在 学员qq %s\033[0m‘%(_class,qq)) 70 qqs.remove(qq) 71 72 session.commit() 73 74 if qqs: # 只有当用户删除的学员qq中至少有一个班级中原本存在时,才打印以下提示信息 75 print(‘已从班级 \033[1;32m%s\033[0m 中成功删除学员qq:\033[1;32m%s\033[0m‘%(_class,‘,‘.join([qq.strip() for qq in qqs]))) 76 77 input(‘\n请输入回车键继续...‘) 78 79 80 def update_student(_class): 81 ‘‘‘ 82 操作student表的函数之一,用来让讲师修改班级中的学员qq 83 :param _class: 班级名称,对应 student 表中的 _class 字段 84 :return: 85 ‘‘‘ 86 87 old = input(‘原学员qq:‘).strip() 88 89 # 虽然理论上一个班级里学员qq是唯一的,但为避免意外情况(如不是通过本程序而是直接操作mysql向同一个班级里添加了2个相同的qq),这里取能够查 90 # 询到的所有结果组成的列表 91 students = session.query(orm_base.Student).filter(and_(orm_base.Student.qq == old , orm_base.Student._class == 92 _class)).all() 93 if students: 94 new = input(‘新学员qq:‘).strip() 95 for student in students: 96 student.qq = new 97 98 session.commit() 99 100 print(‘原学员qq: \033[1;32m%s\033[0m 已修改为 \033[1;32m%s\033[0m‘%(old,new)) 101 102 else: 103 print(‘\033[1;31m在班级 \033[1;32m%s\033[0m 中不存在学员qq:\033[1;32m%s\033[0m \033[0m‘%(_class,old)) 104 105 input(‘\n请输入回车键继续...‘) 106 107 108 def select_student(_class): 109 ‘‘‘ 110 操作student表的函数之一,用来让讲师查看班级中的学员qq 111 :param _class: 班级名称,对应 student 表中的 _class 字段 112 :return: 113 ‘‘‘ 114 115 qqs = session.query(orm_base.Student.qq).filter(orm_base.Student._class == _class).all() 116 print(‘班级 \033[1;32m%s\033[0m 中的所有学员qq:‘%_class) 117 for qq in qqs: 118 print(qq[0]) 119 120 input(‘\n请输入回车键继续...‘) 121 122 123 def class_manage(_class,scenes): 124 ‘‘‘ 125 整合了讲师管理班级的各种操作,通过调用对应的函数来实现对 student 表的增删改查 126 :param _class: 班级名称,对应 student 表中的 _class 字段 127 :param scenes: 调用场景,目前仅支持2个值。‘1’ 指代创建班级之后的调用场合;‘2‘ 指代手动选择‘管理班级‘选项之后的调用场合 128 :return: 129 ‘‘‘ 130 131 if scenes == 1: 132 print(‘班级 \033[1;32m%s\033[0m 已创建,现在您可以-->‘ % _class) 133 elif scenes == 2: 134 print(‘已选择班级 \033[1;32m%s\033[0m ,现在您可以-->‘ % _class) 135 136 while 1: 137 print(‘‘‘------- 管理班级 ------- 138 1.添加学员qq 139 2.删除学员qq 140 3.修改学员qq 141 4.查看学员qq 142 5.返回上一级 143 6.退出系统‘‘‘ 144 ) 145 146 choice = input(‘请选择:‘).strip() 147 if choice == ‘1‘: 148 insert_student(_class) 149 150 elif choice == ‘2‘: 151 delete_student(_class) 152 153 elif choice == ‘3‘: 154 update_student(_class) 155 156 elif choice == ‘4‘: 157 select_student(_class) 158 159 elif choice == ‘5‘: 160 if not session.query(orm_base.Student).filter(orm_base.Student._class == _class).all(): 161 if scenes == 1: 162 print(‘\033[1;31m%s 班中还未添加任何学员,该班级将不会创建\033[0m‘) 163 elif scenes == 2: 164 print(‘\033[1;31m%s 班中已没有任何学员,该班记录将自动删除\033[0m‘) 165 166 break 167 elif choice == ‘6‘: 168 if not session.query(orm_base.Student).filter(orm_base.Student._class == _class).all(): 169 if scenes == 1: 170 print(‘\033[1;31m%s 班中还未添加任何学员,该班级将不会创建\033[0m‘) 171 elif scenes == 2: 172 print(‘\033[1;31m%s 班中已没有任何学员,该班记录将自动删除\033[0m‘) 173 174 exit() 175 else: 176 print(‘该选项不存在,请重试!‘) 177 178 179 def create_record(_class,day): 180 ‘‘‘ 181 创建上课记录 182 :param _class: 班级名称,对应 student 表中的 _class 字段 183 :param day: 第几天,对应 study_record 表中的 day 字段 184 :return: 185 ‘‘‘ 186 187 ids = session.query(orm_base.Student.id).filter(orm_base.Student._class == _class).all() 188 records = [] 189 for id in ids: 190 records.append(orm_base.StudyRecord(day=day, sid=id[0])) 191 192 session.add_all(records) 193 session.commit() 194 195 196 def record_operation(type): 197 ‘‘‘ 198 整合了对上课记录的操作,包括创建上课记录和管理上课记录2种 199 :param type: 用来指定操作类型,目前仅支持2个值: ‘1‘.创建上课记录;‘2‘.管理上课记录 200 :return: 201 ‘‘‘ 202 203 # 第一级无限循环:选择班级和第几天 204 while 1: 205 class_dict = {} 206 _classes = session.query(orm_base.Student._class).group_by(orm_base.Student._class).all() 207 208 n = 1 209 print(‘---- 班级列表 ----‘) 210 for c in _classes: 211 print(‘%s.%s‘ % (n, c[0])) 212 class_dict[n] = c[0] 213 n += 1 214 print(‘‘) 215 216 choice_class = input(‘请选择班级:‘).strip() 217 day = input(‘请输入第几天:‘).strip() 218 219 if choice_class.isdigit(): 220 choice_class = int(choice_class) 221 222 if 1 <= choice_class < n: 223 _class = class_dict[choice_class] 224 225 # 创建上课记录 226 if type == 1: 227 228 if day.isdigit(): 229 original_records = session.query(orm_base.StudyRecord).filter(and_(orm_base.StudyRecord.day == 230 day,orm_base.StudyRecord.sid == orm_base.Student.id,orm_base.Student._class == _class)).all() 231 232 if original_records: 233 overwritten = input(‘班级 \033[1;32m%s\033[0m 第 \033[1;32m%s\033[0m 天的记录已存在,要覆盖吗?234 (\‘N\‘:不覆盖;其他:覆盖)‘% (_class, day)) 235 236 if overwritten.upper() == ‘N‘: 237 input(‘已放弃创建(按回车继续...)‘) 238 else: 239 for r in original_records: 240 session.delete(r) 241 242 create_record(_class,day) 243 input(‘已重新创建 \033[1;32m%s\033[0m 班第 \033[1;32m%s\033[0m 天的上课记录(按回车继续...)‘%(_class,day)) 244 245 else: 246 create_record(_class,day) 247 248 input(‘班级 \033[1;32m%s\033[0m 第 \033[1;32m%s\033[0m 天的上课记录已创建(输入回车键继续...)‘ % (_class, day)) 249 250 break 251 else: 252 print(‘\033[1;31m必须输入数字,请重试\033[0m‘) 253 254 # 修改上课记录 255 elif type == 2: 256 257 if day.isdigit(): 258 # records = session.query(orm_base.StudyRecord).filter(and_(orm_base.StudyRecord.day == day,orm_base.StudyRecord.sid == orm_base.Student.id,orm_base.Student._class == _class)).all() 259 records = session.query(orm_base.StudyRecord).join(orm_base.Student).filter(and_( 260 orm_base.Student._class == _class,orm_base.StudyRecord.day == day)).all() 261 if records: 262 263 # 第二级无限循环:显示选定的上课记录,让用户选择操作 264 while 1: 265 print(‘\n------- \033[1;32m%s\033[0m 班第 \033[1;32m%s\033[0m 天上课记录 -------- 266 \n序号 学员qq 第几天 出勤状态 成绩‘ %(_class, day)) 267 268 n = 1 269 record_dict = {} 270 for r in records: 271 print(str(n).ljust(8), 272 str(r.student.qq).ljust(8), 273 day.ljust(8), 274 (‘出勤‘ if r.status == ‘Y‘ else ‘缺勤‘).ljust(8), 275 str(r.score).ljust(8)) 276 record_dict[n] = r 277 n += 1 278 279 num_chosen = input(‘请选择您要修改的上课记录的序号(\‘b\‘:返回上一级;\‘q\‘:退出系统):‘).strip() 280 if num_chosen.isdigit(): 281 num_chosen = int(num_chosen) 282 if 1 <= num_chosen < n: 283 record_chosen = record_dict[num_chosen] 284 print(‘‘‘您想要: 285 1. 批改成绩 286 2. 修改出勤状态 287 3. 返回上一级 288 4. 退出系统 289 ‘‘‘) 290 291 operation_chosen = input(‘请选择:‘).strip() 292 293 # 批改成绩 294 if operation_chosen == ‘1‘: 295 while 1: 296 _score = input(‘请输入成绩:‘).strip() 297 if _score.isdigit(): 298 record_chosen.score = _score 299 session.commit() 300 301 print(‘已将 \033[1;32m%s\033[0m 班学员 \033[1;32m%s\033[0m 第 302 \033[1;32m%s\033[0m 天的成绩修改为 \033[1;32m%s\033[0m‘%(_class,record_chosen.student.qq,day,_score)) 303 304 input(‘\n按回车键继续...‘) 305 306 break 307 308 else: 309 print(‘\033[1;31m成绩必须为整数,请重新输入\033[0m‘) 310 311 312 # 修改出勤状态 313 elif operation_chosen == ‘2‘: 314 _status = input(‘将出勤状态修改为(N:缺勤;其他:出勤):‘).strip() 315 if _status.upper() == ‘N‘: 316 record_chosen.status = ‘N‘ 317 else: 318 record_chosen.status = ‘Y‘ 319 320 session.commit() 321 322 print(‘已将 \033[1;32m%s\033[0m 班学员 \033[1;32m%s\033[0m 第 323 \033[1;32m%s\033[0m 天的出勤状态修改为 \033[1;32m%s\033[0m‘%(_class,record_chosen.student.qq,day, 324 (‘出勤‘ if record_chosen.status == ‘Y‘ else ‘缺勤‘))) 325 326 327 elif operation_chosen == ‘3‘: 328 break 329 elif operation_chosen == ‘4‘: 330 exit() 331 else: 332 input(‘\033[1;31m您的选择不存在,请按回车键重试\033[0m‘) 333 334 else: 335 input(‘\033[1;31m您选择的上课记录不存在,请按回车键重试\033[0m‘) 336 337 elif num_chosen.lower() == ‘b‘: 338 break 339 elif num_chosen.lower() == ‘q‘: 340 exit() 341 else: 342 input(‘\033[1;31m必须输入整数,请按回车键重试\033[0m‘) 343 344 else: 345 print(‘\033[1;31m班级 %s 第 %s 天的上课记录不存在,请重试\033[0m‘%(_class,day)) 346 347 break 348 349 else: 350 print(‘\033[1;31m必须输入数字,请重试\033[0m‘) 351 352 else: 353 print(‘\033[1;31mtype参数错误,请检查函数调用\033[0m‘) 354 355 else: 356 print(‘\033[1;31m您选择的班级不存在,请重新输入\033[0m‘) 357 358 else: 359 input(‘\033[1;31m您选择的班级不存在,请按回车键重试\033[0m‘) 360 361 362 def main(): 363 while 1: 364 print(‘‘‘---------- Options ---------- 365 1.创建班级 366 2.管理班级 367 3.创建上课记录 368 4.管理上课记录 369 5.退出系统 370 ‘‘‘) 371 372 choice = input(‘请选择您的操作类型:‘).strip() 373 374 if choice == ‘1‘: 375 _class = input(‘请输入班级名称:‘).strip() 376 if session.query(orm_base.Student._class).filter(orm_base.Student._class == _class).first(): 377 print(‘班级 \033[1;32m%s\033[0m 已存在,请不要重复创建‘%_class) 378 elif _class: 379 class_manage(_class,1) 380 else: 381 print(‘\033[1;31m班级名称不能为空,请重新选择!\033[0m‘) 382 383 elif choice == ‘2‘: 384 while 1: 385 class_dict = {} 386 _classes = session.query(orm_base.Student._class).group_by(orm_base.Student._class).all() 387 388 n = 1 389 print(‘---- 班级列表 ----‘) 390 for c in _classes: 391 print(‘%s.%s‘%(n,c[0])) 392 class_dict[n] = c[0] 393 n += 1 394 print(‘‘) 395 396 operations = [‘返回上一级‘,‘退出系统‘] 397 for o in operations: 398 print(‘\033[1;32m%s\033[0m.\033[1;32m%s\033[0m‘ % (n, o)) 399 n += 1 400 401 choice_class = input(‘请选择班级:‘).strip() 402 403 if choice_class.isdigit(): 404 choice_class = int(choice_class) 405 if 1 <= choice_class < (n-2): 406 _class = class_dict[choice_class] 407 class_manage(_class,2) 408 elif choice_class == (n-2): 409 break 410 elif choice_class == (n-1): 411 exit() 412 else: 413 print(‘\033[1;31m您选择的班级不存在,请重新输入\033[0m‘) 414 415 else: 416 print(‘\033[1;31m您选择的班级不存在,请重新输入\033[0m‘) 417 418 419 elif choice == ‘3‘: 420 record_operation(type=1) 421 422 elif choice == ‘4‘: 423 record_operation(type=2) 424 425 elif choice == ‘5‘: 426 exit() 427 else: 428 print(‘\033[1;31mm该选项不存在,请重试!\033[0m‘) 429 430 431 if __name__ == ‘__main__‘: 432 main()
以上是关于module05-2-学员管理系统的主要内容,如果未能解决你的问题,请参考以下文章
解决go: go.mod file not found in current directory or any parent directory; see ‘go help modules‘(代码片段