用python实现学生管理系统
作者:ikalpa 发布时间:2021-05-22 12:13:31
标签: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
界面预览
源码
'''
使用单链表实现的学生管理系统
'''
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,id_,name,sex,age,score):
'''
添加一个学生结点,尾插
'''
#print('当前tail的值',self.tail)
temp = Node(id_,name,sex,age,score)
self.tail.next = temp
self.tail = self.tail.next
self.length += 1
print('[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 += 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,idx,id_,name,sex,age,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_,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 -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,id_,name,sex,age,score):
'''
根据id找到节点,然后修改
'''
node = self.search_id(id0)
if node == -1:
print('[error]:找不到该id')
return -1
else:
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
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,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 #根据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_,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 = '''
*******************
*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()
关于管理系统的更多内容请点击《管理系统专题》进行学习
来源:https://blog.csdn.net/qq_41600708/article/details/107445207


猜你喜欢
- urllib3是一款Python 3的HTTP客户端。Python标准库提供了urllib。在Python 2中,另外提供了urllib2;
- Python是一门面向对象的语言。面向对象都有三大特性:封装、继承、多态。下面分别来说说这三大特性:1、封装隐藏对象的属性和实现细节,仅对外
- 行高的概念看上去很简单——文字行的高度,其实,行高所涉及到的基础知识,对于今后理解其它属性也很重要。大片密密麻麻的文字往往会让人觉得乏味,因
- 这是第二天了,工作之余和女朋友一起学Python3,代码都是她敲的,有点辣眼睛,仅做参考。1.题目:输入“姓名”,输出“你好,姓名”有关安装
- 在所有的比例中黄金分割是最能引起人的美感的,0.618被公认为最具有审美意义的比例数字。黄金分割之所以那么普遍的流行,我猜一定跟理想女人体的
- 1. 问题截图:(8000端口被占用)2. 第一种是可能会打开了多个运行窗口右键关闭即可:3. 第二种是在你运行python的主机上查询出p
- eval()函数可以将字符串型的list、tuple、dict等等转换为原有的数据类型即使用eval可以实现从元组,列表,字典型的字符串到元
- 废话不多说,直接上代码吧!# 矩阵操作# 将矩阵拉成向量import numpy as npx = np.arange(10).reshap
- golang切片和数组拷贝基础Go 语言里面变量有两类,一类是值类型,一类是引用类型。在 Go 语言中:string、int、bool、fl
- 上传html文件内容如下:操作步骤<html><head><meta http-equiv="con
- 正则表达式并不是Python的一部分。正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自
- 在正文前,先简短介绍自己。我任职于广州的某个网站服务公司的系统开发员,主要任务是以.Net编写各种web系统,例如CMS.EIP。大家都知道
- Python中强大的选项处理模块。关于Python之OptionParser模块使用详解可以参考这篇。示例#!/usr/bin/python
- 写爬虫是一项复杂、枯噪、反复的工作,考虑的问题包括采集效率、链路异常处理、数据质量(与站点编码规范关系很大)等。整理自己写一个爬虫程序,单台
- 后台实时监控服务器的CUP与内存占用率的场景很常见,虽然没做过,但是着手写代码之前我真没想到会花2个多小时才最终实现。网上虽然搜 PHP C
- 你说的就是真正的计数器,它只在有新的用户进入网站时,计数器才会加1,忠实可靠。把下列代码放到的global.asa的sessio
- <%Dim sc4Json Sub InitScriptControlSet sc
- 阅读《YUI学习笔记(1)》《YUI学习笔记(2)》YAHOO.lang.later,YAHOO.lang.trim,YAHOO.lang.
- 本文实例讲述了python实现查找两个字符串中相同字符并输出的方法。分享给大家供大家参考。具体实现方法如下:seq1 = "spa
- 描述符类要求:描述符就是将某种特殊类型的类的实例指派给另一个类的属性至少要实现以下的一个方法:•__get__(self, instance