def predict_judge_method(html: str) -> Judge:
    def normalize(sentence):
        return sentence.replace('\\', '').replace("{", "").replace("}", "").replace(",", "").replace(" ", "").replace(
            "−", "-").lower().strip()

    soup = BeautifulSoup(html, "html.parser")
    sentences = soup.get_text().split("\n")

    interactive_sentences = []

    for s in sentences:
        for kw in INTERACTIVE_ANCHORS:
            if kw in s:
                interactive_sentences.append(s)

    if len(interactive_sentences) > 0:
        return InteractiveJudge()

    decimal_sentences = [normalize(s)
                         for s in sentences if is_decimal_context(s)]

    decimal_keyword_cands = set()
    decimal_val_cands = set()

    if len(decimal_sentences) > 0:  # Decimal
        is_absolute = False
        is_relative = False
        for s in decimal_sentences:
            for regexp in DECIMAL_STRATEGY_RE_LIST_KEYWORD:
                r = regexp.findall(s)
                for t in r:
                    if t == "絶対誤差" or t == "absolute":
                        is_absolute = True
                    elif t == "相対誤差" or t == "relative":
                        is_relative = True
                    decimal_keyword_cands.add(t)
        for s in decimal_sentences:
            for regexp in DECIMAL_STRATEGY_RE_LIST_VAL:
                r = regexp.findall(s)
                for t in r:
                    decimal_val_cands.add(int(t))

        if len(decimal_val_cands) == 0:
            # No error value candidate is found
            return NormalJudge()

        if len(decimal_val_cands) == 1:
            if is_absolute and is_relative:
                error_type = ErrorType.AbsoluteOrRelative
            elif is_absolute:
                error_type = ErrorType.Absolute
            else:
                assert is_relative
                error_type = ErrorType.Relative

            return DecimalJudge(error_type, 10.0**(int(list(decimal_val_cands)[0])))

        raise MultipleDecimalCandidatesError(decimal_val_cands)

    return NormalJudge()
Beispiel #2
0
 def default_metadata():
     return Metadata(problem=None,
                     code_filename=None,
                     sample_in_pattern=DEFAULT_IN_EXAMPLE_PATTERN,
                     sample_out_pattern=DEFAULT_OUT_EXAMPLE_PATTERN,
                     lang=None,
                     judge_method=NormalJudge())
def predict_constants(html: str) -> ProblemConstantSet:
    try:
        yes_str, no_str = predict_yes_no(html)
    except YesNoPredictionFailedError:
        yes_str = no_str = None

    try:
        mod = predict_modulo(html)
    except MultipleModCandidatesError as e:
        logger.warning(
            "Modulo prediction failed -- "
            "two or more candidates {} are detected as modulo values".format(
                e.cands))
        mod = None

    try:
        judge = predict_judge_method(html)
    except MultipleModCandidatesError as e:
        logger.warning(
            "decimal prediction failed -- "
            "two or more candidates {} are detected as decimal values".format(
                e.cands))
        judge = NormalJudge()

    return ProblemConstantSet(mod=mod,
                              yes_str=yes_str,
                              no_str=no_str,
                              judge_method=judge)
Beispiel #4
0
    def from_dict(cls, dic):
        if "judge" in dic:
            judge_type = dic["judge"]["judge_type"]
            if judge_type == "normal":
                judge_method = NormalJudge.from_dict(dic["judge"])
            elif judge_type == "decimal":
                judge_method = DecimalJudge.from_dict(dic["judge"])
            else:
                raise Exception("invalid judge type")
        else:
            judge_method = NormalJudge()

        return Metadata(problem=Problem.from_dict(dic["problem"]),
                        code_filename=dic["code_filename"],
                        sample_in_pattern=dic["sample_in_pattern"],
                        sample_out_pattern=dic["sample_out_pattern"],
                        lang=Language.from_name(dic["lang"]),
                        judge_method=judge_method)
