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()
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)
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)
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)
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)
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"))
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
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)