python实现简单的学生管理系统


Posted in Python onFebruary 22, 2021

本文实例为大家分享了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,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 07 Python
python 转换 Javascript %u 字符串为python unicode的代码
Sep 06 Python
Python开发中爬虫使用代理proxy抓取网页的方法示例
Sep 26 Python
sublime python3 输入换行不结束的方法
Apr 19 Python
Python获取航线信息并且制作成图的讲解
Jan 03 Python
python远程连接MySQL数据库
Apr 19 Python
python利用selenium进行浏览器爬虫
Apr 25 Python
pyqt5移动鼠标显示坐标的方法
Jun 21 Python
django中forms组件的使用与注意
Jul 08 Python
python使用ctypes库调用DLL动态链接库
Oct 22 Python
使用Python获取爱奇艺电视剧弹幕数据的示例代码
Jan 12 Python
如何使用python包中的sched事件调度器
Apr 30 Python
matplotlib之pyplot模块坐标轴标签设置使用(xlabel()、ylabel())
Feb 22 #Python
matplotlib之pyplot模块之标题(title()和suptitle())
Feb 22 #Python
matplotlib源码解析标题实现(窗口标题,标题,子图标题不同之间的差异)
Feb 22 #Python
python利用后缀表达式实现计算器功能
Feb 22 #Python
Python使用tkinter实现小时钟效果
Feb 22 #Python
Python tkinter实现日期选择器
Feb 22 #Python
Pyside2中嵌入Matplotlib的绘图的实现
Feb 22 #Python
You might like
PHP 防恶意刷新实现代码
2010/05/16 PHP
php绘制一个矩形的方法
2015/01/24 PHP
PHP常见字符串处理函数用法示例【转换,转义,截取,比较,查找,反转,切割】
2016/12/24 PHP
php 二维数组快速排序算法的实现代码
2017/10/17 PHP
轻松创建nodejs服务器(9):实现非阻塞操作
2014/12/18 NodeJs
javascript实现十秒钟后注册按钮可点击的方法
2015/05/13 Javascript
微信小程序 保留小数(toFixed)详细介绍
2016/11/16 Javascript
JavaScript实现的select点菜功能示例
2017/01/16 Javascript
使用vue.js2.0 + ElementUI开发后台管理系统详细教程(一)
2017/01/21 Javascript
jQuery中用on绑定事件时需注意的事项
2017/03/19 Javascript
javascript算法之二叉搜索树的示例代码
2017/09/12 Javascript
React Native 搭建开发环境的方法步骤
2017/10/30 Javascript
JS中touchstart事件与click事件冲突的解决方法
2018/03/12 Javascript
Vue Echarts实现可视化世界地图代码实例
2019/05/07 Javascript
vue2 拖动排序 vuedraggable组件的实现
2019/08/08 Javascript
JS+CSS实现3D切割轮播图
2020/03/21 Javascript
Element Badge标记的使用方法
2020/07/27 Javascript
在vue中动态修改css其中一个属性值操作
2020/12/07 Vue.js
Python异常处理总结
2014/08/15 Python
python图像处理之镜像实现方法
2015/05/30 Python
关于Python元祖,列表,字典,集合的比较
2017/01/06 Python
python导入csv文件出现SyntaxError问题分析
2017/12/15 Python
tensorflow 获取变量&amp;打印权值的实例讲解
2018/06/14 Python
Django之创建引擎索引报错及解决详解
2019/07/17 Python
selenium+Chrome滑动验证码破解二(某某网站)
2019/12/17 Python
为什么python比较流行
2020/06/19 Python
编写python代码实现简单抽奖器
2020/10/20 Python
H5 canvas中width、height和style的宽高区别详解
2018/11/02 HTML / CSS
印度在线杂货店:bigbasket
2018/08/23 全球购物
英国最大最好的无人机商店:Drones Direct
2019/07/12 全球购物
Interhome丹麦:在线预订度假屋和公寓
2019/07/18 全球购物
Maisons du Monde德国:法国家具和装饰的市场领导者
2019/07/26 全球购物
幼儿园六一儿童节文艺汇演主持词
2014/03/21 职场文书
tp5使用layui实现多个图片上传(带附件选择)的方法实例
2021/11/17 PHP
Win10防火墙白名单怎么设置?Win10添加防火墙白名单方法
2022/04/06 数码科技
pt-archiver 主键自增
2022/04/26 MySQL