实在无法理解这一块代码
本题 包含文件附件,请有空的高手帮助以下,这题因为真的卡了三天,实在走投无路,自己也解读了答案中99%的代码,只剩下一条无法理解
要求根据id.txt和finalscore.txt生成学生成绩。文件都是utf-8格式的
1) id.txt 里面放着学号和姓名,没有排序。姓名很怪,不要在乎
2) finalscore.txt里面放着学生的做题信息。其中第三栏或第四栏是做题数量
有的学生昵称是学号,有的是姓名,有的是姓名学号都有。只要有学号或姓名,就有效
3) 分数计算办法: 1题50,2题60,此后每做一题加4分
4) 生成id.txt里面有的所有学生的成绩,按学号排序输出到指定的结果文件。
如果在 finalscore里面找不到学生的做题记录,该生题数和成绩都记0
结果文件格式如:
学号 姓名 题数 分数
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
这样的结果可以导入excel表格(拷贝粘贴即可)
id.txt里面没有的学生,不用处理。
注意:源文件和目标文件里面的分隔符,都不是空格,都是制表符 \t (Tab)
注意看finalscore.txt里面,有连着两个 Tab 的情况,比如下面学号和做题数之间是2个tab:
4 1700943836 9
也许你需要关注这一点,也许并不需要
5)程序文件名必须叫count.py。运行时,将count.py和id.txt, finalscore.txt放在相同文件夹下面,
然后在命令行窗口进入该文件夹,以命令行方式运行程序,命令行中可以指定结果文件名:
python count.py XXX.txt
程序在同一个文件夹下生成结果文件XXX.txt。这个文件名可以随便指定
6)正确的结果已经给出,即ans.txt。最终生成的结果应该和ans.txt文件一致
以下是网上搜索到的答案
import re
import sys
def chazhao(x,y):
l=len(y)
for i in range(l):
if x in y:
return i
return -1
def grade(a):
if a==1:
x=50
elif a==2:
x=60
elif a>2:
x=60+(a-2)*4
else:
x=0
return x
f=open('id.txt','r',encoding='utf-8')
students=f.readlines()
f.close()
students.sort()
f=open('finalscore.txt','r',encoding='utf-8')
score=f.readlines()
f.close()
f=open(sys.argv,'w',encoding='utf-8')
f.write("学号\t姓名\t题数\t分数\n")
for x in students:
l=x.split()
x1,x2=l,l
if chazhao(x1,score)!=-1 or chazhao(x2,score)!=-1:
i=chazhao(x1,score)
if i==-1:
i=chazhao(x2,score)
l1=re.split('\t',score)
a=int(l1)
agrade=grade(a)
f.write("%s\t%s\t%d\t%d\n"%(x1,x2,a,agrade))
else:
f.write("%s\t%s\t%d\t%d\n"%(x1,x2,0,0))
f.close()
答案中第40行代码我无法理解
l1=re.split('\t',score)
这行代码的i,我无法理解,因为上面 chazhao(x,y)中必然是产生1或者-1,他不是一个循环
而l1=re.split('\t',score) 中我理解是这个i需要一个循环才能每次轮换内容,如果一直都是1那永远都是第一行
而这题我对题目的理解解决思路是这样的,希望有错能更正一下
目标按照文件ID里面的数据作为索引,在文件finalscore寻找数据补充回ID文件
因为finalscore文件内容有错乱内容,我一开始打算先整理好finalscore文件内容再提取,这样感觉简单,但最后连整理也花了半天也没整理出来
然后最后按照上面代码思路,以ID文件作为索引,校验finalscore内容,存在则提取不存在则跳过,然后就卡在了我上面的那个代码那里,因为我写不出,就去搜答案,发现这个答案跟我的思路基本一样,但我看不懂40行这段
还有其他解题思路可以提供下吗?
def chazhao(x,y):
l=len(y)
for i in range(l):
if x in y:
return i
return -1
找到了返回的是 字母i不是数字1,你看错了
i=chazhao(x1,score)
if i==-1:
i=chazhao(x2,score)
这几行代码的意思是,id.txt里的学生若找到了
如果是找到学号了,那么chazhao(x1,score)肯定是返回第几行。但是如果chazhao(x1,score)返回-1则说明不是按照学号找到的,那么就是按照名字找到的,这时候
i=chazhao(x2,score) 这句代码就是按照名字找,看看在第几行,并赋值给 i
然后下边那句话l1=re.split('\t',score) 是把找到的这一行,按照‘\t’切割,切割出来几项。其中第三项或者第四项就是这个人的答题数
下边这句话a=int(l1)是个bug,因为分数不一定在第四项,(其中第三栏或第四栏是做题数量)这句话有可能报错。
我的想法是try:
a=int(l1)
except:
a=int(l1)
但是我并没有跑一遍代码,不知道改的对不对,如果改的对了你也理解了麻烦给我最佳
如果还有哪里没看懂也欢迎继续问 研究一下 学习编程中的Ben 发表于 2023-1-2 08:35
研究一下
老哥你的回复实在太水了
看了一下你的其他回复
更水了{:10_266:} jcpython2 发表于 2023-1-2 11:16
老哥你的回复实在太水了
看了一下你的其他回复
更水了
额,我已经很不睡了,至少还打点字,别人都一个表情 本帖最后由 阿奇_o 于 2023-1-2 13:41 编辑
难点一:finalscore.txt里的记录 存在 名字和学号混连在一起的情况,我尝试用正则表达式一次获取,发现过于复杂,只能退一步,分情况来获取到需要的 (学号, 姓名, 题数)。
难点二:提取到了这些名字或学号,再到ids.txt里,根据名字找学号,或根据学号找名字。。 还要补全没有在finalscore.txt里的学生(缺考0题目数)。。 最后根据题数计算分数。
难点三:很多关于字符串操控和列表遍历的各种小细节
import sys, re
def get_scores(file):
with open(file, 'r', encoding='utf8') as f:
lines = f.readlines()
stu_only_name = list(map(lambda x: re.findall('^(\d+)[\t ]([\u4e00-\u9fa5]{1,})[\t ]+(\d+)', x), lines))
print(stu_only_name)
stu_with_id = list(map(lambda x: re.findall('(\d+)[\t ]+(\d{10})[\t ]+(\d+?)[\t ]+\d+:', x), lines))
print(stu_with_id)
with open('id.txt', 'r', encoding='utf8') as f2:
id_name = dict(map(str.split, f2.readlines()))
name_id = dict(zip(id_name.values(), id_name.keys()))
print(name_id)
fixed_id = {i: name_id.get(i) for i in stu_only_name
if i and len(i) == 3 and i in name_id }
print('\nfixed_id: ', fixed_id)
tmp = [ ] + )] + list(i) for i in stu_only_name
if i and i in name_id]
print(tmp)
s2 = [:2]) + ), i] for i in stu_with_id
if i and i in id_name]
print(s2)
scores = []
s2.extend(tmp)
for i in s2:
if i:
r, t = list(i), i
if t == '0':
scores.append(r + )
elif t == '1':
scores.append(r + )
elif t == '2':
scores.append(r + )
else:
scores.append(r + )
for id in id_name.keys():
if id not in for i in scores]:
scores.append(, '0', '0'])
# print(sorted(scores, key=lambda x: x))
return sorted(scores, key=lambda x: x)
def save_ans(scores, file='my_ans.txt'):
with open(file, 'w', encoding='utf8', newline='\n') as f:
f.write('\t'.join(['学号','姓名','题数','分数']))
f.write('\n')
for s in sorted(scores, key=lambda x:x):
f.write('\t'.join(s))
f.write('\n')
if __name__ == '__main__':
file = sys.argv
# print(file)
scores = get_scores(file)
save_ans(scores, file='my_ans.txt')
楼主的百度的程序,直接生成标准答案,没有错误。
首行要加:
#coding=gbk #coding=gbk
import re
import sys
def chazhao(x,y):
l=len(y)
for i in range(l):
if x in y:
return i
return -1
def grade(a):
if a==1:
x=50
elif a==2:
x=60
elif a>2:
x=60+(a-2)*4
else:
x=0
return x
f=open('id.txt','r',encoding='utf-8')
students=f.readlines()
f.close()
students.sort()
f=open('finalscore.txt','r',encoding='utf-8')
score=f.readlines()
f.close()
print("为便于测试,文本文件暂时设中12345.text,当前工作路径:",sys.argv)
f=open("12345.text",'w',encoding='utf-8')
f.write("学号\t姓名\t题数\t分数\n")
for x in students:
l=x.split()
x1,x2=l,l
if chazhao(x1,score)!=-1 or chazhao(x2,score)!=-1:
i=chazhao(x1,score)
if i==-1:
i=chazhao(x2,score)
l1=re.split('\t',score)
a=int(l1)
agrade=grade(a)
f.write("%s\t%s\t%d\t%d\n"%(x1,x2,a,agrade))
else:
f.write("%s\t%s\t%d\t%d\n"%(x1,x2,0,0))
f.close() 洋洋痒 发表于 2023-1-2 07:19
找到了返回的是 字母i不是数字1,你看错了
i=chazhao(x1,score)
def chazhao(x,y):
l=len(y)
for i in range(l):
if x in y:
return i
return -1
但是i=chazhao(x2,score)按照上面函数的结果是永远都只会是得到1或者-1呢,所以我疑惑这点.这函数决定了他永远只能1或者-1吧?? 洋洋痒 发表于 2023-1-2 07:19
找到了返回的是 字母i不是数字1,你看错了
i=chazhao(x1,score)
晕死,我终于看清了
return i
不是return 1
晕死了 jcpython2 发表于 2023-1-2 16:30
晕死,我终于看清了
return i
你都没有仔细看我的回答啊,我写的清清楚楚是字母i了啊 洋洋痒 发表于 2023-1-2 17:41
你都没有仔细看我的回答啊,我写的清清楚楚是字母i了啊
有的,我有看你的代码的,主要是我一开始去读答案的时候把def chazhao的返回误会成1or-1,看你答案一边醒一边回,我还在消化中,再次感谢老哥 改进版本2:先从id.txt里找学号和学生姓名,再根据学号或姓名到finalscore.txt里找题数,并计算分数。。
这样清晰多了。。我前一个版本是反过来找,搞复杂了。。
import sys, re
def main(file):
with open(file, 'r', encoding='utf8') as f:
t_lines = f.readlines()
with open('id.txt', 'r', encoding='utf8') as f2:
id_name = list(map(lambda x: x.strip().split('\t'), f2.readlines()))
# print(id_name)
scores = dict()# 用字典,方便后面去重和查找
for id, name in id_name:
for line in t_lines:
if id in line or name in line:
m = re.match('(\d+)[\t ].*?(\d+?)[\t ]+\d+:', line)# 匹配序号和题数
if m:
t = m.group(2)# 只取"题数"
# print(t.group(1), id, name, t)# 打印检查是否正确
if t == '0':
scores =
elif t == '1':
scores =
elif t == '2':
scores =
else:
scores =
for id, name in id_name:
scores.setdefault(id, ) # 补上 缺考学生的成绩
# for s in sorted(scores.values(), key=lambda x: x):# 因学号就位于第一个位置,这里key对比函数可省略
# print(s)
with open('my_ans2.txt', 'w', encoding='utf8', newline='\n') as f:
f.write('\t'.join(['学号','姓名','题数','分数']))
f.write('\n')
for s in sorted(scores.values()):
f.write('\t'.join(s))
f.write('\n')
if __name__ == '__main__':
file = sys.argv
main(file) 楼上正解
页:
[1]