Beispiel #5
0
def get_sample_patterns_and_judge_method(
        metadata_file: str) -> Tuple[str, str, Judge]:
    try:
        metadata = Metadata.load_from(metadata_file)
        return metadata.sample_in_pattern, metadata.sample_out_pattern, metadata.judge_method
    except IOError:
        logger.warning(
            "{} is not found. Assume the example file name patterns are {} and {}"
            .format(metadata_file, DEFAULT_IN_EXAMPLE_PATTERN,
                    DEFAULT_OUT_EXAMPLE_PATTERN))
        return DEFAULT_IN_EXAMPLE_PATTERN, DEFAULT_OUT_EXAMPLE_PATTERN, NormalJudge(
        )
Beispiel #6
0
def run_for_samples(exec_file: str,
                    sample_pair_list: List[Tuple[str, str]],
                    timeout_sec: int,
                    judge_method: Judge = NormalJudge(),
                    knock_out: bool = False,
                    skip_io_on_success: bool = False) -> TestSummary:
    success_count = 0
    has_error_output = False
    for in_sample_file, out_sample_file in sample_pair_list:
        # Run program
        exec_res = run_program(exec_file,
                               in_sample_file,
                               timeout_sec=timeout_sec)

        # Output header
        with open(out_sample_file, 'r') as f:
            answer_text = f.read()

        is_correct = exec_res.is_correct_output(answer_text, judge_method)
        has_error_output = has_error_output or exec_res.has_stderr()

        if is_correct:
            if exec_res.has_stderr():
                message = with_color(
                    "CORRECT but with stderr (Please remove stderr!)",
                    Fore.LIGHTYELLOW_EX)
            else:
                message = "{} {elapsed} ms".format(with_color(
                    "PASSED", Fore.LIGHTGREEN_EX),
                                                   elapsed=exec_res.elapsed_ms)
            success_count += 1
        else:
            if exec_res.status == ExecStatus.NORMAL:
                message = with_color("WA", Fore.LIGHTRED_EX)
            else:
                message = with_color(exec_res.status.name, Fore.LIGHTYELLOW_EX)

        print("# {case_name} ... {message}".format(
            case_name=os.path.basename(in_sample_file),
            message=message,
        ))

        # Output details for incorrect results or has stderr.
        if not is_correct or (exec_res.has_stderr()
                              and not skip_io_on_success):
            print('{}\n'.format(
                build_details_str(exec_res, in_sample_file, out_sample_file)))

        if knock_out and not is_correct:
            print('Stop testing ...')
            break
    return TestSummary(success_count, has_error_output)
Beispiel #7
0
 def __init__(self,
              problem: Optional[Problem],
              code_filename: Optional[str],
              sample_in_pattern: Optional[str],
              sample_out_pattern: Optional[str],
              lang: Optional[Language],
              judge_method: Judge = NormalJudge()):
     self.problem = problem
     self.code_filename = code_filename
     self.sample_in_pattern = sample_in_pattern
     self.sample_out_pattern = sample_out_pattern
     self.lang = lang
     self.judge_method = judge_method
Beispiel #8
0
    def from_dict(cls, dic):
        if "judge" in dic:
            judge_type = dic["judge"]["judge_type"]
            if judge_type == "normal":
                judge_method = NormalJudge.from_dict(dic["judge"])
            elif judge_type == "decimal":
                judge_method = DecimalJudge.from_dict(dic["judge"])
            elif judge_type == "multisolution":
                judge_method = MultiSolutionJudge()
            elif judge_type == "interactive":
                judge_method = InteractiveJudge()
            else:
                raise NoJudgeTypeException()
        else:
            judge_method = NormalJudge()

        return Metadata(problem=Problem.from_dict(dic["problem"]),
                        code_filename=dic["code_filename"],
                        sample_in_pattern=dic["sample_in_pattern"],
                        sample_out_pattern=dic["sample_out_pattern"],
                        lang=Language.from_name(dic["lang"]),
                        judge_method=judge_method)
