예제 #1
0
 def f(x):
     try:
         y = float(x)
         if not math.isfinite(y):
             log.faster_warning('not an real number found: %f', y)
         return y
     except ValueError:
         return x
예제 #2
0
        def match(a, b):
            # 自分で書き換えた箇所
            a = a.replace(chr(13), '')
            b = b.replace(chr(13), '')
            if a == b:
                return 'AC'
            if args.rstrip and a.rstrip(rstrip_targets) == b.rstrip(rstrip_targets):
                log.faster_warning('WA if no rstrip')
                return 'AC'

            # 自分で書き換えた箇所
            # 小数出力の誤差許容
            def make_outlist(s):
                outlist = []
                tmp_token = ''
                for i in range(len(s)):
                    if s[i] == ' ' or s[i] == '\n' or i == len(s)-1:
                        if tmp_token != '':
                            outlist.append(tmp_token)
                        tmp_token = ''
                        continue
                    else:
                        tmp_token += s[i]
                return outlist

            outlist_a = make_outlist(a)
            outlist_b = make_outlist(b)

            if len(outlist_a) == len(outlist_b):
                flg = False
                for i in range(len(outlist_a)):
                    def isnum(s):
                        ''' 小数点およびマイナスも含めて数字であるか '''
                        try:
                            int(s)
                        except:
                            return re.fullmatch(r'[-]?[0-9]+[.][0-9]+', s) != None
                        return True

                    if isnum(outlist_a[i]) and isnum(outlist_b[i]):
                        # b が correct だと想定
                        if '.' in outlist_b[i]:
                            flg = True
                        permissible_error = float('1e-6')
                        if not (abs(float(outlist_a[i]) - float(outlist_b[i])) <= permissible_error or abs(float(outlist_a[i]) - float(outlist_b[i])) <= abs(float(outlist_b[i])) * permissible_error):
                            return 'WA'
                    else:
                        return 'WA'
                return ['AC_with_error', flg]
            return 'WA'
예제 #3
0
def download(args: 'argparse.Namespace') -> None:
    # prepare values
    problem = onlinejudge.dispatch.problem_from_url(args.url)
    if problem is None:
        sys.exit(1)
    is_default_format = args.format is None and args.directory is None  # must be here since args.directory and args.format are overwritten
    if args.directory is None:
        args.directory = pathlib.Path('test')
    if args.format is None:
        if args.system:
            if problem.get_service().get_name() == 'yukicoder':
                args.format = '%b.%e'
            else:
                args.format = '%i.%e'
        else:
            args.format = 'sample-%i.%e'

    # get samples from the server
    with utils.with_cookiejar(utils.new_default_session(),
                              path=args.cookie) as sess:
        if args.system:
            samples = problem.download_system_cases(
                session=sess)  # type: ignore
        else:
            samples = problem.download_sample_cases(
                session=sess)  # type: ignore

    # append the history for submit command
    if not args.dry_run and is_default_format:
        history = onlinejudge.implementation.download_history.DownloadHistory()
        history.add(problem)

    # write samples to files
    for i, sample in enumerate(samples):
        log.faster_emit('')
        log.faster_info('sample %d', i)
        for kind in ['input', 'output']:
            ext = kind[:-3]
            data = getattr(sample, kind).data
            name = getattr(sample, kind).name
            table = {}
            table['i'] = str(i + 1)
            table['e'] = ext
            table['n'] = name
            table['b'] = os.path.basename(name)
            table['d'] = os.path.dirname(name)
            path = args.directory / utils.percentformat(
                args.format, table)  # type: pathlib.Path
            log.faster_status('%sput: %s', ext, name)
            log.faster_emit(colorama.Style.BRIGHT + data.rstrip() +
                            colorama.Style.RESET_ALL)
            if args.dry_run:
                continue
            if path.exists():
                log.faster_warning('file already exists: %s', path)
                if not args.overwrite:
                    log.faster_warning('skipped')
                    continue
            path.parent.mkdir(parents=True, exist_ok=True)
            with path.open('w') as fh:
                fh.write(data)
            log.faster_success('saved to: %s', path)

    # print json
    if args.json:
        print(json.dumps(list(map(convert_sample_to_dict, samples))))
