用python实现学生管理系统


Posted in Python onJuly 24, 2020

学生管理系统

相信大家学各种语言的时候,练习总是会写各种管理系统吧,管理系统主要有对数据的增删查改操作,原理不难,适合作为练手的小程序

数据的结构

要保存数据就需要数据结构,比如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,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()

关于管理系统的更多内容请点击《管理系统专题》进行学习

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python实现逆波兰计算表达式实例详解
May 06 Python
在Django的URLconf中使用命名组的方法
Jul 18 Python
python删除特定文件的方法
Jul 30 Python
使用python实现接口的方法
Jul 07 Python
对Python闭包与延迟绑定的方法详解
Jan 07 Python
利用pyinstaller打包exe文件的基本教程
May 02 Python
python函数修饰符@的使用方法解析
Sep 02 Python
django框架单表操作之增删改实例分析
Dec 16 Python
简单了解Python write writelines区别
Feb 27 Python
python中get和post有什么区别
Jun 19 Python
Python使用sys.exc_info()方法获取异常信息
Jul 23 Python
Python之多进程与多线程的使用
Feb 23 Python
Python 解析简单的XML数据
Jul 24 #Python
深入了解NumPy 高级索引
Jul 24 #Python
python实现学生管理系统开发
Jul 24 #Python
浅析Python 多行匹配模式
Jul 24 #Python
Python图像处理二值化方法实例汇总
Jul 24 #Python
Python如何合并多个字典或映射
Jul 24 #Python
Matplotlib 绘制饼图解决文字重叠的方法
Jul 24 #Python
You might like
php生成数字字母的验证码图片
2015/07/14 PHP
PHP读取文件内容的五种方式
2015/12/28 PHP
PHP中addslashes与mysql_escape_string的区别分析
2016/04/25 PHP
yii2控制器Controller Ajax操作示例
2016/07/23 PHP
PHP实现新型冠状病毒疫情实时图的实例
2020/02/04 PHP
PHP 数组操作详解【遍历、指针、函数等】
2020/05/13 PHP
用js判断浏览器是否是IE的比较好的办法
2007/05/08 Javascript
11款基于Javascript的文件管理器
2009/10/25 Javascript
ExtJS GridPanel 根据条件改变字体颜色
2010/03/08 Javascript
JavaScript的单例模式 (singleton in Javascript)
2010/06/11 Javascript
JavaScript中的Array对象使用说明
2011/01/17 Javascript
js弹出层之1:JQuery.Boxy (二)
2011/10/06 Javascript
jQuery中trigger()方法用法实例
2015/01/19 Javascript
javascript跨域的方法汇总
2015/10/23 Javascript
深入php面向对象、模式与实践
2016/02/16 Javascript
JS简单编号生成器实现方法(附demo源码下载)
2016/04/05 Javascript
jQuery实现简单的回到顶部totop功能示例
2017/10/16 jQuery
Vue.js实现可配置的登录表单代码详解
2018/03/29 Javascript
详解vue组件基础
2018/05/04 Javascript
vue中组件的过渡动画及实现代码
2018/11/21 Javascript
vue轮播组件实现$children和$parent 附带好用的gif录制工具
2019/09/26 Javascript
js实现浏览器打印功能的示例代码
2020/07/15 Javascript
基于vue与element实现创建试卷相关功能(实例代码)
2020/12/07 Vue.js
python计算书页码的统计数字问题实例
2014/09/26 Python
python如何通过twisted实现数据库异步插入
2018/03/20 Python
Python操作Excel插入删除行的方法
2018/12/10 Python
python 函数的缺省参数使用注意事项分析
2019/09/17 Python
python实现mask矩阵示例(根据列表所给元素)
2020/07/30 Python
Python中qutip用法示例详解
2020/10/02 Python
美国最便宜的旅游网站:CheapTickets
2017/07/09 全球购物
介绍一下linux的文件权限
2014/07/20 面试题
日语系毕业生推荐信
2013/11/11 职场文书
2015毕业设计工作总结
2015/07/24 职场文书
运动会班级口号霸气押韵
2015/12/24 职场文书
解决golang post文件时Content-Type出现的问题
2021/05/02 Golang
使用PostGIS完成两点间的河流轨迹及流经长度的计算(推荐)
2022/01/18 PostgreSQL