學生選課系統專案開發
1.專案需求
1. 創建北京、上海 2 所學校
2. 創建linux , python , go 3個課程 , linux\py 在北京開, go 在上海開
3. 課程包含,周期,價格,通過學校創建課程
4. 通過學校創建班級, 班級關聯課程、講師
5. 創建學員時,選擇學校,關聯班級
6. 創建講師角色時要關聯學校,
7. 提供兩個角色介面,一個管理介面
2.專案分析
各部分需要完成的任務
管理員視圖:
1. 注冊
2. 登錄
3. 創建講師
4. 創建學校
5. 創建學生
講師視圖:
1. 登錄
2. 講課
3. 查看學生成績
學生視圖:
1. 注冊
2. 登錄
3. 選擇課程
4. 查看分數
分析:
- 和上一個atm相似.本專案也是采用用戶層. 介面層. 資料庫層三層架構
- 代碼中要用到面向物件編程寫. 具體的代碼邏輯如下圖
檔案夾結構預覽:

3.代碼部分
本文篇幅較長. 可使用導航欄點擊標題部分查看:
bin檔案夾
start.py
# -*- encoding:utf-8 -*- # @time: 2022/7/22 10:20 # @author: Maxs_hu import os import sys BASE_PATH = os.path.dirname(os.path.dirname(__file__)) sys.path.append(BASE_PATH) # 直接將專案根目錄加上. 后面全部可以直接呼叫. 一勞永逸 from core.src import run if __name__ == '__main__': run()
conf檔案夾
settings.py
# -*- encoding:utf-8 -*- # @time: 2022/7/22 10:36 # @author: Maxs_hu import os BASE_PATH = os.path.dirname(os.path.dirname(__file__)) DB_PATH = os.path.join(BASE_PATH, 'db') SCHOOL_DB_PATH = os.path.join(DB_PATH, 'school')
core檔案夾
admin.py
# -*- encoding:utf-8 -*- # @time: 2022/7/22 10:37 # @author: Maxs_hu from interface import common_interface, admin_interface from lib import common # 設定用戶登錄狀態 admin_status = { "name": None } def admin_register(): while True: print('管理員注冊') username = input('請輸入用戶名>>>').strip() password = input('請輸入密碼>>>').strip() if password: flag, msg = admin_interface.admin_register_interface(username, password) # 調介面 if not flag: print(msg) else: print(msg) break def admin_login(): while True: print('管理員登錄') username = input('請輸入用戶名>>>').strip() password = input('請輸入密碼>>>') if admin_status['name'] == username: print('已登錄完成. 無需重復登錄') break if password: flag, msg = common_interface.login_interface(username, password, 'admin') # 調介面 if not flag: print(msg) else: admin_status["name"] = username print(msg) break @common.auth_login(user_type='admin') def create_teacher(): print('創建講師') teacher_name = input('請輸入老師名稱>>>').strip() teacher_password = input('請設定老師密碼>>>').strip() if teacher_name: flag, msg = admin_interface.create_teacher_interface(admin_status['name'], teacher_name, teacher_password) if flag: print(msg) else: print(msg) else: print('老師名不能為空') @common.auth_login(user_type='admin') def create_school(): print('創建學校') school = input('請輸入學校名稱>>>').strip() addr = input('請輸入學校地址>>>').strip() if school: flag, msg = admin_interface.create_school_interface(admin_status['name'], school, addr) if flag: print(msg) else: print(msg) else: print('學校名稱不能為空') @common.auth_login(user_type='admin') def create_course(): while True: print('創建課程') # 先查看學校. 再創建課程. 最后在學校中添加課程 school_list = common_interface.check_school_interface() for i, school in enumerate(school_list): print("%s: %s" % (i+1, school)) choice = input('請輸入需要選擇的校區>>>').strip() course_name = input('請輸入需要添加的課程>>>').strip() course_fee = input('請輸入課程費用>>>').strip() if choice.isdigit(): choice = int(choice) if 0 < choice <= len(school_list): flag, msg = admin_interface.create_course_interface(admin_status['name'], course_name, course_fee, school_list[choice-1]) if flag: print(msg) break else: print(msg) else: print('請輸入有效數字') else: print('請輸入數字') func_dic = { '1': admin_register, '2': admin_login, '3': create_teacher, '4': create_school, '5': create_course, } def admin_view(): while True: print(""" 1. 注冊 2. 登錄 3. 創建講師 4. 創建學校 5. 創建課程 """) choice = input('請輸入的業務序號(q退出)>>>').strip() if choice not in func_dic: print('沒有業務資訊') break if choice == "q": break func_dic[choice]()src.py
# -*- encoding:utf-8 -*- # @time: 2022/7/22 10:37 # @author: Maxs_hu from core import admin, student, teacher identify_dic = { "1": admin.admin_view, "2": teacher.teacher_view, "3": student.student_view, } def run(): while 1: print(""" >>>歡迎進入選課系統<<< 1. 管理員 2. 講師 3. 學生 """) choice = input('請輸入身份(q退出)>>>').strip() if choice == 'q': print('選課系統已關閉') break if not choice in identify_dic: print('無相關身份') break identify_dic[choice]() # 直接加括號呼叫student.py
# -*- encoding:utf-8 -*- # @time: 2022/7/22 10:37 # @author: Maxs_hu from interface import student_interface, common_interface from lib import common # 用戶登錄狀態 student_status = { 'name': None } def student_register(): print('學生注冊') while True: username = input('請輸入用戶名>>>').strip() password = input('請輸入密碼>>>').strip() if password: flag, msg = student_interface.student_register_interface(username, password) if flag: print(msg) break else: print(msg) else: print('用戶名或密碼不能為空') def student_login(): print('學生登錄') while True: username = input('請輸入用戶名>>>').strip() password = input('請輸入密碼>>>').strip() if student_status['name'] == username: print('已登錄完成. 無需重復登錄') break if password: flag, msg = common_interface.login_interface(username, password, 'student') if flag: student_status['name'] = username print(msg) break else: print(msg) else: print('用戶名和密碼不能為空') @common.auth_login(user_type='student') def choose_school(): while True: print('選擇學校') school_list = student_interface.check_all_school_interface() for i, school in enumerate(school_list): print('%s: %s' % (i+1, school)) choice = input('請輸入你想選擇的學校>>>').strip() if choice.isdigit(): choice = int(choice) if 0 < choice <= len(school_list): flag, msg = student_interface.choose_school_interface(student_status['name'], school_list[choice-1]) print(msg) break else: print('請輸入有效數字') else: print('請輸入數字') @common.auth_login(user_type='student') def choose_course(): while True: print('選擇課程') # 先查看可以選擇的課程. 在進行選課 flag, msg = student_interface.check_avaliable_course_interface(student_status['name']) if flag: for i, course in enumerate(msg): print('%s: %s' % (i+1, course)) choice = input('請輸入你想選擇的課程>>>').strip() if choice.isdigit(): choice = int(choice) if 0 < choice <= len(msg): flag, msg = student_interface.choose_course_interface(student_status['name'], msg[choice-1]) if flag: print(msg) break else: print(msg) else: print('請輸入有效數字') else: print('請輸入數字') else: print('沒有可以選擇的課程') break @common.auth_login(user_type='student') def check_score(): print('查看成績') flag, msg = student_interface.check_score_interface(student_status['name']) print(msg) func_dic = { '1': student_register, '2': student_login, '3': choose_school, '4': choose_course, '5': check_score, } def student_view(): while True: print(''' 1 注冊 2 登錄 3 選擇學校 4 選擇課程 5 查看成績 ''') choice = input('請選擇辦理的業務>>>').strip() if choice not in func_dic: print('無此業務') break func_dic[choice]()teacher.py
# -*- encoding:utf-8 -*- # @time: 2022/7/22 10:37 # @author: Maxs_hu from interface import teacher_interface, common_interface from lib import common # 用戶狀態 teacher_status = { 'name': None } def teacher_register(): print('講師注冊') while True: username = input('請輸入用戶名>>>').strip() password = input('請輸入密碼>>>').strip() if password: flag, msg = teacher_interface.teacher_register_interface(username, password) if flag: print(msg) break else: print(msg) else: print('用戶名和密碼不能為空') def teacher_login(): print('講師登錄') while True: username = input('請輸入用戶名>>>').strip() password = input('請輸入密碼>>>').strip() if teacher_status['name'] == username: print('已登錄完成. 無需重復登錄') break if password: flag, msg = common_interface.login_interface(username, password, 'teacher') if flag: teacher_status['name'] = username print(msg) break else: print(msg) else: print('用戶名或密碼不能為空') @common.auth_login(user_type='teacher') def choose_course(): while True: print('選擇課程') # 先查看所有的課程. 在添加課程到teacher類中 course_list = teacher_interface.choose_course_interface() for i, course in enumerate(course_list): print('%s: %s' % (i+1, course)) choice = input('請輸入你想選擇的課程>>>').strip() if choice.isdigit(): choice = int(choice) if 0 < choice <= len(course_list): flag, msg = teacher_interface.add_course_interface(teacher_status['name'], course_list[choice-1]) if flag: print(msg) break else: print(msg) else: print('請輸入有效數字') else: print('請輸入數字') @common.auth_login(user_type='teacher') def check_course(): while True: print('查看課程') course_list = teacher_interface.check_course_interface(teacher_status['name']) if course_list: for course in course_list: print(course) break else: print("請先選擇課程") @common.auth_login(user_type='teacher') def check_student(): while True: print('查看學生') # 先查看課程. 再查看課程對應的學生 course_list = teacher_interface.check_course_interface(teacher_status['name']) for i, course in enumerate(course_list): print('%s: %s' % (i+1, course)) choice = input('請選擇想要查看的課程.課程對應的學生會被回傳>>>').strip() if choice.isdigit(): choice = int(choice) if 0 < choice <= len(course_list): student_list = teacher_interface.check_student_interface(course_list[choice-1]) if student_list: for student in student_list: print(student) break else: print('暫時沒有學生') break else: print('請輸入有效的數字') else: print('請輸入數字') @common.auth_login(user_type='teacher') def modify_score(): while True: print('修改學生成績') # 先查看課程. 再查看課程對應的學生. 在對學生進行打分 course_list = teacher_interface.check_course_interface(teacher_status['name']) for i, course in enumerate(course_list): print('%s: %s' % (i + 1, course)) choice = input('請選擇想要查看的課程.課程對應的學生會被回傳>>>').strip() if choice.isdigit(): choice = int(choice) if 0 < choice <= len(course_list): course = course_list[choice-1] student_list = teacher_interface.check_student_interface(course) if student_list: for i, student in enumerate(student_list): print('%s: %s' % (i + 1, student)) choice = input('請輸入學生名稱并對其進行打分>>>').strip() score = int(input('請輸入要打的分數>>>').strip()) if choice.isdigit(): choice = int(choice) if 0 < choice <= len(student_list): flag, msg = teacher_interface.modify_score_interface(student_list[choice-1], course, score, ) print(msg) break else: print('請輸入有效數字') else: print('請輸入數字') else: print('暫時沒有學生') else: print('請輸入有效的數字') else: print('請輸入數字') func_dic = { '1': teacher_register, '2': teacher_login, '3': choose_course, '4': check_course, '5': check_student, '6': modify_score } def teacher_view(): while True: print(""" 1. 注冊 2. 登錄 3. 選擇課程 4. 查看課程 5. 查看學生 6. 修改學生成績 """) choice = input('請輸入想要辦理的業務>>>').strip() if choice not in func_dic: print('無此業務') break func_dic[choice]()
db檔案夾
db_handler.py
# -*- encoding:utf-8 -*- # @time: 2022/7/22 13:44 # @author: Maxs_hu from conf import settings import os import pickle def save(obj): db_dir = settings.DB_PATH db_path = os.path.join(db_dir, obj.__class__.__name__.lower()) # /admin if not os.path.exists(db_path): os.makedirs(db_path) # 創建檔案夾 detail_path = os.path.join(db_path, obj.name) with open(detail_path, 'wb') as f: pickle.dump(obj, f) # 直接將物件寫到pickle中 f.flush() # 刷入硬碟 def select(name, type_dir): db_dir = settings.DB_PATH db_path = os.path.join(db_dir, type_dir) if not os.path.exists(db_path): os.makedirs(db_path) # 創建檔案夾 detail_path = os.path.join(db_path, name) if os.path.exists(detail_path): # 判斷檔案夾是否存在 with open(detail_path, 'rb') as f: return pickle.load(f) # 將查詢到的資訊回傳 else: return Nonemoudle.py
# -*- encoding:utf-8 -*- # @time: 2022/7/22 13:44 # @author: Maxs_hu from db import db_handler class BaseClass: def save(self): db_handler.save(self) @classmethod def get_obj_by_name(cls, name): return db_handler.select(name, cls.__name__.lower()) # 直接將類的名字進行傳參 class Admin(BaseClass): def __init__(self, name, password): self.name = name self.password = password self.save() # 這樣將Admin實體化可以直接呼叫保存功能 # 管理員功能設定 def create_teacher(self, name, password): # 直接初始化一個類即可 Teacher(name, password) def create_school(self, name, addr): School(name, addr) def create_course(self, name, fee): Course(name, fee) class Teacher(BaseClass): def __init__(self, name, password): self.name = name self.password = password self.course_list = [] self.save() def add_course(self, name): self.course_list.append(name) self.save() class Student(BaseClass): def __init__(self, name, password): self.name = name self.password = password self.school = None self.score = {} self.course_list = [] self.save() def choose_school(self, school): self.school = school self.save() def get_school(self): return self.school def choose_course(self, course): self.course_list.append(course) self.score[course] = 0 # 初始化為0分 self.save() def modify_score(self): self.save() class School(BaseClass): def __init__(self, name, addr): self.name = name self.addr = addr self.course_list = [] self.save() def add_course(self, name): # 課程和學校系結 self.course_list.append(name) self.save() class Course(BaseClass): def __init__(self, name, fee): self.name = name self.fee = fee self.student_list = [] self.save() def add_student(self, name): self.student_list.append(name) self.save() # 這里存在一個報錯案例: 原因在于我程式沒撰寫完成之前做了測驗. 后期填寫的屬性都沒有在已保存的型別中. 導致報錯no attribute
interface檔案夾
admin_interface.py
# -*- encoding:utf-8 -*- # @time: 2022/7/22 14:21 # @author: Maxs_hu from db import moudle def admin_register_interface(username, password): admin_obj = moudle.Admin.get_obj_by_name(username) if admin_obj: return False, '管理員已注冊' else: moudle.Admin(username, password) # 直接實體化__init__觸發save() return True, f'{username}已注冊' def create_teacher_interface(username, teacher_name, teacher_password): teacher_obj = moudle.Teacher.get_obj_by_name(teacher_name) # 查看老師是否存在 if teacher_obj: return False, '老師已存在' else: obj = moudle.Admin.get_obj_by_name(username) obj.create_teacher(teacher_name, teacher_password) # 通過物件呼叫系結物件 return True, f'{teacher_name}創建完成' def create_school_interface(username, school_name, school_addr): school_obj = moudle.School.get_obj_by_name(school_name) # 判斷學校是否存在 if school_obj: return False, '學校已經存在' else: obj = moudle.Admin.get_obj_by_name(username) obj.create_school(school_name, school_addr) return True, f'{school_name}創建完成' def create_course_interface(username, course_name, course_fee, school): course_obj = moudle.Course.get_obj_by_name(course_name) if course_obj: return False, '課程已存在' else: # 先創建課程 obj = moudle.Admin.get_obj_by_name(username) obj.create_course(course_name, course_fee) # 將課程和學校系結 school_obj = moudle.School.get_obj_by_name(school) school_obj.add_course(course_name) return True, f'{course_name}創建完成'student_interface.py
# -*- encoding:utf-8 -*- # @time: 2022/7/22 17:11 # @author: Maxs_hu from db import moudle import os from conf import settings def student_register_interface(username, password): student_obj = moudle.Student.get_obj_by_name(username) if student_obj: return False, '該用戶已存在' else: moudle.Student(username, password) return True, f'{username}已注冊' def check_all_school_interface(): db_path = settings.DB_PATH school_path = os.path.join(db_path, 'school') if os.path.exists(school_path): return os.listdir(school_path) else: return '請聯系管理員創建學校' def choose_school_interface(username, school): student_obj = moudle.Student.get_obj_by_name(username) student_obj.choose_school(school) return True, '學校選擇完畢' def check_score_interface(username): obj = moudle.Student.get_obj_by_name(username) score = obj.score if score: return True, score else: return False, '請聯系老師進行打分' def check_avaliable_course_interface(username): student_obj = moudle.Student.get_obj_by_name(username) school = student_obj.get_school() if school: school_obj = moudle.School.get_obj_by_name(school) return True, school_obj.course_list else: return False, '請先選擇學校' def choose_course_interface(username, course): obj = moudle.Student.get_obj_by_name(username) if course in obj.course_list: return False, '您已選過該課程' obj.choose_course(course) course_obj = moudle.Course.get_obj_by_name(course) course_obj.add_student(username) return True, '選課成功'teacher_interface.py
# -*- encoding:utf-8 -*- # @time: 2022/7/22 17:11 # @author: Maxs_hu from db import moudle from conf import settings import os def teacher_register_interface(username, password): if moudle.Teacher.get_obj_by_name(username): return False, '用戶已存在' else: moudle.Teacher(username, password) return True, f'{username}用戶已注冊' def choose_course_interface(): path = settings.DB_PATH course_path = os.path.join(path, 'course') if os.path.exists(course_path): course_list = os.listdir(course_path) return course_list else: return '請聯系管理員創建課程' def add_course_interface(username, course): teacher_obj = moudle.Teacher.get_obj_by_name(username) if course in teacher_obj.course_list: return False, '該課程已經選過了' else: teacher_obj.add_course(course) return True, f'{course}選擇完成' def check_course_interface(name): teacher_obj = moudle.Teacher.get_obj_by_name(name) return teacher_obj.course_list def check_student_interface(course): obj = moudle.Course.get_obj_by_name(course) return obj.student_list def modify_score_interface(name, course, score): student_obj = moudle.Student.get_obj_by_name(name) student_obj.score[course] = score student_obj.modify_score() return True, '打分完成'common_interface.py
# -*- encoding:utf-8 -*- # @time: 2022/7/22 21:23 # @author: Maxs_hu from db import moudle import os from conf import settings def login_interface(name, password, user_type): global obj if user_type == "admin": obj = moudle.Admin.get_obj_by_name(name) # 直接拿到admin的物件. 方便后面呼叫 elif user_type == "teacher": obj = moudle.Teacher.get_obj_by_name(name) elif user_type == "student": obj = moudle.Student.get_obj_by_name(name) else: return False, '沒有這個用戶型別' if obj: if obj.password == password: return True, '%s登錄成功' % name else: return False, '密碼錯誤' else: return False, '用戶不存在' def check_school_interface(): school_path = settings.SCHOOL_DB_PATH if os.path.exists(school_path): school_list = os.listdir(school_path) return school_list else: return None
lib檔案夾
common.py
# -*- encoding:utf-8 -*- # @time: 2022/7/22 10:36 # @author: Maxs_hu # 寫一個加參裝飾器 def auth_login(user_type): from core import admin, teacher, student # 在區域變數內匯入. 每次需要時才使用. 防止交叉呼叫 def auth(func): def wrapper(*args, **kwargs): if user_type == 'admin': if not admin.admin_status['name']: admin.admin_login() # 直接呼叫登錄介面進行登錄 else: res = func(*args, **kwargs) return res elif user_type == 'student': if not student.student_status['name']: student.student_login() else: return func(*args, **kwargs) elif user_type == 'teacher': if not teacher.teacher_status['name']: teacher.teacher_login() else: return func(*args, **kwargs) else: raise TypeError('沒有此型別') return wrapper return auth
4.運行效果及總結



