学生管理システム
いろいろな言語を学ぶときは、いつもいろいろな管理システムを書いて練習することになると思います。管理システムは、主にデータの追加、削除、変更が含まれます。原則は難しくなく、小さな練習プログラムとして適しています。
データの構造
データを保存するには、cの構造、リスト、辞書などのデータ構造が必要です。Pythonのクラスはすべて一般的に使用されるデータタイプです。
ここでは、学生データのデータ構造としてリンクリストを使用しました。
つまり、ノードクラスとStudent_LinkListクラスは、リンクされたリストを実現します
データの永続性
プログラムで生成されたデータはメモリに保存されます。プログラムが終了すると、次回はデータを復元できません。そのため、メモリ内のデータをファイルまたはデータベースに保存して保存する必要があります。データの永続性
このプログラムは、python標準ライブラリpickleによって提供されるシリアル化メソッドdump()およびload()を使用して、データの永続性を実現します
構成ファイル
構成ファイルを使用すると、プログラム内のさまざまなサブクラスの使用が容易になります。
このプログラムは、configparserを使用して構成ファイルを解析します
このプログラムの構成ファイルの名前はStudent.iniです。
# Student.iniファイル
[ Student]
student = Student_LinkList
[ Persistence]
persistence = Persistence_Pickle
file = student.pik
クラス間の関係
学生データに関連する学生#abstractクラス
±- Student_LinkList
永続性#永続性に関連する抽象クラス
±- Persistence_Pickle
MyConfigure#構成ファイルの読み取りに関連するクラス
UI#Interaction関連の親クラス
±- Cmd_UI
インターフェイスプレビュー
ソースコード
'''
単一のリンクリストを使用して実現された学生管理システム
'''
import pickle
import abc
import configparser
classStudent(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):'''
名前に従ってノードを照会する
'''
@ abc.abstractmethod
def modity_id(self):'''
IDに従ってノードを見つけ、それを変更します
'''
pass
classNode(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}"classStudent_LinkList(Student):'''
学生リンクリスト
'''
def __init__(self):
self.head =Node(-1,'head','-1',-1,-1)
self.length =0
self.tail = self.head #テールノードはテール挿入に使用されます
def add(self,id_,name,sex,age,score):'''
学生ノードを追加する,テールプラグ
'''
# print('現在のテール値',self.tail)
temp =Node(id_,name,sex,age,score)
self.tail.next = temp
self.tail = self.tail.next
self.length +=1print('[info]:正常に追加されました')
def ladd(self,id_,name,sex,age,score):'''
学生を追加し、
'''
temp =Node(id_,name,sex,age,score)
temp.next = self.head.next
self.head.next = temp
if self.tail == self.head:
self.tail = temp
self.length +=1print('[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-1else:
temp = p.next
p.next = temp.next
# テールノードを削除する場合は、テールを移動します
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]:名前が見つかりません')return False
elif node.next.name == name:
temp = node.next
node.next = temp.next
# テールノードを削除する場合は、テールを移動します
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,idx,id_,name,sex,age,score):'''
指定した場所にデータを挿入します
'''
if idx self.length or idx ==0:print(f'[error]:入力したインデックスは違法です(1-{self.length})')return0
p,cur = self.head,0while p != None and cur < idx-1:
p = p.next
if cur < idx-1:return-1else:
temp =Node(id_,name,sex,age,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-1else:return p
def search_name(self,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,id_,name,sex,age,score):'''
IDに従ってノードを見つけ、それを変更します
'''
node = self.search_id(id0)if node ==-1:print('[error]:IDが見つかりません')return-1else:
node.modity(id_,name,sex,age,score)
def show(self):'''
すべての学生ノードを表示,反復
'''
print(f'\n{"-"*25}以下はシステム内のデータです{"-"*25}')
temp =[]
p = self.head
while p != None:
temp.append(p)
p = p.next
return temp
classStudent_Array():'''
アレイを使用して学生のデータストレージを実現する
'''
pass
classStudent_Queue():'''
キューで実現
'''
pass
classStudent_Dict():'''
キューで実現
'''
pass
classPersistence(abc.ABC):'''
リンクリストデータの永続性
'''
@ abc.abstractmethod
def save(self):'''
オブジェクトを保存します
'''
pass
@ abc.abstractmethod
def load(self):'''
オブジェクトをロードします
'''
pass
classPersistence_Pickle(Persistence):'''
ピクルスを使用してシリアル化する
'''
def __init__(self,cls: Student,file_):
self.filename = file_
self.obj = None
self.cls = cls
def save(self):withopen(self.filename,'wb')as f:
pickle.dump(self.obj,f)
def load(self):try:withopen(self.filename,'rb')as f:
temp = pickle.load(f)
except:
temp =globals()[self.cls]()print('戻り温度:',type(temp))
self.obj = temp
return temp
classPersistence_File(Persistence):'''
ファイルを使用して永続化する
'''
pass
classPersistence_Mysql(Persistence):'''
Mysqlデータベースを使用して永続化する
'''
pass
classPersistence_Socket(Persistence):'''
リモートソケットの永続性を使用する
'''
pass
classMyConfigure(object):'''
構成ファイルの読み取りに使用されるクラス
'''
def __init__(self):
self.config = configparser.ConfigParser()
def save(self):'''
構成ファイルを保存します
'''
withopen('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の場合、保存されたファイル名としてfileがあります
'''
temp ={}
temp['persistence']= self.config['Persistence']['persistence']if'Persistence_Pickle'in temp['persistence']:
temp['file']= self.config['Persistence']['file']return temp
classUI(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):'''
学生ノードを増やす,
方向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,idx,*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,attribute,id_,*temp):'''
変更する
'''
if attribute ==1:
self.student.modity_id(id_,*temp)
elif attribute ==2:print('[info]:起こらなかったので何もしない')
pass #名前に従って変更する
classCmd_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 =2else:print('1つまたは2つしか入力できません')return x
def get_input_arg(self):'''
学生ノードを構築するためのユーザー入力を取得する
'''
id_ =input('IDを入力してください')
name =input('名前を入力してください')
sex =input('性別を入力してください')
age =input('年齢を入力してください')
score =input('成績を入力してください')return(id_,name,sex,age,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 ='''
********************カルパ学生管理システム**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()
Recommended Posts