Beispiel #9
0
 def __init__(self,
              problem: Problem,
              code_filename: str,
              sample_in_pattern: str,
              sample_out_pattern: str,
              lang: Language,
              judge_method: Judge = NormalJudge()):
     self.problem = problem
     self.code_filename = code_filename
     self.sample_in_pattern = sample_in_pattern
     self.sample_out_pattern = sample_out_pattern
     self.lang = lang
     self.judge_method = judge_method
Beispiel #10
0
def _decide_judge_method(args: argparse.Namespace, metadata: Metadata,
                         lang: Optional[Language]):
    def _decide_decimal_judge():
        if args.error_value is not None:
            diff = args.error_value
        elif isinstance(metadata.judge_method, DecimalJudge):
            diff = metadata.judge_method.diff
        else:
            diff = DEFAULT_EPS

        if args.judge_type:
            assert args.judge_type in [
                "absolute", "relative", "absolute_or_relative"
            ]
            error_type = ErrorType(args.judge_type)
        elif isinstance(metadata.judge_method, DecimalJudge):
            error_type = metadata.judge_method.error_type
        else:
            raise Exception("Must not reach")

        return DecimalJudge(diff=diff, error_type=error_type)

    if args.judge_type is not None:
        if args.judge_type == "normal":
            return NormalJudge()
        elif args.judge_type in [
                "absolute", "relative", "absolute_or_relative"
        ]:
            return _decide_decimal_judge()
        elif args.judge_type == "multisolution":
            assert lang is not None
            return MultiSolutionJudge()
        elif args.judge_type == "interactive":
            assert lang is not None
            return InteractiveJudge()
        else:
            logger.error(
                "Unknown judge type: {}. judge type must be one of [{}]".
                format(args.judge_type,
                       ", ".join(USER_FACING_JUDGE_TYPE_LIST)))
            raise InvalidJudgeTypeError()

    if isinstance(metadata.judge_method, DecimalJudge):
        return _decide_decimal_judge()

    return metadata.judge_method
