# -*- coding: utf-8 -*- # @Time : 18-10-7 上午11:45 # @Author : Felix Wang ''' 选课系统开发 系统登录需要有三类用户:学生、管理员、讲师,针对不同用户提供不 同功能: 学生用户 :对于学生用户来说,登陆之后有三个功能 1、查看所有课程 2、选择课程 3、查看所选课程 4、删除已选课程 管理员用户:管理员用户除了可以做一些查看功能之外,还有很多创建工作。 1、创建课程 2、创建学生学生账号 3、查看所有课程 4、查看所有学生 5、查看所有学生的选课情况 讲师用户: 1、查看所有课程 2、选择所教课程 3、查看所教课程 4、删除所教课程 ''' from hashlib import md5 import shelve # 用来存储对象 import logging # 记录日志 STUDENTOBJ = 'stu_obj' ADMINOBJ = 'admin_obj' TEACHEROBJ = 'teacher_obj' COURSEOBJ = 'course_obj' # 用来存储操作日志 def my_log(logfile, partName, level): """ :param logfile: 日志文件名 :param partName: 项目名称,模块名称或者其他日志使用者 :param level: 日志等级 :return: logger object # CRITICAL = 50 # FATAL = CRITICAL # ERROR = 40 # WARNING = 30 # WARN = WARNING # INFO = 20 # DEBUG = 10 # NOTSET = 0 """ # 多文件日志处理 # 创建⼀个操作⽇志的对象logger(依赖FileHandler) file_handler = logging.FileHandler(logfile, 'a', encoding='utf-8') # 设置日志文件内容的格式 file_handler.setFormatter(logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(message)s")) logger = logging.Logger(partName, level=level) logger.addHandler(file_handler) return logger # 用来将密码加密 def encryption(pwd): """ :param pwd: 密码 :return: 密码加密后得到的md5值 """ flag = bytes('@#$%', encoding='utf8') if type(pwd) == type(str()): byte1 = flag + bytes(pwd, encoding='utf8') + flag # print(str(byte,'utf8')) elif type(pwd) == type(bytes()): byte1 = flag + pwd + flag else: raise Exception('必须是字符串或者字节') return md5(byte1).hexdigest() # 将对象存储 def saveObj(filename, obj): """ :param filename: 对象存储的文件名 :param obj: 对象 :return: """ with shelve.open(filename) as f: if hasattr(obj, 'userName'): f[obj.userName] = obj elif hasattr(obj, 'name'): f[obj.name] = obj # 获取对象 def getObj(filename, keyvalue=None): """ :param filename: 对象存储的文件名 :param keyvalue: 对象存的键 :return: 如果keyvalue为None,以字典形式返回文件中所有对象,如果keyvalue不为None,返回文件中对应的对象,如果不存在,返回None """ if keyvalue == None: dic = {} with shelve.open(filename) as f: for key in f: dic[key] = f[key] return dic else: with shelve.open(filename) as f: if keyvalue in f: return f[keyvalue] else: return None class Person: def __init__(self, userName, pwd): self.userName = userName self.__pwd = encryption(pwd) def login(self, userName, pwd): if self.userName == userName and self.__pwd == encryption(pwd): return True return False def showAllCourses(self): return getObj(COURSEOBJ) def __repr__(self): return self.userName class Student(Person): def __init__(self, userName, pwd): super().__init__(userName, pwd) self.courses = [] def __repr__(self): return '学生用户名:{}'.format(self.userName) # 查看选择的课程 def showCourses(self): return self.courses # 选择课程 def selectCourse(self, course): self.courses.append(course) # 删除课程 def removeCourse(self, course): self.courses.remove(course) class Admin(Person): # 创建学生 def createStudent(self, name, pwd): newStu = Student(name, pwd) saveObj(STUDENTOBJ, newStu) return True # 创建课程 def createCourse(self, name): course = Course(name) saveObj(COURSEOBJ, course) return True # 查看所有学生 def showAllStudents(self): return getObj(STUDENTOBJ) class Teacher(Person): def __init__(self, userName, pwd): super().__init__(userName, pwd) self.courses = [] # 选择要教课程 def selectCourse(self, course): self.courses.append(course) c = getObj(COURSEOBJ, course) c.setTeacher(self.userName) saveObj(COURSEOBJ, c) # 更新 # 查看所教的课程 def showCourses(self): return self.courses # 删除所教课程 def removeCourse(self, course): self.courses.remove(course) c = getObj(COURSEOBJ, course) c.setTeacher(None) saveObj(COURSEOBJ, c) # 更新 class Course: def __init__(self, name): self.name = name self.teacher = None def setTeacher(self, teacher): self.teacher = teacher def __repr__(self): return '课程名:{},讲师:{}'.format(self.name, self.teacher if self.teacher else '无') # 主程序 def main(): print('欢迎来到felix选课系统!') while True: while True: num1 = input('请选择用户类型:1:学生 2:管理员 3:讲师 q:退出\n:') if num1 in ['1', '2', '3', 'q', 'Q']: break else: print('输入有误,请重新输入') if num1 == '1': while True: while True: numStu = input('欢迎进入学生系统:请选择要执行的操作(1,登录 2、注册 b、返回上一级)\n:').strip() if numStu in ['1', '2', 'b', 'B']: break else: print('输入有误,请重新输入') if numStu == '2': print('正在注册...') while True: userName = input('请输入用户名:') if userName in getObj(STUDENTOBJ).keys(): print('用户名已存在,请重新输入') continue pwd = input('请输入密码:') break newStu = Student(userName, pwd) saveObj(STUDENTOBJ, newStu) print('注册成功') elif numStu == '1': print('正在登录...') userName = input('请输入用户名:') pwd = input('请输入密码:') stu = getObj(STUDENTOBJ, userName) if stu and stu.login(userName, pwd): print('登录成功') stulog = my_log('操作日志.log', 'stu-' + userName, 2) stulog.log(2, '学生{}登录'.format(userName)) while True: print('请选择需要执行的操作:') while True: numlogin = input('1、查看所有课程 2、选择课程 3、查看所选课程 4、删除已选课程 b、返回上一级\n:') if numlogin in ['1', '2', '3', '4', 'b', 'B']: break else: print('输入有误,请重新输入') if numlogin == '1': all_courses = stu.showAllCourses() print('当前的全部课程:{}'.format('' if all_courses else '无')) for k, v in all_courses.items(): print(v) stulog.log(2, '查看所有课程') elif numlogin == '2': all_courses = stu.showAllCourses() print('目前有如下课程:{}'.format('' if all_courses else '无')) if all_courses: for k, v in all_courses.items(): print(v) else: print() while True: courseName = input('请输入您要选择的课程名:').strip() if courseName not in all_courses.keys(): print('您输入的课程名不存在,请重新输入') else: break if courseName not in stu.showCourses(): stu.selectCourse(courseName) saveObj(STUDENTOBJ, stu) # 更新 print('课程选择成功') stulog.log(2, '选择了{}课程'.format(courseName)) else: print('课程已存在,不要重复选择') else: print('当前没有课程,不能选择') elif numlogin == '3': print('当前已选择的课程有:{}'.format('' if stu.showCourses() else '无')) for course in stu.showCourses(): c = getObj(COURSEOBJ, course) print(c) stulog.log(2, '查看了已经选择的课程') elif numlogin == '4': print('当前已选课程:{}'.format('' if stu.showCourses() else '无')) if stu.showCourses(): for course in stu.showCourses(): print(course, end=' ') else: print() while True: delCourseName = input('请输入需要删除的课程名:').strip() if delCourseName in stu.showCourses(): break else: print('您没有选择该课程,请重新输入') stu.removeCourse(delCourseName) saveObj(STUDENTOBJ, stu) # 更新 print('删除成功') stulog.log(2, '删除了{}课程'.format(delCourseName)) else: print('当前没有选择课程,不能删除') # / elif numlogin.upper() == 'B': stulog.log(2, '学生退出') break else: print('账号或密码错误') elif numStu.upper() == 'B': break elif num1 == '2': while True: while True: numStu = input('欢迎进入管理员系统:请选择要执行的操作(1,登录 2、注册 b、返回上一级)\n:') if numStu in ['1', '2', 'b', 'B']: break else: print('输入有误,请重新输入') if numStu == '2': print('正在注册...') while True: userName = input('请输入用户名:') if userName in getObj(ADMINOBJ).keys(): print('用户名已存在,请重新输入') continue pwd = input('请输入密码:') break newAdmin = Admin(userName, pwd) saveObj(ADMINOBJ, newAdmin) print('注册成功') elif numStu == '1': print('正在登录...') userName = input('请输入用户名:') pwd = input('请输入密码:') admin = getObj(ADMINOBJ, userName) if admin and admin.login(userName, pwd): print('登录成功') adminlog = my_log('操作日志.log', 'admin-' + userName, 2) adminlog.log(2, '管理员{}登录'.format(userName)) while True: print('请选择要执行的操作:') while True: numlogin = input('1、创建课程 2、创建学生学生账号 3、查看所有课程 4、查看所有学生 5、查看所有学生的选课情况 b、返回上一级\n:') if numlogin in ['1', '2', '3', '4', '5', 'b', 'B']: break else: print('输入有误,请重新输入') if numlogin == '1': while True: courseName = input('请输入课程名称:') if courseName in getObj(COURSEOBJ).keys(): print('课程已存在,请重新输入') continue break admin.createCourse(courseName) print('课程创建成功') adminlog.log(2, '创建了{}课程'.format(courseName)) elif numlogin == '2': print('正在创建学生账号...') while True: userName = input('请输入学生用户名:') if userName in getObj(STUDENTOBJ).keys(): print('用户名已存在,请重新输入') continue pwd = input('请输入密码:') break admin.createStudent(userName, pwd) print('学生账号创建成功') adminlog.log(2, '创建了{}学生'.format(userName)) elif numlogin == '3': all_courses = admin.showAllCourses() print('当前的全部课程:{}'.format('' if all_courses else '无')) for k, v in all_courses.items(): print(v) adminlog.log(2, '查看了当前的全部课程') elif numlogin == '4': all_student = admin.showAllStudents() for k, v in all_student.items(): print(v) adminlog.log(2, '查看了当前全部学生') elif numlogin == '5': all_student = admin.showAllStudents() for k, v in all_student.items(): print('学生用户名:{},选择的课程:{}'.format(str(k), str(v.showCourses() if v.showCourses() else '无'))) adminlog.log(2, '查看了全部学生的选课信息') elif numlogin.upper() == 'B': adminlog.log(2, '管理员退出') break else: print('账号或密码错误') elif numStu.upper() == 'B': break elif num1 == '3': while True: while True: numStu = input('欢迎进入讲师系统:请选择要执行的操作(1,登录 2、注册 b、返回上一级)\n:') if numStu in ['1', '2', 'b', 'B']: break else: print('输入有误,请重新输入') if numStu == '2': print('正在注册...') while True: userName = input('请输入用户名:') if userName in getObj(TEACHEROBJ).keys(): print('用户名已存在,请重新输入') continue pwd = input('请输入密码:') break newTeacher = Teacher(userName, pwd) saveObj(TEACHEROBJ, newTeacher) print('注册成功') elif numStu == '1': print('正在登录...') userName = input('请输入用户名:') pwd = input('请输入密码:') teacher = getObj(TEACHEROBJ, userName) if teacher and teacher.login(userName, pwd): print('登录成功') teacherlog = my_log('操作日志.log', 'teacher-' + userName, 2) teacherlog.log(2, '讲师{}登录'.format(userName)) while True: print('请选择需要执行的操作:') while True: numlogin = input('1、查看所有课程 2、选择所教课程 3、查看所教课程 4、删除所教课程 b、返回上一级\n:') if numlogin in ['1', '2', '3', '4', 'b', 'B']: break else: print('输入有误,请重新输入') if numlogin == '1': all_courses = teacher.showAllCourses() print('当前的全部课程:{}'.format('' if all_courses else '无')) for k, v in all_courses.items(): print(v) teacherlog.log(2, '查看了所有课程') elif numlogin == '2': all_courses = teacher.showAllCourses() print('目前有如下课程:{}'.format('' if all_courses else '无')) if all_courses: for k, v in all_courses.items(): print(v) else: print() while True: courseName = input('请输入您要教的课程名:').strip() if courseName not in all_courses.keys(): print('您输入的课程名不存在,请重新输入') else: break if courseName not in teacher.showCourses(): teacher.selectCourse(courseName) saveObj(TEACHEROBJ, teacher) # 更新 print('课程选择成功') teacherlog.log(2, '选择了教{}课程'.format(courseName)) else: print('您已选择该课程,不能重复选择') else: print('当前没有课程,无法选择') elif numlogin == '3': print('当前已选择的课程有:{}'.format('' if teacher.showCourses() else '无')) for course in teacher.showCourses(): c = getObj(COURSEOBJ, course) print(c) teacherlog.log(2, '查看了当前选择的课程') elif numlogin == '4': print('当前已选课程:{}'.format('' if teacher.showCourses() else '无')) if teacher.showCourses(): for course in teacher.showCourses(): print(course, end=' ') else: print() while True: delCourseName = input('请输入需要删除的课程名:').strip() if delCourseName in teacher.showCourses(): break else: print('您没有选择该课程,请重新输入') teacher.removeCourse(delCourseName) saveObj(STUDENTOBJ, teacher) # 更新 print('删除成功') teacherlog.log(2, '取消了教{}课程'.format(delCourseName)) else: print('当前没有教的课程,不能删除') elif numlogin.upper() == 'B': teacherlog.log(2, '讲师退出') break else: print('账号或密码错误') elif numStu.upper() == 'B': break elif num1.upper() == 'Q': print('感谢使用felix选课系统,欢迎下次使用!') break if __name__ == '__main__': try: main() except Exception as e: print('发生未知错误,请联系管理员改进')