以上是部分運行截圖. 在代碼完成過后還發生過一些錯誤:
- 最后測驗的時候一直報類的no attribute. 找了半天發現原因是在編程中途存的資料. 在那個類中還沒有存放那個屬性. 所以一定要注意在程式開發中 -> 之前的測驗資料可能跟后期的不匹配
- 程式健壯性問題: 一個程式可能有很多中報錯的型別. 這就需要在編程的時候足夠細心. 盡量將報錯方式都想到. 實在不行可以使用try...except捕獲例外
- 變數及程式命名問題: 如果命名出現相同可能會導致程式之間發生交叉呼叫. 我們要盡量避免這種命名相同. 讓每一個變數都有自己的獨特的含義
- 資料儲存問題: 每一次呼叫到資料庫中的類去改變資料之后不能僅僅只是表面上改變. 而要去調永db_handler中的save方法. 將資料保存到本地地址里面. 這樣后面在使用的時候才會有記錄
- 最后一個就是程式之間的呼叫一定要邏輯清晰. 稍有不慎可能就調錯了類或者傳錯了名字. 這就需要程式命名可讀性高. 編碼的時候保持細心. 思路清晰.
本文來自博客園,作者:{Max},僅供學習和參考
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/500170.html
標籤:其他
上一篇:Python 實作貪心演算法

