zoukankan      html  css  js  c++  java
  • 使用Python编写的对拍程序

    简介

    支持数据生成程序模式, 只要有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配置文件
    ")
            settings['std'] = getinput(
                "标准程序源代码路径", "1. 不需要使用freopen
    2. 可以使用绝对路径或相对路径")
            settings['target'] = getinput(
                "测试程序源代码路径", "1. 不需要使用freopen
    2. 可以使用绝对路径或相对路径")
            settings['ifpro'] = confirm(
                "是否使用数据生成程序?", "若输入yes, 将会使用数据生成程序生成数据
    若输入no,  将会使用数据文件")
            if settings['ifpro']:
                settings['pro'] = getinput("数据生成程序路径", "源程序应该直接输出数据")
            else:
                settings['file'] = getinput(
                    "数据文件路径", "1. 可以使用绝对路径或相对路径
    2. 支持通配符")
            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("编译完成
    正在编译测试程序...", 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("
    输入:
    ")
                    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("
    输入:
    ")
                    with open("in.in", "r") as f:
                        print(f.read())
                    print("
    标准程序输出:
    ")
                    with open("std.out", "r") as f:
                        print(f.read())
                    print("
    测试程序输出:
    ")
                    with open("target.out", "r") as f:
                        print(f.read())
                    print("
    差异比较:
    ")
                    with open("diff.out", "r") as f:
                        print(f.read())
                    break
                else:
                    account += 1
                    print("
    # {} 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("
    输入保存在文件 result{}.in
    ".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("
    输入保存在文件result{}.in
    ".format(count))
                    shutil.copy(i, "result{}.in".format(count))
                    print("
    标准程序输出保存在文件 result{}.ans
    ".format(count))
                    shutil.copy("std.out", "result{}.out".format(count))
                    print("
    测试程序输出保存在文件 result{}.out
    ".format(count))
                    shutil.copy("target.out", "result{}.ans".format(count))
                    print("
    差异比较保存在文件 result{}.diff
    ".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("
    共测试 {} 个数据点".format(count))
    if count:
        print("{} 个数据点正确".format(account))
        print("正确率 {} %".format(round(account/count*100, 2)))
        if count:
            print("标准程序在正确的数据点中:
    	平均时间 {} s".format(round(sum(stdtimes)/count, 2)))
        print("	最长时间 {} s".format(round(max(stdtimes), 2)))
        print("	最短时间 {} s".format(round(min(stdtimes), 2)))
        if account:
            print("测试程序在正确的数据点中:
    	平均时间 {} s".format(round(sum(times)/account, 2)))
            print("	最长时间 {} s".format(round(max(times), 2)))
            print("	最短时间 {} 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")
    
  • 相关阅读:
    采用二叉搜索树来统计文本中单词出现的频率
    一个表查找程序
    unix grep命令的大致实现
    字符串操作函数
    关于宏和逗号表达式
    http状态码的分类
    nginx源码学习资源(不断更新)转
    什么是CGI
    字符串操作 删除字符
    Ubuntu安装特定版本安装包
  • 原文地址:https://www.cnblogs.com/youxam/p/check-with-python.html
Copyright © 2011-2022 走看看