Beispiel #11
0
def main(prog, args) -> bool:
    parser = argparse.ArgumentParser(
        prog=prog,
        formatter_class=argparse.RawTextHelpFormatter)

    parser.add_argument("--exec", '-e',
                        help="File path to the execution target. [Default] Automatically detected exec file",
                        default=None)

    parser.add_argument("--num", '-n',
                        help="The case number to test (1-origin). All cases are tested if not specified.",
                        type=int,
                        default=None)

    parser.add_argument("--dir", '-d',
                        help="Target directory to test. [Default] Current directory",
                        default=".")

    parser.add_argument("--timeout", '-t',
                        help="Timeout for each test cases (sec) [Default] 1",
                        type=int,
                        default=1)

    parser.add_argument("--knock-out", '-k',
                        help="Stop execution immediately after any example's failure [Default] False",
                        action="store_true",
                        default=False)

    parser.add_argument('--skip-almost-ac-feedback', '-s',
                        help='Hide inputs and expected/actual outputs if result is correct and there are error outputs'
                             ' [Default] False,',
                        action='store_true',
                        default=False)

    parser.add_argument('--judge-type', '-j',
                        help='error type'
                             ' must be one of [{}]'.format(
                                 ', '.join(USER_FACING_JUDGE_TYPE_LIST)),
                        type=str,
                        default=None)

    parser.add_argument('--error-value', '-v',
                        help='error value for decimal number judge:'
                             ' [Default] ' + str(DEFAULT_EPS),
                        type=float,
                        default=None)

    parser.add_argument('--compile-before-testing', '-c',
                        help='compile source before testing [true, false]: '
                             ' [Default]: false',
                        type=bool,
                        default=None)

    parser.add_argument('--compile-only-when-diff-detected',
                        help='compile only when diff detected [true, false]'
                             ' [Default]: true',
                        type=bool,
                        default=None)

    parser.add_argument("--config",
                        help="File path to your config file\n{0}{1}".format("[Default (Primary)] {}\n".format(
                            USER_CONFIG_PATH),
                            "[Default (Secondary)] {}\n".format(
                                get_default_config_path()))
                        )

    args = parser.parse_args(args)

    config = get_config(args)

    if config.etc_config.compile_before_testing is not None and args.compile_before_testing is None:
        args.compile_before_testing = config.etc_config.compile_before_testing
    if args.compile_before_testing:
        if config.etc_config.compile_only_when_diff_detected is not None and args.compile_only_when_diff_detected is None:
            args.compile_only_when_diff_detected = config.etc_config.compile_only_when_diff_detected

    metadata_file = os.path.join(args.dir, "metadata.json")
    metadata = get_metadata(metadata_file)
    judge_method = metadata.judge_method
    lang = metadata.lang

    in_sample_file_list = sorted(
        glob.glob(os.path.join(args.dir, metadata.sample_in_pattern)))
    out_sample_file_list = sorted(
        glob.glob(os.path.join(args.dir, metadata.sample_out_pattern)))

    user_input_decimal_error_type = None
    if args.judge_type is not None:
        if args.judge_type == "normal":
            judge_method = NormalJudge()
        elif args.judge_type in ["absolute", "relative", "absolute_or_relative"]:
            user_input_decimal_error_type = ErrorType(args.judge_type)
        elif args.judge_type == "multisolution":
            judge_method = MultiSolutionJudge(lang.name)
        elif args.judge_type == "interactive":
            judge_method = InteractiveJudge(lang.name)
        else:
            logger.error("Unknown judge type: {}. judge type must be one of [{}]".format(
                args.judge_type, ", ".join(USER_FACING_JUDGE_TYPE_LIST)))
            sys.exit(-1)

    user_input_error_value = args.error_value

    if isinstance(judge_method, DecimalJudge):
        judge_method = DecimalJudge(error_type=user_input_decimal_error_type or judge_method.error_type,
                                    diff=user_input_error_value or judge_method.diff)
    elif user_input_decimal_error_type is not None:
        judge_method = DecimalJudge(error_type=user_input_decimal_error_type,
                                    diff=user_input_error_value or DEFAULT_EPS)
    elif user_input_error_value is not None:
        assert judge_method.judge_type == JudgeType.Normal
        logger.warn("error_value {} is ignored because this is normal judge".format(
            user_input_error_value))

    if isinstance(judge_method, DecimalJudge):
        logger.info("Decimal number judge is enabled. type={}, diff={}".format(
            judge_method.error_type.value, judge_method.diff))

    if metadata.code_filename is None or not args.compile_before_testing:
        print("compile is skipped and infer exec file")
        exclude_exec_files = []

        if hasattr(judge_method, "judge_exec_filename"):
            judge_method.judge_exec_filename = os.path.join(
                args.dir, judge_method.judge_exec_filename)
            exclude_exec_files.append(judge_method.judge_exec_filename)

        exec_file = args.exec or infer_exec_file(
            glob.glob(os.path.join(args.dir, '*')), exclude_exec_files)
    else:
        if args.compile_only_when_diff_detected:
            force_compile = True
        else:
            force_compile = False
        exec_file = lang.get_test_command('main', args.dir)
        print("command: ", exec_file)
        print("directory: ", args.dir)
        # Compile
        if not compile_main_and_judge_programs(metadata, args.dir, force_compile=force_compile):
            exit()

    if args.num is None:
        return run_all_tests(exec_file, in_sample_file_list, out_sample_file_list, args.timeout, args.knock_out,
                             args.skip_almost_ac_feedback, judge_method, args.dir)
    else:
        return run_single_test(exec_file, in_sample_file_list, out_sample_file_list, args.timeout, args.num,
                               judge_method, args.dir)
