Exemple #1
0
def get_graders(task: IOITask):
    """
    Get the paths of all the graders/stubs according to the task type.
    """
    if task.task_type == TaskType.Communication:
        return list_files(["sol/stub.*"])
    else:
        return list_files(["sol/grader.*"])
Exemple #2
0
def check_att_folder(task: IOITask, solutions: List[Solution],
                     interface: IOIUIInterface):
    """
    Check if the following files are present:
    - grader.* for all the languages which have a solution
    - task_name.* for all the languages above
    - task_name.inputX.txt / task_name.outputX.txt / inputX.txt / outputX.txt
      making sure that they are symlinks
    """
    languages = _get_languages(solutions)
    _check_graders("att/", languages, solutions, interface)
    if _has_grader(solutions):
        for language in languages:
            if not os.path.exists("att/{}{}".format(
                    task.name, language.source_extension)):
                interface.add_warning("Missing {}{} in att/ folder".format(
                    task.name, language.source_extension))
    sample_files = list_files([
        "att/input*.txt", "att/output*.txt",
        "att/{}.input*.txt".format(task.name),
        "att/{}.output*.txt".format(task.name)
    ])
    for sample in sample_files:
        if not os.path.islink(sample):
            interface.add_warning(
                "Sample file {} is not a symlink".format(sample))
    if len(sample_files):
        interface.add_warning("No sample files provided")
Exemple #3
0
def get_official_solution() -> Optional[str]:
    """
    Get the first solution that matches sol/solution.* or sol/soluzione.*
    If no solution is found None is returned.
    """
    for sol in list_files(["sol/solution.*", "sol/soluzione.*"]):
        return sol
    return None
Exemple #4
0
def get_validator() -> Optional[str]:
    """
    Get the first validator that matches gen/validator.* or gen/valida.*
    If no validator is found None is returned.
    """
    for validator in list_files(["gen/validator.*", "gen/valida.*"]):
        return validator
    return None
Exemple #5
0
def get_generator() -> Optional[str]:
    """
    Get the first generator that matches gen/generator.* or gen/generatore.*
    If no generator is found None is returned.
    """
    for generator in list_files(["gen/generator.*", "gen/generatore.*"]):
        return generator
    return None
Exemple #6
0
def get_manager() -> Optional[str]:
    """
    Get the first manager that matches check/manager.* or cor/manager.*
    If no manager is found None is returned.
    """
    managers = list_files(["check/manager.*", "cor/manager.*"])
    if not managers:
        manager = None
    elif len(managers) == 1:
        manager = managers[0]
    else:
        raise ValueError("Too many managers in check/cor folder")
    return manager
Exemple #7
0
def get_checker() -> Optional[str]:
    """
    Get the first checker that matches check/checker.* or cor/correttore.*
    If no checker is found None is returned.
    """
    checkers = list_files(["check/checker.*", "cor/correttore.*"])
    if not checkers:
        checker = None
    elif len(checkers) == 1:
        checker = checkers[0]
    else:
        raise ValueError("Too many checkers in check/cor folder")
    return checker
Exemple #8
0
def check_sol_folder(solutions: List[Solution], interface: IOIUIInterface):
    """
    Check if the following files are present:
    - grader.* for all the languages which have a solution
    - solution.* / soluzione.cpp is a symlink
    """
    languages = _get_languages(solutions)
    _check_graders("sol/", languages, solutions, interface)
    sols = list_files(["sol/solution.*", "sol/soluzione.*"])
    if len(sols) > 1:
        interface.add_warning("More than one official solution found")
    for sol in sols:
        if not os.path.islink(sol):
            interface.add_warning(
                "Official solution {} is not a symlink".format(sol))
Exemple #9
0
def compile_statements(pool: ExecutionPool, task: IOITask,
                       interface: IOIUIInterface):
    """
    Create the statement compilation part of the DAG
    """
    tex_files = list_files(["statement/*.tex", "testo/*.tex"],
                           valid_extensions=[".tex"])
    for tex_file in tex_files:
        pdf_file = tex_file.replace(".tex", ".pdf")
        language = os.path.split(os.path.splitext(tex_file)[0])[1]
        statement = OIITexStatement(task, os.path.abspath(tex_file))
        statement.compile(pool, language)
        if not pool.config.dry_run:
            statement.pdf_file.getContentsToFile(pdf_file, True, True)
        interface.add_statement(statement)
Exemple #10
0
    def make_booklet(frontend: Frontend, config: Config,
                     tasks: List[Tuple[str, IOITask]]) -> int:
        statements = dict()  # type: Dict[str, List[OIITexStatement]]
        for path, task in tasks:
            config.task_dir = path
            os.chdir(path)
            tex_files = list_files(["statement/*.tex", "testo/*.tex"],
                                   valid_extensions=[".tex"])
            for tex_file in tex_files:
                lang = os.path.basename(tex_file)[:-4]
                statement = OIITexStatement(task, os.path.abspath(tex_file))
                if lang not in statements:
                    statements[lang] = list()
                statements[lang].append(statement)

        if config.ui == UIS.PRINT:
            printer = StdoutPrinter()
        else:
            printer = Printer()
        ui_printer = UIPrinter(printer, config.ui == UIS.JSON)
        pool = ExecutionPool(config, frontend, ui_printer)

        successful_compilations = 0
        for lang, texts in statements.items():
            file_name = "booklet_%s.pdf" % lang
            target_file = os.path.join(config.contest_dir, file_name)
            compilation, pdf_file, deps = OIITexStatement.compile_booklet(
                pool, texts, lang)
            if not pool.config.dry_run:
                pdf_file.getContentsToFile(target_file)

            def on_done(res: Result):
                nonlocal successful_compilations
                if res.status == ResultStatus.SUCCESS or \
                        res.status == ResultStatus.RETURN_CODE:
                    successful_compilations += 1

            compilation.bind(on_done)

        pool.start()
        return len(statements) - successful_compilations
