462OJ搭建分享-输出结果评判

本文最后更新于:2024年4月22日 晚上

前言

有幸和zlr同学、lpf同学合作开发了462OJ1st项目。

作为一款OJ,最重要的功能就是评判用户程序的输出与期望输出是否一致。这当中就涉及到了两个需求:

  • 生成期望输出
  • 将期望输出与用户输出进行比较

这里就简单分享一下项目中,这两个需求是怎么实现的。

与另外两个人的工作相比,这个工作是最简单的

生成期望输出

项目当中使用了Toby Shi学长的魔改版Mars,通过命令行执行得到期望输出。

可以利用python的os库实现这一功能。

1
2
3
4
command = "java -jar mars.jar temp.asm mc CompactLargeText coL1 ig" 
# test.asm包含随机生成的测试点源码
with os.popen(command) as f:
answer = f.readlines()

os.popen(command):这种调用方式是通过管道的方式来实现,函数返回一个file对象,里面的内容是脚本输出的内容,可简单理解为echo输出的内容。

当然,有时候生成的随机数据点会存在一些问题,此时Mars的输出就会带有Error,此时我们就在answer里捕捉Error即可。

与此同时,也可以利用Mars生成相应的机器码,供.v文件执行。

1
2
3
command = "java -jar mars.jar a mc CompactLargeText dump .text HexText tempcode.txt temp.asm"
f = os.popen(command)
f.close()

比较输出

这里用到了python中的difflib库。

我才知道difflib是标准库

difflib可以对比文本之间的差异,并且支持输出可读性比较强的HTML文档,与Linux下的diff命令相似。

用法 说明
splitlines() 按照行(’\r’, ‘\r\n’, \n’)分隔,返回一个包含各行作为元素的列表,如果参数 keepends 为 False,不包含换行符,如果为 True,则保留换行符
d.compare(a,b) 比较两个行序列,并生成delta(一系列行)
difflib.HtmlDiff() 可以用于创建一个完整HTML文件,该文件显示具有行间和行内更改突出的文本的逐行比较
d.make_file(text1,text2) 比较两个字符串列表并返回一个字符串,该字符串是一个完整的HTML文件,其中包含一个表格,显示逐行差异,突出显示行间和行内更改
difflib.SequenceMatcher(None, s1, s2).ratio() None参数是一个函数,用来去掉不需要比较的字符。
s1,s2参数为两个需要计算相似度的字符串。
函数返回值是0~1之间的一个浮点数,如果为1则认为完全相等

最终的文本当中会出现一系列标识符,他们的含义如下。

符号 说明
‘-’ 包含在第一个系列行中,但不包含第二个
‘+’ 包含在第二个系列行中,但不包含第一个
’ ’ 两个系列行一致
‘?’ 存在增量差异
‘^’ 存在差异字符

实现文本对比

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import difflib
text1 = ''' 1. Beautiful is better than ugly.
2. Explicit is better than implicit.
3. Simple is better than complex.
4. Complex is better than complicated.
'''.splitlines(keepends=True)
text2 = ''' 1. Beautiful is better than ugly.
3. Simple is better than complex.
4. Complicated is better than complex.
5. Flat is better than nested.
'''.splitlines(keepends=True)

d = difflib.Differ()
print(''.join(list(d.compare(text1,text2))))

使用html对比

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import difflib
text1 = '''
1. Beautiful is better than gly.
2. Explicit is better than implicit.
3. Simple is better than complex.
4. Complex is better than complicated.
'''.splitlines(keepends=True)
text2 = '''
1. Beautiful is better than ugly.
3. Simple is better than complex.
4. Complicated is beter than complex.
5. Flat is better than nested.
'''.splitlines(keepends=True)

d = difflib.HtmlDiff()
htmlContent = d.make_file(text1,text2)
# print(htmlContent)
with open('diff.html','w') as f:
f.write(htmlContent)

输出的结果为:
输出结果

difflib库中的内容还有很多,欢迎大家前去探索!


462OJ搭建分享-输出结果评判
https://galaxy-jewxw.github.io/2023/11/07/462OJ搭建分享-输出结果评判/
作者
Traumtänzer aka 'Jew1!5!'
发布于
2023年11月7日
许可协议