Beispiel #12
0
def run_for_samples(exec_file: str, sample_pair_list: List[Tuple[str, str]], timeout_sec: int,
                    judge_method: Judge = NormalJudge(), knock_out: bool = False,
                    skip_io_on_success: bool = False, cwd: str = "./") -> TestSummary:
    success_count = 0
    has_error_output = False
    for in_sample_file, out_sample_file in sample_pair_list:
        if judge_method.judge_type == JudgeType.Interactive:
            exec_res = run_interactive_program(exec_file,
                                               judge_method.judge_code_lang.get_test_command(
                                                   'judge', cwd),
                                               in_sample_file, out_sample_file,
                                               timeout_sec=timeout_sec,
                                               current_working_dir=cwd
                                               )
            is_correct = exec_res.is_correct_output(judge_method=judge_method)
        else:
            # Run program
            exec_res = run_program(exec_file, in_sample_file,
                                   timeout_sec=timeout_sec, current_working_dir=cwd)

            if judge_method.judge_type == JudgeType.MultiSolution:
                is_correct = exec_res.is_correct_output(
                    judge_method=judge_method, sample_input_file=in_sample_file, sample_output_file=out_sample_file, cwd=cwd)
            else:
                # Output header
                with open(out_sample_file, 'r') as f:
                    expected_answer_text = f.read()

                is_correct = exec_res.is_correct_output(
                    expected_answer_text, judge_method)

        if exec_res.output is None:
            exec_res.output = ""
        elif isinstance(exec_res.output, bytes):
            exec_res.output = exec_res.output.decode()
        if exec_res.stderr is None:
            exec_res.stderr = ""
        elif isinstance(exec_res.stderr, bytes):
            exec_res.stderr = exec_res.stderr.decode()

        has_error_output = has_error_output or exec_res.has_stderr()

        if is_correct:
            if exec_res.has_stderr():
                message = with_color(
                    "CORRECT but with stderr (Please remove stderr!)", Fore.LIGHTYELLOW_EX)
            else:
                message = "{} {elapsed} ms".format(
                    with_color("PASSED", Fore.LIGHTGREEN_EX),
                    elapsed=exec_res.elapsed_ms)
            success_count += 1
        else:
            if exec_res.status == ExecStatus.NORMAL:
                message = with_color("WA", Fore.LIGHTRED_EX)
            else:
                message = with_color(
                    exec_res.status.name, Fore.LIGHTYELLOW_EX)

        print("# {case_name} ... {message}".format(
            case_name=os.path.basename(in_sample_file),
            message=message,
        ))

        # Output details for incorrect results or has stderr.
        if not is_correct or (exec_res.has_stderr() and not skip_io_on_success):
            print('{}\n'.format(build_details_str(
                exec_res, in_sample_file, out_sample_file)))

        if knock_out and not is_correct:
            print('Stop testing ...')
            break
    return TestSummary(success_count, has_error_output)
