文件处理问题是一个比较接近真正应用方面的问题,接下来让我们一起开始吧!!!
题干:
要求根据id.txt和finalscore.txt生成学生成绩。
1) id.txt 里面放着学号和姓名,没有排序。
2) finalscore.txt里面放着学生的做题信息。其中第三栏或第四栏是做题数量有的学生昵称是学号,有的是姓名,有的是姓名学号都有。只要有学号或姓名,就有效。
3) 分数计算办法: 1题50,2题60,此后每做一题加4分
4) 生成id.txt里面有的所有学生的成绩,按学号排序输出到指定的结果文件。
如果在 finalscore里面找不到学生的做题记录,该生题数和成绩都记0。id.txt里面没有的学生,不用处理。
结果文件格式如:
学号 姓名 题数 分数
1700943357 玘尜寋 0 0
1700943359 杛旺煃 0 0
1700943383 玘签翢 2 60
1700943405 陕榄伳 0 0
1700943465 匒乡奡 5 72
1700943469 巸俗杽 3 64
1700943472 钬内佦 0 0
1700943481 別珜辽 0 0
1700943523 趂盨淦 7 80
注意:源文件和目标文件里面的分隔符,都不是空格,都是制表符 \t (Tab)
5)程序文件名必须叫count.py。运行时,将count.py和id.txt, finalscore.txt放在相同文件夹下面,
然后在命令行窗口进入该文件夹,以命令行方式运行程序,命令行中可以指定结果文件名:
python count.py XXX.txt
程序在同一个文件夹下生成结果文件XXX.txt。这个文件名可以随便指定
6)正确的结果已经给出,即ans.txt。最终生成的结果应该和ans.txt文件一致
解题思路:
题目结果中的数据来自两个文件,所以分别处理得到所需的信息即可。
1.处理id.txt(最好优先处理)
因为所有需要处理的学生信息均来自id.txt ,所以先处理id.txt,然后按学号进行排序。得到学号和姓名的信息后,直接遍历fianlscore.txt文件,获取题数即可。
2.处理finalscore.txt
重点考虑有效信息的准确获取,因为finalscore.txt中信息的位置不唯一确定。确定做题数量后,根据规则计算分数,然后记录。
3.命令行窗口运行
这个问题对于一直使用集成开发环境——Pycharm我来说有一点困难。终于在b站大佬指引下成功突破。 大致步骤有 win+R ->cmd -> cd (+程序文件所在文件夹地址) - > + python count.py ans.txt有些许Linux的样子。
题目解决:
import re
import sys
sco=[]#临时存储finalscore文件内容
student=[]#临时存储id.txt文件内容
answ=[]#存储处理过的学生信息
score=[]#存储处理过的学生试题信息
sa=0 #记录answ的状态
f=open("finalscore.txt","r",encoding='UTF-8')
sco=f.readlines()#按行读取final.txt文件
f.close()
for i in sco:
i=re.split('\\t|\\n',i)#处理文件 清洗掉制表符 和换行符
while "" in i:#去除空元素
i.remove("")
score.append(i)
f=open("id.txt","r",encoding='UTF-8')
student=f.readlines()#按行读取id.txt文件
f.close()
#以相似的方法处理
for i in student:
i=re.split('\\t|\\n',i)
i[0]=int(i[0])
while "" in i:
i.remove("")
answ.append(i)
answ.sort(key=lambda x:x[0])#按学号排序
#向answ列表添加题数 分数信息
for i in answ:#遍历answ列表
sa=0#题数未添加 状态设为零
for j in score:#遍历score列表
for m in j:#遍历score列表中每一个子列表的每个元素 方便进行信息比对
if str(i[0]) in m or str(i[1]) in m or str(i[0])==m or str(i[1])==m:#目标的学号或者姓名是否匹配
try:#防止j[2]为文字无法转为int类型而报错
if int(j[2])<=10 and int(j[2])>0: #观察结果发现题数在0到10之间
i.append(int(j[2]))
sa=1
except:
pass
try:#防止j[3]为文字无法转为int类型而报错
if int(j[3])<=10 and int(j[3])>0:
sa=1
i.append(int(j[3]))
except:
pass
#提示指出题数只在3或4列 没有则结为0
if sa==0:
i.append(0)
#成绩计算
if int(i[2])==1:#1题直接记为50
i.append(50)
elif int(i[2])==2:#两题记为60
i.append(60)
elif int(i[2])>2:#以上根据规则计算
i.append(60+(i[2]-2)*4)
else:
i.append(0)#其他为0
# print(answ)
#输出结果
f=open(sys.argv[1],'w',encoding="UTF-8")
f.write("学号\t姓名\t题数\t分数\n")#输出第一行信息
for i in answ:#遍历输出结果
f.write("%s\t%s\t%d\t%d\n"%(i[0],i[1],i[2],i[3]))
# for i in range(40):
# print(i+1,answ[i])
命令行运行截图:
文档链接:
finalscore.txt原文档:
https://s12.aconvert.com/convert/p3r68-cdx67/aw67d-faulj.html
id.txt原文档:
https://s12.aconvert.com/convert/p3r68-cdx67/a6ogb-gvbsh.html
标准答案文档:
https://s12.aconvert.com/convert/p3r68-cdx67/acjvk-c94qd.html