jcpython2 发表于 2023-1-2 02:04:56

实在无法理解这一块代码


本题 包含文件附件,请有空的高手帮助以下,这题因为真的卡了三天,实在走投无路,自己也解读了答案中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行这段

还有其他解题思路可以提供下吗?

洋洋痒 发表于 2023-1-2 02:04:57

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:18

研究一下

jcpython2 发表于 2023-1-2 11:16:04

学习编程中的Ben 发表于 2023-1-2 08:35
研究一下

老哥你的回复实在太水了
看了一下你的其他回复
更水了{:10_266:}

学习编程中的Ben 发表于 2023-1-2 11:20:30

jcpython2 发表于 2023-1-2 11:16
老哥你的回复实在太水了
看了一下你的其他回复
更水了

额,我已经很不睡了,至少还打点字,别人都一个表情

阿奇_o 发表于 2023-1-2 13:37:35

本帖最后由 阿奇_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')

chinajz 发表于 2023-1-2 15:03:42

楼主的百度的程序,直接生成标准答案,没有错误。
首行要加:
#coding=gbk

chinajz 发表于 2023-1-2 15:16:26

#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()

jcpython2 发表于 2023-1-2 16:28:49

洋洋痒 发表于 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吧??

jcpython2 发表于 2023-1-2 16:30:01

洋洋痒 发表于 2023-1-2 07:19
找到了返回的是 字母i不是数字1,你看错了

      i=chazhao(x1,score)


晕死,我终于看清了

return i

不是return 1

晕死了

洋洋痒 发表于 2023-1-2 17:41:44

jcpython2 发表于 2023-1-2 16:30
晕死,我终于看清了

return i


你都没有仔细看我的回答啊,我写的清清楚楚是字母i了啊

jcpython2 发表于 2023-1-2 18:29:15

洋洋痒 发表于 2023-1-2 17:41
你都没有仔细看我的回答啊,我写的清清楚楚是字母i了啊

有的,我有看你的代码的,主要是我一开始去读答案的时候把def chazhao的返回误会成1or-1,看你答案一边醒一边回,我还在消化中,再次感谢老哥

阿奇_o 发表于 2023-1-2 21:46:26

改进版本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)

chinajz 发表于 2023-1-3 15:18:49

楼上正解
页: [1]
查看完整版本: 实在无法理解这一块代码