1. 程式人生 > 程式設計 >用python實現學生管理系統

用python實現學生管理系統

學生管理系統

相信大家學各種語言的時候,練習總是會寫各種管理系統吧,管理系統主要有對資料的增刪查改操作,原理不難,適合作為練手的小程式

資料的結構

要儲存資料就需要資料結構,比如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 #和配置檔案讀取有關的類

UI #和互動有關的父類
±- Cmd_UI

介面預覽

用python實現學生管理系統

原始碼

'''
使用單鏈表實現的學生管理系統
'''
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()

關於管理系統的更多內容請點選《管理系統專題》進行學習

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。