前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python 实现简易版成绩管理系统

Python 实现简易版成绩管理系统

作者头像
用户2870857
发布2019-12-20 12:43:47
1.3K0
发布2019-12-20 12:43:47
举报
文章被收录于专栏:Python高效编程Python高效编程

上一次,公众号介绍了如何使用 Python 实现单链表,下面让我们一探单链表的简单应用:在命令行,实现简易版成绩管理系统。

这次的简易版成绩管理系统,主要有六大功能:增加学生信息、删除学生信息、修改学生信息、查找学生信息、显示学生信息、按 ID 排序。

实现效果如下:

保存与读取信息

首先判断当前路径下,是否存在database.txt这个文件。如果不存在的话,就新建一个。如果存在的话,就按行读取数据。其中,eval函数将读取的字符床解析为字典。然后,将学生信息存储在单链表中。

代码语言:javascript
复制
try:
   with open('database.txt', 'r') as f:
       for data in f.readlines():
           SCS.append(eval(data))
except:
   with open('database.txt', 'w') as f:
       pass

接着,如果用户选择退出程序的话,就遍历学生信息,并且以字符串的形式按行存储学生信息。

代码语言:javascript
复制
elif item == 0:
   with open('database.txt', 'w') as f:
       self.point = self.head
       while self.point.next:
           self.point = self.point.next
           f.writelines('{}\n'.format(self.point.data))
   exit()

增加学生信息

由于本次实现的成绩管理系统比较简易,我们只对学生 id 和 成绩进行限制。

其一,我们要确保学生 id 不能重复。当我们希望向链表中添加数据时,首先要迭代整个链表,判断要添加元素的 id 是否已经在链表中存在。

代码语言:javascript
复制
def unique_id(self, std_id):
   self.point = self.head
   while self.point.next:
       self.point = self.point.next
       if self.point.data['id'] == std_id:
           return False
   return True

其二,我们要确保学生成绩在 0 ~ 100 分之间。当用户完成输入时,需要判断是否要保存数据,如果否,那么就不进行插入数据操作。为了降低用户误输入造成的影响,我们设定四种用户可能输入的字符:[‘y’, ‘yes’, ‘Y’, ‘Yes’]。

最后,我们以字典的形式插入学生信息。

代码语言:javascript
复制
# 增加信息
def add_info(self):
   # id 不能重复
   # 成绩不能超出范围
   name = input('姓名:')
   std_id = input('学生id:')
   while not self.unique_id(std_id=std_id):
       print('id重复')
       std_id = input('学生id:')
   grade = input('学生成绩:')
   if eval(grade) < 0 or eval(grade) > 100:
       print('超出范围')
       grade = input('学生成绩:')
   print(name, std_id, grade)
   print('请确认无误后保存')
   choice = input('y/n')
   items = ['y', 'yes', 'Y', 'Yes']
   if choice in items:
       data = {'id': std_id, 'name': name, 'grade': grade}
       self.append(data)

删除学生信息

删除学生信息的方法,与上一节我们提到的单链表的删除操作相类似。最大的不同之处,我们不再比较整个的 data 域。而是取出 data 关键字 id 所对应的值,将其与用户输入的 id 相比较。

代码语言:javascript
复制
def del_info(self, find):
   print('请确认无误后保存')
   choice = input('y/n')
   items = ['y', 'yes', 'Y', 'Yes']
   if choice in items:
       if not self.head.next:
           print('链表为空')
           return None
       self.point = self.head
       while self.point.next.data['id'] != find:
           self.point = self.point.next
       pointer = self.point.next
       self.point.next = self.point.next.next
       del pointer

修改学生数据

由于姓名之类的信息有可能会重复,而我们已经确保学生 id 的唯一性。所以进行修改操作时,我们以学生 id 为搜索项。如果找到了该学生 id,我们就直接更改其对应的姓名与成绩等信息。

代码语言:javascript
复制
def modify_info(self):
   find = input('输入需要修改的学生的id:')
   if not self.head.next:
       print('链表为空')
       return None
   self.point = self.head
   while str(self.point.next.data['id']) != find:
       self.point = self.point.next
       if self.point.next is None:
           print('没有找到该元素')
           return None
   name = input('姓名:')
   grade = input('学生成绩:')
   self.point.next.data['name'] = name
   self.point.next.data['grade'] = grade

查找学生信息

查找学生信息,与修改学生信息的区别在于:找到对应的学生 id 之后,就直接打印 id 所对应的学生信息。

代码语言:javascript
复制
def search_info(self):
   find = input('输入需要查找的学生的id:')
   if not self.head.next:
       print('链表为空')
       return None
   self.point = self.head
   while str(self.point.next.data['id']) != find:
       self.point = self.point.next
       if self.point.next is None:
           print('没有找到该元素')
           return None
   data = self.point.next.data
   print('ID 姓名 成绩')
   print('{}  {}  {}'.format(data['id'], data['name'], data['grade']))

显示学生信息

该方法就是一边迭代链表,一边打印节点对应的学生信息,和上节的单链表的打印操作差不多。

代码语言:javascript
复制
# 显示信息
def display_info(self):
   self.point = self.head
   print('ID 姓名 成绩')
   while self.point.next:
       self.point = self.point.next
       data = self.point.data
       print('{}  {}  {}'.format(data['id'], data['name'], data['grade']))
   print('')

排序

最后,我们要实现排序操作。

首先,要实现链表版的冒泡排序。冒泡排序(顺序形式),从左向右,两两比较,如果左边元素大于右边,就交换两个元素的位置。其中,每一轮排序,序列中最大的元素浮动到最右面。也就是说,每一轮排序,至少确保有一个元素在正确的位置。这样接下来的循环,就不需要考虑已经排好序的元素了,每次内层循环次数都会减一。其中,如果有一轮循环之后,次序并没有交换,这时我们就可以停止循环,得到我们想要的有序链表了。

代码语言:javascript
复制
def sort(self, item):
   length = self.get_size()
   i, j = 0, 0
   flag = 1
   while i < length:
       self.point = self.head.next
       while j < length - i - 1:
           if int(self.point.data[item]) > int(self.point.next.data[item]):
               # self.point.data, self.point.next.data =
               # self.point.next.data, self.point.data
               temp = self.point.data
               self.point.data = self.point.next.data
               self.point.next.data = temp
           self.point = self.point.next
           j += 1
           flag = 0
       if flag:
           break
       i += 1
       j = 0

对于学生信息,我们可以通过成绩与学号这两个关键字进行排序。用户除了可以选择按成绩还是按学号排序,还可以选择顺序还是逆序排序。如果用户选择逆序的话,只要通过 reverse 方法,我们就可以创建一个新的 SCS 对象,其中新对象的数据顺序与原对象的数据顺序完全相反。该方法,也是基于单链表 reverse 操作的改进。最后排好序,我们只需完整显示数据即可。

代码语言:javascript
复制
def rank_info(self):
   choice = input('1.成绩排序 2.学号排序:')
   order = input('1.升序 2.降序:')
   if choice == '1':
       item = 'grade'
   elif choice == '2':
       item = 'id'
   else:
       return None
   self.sort(item=item)
   if order == '2':
       temp = self.reverse()
       temp.display_info()
       return None
   self.display_info()

def reverse(self):
   local_list = StudentControlSystem()
   self.point = self.head
   count = 0
   while self.point.next:
       count += 1
       self.point = self.point.next
       data = self.point.data
       local_list.insert_after_head(data)
   return local_list

以上,我们已经介绍了学生成绩管理系统的主要操作。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-01-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python高效编程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 保存与读取信息
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档