예제 #4
0
def test(args: 'argparse.Namespace') -> None:
    # prepare
    if not args.test:
        args.test = cutils.glob_with_format(args.directory, args.format)  # by default
    if args.ignore_backup:
        args.test = cutils.drop_backup_or_hidden_files(args.test)
    # 自分で書き換えた箇所
    f = open('onlinejudge/communication.py', 'r')
    com_prob = f.read().split()[1]
    f.close()
    path = com_prob.upper() + '/test'
    args.test = []
    for p in os.listdir(path):
        args.test.append(pathlib.Path(com_prob.upper() + '/test/' + p))
    tests = cutils.construct_relationship_of_files(args.test, args.directory, args.format)
    if args.error: # float mode
        match = lambda a, b: compare_as_floats(a, b, args.error)
    else:
        def match(a, b):
            # 自分で書き換えた箇所
            a = a.replace(chr(13), '')
            b = b.replace(chr(13), '')
            if a == b:
                return 'AC'
            if args.rstrip and a.rstrip(rstrip_targets) == b.rstrip(rstrip_targets):
                log.faster_warning('WA if no rstrip')
                return 'AC'

            # 自分で書き換えた箇所
            # 小数出力の誤差許容
            def make_outlist(s):
                outlist = []
                tmp_token = ''
                for i in range(len(s)):
                    if s[i] == ' ' or s[i] == '\n' or i == len(s)-1:
                        if tmp_token != '':
                            outlist.append(tmp_token)
                        tmp_token = ''
                        continue
                    else:
                        tmp_token += s[i]
                return outlist

            outlist_a = make_outlist(a)
            outlist_b = make_outlist(b)

            if len(outlist_a) == len(outlist_b):
                flg = False
                for i in range(len(outlist_a)):
                    def isnum(s):
                        ''' 小数点およびマイナスも含めて数字であるか '''
                        try:
                            int(s)
                        except:
                            return re.fullmatch(r'[-]?[0-9]+[.][0-9]+', s) != None
                        return True

                    if isnum(outlist_a[i]) and isnum(outlist_b[i]):
                        # b が correct だと想定
                        if '.' in outlist_b[i]:
                            flg = True
                        permissible_error = float('1e-6')
                        if not (abs(float(outlist_a[i]) - float(outlist_b[i])) <= permissible_error or abs(float(outlist_a[i]) - float(outlist_b[i])) <= abs(float(outlist_b[i])) * permissible_error):
                            return 'WA'
                    else:
                        return 'WA'
                return ['AC_with_error', flg]
            return 'WA'

    rstrip_targets = ' \t\r\n\f\v\0'  # ruby's one, follow AnarchyGolf
    slowest = -1  # type: Union[int, float]
    slowest_name = ''
    ac_count = 0
    ac_with_error_count = 0
    error_permission = False

    history = []  # type: List[Dict[str, Any]]
    for name, it in sorted(tests.items()):
        is_printed_input = not args.print_input
        def print_input():
            nonlocal is_printed_input
            if not is_printed_input:
                is_printed_input = True
                with open(it['in']) as inf:
                    log.faster_emit('input:\n%s', log.bold(inf.read()))

        log.faster_emit('')
        log.faster_info('%s', name)

        # run the binary
        with it['in'].open() as inf:
            begin = time.perf_counter()
            answer_byte, proc = utils.exec_command(args.command, shell=True, stdin=inf, timeout=args.tle)
            end = time.perf_counter()
            elapsed = end - begin
            answer = answer_byte.decode()
            if slowest < elapsed:
                slowest = elapsed
                slowest_name = name
            log.faster_status('time: %f sec', elapsed)
            proc.terminate()

        # check TLE, RE or not
        result = 'AC'
        if proc.returncode is None:
            log.faster_failure(log.red('TLE'))
            result = 'TLE'
            print_input()
        elif proc.returncode != 0:
            log.faster_failure(log.red('RE') + ': return code %d', proc.returncode)
            result = 'RE'
            print_input()

        # check WA or not
        if 'out' in it:
            with it['out'].open() as outf:
                correct = outf.read()
            # compare
            if args.mode == 'all':
                if match(answer, correct) == 'WA':
                    log.faster_failure(log.red('WA'))
                    print_input()
                    if not args.silent:
                        log.faster_emit('output:\n%s', log.bold(answer))
                        log.faster_emit('expected:\n%s', log.bold(correct))
                    result = 'WA'
                elif match(answer, correct) == ['AC_with_error', True]:
                    print_input()
                    if not args.silent:
                        log.faster_emit('output:\n%s', log.bold(answer))
                        log.faster_emit('expected:\n%s', log.bold(correct))
                    result = 'AC_with_error'
                    error_permission = True
                elif match(answer, correct) == ['AC_with_error', False]:
                    print_input()
                    if not args.silent:
                        log.faster_emit('output:\n%s', log.bold(answer))
                        log.faster_emit('expected:\n%s', log.bold(correct))
                    result = 'AC_with_error'
            elif args.mode == 'line':
                answer_words  = answer .splitlines()
                correct_words = correct.splitlines()
                for i, (x, y) in enumerate(zip(answer_words + [ None ] * len(correct_words), correct_words + [ None ] * len(answer_words))):  # type: ignore
                    if x is None and y is None:
                        break
                    elif x is None:
                        print_input()
                        log.faster_failure(log.red('WA') + ': line %d: line is nothing: expected "%s"', i + 1, log.bold(y))
                        result = 'WA'
                    elif y is None:
                        print_input()
                        log.faster_failure(log.red('WA') + ': line %d: unexpected line: output "%s"', i + 1, log.bold(x))
                        result = 'WA'
                    elif match(x, y) == 'WA':
                        print_input()
                        log.faster_failure(log.red('WA') + ': line %d: output "%s": expected "%s"', i + 1, log.bold(x), log.bold(y))
                        result = 'WA'
            else:
                assert False
        else:
            if not args.silent:
                log.faster_emit(log.bold(answer))
        if result == 'AC':
            log.faster_success(log.green('AC'))
            ac_count += 1
        elif result == 'AC_with_error':
            log.faster_success(log.green('AC (with error)'))
            ac_count += 1
            ac_with_error_count += 1

        # push the result
        testcase = {
            'name': name,
            'input': str(it['in'].resolve()),
        }
        if 'out' in it:
            testcase['output'] = str(it['out'].resolve())
        history += [ {
            'result': result,
            'testcase': testcase,
            'output': answer,
            'exitcode': proc.returncode,
            'elapsed': elapsed,
        } ]

    # summarize
    log.faster_emit('')
    log.faster_status('slowest: %f sec  (for %s)', slowest, slowest_name)
    if ac_count == len(tests):
        # 自分で書き換えた箇所
        if ac_with_error_count > 0:
            if error_permission == True:
                log.faster_success('test ' + log.green('success (with error)') + ': %d cases', len(tests))
            else:
                log.faster_failure('test ' + log.green('success (with error)') + ': %d cases', len(tests))
                log.faster_error('your answer has error while correct answer has no error')
                log.faster_warning('please remove error from your answer')
                f = open('onlinejudge/communication.py', 'r')
                com_prev = f.readlines()
                f.close()
                f = open('onlinejudge/communication.py', 'w')
                f.writelines([' '.join(com_prev[0].split())] + [' ', 'WA', '\n'] + com_prev[1].split())
                f.close()
        else:
            log.faster_success('test ' + log.green('success') + ': %d cases', len(tests))
        # 自分で書き換えた箇所
        f = open('onlinejudge/communication.py', 'r')
        com_prev = f.readlines()
        f.close()
        f = open('onlinejudge/communication.py', 'w')
        f.writelines([' '.join(com_prev[0].split())] + [' ', 'AC', '\n'] + com_prev[1].split())
        f.close()
    else:
        log.faster_failure('test ' + log.red('failed') + ': %d AC / %d cases', ac_count, len(tests))
        # 自分で書き換えた箇所
        f = open('onlinejudge/communication.py', 'r')
        com_prev = f.readlines()
        f.close()
        f = open('onlinejudge/communication.py', 'w')
        f.writelines([' '.join(com_prev[0].split())] + [' ', 'WA', '\n'] + com_prev[1].split())
        f.close()

    if args.json:
        print(json.dumps(history))

    if ac_count != len(tests):
        sys.exit(1)
예제 #5
0
import os
import subprocess
import datetime
import re

contest_name = 'abc159'  # 暫定
command_list = ['init', 'info', 'standby', 'login', 'nosub', 'sub']

if __name__ == '__main__':
    args = [] + sys.argv[1:]
    for i in range(len(args)):
        cmd = args[i]
        if cmd not in command_list and re.fullmatch(r'[a-zA-Z][.](cpp|py|awk)',
                                                    cmd) == None:
            log.faster_error('invalid comand was called')
            log.faster_warning(f'please run the valid comand: {command_list}')
            sys.exit()
        if cmd == 'nosub' or cmd == 'sub':
            if i == 0 or re.fullmatch(r'[a-zA-Z][.](cpp|py|awk)',
                                      args[i - 1]) == None:
                log.faster_error('invalid command was called')
                log.faster_warning(
                    f'\'{cmd}\' takes the file name as an argument')
                sys.exit()

    # 初期化
    if 'init' in args:
        if len(args) != 1:
            log.faster_error('invalid argument')
            log.faster_warning(
                f'\'init\' takes no argument ({len(args) - 1} given)')