Exemple #11
0
def get_manager(manager: str,
                target_arch: Arch,
                optional: bool = False) -> Optional[SourceFile]:
    """
    Search for a manager and create the relative SourceFile. `manager` is the
    base name without the extension (eg. "checker"). If `optional` is set to
    true and no managers are found, None is returned, otherwise an exception is
    raised.
    """
    managers = list_files(["managers/%s.*" % manager],
                          exclude=["managers/%s.*.*" % manager])
    if len(managers) == 0:
        if not optional:
            raise FileNotFoundError("Missing manager: %s" % manager)
        return None
    if len(managers) != 1:
        raise ValueError("Ambiguous manager: " + ", ".join(managers))
    return SourceFile.from_file(
        managers[0], manager, True,
        "managers/%s%s" % (manager, get_extension(target_arch)), target_arch,
        {})
Exemple #12
0
def _get_statement_tex():
    return list_files(["statement/*.tex", "testo/*.tex"],
                      valid_extensions=[".tex"])
Exemple #13
0
def check_sample_cases(task: IOITask, pool: ExecutionPool,
                       interface: IOIUIInterface):
    """
    Check if the sample cases in the statement are valid and the output is
    correct
    """
    # Communication tasks does not have output files
    if task.task_type != TaskType.Batch:
        return

    # without official solution we cannot solve the input files
    if not task.official_solution:
        return

    inputs = list_files([
        "statement/input*.txt", "statement/{}.input*.txt".format(task.name),
        "testo/input*.txt", "testo/{}.input*.txt".format(task.name)
    ],
                        valid_extensions=[".txt"])
    outputs = list_files([
        "statement/output*.txt", "statement/{}.output*.txt".format(task.name),
        "testo/output*.txt", "testo/{}.output*.txt".format(task.name)
    ],
                         valid_extensions=[".txt"])
    num_to_input = dict()  # type: Dict[int, str]
    num_to_output = dict()  # type: Dict[int, str]
    num_to_input_file = dict()  # type: Dict[int, File]
    num_to_output_file = dict()  # type: Dict[int, File]
    num_to_sol_output_file = dict()  # type: Dict[int, File]
    num_to_validation = dict()  # type: Dict[int, File]

    for infile in inputs:
        match = re.match(r".*input(\d+).txt", infile)
        # invalid sample file format, skip it
        if not match:
            continue
        sample_num = int(match.group(1))
        num_to_input[sample_num] = infile
        num_to_input_file[sample_num] = pool.frontend.provideFile(
            infile, "Sample input {}".format(infile), False)
        # skip the validation if there is no default validator
        if not task.default_val:
            continue
        in_files = {VALIDATION_INPUT_NAME: num_to_input_file[sample_num]}
        validation = Execution("Validation of sample input {}".format(infile),
                               pool,
                               task.default_val.source_file,
                               [VALIDATION_INPUT_NAME, "0"],
                               "sanity-check-validation",
                               {"sample_testcase": sample_num},
                               inputs=in_files)
        num_to_validation[sample_num] = validation.stdout
        _setup_execution_callback(
            interface, validation,
            "Validation of sample input {} failed".format(infile))

    # if the output files were not yet generated (e.g. when they are just
    # copied), the solution is not prepared
    if not task.official_solution.prepared:
        task.official_solution.prepare(pool)

    for outfile in outputs:
        match = re.match(r".*output(\d+).txt", outfile)
        if not match:
            continue
        sample_num = int(match.group(1))
        # skip the output if there is no corresponding input
        if sample_num not in num_to_input:
            continue
        num_to_output[sample_num] = outfile
        num_to_output_file[sample_num] = pool.frontend.provideFile(
            outfile, "Sample output {}".format(outfile), False)
        in_files = dict()
        # if the validator is not present we don't wait for it
        if sample_num in num_to_validation:
            in_files["wait_for_validation"] = num_to_validation[sample_num]
        if task.input_file:
            in_files[task.input_file] = num_to_input_file[sample_num]
            stdin = None
        else:
            stdin = num_to_input_file[sample_num]
        out_files = []
        if task.output_file:
            out_files.append(task.output_file)

        solving = Execution("Solving sample output {}".format(outfile),
                            pool,
                            task.official_solution, [],
                            "sanity-check-solution",
                            {"sample_testcase": sample_num},
                            inputs=in_files,
                            stdin=stdin,
                            outputs=out_files)
        if task.output_file:
            num_to_sol_output_file[sample_num] = solving.output(
                task.output_file)
        else:
            num_to_sol_output_file[sample_num] = solving.stdout

        _setup_execution_callback(
            interface, solving, "Solution of sample input {} failed".format(
                num_to_input[sample_num]))

        check = get_checker_execution(
            pool, task, "", -1, sample_num, task.checker,
            num_to_input_file[sample_num], num_to_output_file[sample_num],
            num_to_sol_output_file[sample_num],
            "Checking sample output {}".format(outfile),
            {"sanity_check": True})

        _setup_checker_callback(
            interface, check,
            "Checking sample output {} failed".format(outfile), task.checker
            is not None)