简介

支持数据生成程序模式, 只要有RE或者WA的数据点, 就会停止

支持数据文件模式, 使用通配符指定输入文件, 将会对拍所有文件

结束后将会打印统计信息

第一次在某目录执行,将会通过交互方式获取配置, 生成配置文件, 以后读取配置文件运行

支持Linux和Windows系统

代码

#!/usr/bin/python3
import os
import json
import platform
import time
import glob
import shutil def confirm(msg, helpi=''):
while True:
cmd = input("{} [yes]/no{} : ".format(msg, "/help" if helpi else ''))
if cmd == "no":
return False
elif cmd == "help" and helpi:
print(helpi)
else:
return True def getinput(msg, helpi=''):
while True:
cmd = input("{} {} : ".format(msg, "<input>/help" if helpi else ''))
if cmd == "help" and helpi:
print()
print(helpi)
print()
elif cmd:
return cmd settings = {}
if not os.path.isfile("checkx.json"):
try:
print("未找到checkx.json配置文件\n")
settings['std'] = getinput(
"标准程序源代码路径", "1. 不需要使用freopen\n2. 可以使用绝对路径或相对路径")
settings['target'] = getinput(
"测试程序源代码路径", "1. 不需要使用freopen\n2. 可以使用绝对路径或相对路径")
settings['ifpro'] = confirm(
"是否使用数据生成程序?", "若输入yes, 将会使用数据生成程序生成数据\n若输入no, 将会使用数据文件")
if settings['ifpro']:
settings['pro'] = getinput("数据生成程序路径", "源程序应该直接输出数据")
else:
settings['file'] = getinput(
"数据文件路径", "1. 可以使用绝对路径或相对路径\n2. 支持通配符")
with open("checkx.json", "w") as f:
f.write(json.dumps(settings))
except KeyboardInterrupt:
exit(0)
else:
with open("checkx.json", "r") as f:
settings = json.loads(f.read())
print("正在编译标准程序...", end='')
os.system("g++ {} -DDEBUG -o {}.out".format(settings['std'], settings['std']))
print("编译完成\n正在编译测试程序...", end='')
os.system(
"g++ {} -DDEBUG -o {}.out".format(settings['target'], settings['target']))
print("编译完成")
if "Windows" in platform.platform():
diffcmd = "fc /w target.out std.out > diff.out"
else:
diffcmd = "diff -ZE target.out std.out > diff.out"
count = 0
times = []
stdtimes = []
account = 0
if settings['ifpro']:
try:
while True:
count += 1
os.system(".{}{} > in.in".format(os.sep, settings['pro']))
zerotime = time.time()
os.system(".{}{} < in.in > std.out".format(os.sep, settings['std']+".out"))
begin = time.time()
stdtimes.append(begin-zerotime)
if not os.system("{} < in.in > target.out".format(settings['target']+".out")):
print()
print("# {} Runtime Error".format(count))
print("\n输入:\n")
with open("in.in", "r") as f:
print(f.read())
break
end = time.time()
times.append(end-begin)
if os.system(diffcmd):
print()
print("Wrong Answer")
print("\n输入:\n")
with open("in.in", "r") as f:
print(f.read())
print("\n标准程序输出:\n")
with open("std.out", "r") as f:
print(f.read())
print("\n测试程序输出:\n")
with open("target.out", "r") as f:
print(f.read())
print("\n差异比较:\n")
with open("diff.out", "r") as f:
print(f.read())
break
else:
account += 1
print("\r# {} Accepted {}s".format(
count, round(end-begin, 2)), end='')
except KeyboardInterrupt:
pass
else:
try:
for i in glob.glob(settings['file']):
count += 1
zerotime = time.time()
os.system(".{}{} < {} > std.out".format(os.sep, settings['std']+".out", i))
begin = time.time()
stdtimes.append(begin-zerotime)
if not os.system(".{}{} < {} > target.out".format(os.sep, settings['target']+".out", i)):
print("# {} Runtime Error".format(count))
print("\n输入保存在文件 result{}.in\n".format(count))
shutil.copy(i, "result{}.in".format(count))
continue
end = time.time()
times.append(end-begin)
if os.system(diffcmd):
print("# {} Wrong Answer".format(count))
print("\n输入保存在文件result{}.in\n".format(count))
shutil.copy(i, "result{}.in".format(count))
print("\n标准程序输出保存在文件 result{}.ans\n".format(count))
shutil.copy("std.out", "result{}.out".format(count))
print("\n测试程序输出保存在文件 result{}.out\n".format(count))
shutil.copy("target.out", "result{}.ans".format(count))
print("\n差异比较保存在文件 result{}.diff\n".format(count))
shutil.copy("diff.out", "result{}.diff".format(count))
else:
account += 1
print("# {} Accepted {}s".format(count, round(end-begin, 2)))
except KeyboardInterrupt:
pass
print("\n共测试 {} 个数据点".format(count))
if count:
print("{} 个数据点正确".format(account))
print("正确率 {} %".format(round(account/count*100, 2)))
if count:
print("标准程序在正确的数据点中:\n\t平均时间 {} s".format(round(sum(stdtimes)/count, 2)))
print("\t最长时间 {} s".format(round(max(stdtimes), 2)))
print("\t最短时间 {} s".format(round(min(stdtimes), 2)))
if account:
print("测试程序在正确的数据点中:\n\t平均时间 {} s".format(round(sum(times)/account, 2)))
print("\t最长时间 {} s".format(round(max(times), 2)))
print("\t最短时间 {} s".format(round(min(times), 2)))
os.remove("diff.out")
os.remove("std.out")
os.remove("target.out")
os.remove(settings['std']+".out")
os.remove(settings['target']+".out")
if settings['ifpro']:
os.remove("in.in")

最新文章

  1. NOIp 2016 总结
  2. 移动混合应用HTML5数据查询优化
  3. Radar Installation(贪心)
  4. #ifdef预编译相关用法
  5. Find your present (2) (位异或)
  6. INDEX FAST FULL SCAN和INDEX FULL SCAN
  7. 阿里UX矢量图标库–最强大的矢量图标库(Icon font制作力荐工具)
  8. cxf webservice异步调用
  9. Android进程间通信(IPC)机制Binder简介和学习计划
  10. Ansible系列(二):选项和常用模块
  11. 错误:Invalid action class configuration that references an unknown class named [XXX]的解决
  12. 企业内部DNS跨国配置案例
  13. session 存到memcache里
  14. fatal error: No such file or directory
  15. ECharts基础
  16. 为JSP写的一套核心标签
  17. google test框架与eclipse插件
  18. Android Studio占用C盘内存
  19. 实战:mysql检查物理磁盘中的二进制日志文件是否有丢失
  20. vue基础——组件(组件嵌套)

热门文章

  1. 对SSH框架的理解
  2. 制作zipkin docker镜像
  3. linux安装QT-Designer两种方法
  4. filebeat v6.3 多行合并的步骤 多个表达式同时匹配
  5. 小师妹学JavaIO之:NIO中那些奇怪的Buffer
  6. (二)JPA实体类主键生成策略
  7. apt用法详解
  8. Winner Winner【模拟、位运算】
  9. python基础--程序交互、格式化输出、流程控制、break、continue
  10. CODING DevOps 系列第四课:DevOps 中的质量内建实践