Beispiel #13
0
def main(prog, args) -> None:
    if len(args) == 0:
        print("Usage: atcoder tools set [options]")
        return

    parser = argparse.ArgumentParser(
        prog=prog, formatter_class=argparse.RawTextHelpFormatter)

    parser.add_argument('--judge-type',
                        '-j',
                        help='error type'
                        ' must be one of [{}]'.format(
                            ', '.join(USER_FACING_JUDGE_TYPE_LIST)),
                        type=str,
                        default=None)

    parser.add_argument('--error-value',
                        '-v',
                        help='error value for decimal number judge:'
                        ' [Default] ' + str(DEFAULT_EPS),
                        type=float,
                        default=None)

    parser.add_argument(
        "--lang",
        help="Programming language of your template code, {}.\n".format(
            " or ".join([lang.name for lang in ALL_LANGUAGES])),
        default=None)

    parser.add_argument(
        "--dir",
        '-d',
        help="Target directory to test. [Default] Current directory",
        default=".")

    args = parser.parse_args(args)

    old_metadata = Metadata.load_from(os.path.join(args.dir, "metadata.json"))

    # Use the old metadata as base metadata.
    output_metadata = Metadata.load_from(
        os.path.join(args.dir, "metadata.json"))

    if args.judge_type in ["absolute", "relative", "absolute_or_relative"]:
        new_metadata_judge_type = "decimal"
    else:
        new_metadata_judge_type = args.judge_type

    old_metadata_judge_type = old_metadata.judge_method.judge_type.value

    if new_metadata_judge_type is not None and new_metadata_judge_type != old_metadata_judge_type:
        if new_metadata_judge_type == JudgeType.Normal.value:
            output_metadata.judge_method = NormalJudge()
        elif new_metadata_judge_type == JudgeType.Decimal.value:
            output_metadata.judge_method = DecimalJudge()
        elif new_metadata_judge_type == JudgeType.MultiSolution.value:
            output_metadata.judge_method = MultiSolutionJudge()
        elif new_metadata_judge_type == JudgeType.Interactive.value:
            output_metadata.judge_method = InteractiveJudge()
        else:
            raise NoJudgeTypeException()

    judge_code_filename = os.path.join(args.dir, "judge.cpp")

    if new_metadata_judge_type == JudgeType.Decimal.value:
        if args.error_value is not None:
            output_metadata.judge_method.diff = args.error_value
        else:
            logger.warn(
                "Error-value is not specified. Default value will be set.")
        output_metadata.judge_method.error_type = ErrorType(args.judge_type)

    elif new_metadata_judge_type == JudgeType.MultiSolution.value:
        if not os.path.exists(judge_code_filename):
            print("Creating {} (multi-solution)".format(judge_code_filename))
            judge_template_path = get_default_judge_template_path('cpp')
            shutil.copy(judge_template_path, judge_code_filename)
        else:
            print("Judge code exists. Skipping creating judge code...")
    elif new_metadata_judge_type == JudgeType.Interactive.value:
        if not os.path.exists(judge_code_filename):
            print("Creating {} (interactive)".format(judge_code_filename))
            judge_template_path = get_default_judge_template_path('cpp')
            shutil.copy(judge_template_path, judge_code_filename)
        else:
            print("Judge code exists. Skipping creating judge code...")

    if args.lang is not None:
        if args.lang != output_metadata.lang.name:
            output_metadata.lang = Language.from_name(args.lang)
            output_metadata.code_filename = output_metadata.lang.get_code_filename(
                'main')
            url = "https://atcoder.jp/contests/{}/tasks/{}".format(
                output_metadata.problem.contest.contest_id,
                output_metadata.problem.problem_id)
            main_code_filename = os.path.join(args.dir,
                                              output_metadata.code_filename)
            if not os.path.exists(main_code_filename):
                codegen_main("", ["--lang", output_metadata.lang.name, url],
                             open(main_code_filename, 'w'))
            else:
                print("File exists: ", output_metadata.code_filename)
        else:
            print("Already set to {}. Skipping changing language...".format(
                args.lang))
    output_metadata.save_to(os.path.join(args.dir, "metadata.json"))
Beispiel #14
0
    @classmethod
    def update_from_source(cls, old, program):
        dic = old.to_dict() if old else {}
        with open(program, 'r') as f:
            source = f.read()
        m = re.search(
            r'^# contest: (\S+?), problem: (\S+?), alphabet: (\S+?)$', source, re.MULTILINE)
        dic['code_filename'] = program
        dic['problem'] = {'alphabet': m.group(3),
                          'contest': {'contest_id': m.group(1)},
                          'problem_id': m.group(2)}
        ext = os.path.splitext(program)[1][1:]
        langs = [language for language in ALL_LANGUAGES if language.extension == ext]
        if len(langs) == 1:
            dic['lang'] = langs[0].name
        if 'sample_in_pattern' not in dic:
            dic['sample_in_pattern'] = DEFAULT_IN_EXAMPLE_PATTERN
        if 'sample_out_pattern' not in dic:
            dic['sample_out_pattern'] = DEFAULT_IN_EXAMPLE_PATTERN
        return cls.from_dict(dic)


