【软件实践 1】 小程序的测试与修改

🚀【软件实践 1】小程序的测试与修改

  •   项目介绍  
  •   修改方案  
  •   代码实现  
  •   运行截图  
  •   实验总结  
  •   参考资料  

 

项目介绍

 

项目名称:基于Python的课堂点名器

项目来源:博客来源链接  https://blog.csdn.net/qq_45405176/article/details/105004692

项目概要:用Python实现一个简单课堂点名器

    1. 以某班级学生名单为例,从外部文件导入学生信息,随机对班级所有同学进行点名;
    2. 判断未到学生是否有请假条,有则视为请假,无则视为旷课。
    3. 对点名结束后进入教室的学生将旷课改为迟到。
    4. 对中途离开课堂学生计为早退(需要考虑学生既是迟到又是早退的情况)。
    5. 按照请假、旷课、迟到、早退四类分别展示。
    6. 将未到学生按照请假、旷课、迟到、早退四类分别存储在四个.csv格式的文件中。

 

原项目部分源代码如下 (源码较长,完整代码请点击链接查看原文)

 1 import xlrd                 #导入xlrd包,对Excel读取数据
 2 import pandas as pd         #导入pandas包,用于对Excel操作
 3 import random
 4 
 5 #定义函数:从Excel文件读取学号和姓名,返回全体学号和姓名列表
 6 def student(address):
 7     data = xlrd.open_workbook(address)
 8     table = data.sheet_by_name('Sheet1')    #选定页码1--(Sheet1).
 9 
10     rowNum = table.nrows    #总行数
11     colNum = table.ncols    #总列数
12     a = []  # 获得学号
13     b = []  # 获得姓名
14 
15     for y in range(colNum):  #自动索引学号(xuehao),姓名(name)
16         if table.cell_value(0, y) == 'xuehao':
17             for x in range(1, rowNum):
18                 vaule = table.cell_value(x, y)
19                 vaule = float(vaule)
20                 vaule = int(vaule)
21                 a.append(vaule)
22 
23         if table.cell_value(0, y) == 'name':
24             for x in range(1, rowNum):
25                 vaule = table.cell_value(x, y)
26                 b.append(vaule)
27     return a, b
28 
29     ......
30     ......      
31     
32 #定义函数:输入列表学号,姓名,得到table表中date数据
33 def date(a,b):
34     students = dict(zip(a, b))
35     d = []
36     for c in a:
37         e = []
38         e.append(c)
39         e.append(students[c])
40         d.append(e)
41     return d
42 
43 #主函数
44 address = r'D:\mingdan.xls'
45 x = student(address)
46 a = x[0]
47 b = x[1]
48 print('请输入本班要点名的人数(全班人数:{0}):'.format(len(a)),end='')
49 num1 = num()
50 x = dianming(a, b, num1)
51 c = x[0]
52 d = x[1]
53 x = panduan1(c,d)
54 e = x[0]        #早退1
55 f = x[1]
56 g = x[2]
57 h = x[3]
58 x = qingjia(g,h)
59 i = x[0]        #早退2
60 j = x[1]
61 k = e + i
62 l = f + j
63 m = []
64 for i in k:
65     hao = 'id'+str(i)
66     m.append(hao)
67 o = date(m,l)
68 table('早退学号','早退姓名',o,'D:/zaotui.csv')

 


 

源程序分析

  • 经过分析,源程序的逻辑如图

图为手写简略分析图

微信图片_20210306140202.jpg

 

  1. 由于定名方式是随机点名,所以导入random模块;
  2. 想要从外部文件读取学生名单,这里用到xlrd包;
  3. 想要将请假…等四类名单分别存储在四个.csv格式的文件中。
  4. 这里采用pandas包,用于对excel的操作。

 

图为需要提前导入的包和模块

ex31.png

 

  • 外部文件为Excel格式,从D盘读取名单。原名单保存为xls格式,不知道为什么保存为xlsx.模式无法运行程序。
  • 后来查了一下,因为我的python版本下的是python3,不支持xlsx文档格式。

 

图为创建的”mingdan.xls“文件

ex3.png

图为创建的”mingdan.xls“名单

ex4.png
 
  • 由于学号过长时,显示为科学计数的方式,这里将学号转化为字符,前面加上id,采用 id+学号 的格式;
  • 注意test.to_csv(address, encoding=“gbk”),这样可以保证csv文件中文不是乱码
  • 由于要对学生点名,这里采用学号索引,用了大量的函数模块,利用函数来返回学号和姓名,通过函数来实现不同的功能:
  • 按照函数顺序依次进行点名流程;

 

