用python實現學生管理系統
阿新 • • 發佈:2020-07-28
學生管理系統
相信大家學各種語言的時候,練習總是會寫各種管理系統吧,管理系統主要有對資料的增刪查改操作,原理不難,適合作為練手的小程式
資料的結構
要儲存資料就需要資料結構,比如c裡面的結構體啊,python裡面的列表,字典,還有類都是常用的資料型別
在這裡,我使用了連結串列來作為學生資料的資料結構,
即 Node類 和 Student_LinkList類,來實現連結串列
資料的持久化
我們在程式中產生的資料是儲存在記憶體中的,程式一旦退出,下次就不能恢復此次的資料了,因此需要把記憶體種的資料,儲存到檔案或資料庫中,儲存起來,這個過程就叫資料的持久化
本程式使用了python標準庫pickle提供的序列化方法dump()和load()來實現資料的持久化
配置檔案
使用配置檔案,可以方便程式中使用不同的子類實現,
本程式使用configparser來對配置檔案解析
本程式配置檔名為 Student.ini
#Student.ini檔案 [Student] student = Student_LinkList [Persistence] persistence = Persistence_Pickle file = student.pik
類之間的關係
Student #和學生資料有關的抽象類
±- Student_LinkList
Persistence #和持久化有關的抽象類
±- Persistence_Pickle
MyConfigure #和配置檔案讀取有關的類
±- Cmd_UI
介面預覽
原始碼
''' 使用單鏈表實現的學生管理系統 ''' import pickle import abc import configparser class Student(abc.ABC): ''' 抽象學生類 ''' @abc.abstractmethod def add(self): ''' 增加學生結點 ''' pass @abc.abstractmethod def ladd(self): ''' 從左側增加學生結點 ''' pass @abc.abstractmethod def delete(self,id_): ''' 根據id值來刪除一個結點 ''' pass @abc.abstractmethod def delete_name(self,name): ''' 根據姓名來刪除一個結點 ''' pass @abc.abstractmethod def insert(self,idx,val): ''' 插入到指定的位置 ''' pass @abc.abstractmethod def show(self): ''' 顯示所有的學生結點 ''' pass @abc.abstractmethod def search_id(self): ''' 根據id查詢節點 ''' pass @abc.abstractmethod def search_name(self): ''' 根據name查詢節點 ''' @abc.abstractmethod def modity_id(self): ''' 根據id找到節點,然後修改 ''' pass class Node(object): ''' 學生連結串列結點 ''' def __init__(self,id_: int,name: str,sex: str,age: int,score: int): self.id = id_ self.name = name self.sex = sex self.age = age self.score = score self.next = None def modity(self,id_,name,sex,age,score): ''' 修改 ''' self.id = id_ self.name = name self.sex = sex self.age = age self.score = score def __str__(self): ''' 用於顯示輸出 ''' return f"[學生:{self.id:^2}]-->name:{self.name:^10}sex:{self.sex:^10}age:{self.age:^10}score:{self.score:^10}" class Student_LinkList(Student): ''' 學生連結串列 ''' def __init__(self): self.head = Node(-1,'head','-1',-1,-1) self.length = 0 self.tail = self.head #尾部結點用於尾插 def add(self,score): ''' 新增一個學生結點,尾插 ''' #print('當前tail的值',self.tail) temp = Node(id_,score) self.tail.next = temp self.tail = self.tail.next self.length += 1 print('[info]:新增成功') def ladd(self,score): ''' 新增一個學生,頭插 ''' temp = Node(id_,score) temp.next = self.head.next self.head.next = temp if self.tail == self.head: self.tail = temp self.length += 1 print('[info]:新增成功') def delete(self,id_): ''' 根據id值來刪除一個結點,用迭代實現 ''' p = self.head while p.next != None and p.next.id != id_: p = p.next if p.next == None: print('[error]:找不到id') return -1 else: temp = p.next p.next = temp.next #如果刪除的是尾結點,還要移動tail if temp.next == None: self.tail = p del temp print('[info]:刪除成功') def delete_name(self,name): ''' 根據姓名來刪除一個結點,用遞迴實現 ''' def _func(node: Node,name: str): ''' 遞迴函式 ''' #到了尾巴節點了,還沒有找到 if node.next == None: print('[info]:找不到name') return False elif node.next.name == name: temp = node.next node.next = temp.next #如果刪除的是尾結點,還要移動tail if temp.next == None: self.tail = node del temp print('[info]:刪除成功') return True else: return _func(node.next,name) t = self.head return _func(t,name) def insert(self,score): ''' 在指定位置插入資料 ''' if idx > self.length or idx == 0: print(f'[error]:你輸入的索引非法(1-{self.length})') return 0 p,cur = self.head,0 while p != None and cur < idx-1: p = p.next if cur < idx-1: return -1 else: temp = Node(id_,score) temp.next = p.next p.next = temp return True print('[info]:插入成功') def search_id(self,id_): ''' 根據id查詢節點 ''' p = self.head while p != None and p.id != id_: p = p.next if p == None: return -1 else: return p def search_name(self,name): ''' 根據name查詢節點 ''' p = self.head def _func(node: Node,name: str): ''' 遞迴函式 ''' if node == None: return -1 elif node.name == name: return node return _func(node.next,name) return _func(p,name) def modity_id(self,id0,score): ''' 根據id找到節點,然後修改 ''' node = self.search_id(id0) if node == -1: print('[error]:找不到該id') return -1 else: node.modity(id_,score) def show(self): ''' 顯示所有的學生結點,迭代 ''' print(f'\n{"-"*25}以下是系統內資料{"-"*25}') temp = [] p = self.head while p != None: temp.append(p) p = p.next return temp class Student_Array(): ''' 用陣列實現學生資料儲存 ''' pass class Student_Queue(): ''' 用佇列實現 ''' pass class Student_Dict(): ''' 用佇列實現 ''' pass class Persistence(abc.ABC): ''' 連結串列資料的持久化 ''' @abc.abstractmethod def save(self): ''' 把物件儲存 ''' pass @abc.abstractmethod def load(self): ''' 載入物件 ''' pass class Persistence_Pickle(Persistence): ''' 使用pickle來序列化 ''' def __init__(self,cls: Student,file_): self.filename = file_ self.obj = None self.cls = cls def save(self): with open(self.filename,'wb') as f: pickle.dump(self.obj,f) def load(self): try: with open(self.filename,'rb') as f: temp = pickle.load(f) except: temp = globals()[self.cls]() print('返回temp:',type(temp)) self.obj = temp return temp class Persistence_File(Persistence): ''' 使用檔案來持久化 ''' pass class Persistence_Mysql(Persistence): ''' 使用Mysql資料庫來持久化 ''' pass class Persistence_Socket(Persistence): ''' 使用遠端套接字持久化 ''' pass class MyConfigure(object): ''' 用來讀取配置檔案的類 ''' def __init__(self): self.config = configparser.ConfigParser() def save(self): ''' 儲存配置檔案 ''' with open('Student.ini','w') as f: self.config.write(f) def load(self): ''' 載入配置檔案 ''' self.config.read('Student.ini') def get_student_class(self): ''' 獲得Student該使用哪個子類 ''' return self.config['Student']['student'] def get_persistence_class(self): ''' 獲得持久化,該使用那個類, 如果是Pickle或檔案,還有file作為儲存的檔名 ''' temp = {} temp['persistence'] = self.config['Persistence']['persistence'] if 'Persistence_Pickle' in temp['persistence']: temp['file'] = self.config['Persistence']['file'] return temp class UI(object): ''' 介面互動 ''' def __init__(self): self.config = MyConfigure() self.config.load() s_class = self.config.get_student_class() p_class = self.config.get_persistence_class() self.persistence = globals()[p_class['persistence']](s_class,p_class['file']) self.student = self.persistence.load() print('例項化成功:',self.student,self.persistence) def save(self): ''' 把資料儲存 ''' self.persistence.save() def quit(self): ''' 退出:先儲存配置,然後退出 ''' self.config.save() self.save() def _show(self): ''' 顯示所有學生節點 ''' return self.student.show() def _add(self,direction,*temp): ''' 增加學生結點,direction 1左新增,2右新增 ''' if direction == 1: self.student.ladd(*temp) elif direction == 2: self.student.add(*temp) def _delete(self,attribute: int,val: str): ''' 刪除學生節點 attribute: 需要根據哪個屬性刪除,1.id 或 2.name ''' if attribute == 1: self.student.delete(val) elif attribute == 2: self.student.delete_name(val) def _insert(self,*temp): ''' 把學生節點插入到指定的位置 ''' self.student.insert(idx,*temp) def _search(self,attribute,val): ''' 查詢 ''' if attribute == 1: return self.student.search_id(val) elif attribute == 2: return self.student.search_name(val) def _modity(self,*temp): ''' 修改 ''' if attribute == 1: self.student.modity_id(id_,*temp) elif attribute == 2: print('[info]:因為沒實現,所以什麼也不做') pass #根據name修改沒有寫 class Cmd_UI(UI): ''' 命令列的互動介面 ''' def __init__(self): super(Cmd_UI,self).__init__() def get_input_1_2(self,info: str): ''' 獲得輸入,返回1或者2 info: 描述輸入的資訊 ''' x = None while x == None: temp = input(info) if temp == '1': x = 1 elif temp == '2': x = 2 else: print('你只能輸入1或者2') return x def get_input_arg(self): ''' 獲得使用者的輸入構造學生節點 ''' id_ = input('請輸入id') name = input('請輸入姓名') sex = input('請輸入性別') age = input('請輸入年齡') score = input('請輸入成績') return (id_,score) def delete(self): ''' 刪除節點 ''' info = '你想要根據哪個屬性刪除節點:1.id 2.name' attribute = self.get_input_1_2(info) val = input('輸入你想要刪除的值:') self._delete(attribute,val) def show(self): ''' 顯示 ''' rel = self._show() for i in rel: print(i) def add(self): ''' 增加學生結點 ''' info = '你想要插入的位置:1.左邊 2.右邊' direction = self.get_input_1_2(info) arg = self.get_input_arg() self._add(direction,*arg) def insert(self): ''' 新學生,插入到指定的位置 ''' idx = int(input('輸入要插入的位置')) temp = self.get_input_arg() self._insert(idx,*temp) def search(self): ''' 查詢學生 ''' info = '你想要根據哪個屬性搜尋節點:1.id 2.name' attribute = self.get_input_1_2(info) val = input('輸入你想要查詢的值:') print(self._search(attribute,val)) def modity(self): ''' 修改學生資訊 ''' info = '你想要根據哪個屬性搜尋節點:1.id 2.name' attribute = self.get_input_1_2(info) val_ = input('輸入要查詢的值:') temp = self.get_input_arg() self._modity(attribute,val_,*temp) def main(self): ''' 主流程 ''' info = ''' ******************* *kalpa學生管理系統* * 0.顯示資料 * * 1.增加資料 * * 2.刪除資料 * * 3.查詢資料 * * 4.修改資料 * * 5.儲存並退出 * ******************* ''' print(info) a = '0' while a in ['0','1','2','3','4','5']: if a == '0': self.show() elif a == '1': self.add() elif a == '2': self.delete() elif a == '3': self.search() elif a == '4': self.modity() elif a == '5': self.quit() return a = input('>>') if __name__ == "__main__": ui = Cmd_UI() ui.main()
關於管理系統的更多內容請點選《管理系統專題》進行學習
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。