DEFAULT_METADATA = Metadata(
    problem=None,
    code_filename=None,
    sample_in_pattern=DEFAULT_IN_EXAMPLE_PATTERN,
    sample_out_pattern=DEFAULT_OUT_EXAMPLE_PATTERN,
    lang=CPP,
    judge_method=NormalJudge()
)
Beispiel #15
0
def main(prog, args):
    if len(args) == 0:
        print("Usage: atcoder tools set [options]")
        return

    parser = argparse.ArgumentParser(
        prog=prog,
        formatter_class=argparse.RawTextHelpFormatter)

    parser.add_argument('--judge-type', '-j',
                        help='error type'
                             ' must be one of [{}]'.format(
                                 ', '.join(USER_FACING_JUDGE_TYPE_LIST)),
                        type=str,
                        default=None)

    parser.add_argument('--error-value', '-v',
                        help='error value for decimal number judge:'
                             ' [Default] ' + str(DEFAULT_EPS),
                        type=float,
                        default=None)

    parser.add_argument("--lang",
                        help="Programming language of your template code, {}.\n".format(
                            " or ".join([lang.name for lang in ALL_LANGUAGES])),
                        default=None)

    parser.add_argument("--dir", '-d',
                        help="Target directory to test. [Default] Current directory",
                        default=".")

    args = parser.parse_args(args)

    metadata = Metadata.load_from(args.dir + "/metadata.json")

    new_judge_type = args.judge_type
    if new_judge_type in ["decimal", "absolute", "relative", "absolute_or_relative"]:
        new_judge_type = "decimal"
        if args.judge_type == "decimal":
            args.judge_type = "absolute_or_relative"

    old_judge_type = metadata.judge_method.judge_type.value

    if new_judge_type is not None and new_judge_type != old_judge_type:
        if new_judge_type == JudgeType.Normal.value:
            metadata.judge_method = NormalJudge()
        elif new_judge_type == JudgeType.Decimal.value:
            metadata.judge_method = DecimalJudge()
        elif new_judge_type == JudgeType.MultiSolution.value:
            metadata.judge_method = MultiSolutionJudge()
        elif new_judge_type == JudgeType.Interactive.value:
            metadata.judge_method = InteractiveJudge()
        else:
            raise NoJudgeTypeException()

    if new_judge_type == JudgeType.Decimal.value:
        if args.error_value is not None:
            metadata.judge_method.diff = args.error_value
        else:
            print("Warning: error-value is not specified default value is set. ")
        metadata.judge_method.error_type = ErrorType(args.judge_type)
    elif new_judge_type == JudgeType.MultiSolution.value:
        if not os.path.exists("./judge.cpp"):
            print("touch ./judge.cpp (multi sotlution)")
            judge_template_path = get_default_judge_template_path('cpp')
            shutil.copy(judge_template_path, "./judge.cpp")
        else:
            print("Judge Code exists")
    elif new_judge_type == JudgeType.Interactive.value:
        if not os.path.exists("/judge.cpp"):
            print("touch ./judge.cpp (interactive)")
            judge_template_path = get_default_judge_template_path('cpp')
            shutil.copy(judge_template_path, "./judge.cpp")
        else:
            print("Judge Code exists")

    if args.lang is not None:
        if args.lang != metadata.lang.name:
            metadata.lang = Language.from_name(args.lang)
            metadata.code_filename = metadata.lang.get_code_filename('main')
            url = "https://atcoder.jp/contests/{}/tasks/{}".format(
                metadata.problem.contest.contest_id, metadata.problem.problem_id)
            if not os.path.exists(metadata.code_filename):
                codegen_main("", ["--lang", metadata.lang.name,
                                  url], open(metadata.code_filename, 'w'))
            else:
                print("file exists: ", metadata.code_filename)
        else:
            print("already set to {}".format(args.lang))
    metadata.save_to(args.dir + "/metadata.json")
    return metadata