图为运行截图

ex34.png

 

  •  图一内红点标出的是新生成的文件。图二为打开新生成的文件后显示的名单,名单仅在xlsx文档内显示而不在运行界面上显示。

 

ex36.png

ex37.png

 

以上就是原程序大致分析,经过总结,原程序需要实现的主要功能是后面修改程序时仍需要保留的功能,基于以下几个基本功能:

  • 读取名单
  • 产生随机点名名单
  • 点名并输出特定学生名单
  • 将特定名单写入表格存档

 


 

 

 修改方案

  • 仍需要保留原程序的四个基本功能,在此基础上对原程序进行修改。
  • 将原项目中的xlsx.文件转化成csv.文件后再进行处理,因为csv中的open()/reader()等函数可以更方便的读取和写入数据。然后通过项目1的思路(这里不再赘述),达到项目2的目的。
  • 直接将迟到/未到/已到的学生显示在交互界面,并且也会录入xlsx.表格中,这些同学的信息会被输出且导入到新的csv文件中。
  • 在点名环节新增了捕获异常的功能。用于处理不按要求签到的用户,单独定义了一个list,并对这些同学单独进行一次点名,将再次输入错误的学生导入“未到学生名单”中;
  • 点名环节不但会捕获异常,并且还会将连续两次输入错入的学生加入旷课名单中。点名环节需要处理不按要求输入的用户,可以单独定义一个list,然后最后再进行点名;若同一个学生答道再次输入错误,该同学将会被导入未到学生名单。
  • 根据以上初步想法,可拟出修改后程序的大致功能:
    1. 读入csv文件学生名单
    2. 产生随机学生名单
    3. 完成点名器的初始化
    4. 点名
    5. 写入csv文件,输出未到名单
    6. 输出传入的特定列表数据
    7. 主函数

 

 

代码实现

  • 根据以上修改目标,修改后完整代码如下
 1 ''' @信息学院软工1--【软件工程综合实践1】 '''
 2 
 3 import csv
 4 import random
 5 
 6 
 7 #   功能:读入csv文件学生名单
 8 #   输入:文件名
 9 #   返回值:学生名单(list),学生全部信息(dict)
10 def file_in(file_name):
11     students_info = {}
12     students_name = []
13     with open(file_name, newline='') as info:
14         reader = csv.reader(info)
15         for row in reader:
16             students_info[row[0]] = row[1]
17             students_name.append(row[0])
18     return students_info, students_name
19 
20 
21 #   功能:产生随机学生名单
22 #   输入:学生名单(list)
23 #   返回值:打乱的学生名单(list)
24 def new_list(students_name):
25     student_upset_name = random.sample(students_name, len(students_name))
26     return student_upset_name
27 
28 
29 #   功能:完成点名器的初始化
30 #   输入:学生名单(list)
31 #   返回值:学生信息(dict)和打乱的学生名单(list)
32 def dmq_init(file_name):
33     student_info = file_in(file_name)[0]
34     # print(students_wg_dict)
35     student_upset_name = new_list(file_in(file_name)[1])
36     # print(students_wg_list)
37     return student_info, student_upset_name
38 
39 
40 #   功能:点名
41 #   输入:打乱的学生名单(list)
42 #   返回值:未到学生名单(list)
43 def dmq_dm(student_upset_name):
44     student_late = []
45     student_dm_wrong = []
46     for name in student_upset_name:
47         temp = input(name + "到了吗?(是:1,否:2)")
48         if temp == "1":
49             continue
50         elif temp == "2":
51             student_late.append(name)
52         else:
53             student_dm_wrong.append(name)
54             print("请按要求输入!该名字被放置最后点名。")
55     if student_dm_wrong:
56         for name in student_dm_wrong:
57             temp = input(name + "到了吗?(是:1,否:2)")
58             if temp == "1":
59                 continue
60             elif temp == "2":
61                 student_late.append(name)
62             else:
63                 print("仍然未按照要求输入!算入未到名单!")
64                 student_late.append(name)
65     return student_late
66 
67 
68 #   功能:写入csv文件,输出未到名单
69 #   输入:未到学生名单(list)和学生全部信息(dict)
70 #   返回值:无
71 def dmq_file_in(students_late, student_info, num):
72     students_late_info = []
73     for name in students_late:
74         students_late_info.append([name, student_info[name]])
75     print_info(students_late_info, num)
76     with open("late_students_info.csv", "w", newline="") as file_in:
77         file_writer = csv.writer(file_in, quotechar='|', quoting=csv.QUOTE_MINIMAL)
78         for info in students_late_info:
79             file_writer.writerow(info)
80     print("\n已导出未到学生名单!文件位置位于当前目录下late_students_info.csv")
81 
82 
83 #   功能:输出传入的 特定 列表数据
84 #   输入:特定的list  [[*, *], [*, *], [*, *], ...]
85 #   返回值:无
86 def print_info(special_list, num):
87     count = 0
88     print("未到名单如下("+str(num)+"个一行):")
89     for i in special_list:
90         if (count % num == 0) & (count != 0):
91 print()
92 print(i[0]+","+i[1], end=' ')
93 count += 1
94 # 主函数 95 def main(file_name):
96 # 5代表5个名字一行输出 97 dmq_file_in(dmq_dm(dmq_init(file_name)[1]), dmq_init(file_name)[0], 5) 98 main("D:/mingdan.csv")

 

  • 修改后的程序加入了更多错误处理机制,对点名时输入错误进行了进一步的判断和处理,减少了点名时的干扰因素。同时将名单更直接地输出在运行框内,更方便直观地展示了点名信息。
  • 修改后的程序与原程序最大的区别就是创建了更多的函数,将各个功能模块分开了,降低了各个功能之间的耦合程度,这样在后期需要加入更多功能时更容易修改和完善代码,在代码层面上实现了改善;。
  • 特别说明:本修改程序由于时间和任务量限制,没有和原程序一样将学生分为迟到、缺勤、早退等类别,仅实现了记录了未到学生。但是,其它分类的操作可以套用本程序的函数进行实现。

 


 

