# -*- 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('發生未知錯誤,請聯系管理員改進')