Beispiel #16
0
def main(prog, args) -> bool:
    parser = argparse.ArgumentParser(
        prog=prog, formatter_class=argparse.RawTextHelpFormatter)

    parser.add_argument(
        "--exec",
        '-e',
        help=
        "File path to the execution target. [Default] Automatically detected exec file",
        default=None)

    parser.add_argument(
        "--num",
        '-n',
        help=
        "The case number to test (1-origin). All cases are tested if not specified.",
        type=int,
        default=None)

    parser.add_argument(
        "--dir",
        '-d',
        help="Target directory to test. [Default] Current directory",
        default=".")

    parser.add_argument("--timeout",
                        '-t',
                        help="Timeout for each test cases (sec) [Default] 1",
                        type=int,
                        default=1)

    parser.add_argument(
        "--knock-out",
        '-k',
        help=
        "Stop execution immediately after any example's failure [Default] False",
        action="store_true",
        default=False)

    parser.add_argument(
        '--skip-almost-ac-feedback',
        '-s',
        help=
        'Hide inputs and expected/actual outputs if result is correct and there are error outputs'
        ' [Default] False,',
        action='store_true',
        default=False)

    parser.add_argument('--judge-type',
                        '-j',
                        help='error type'
                        ' must be one of [{}]'.format(
                            ', '.join(USER_FACING_JUDGE_TYPE_LIST)),
                        type=str,
                        default=None)

    parser.add_argument('--error-value',
                        '-v',
                        help='error value for decimal number judge:'
                        ' [Default] ' + str(DEFAULT_EPS),
                        type=float,
                        default=None)

    args = parser.parse_args(args)
    exec_file = args.exec or infer_exec_file(
        glob.glob(os.path.join(args.dir, '*')))

    metadata_file = os.path.join(args.dir, "metadata.json")
    in_ex_pattern, out_ex_pattern, judge_method = get_sample_patterns_and_judge_method(
        metadata_file)

    in_sample_file_list = sorted(
        glob.glob(os.path.join(args.dir, in_ex_pattern)))
    out_sample_file_list = sorted(
        glob.glob(os.path.join(args.dir, out_ex_pattern)))

    user_input_decimal_error_type = None
    if args.judge_type is not None:
        if args.judge_type == "normal":
            judge_method = NormalJudge()
        elif args.judge_type in [
                "absolute", "relative", "absolute_or_relative"
        ]:
            user_input_decimal_error_type = ErrorType(args.judge_type)
        else:
            logger.error(
                "Unknown judge type: {}. judge type must be one of [{}]".
                format(args.judge_type,
                       ", ".join(USER_FACING_JUDGE_TYPE_LIST)))
            sys.exit(-1)

    user_input_error_value = args.error_value

    if isinstance(judge_method, DecimalJudge):
        judge_method = DecimalJudge(error_type=user_input_decimal_error_type
                                    or judge_method.error_type,
                                    diff=user_input_error_value
                                    or judge_method.diff)
    elif user_input_decimal_error_type is not None:
        judge_method = DecimalJudge(error_type=user_input_decimal_error_type,
                                    diff=user_input_error_value or DEFAULT_EPS)
    elif user_input_error_value is not None:
        assert judge_method.judge_type == JudgeType.Normal
        logger.warn(
            "error_value {} is ignored because this is normal judge".format(
                user_input_error_value))

    if isinstance(judge_method, DecimalJudge):
        logger.info("Decimal number judge is enabled. type={}, diff={}".format(
            judge_method.error_type.value, judge_method.diff))

    if args.num is None:
        return run_all_tests(exec_file, in_sample_file_list,
                             out_sample_file_list, args.timeout,
                             args.knock_out, args.skip_almost_ac_feedback,
                             judge_method)
    else:
        return run_single_test(exec_file, in_sample_file_list,
                               out_sample_file_list, args.timeout, args.num,
                               judge_method)