运行截图

  • 先在D盘中创建一个学生名单(保存为csv格式(显示为xls))
  • 以下选中的文件是新创建"mingdan.csv"文件,注意与源程序同名文件区别(源文件为xls格式)。
  • 其它文件均为原程序创建的文件,与修改后程序无关。

ex41.png

  • 我将信息学院部分学生的信息导入了,用学号索引。

ex51.png

 

  • 在python中导入csv模块(若没有就打开cmd,使用pip命令下载csv)
  • 用random函数实现乱序点名功能

图为需要导入的模块和包

ex42.png

 

  • 这是第一次输入错误,程序会要求重新输入一次,再次输入错误将被加入到未到名单中。

ex45.png

 

  • 这是第二次输入,程序会将连续两次输入错误的名单输出到未到学生名单里。与原程序不同的是,原程序不会将未到名单直接打印出来,只能通过打开excel文件才能看到名单。
  • 通过标红的可以看出,程序已将连续两次输入错误的学生名单加入了未到学生名单中。

ex48.png

 

  • 最后程序会导出未到学生名单,生成一个新的csv文件到py文件源目录下。

 

ex450.png

  • 这是新生成的文件。储存在源文件文件夹目录中。

 

ex49.png

 

 


  

实验总结

  • 虽然比原程序优化了很多,但是总觉得好像哪里还能优化,但是因为自己技术有限暂时还没想出更好的方法。不过已经基本完成了想要改进的目标。以后学习了新的excel处理方法和技术再继续优化。

  • 不知道为什么一开始我创建了一个xlsx文件程序一直无法运行,说是不支持xlsx文件格式,难道是因为我的py版本问题吗。后来创建了xls文件后就可以运行了。(更新:python3不支持xlsx格式)

  • test.to_csv(address, encoding=“gbk”),这样可以保证csv文件中文不是乱码

  • 为了防止学号过长时,显示为科学计数的方式,这里将学号转化为字符,前面加上id,采用 id+学号 的格式

  • randomcsv两个模块,random模块是为了实现随机点名,只用到了sample();csv模块用到了reader()writer(),搭配open()函数完成文件读入写出。

  • csv是文本文件,用记事本就能打开,XLS是二进bai的文件只有用EXCEL才能打开, csv文件是以逗号为分隔符号,将各字段列分离出的一种ASCII文件;

  • xls 是一个特有的二进bai制格式,其核心结构是复合文档类型的结构,而 xlsx 的核心结构是 XML 类型的结构,采用的是基于 XML 的压缩方式,使其占用的空间更小。

 

 

 

🛸 参考资料

posted @ 2021-03-06 15:27  小尹和她的blog  阅读(346)  评论(0编辑  收藏  举报