当前位置 博文首页 > python实现简单的学生管理系统

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

    作者:ikalpa 时间:2021-07-25 11:46

    本文实例为大家分享了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()
    jsjbwy
    下一篇:没有了