예제 #1
0
class CppChecker(Checker):
    def __init__(self, source):
        """
        Args:
            source (FilePath)
        """
        self._source = source
        self._compiler = CppCompiler(['-I"%s"' % source.directory()])
        self._binary_path = FilePath(source.directory(), 'checker')

    def __call__(self, in_path, expected_path, out_path):
        """Run checker to evaluate outcome. Parameters correspond to convention
        for checker in cms.
        Args:
            in_path (FilePath)
            expected_path (FilePath)
            out_path (FilePath)
        """
        assert in_path.exists()
        assert expected_path.exists()
        assert out_path.exists()
        if self._binary_path.mtime() < self._source.mtime():
            if not self.build():
                return (False, 0.0, "Failed to build checker")
        complete = subprocess.run([
            str(self._binary_path),
            str(in_path),
            str(expected_path),
            str(out_path)
        ],
                                  universal_newlines=True,
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE)
        ret = complete.returncode
        st = ret == 0
        if st:
            outcome = float(complete.stdout)
            msg = complete.stderr
        else:
            stderr = complete.stderr.strip('\n')
            outcome = 0.0
            if stderr and len(stderr) < 75:
                msg = stderr
            else:
                if ret < 0:
                    sig = -ret
                    msg = 'Execution killed with signal %d' % sig
                    if sig in SIGNALS:
                        msg += ': %s' % SIGNALS[sig]
                else:
                    msg = 'Execution ended with error (return code %d)' % ret

        return (st, outcome, msg)

    def build(self):
        """Build source of the checker
        Returns:
            bool: True if compilation is successful. False otherwise
        """
        return self._compiler(self._source, self._binary_path)
예제 #2
0
    def compress(self, in_ext=None, sol_ext=None):
        """Compress all test cases in this dataset in a single zip file.
        The basename of the corresponding subtask subdirectory is prepended
        to each file.
        """
        in_ext = in_ext or self._in_ext
        sol_ext = sol_ext or self._sol_ext
        dst_file = FilePath(self._directory, 'data.zip')
        if dst_file.exists() and dst_file.mtime() >= self.mtime():
            return True

        tmpdir = Directory.tmpdir()
        try:
            copied = 0
            for subtask in self._subtasks:
                copied += subtask.copy_to(tmpdir)

            if not copied:
                # ui.show_message("Warning", "no files in dataset", ui.WARNING)
                return True

            cmd = 'cd %s && zip data.zip *%s *%s' % (tmpdir, in_ext, sol_ext)
            st = subprocess.call(cmd, stdout=subprocess.DEVNULL, shell=True)
            FilePath(tmpdir, 'data.zip').copy(dst_file)
        finally:
            tmpdir.rmtree()

        return st == 0
예제 #3
0
    def compress(self, in_ext=None, sol_ext=None, random_sort=False):
        """Compress all test cases in this dataset in a single zip file.
        The basename of the corresponding subtask subdirectory is prepended
        to each file.
        """
        in_ext = in_ext or self._in_ext
        sol_ext = sol_ext or self._sol_ext
        dst_file = FilePath(self._directory, 'data.zip')
        if dst_file.exists() and dst_file.mtime() >= self.mtime():
            return True

        tmpdir = Directory.tmpdir()
        try:
            copied = 0
            for subtask in self._subtasks:
                copied += subtask.copy_to(tmpdir, random_sort=random_sort)

            if not copied:
                # ui.show_message("Warning", "no files in dataset", ui.WARNING)
                return True

            cmd = 'cd %s && zip data.zip *%s *%s' % (tmpdir, in_ext, sol_ext)
            st = subprocess.call(cmd, stdout=subprocess.DEVNULL, shell=True)
            FilePath(tmpdir, 'data.zip').copy(dst_file)
        finally:
            tmpdir.rmtree()

        return st == 0
예제 #4
0
class CppChecker(Checker):
    def __init__(self, source):
        """
        Args:
            source (FilePath)
        """
        self._source = source
        self._compiler = CppCompiler(['-I"%s"' % source.directory()])
        self._binary_path = FilePath(source.directory(), 'checker')

    def __call__(self, in_path, expected_path, out_path):
        """Run checker to evaluate outcome. Parameters correspond to convention
        for checker in cms.
        Args:
            in_path (FilePath)
            expected_path (FilePath)
            out_path (FilePath)
        """
        assert in_path.exists()
        assert expected_path.exists()
        assert out_path.exists()
        if self._binary_path.mtime() < self._source.mtime():
            if not self.build():
                return (False, 0.0, "Failed to build checker")
        complete = subprocess.run(
            [str(self._binary_path),
             str(in_path), str(expected_path),
             str(out_path)],
            universal_newlines=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE)
        ret = complete.returncode
        st = ret == 0
        if st:
            outcome = float(complete.stdout)
            msg = complete.stderr
        else:
            stderr = complete.stderr.strip('\n')
            outcome = 0.0
            if stderr and len(stderr) < 75:
                msg = stderr
            else:
                if ret < 0:
                    sig = -ret
                    msg = 'Execution killed with signal %d' % sig
                    if sig in SIGNALS:
                        msg += ': %s' % SIGNALS[sig]
                else:
                    msg = 'Execution ended with error (return code %d)' % ret

        return (st, outcome, msg)

    def build(self):
        """Build source of the checker
        Returns:
            bool: True if compilation is successful. False otherwise
        """
        return self._compiler(self._source, self._binary_path)
예제 #5
0
 def build_validator(self, source):
     fp = FilePath(self._directory, source)
     if not fp.exists():
         return (None, 'File does not exists.')
     if fp.ext == '.cpp':
         binary = fp.chext('.bin')
         if binary.mtime() < fp.mtime() and not self._cpp_compiler(fp, binary):
             return (None, 'Failed to build validator.')
         return (Runnable(binary), 'OK')
     if fp.ext in ['.py', '.py3']:
         return (Runnable('python3', [str(source)]), 'OK')
     if fp.ext == '.py2':
         return (Runnable('python2', [str(source)]), 'OK')
     return (None, 'Not supported source file.')
예제 #6
0
 def build_validator(self, source):
     fp = FilePath(self._directory, source)
     if not fp.exists():
         return (None, 'File does not exists.')
     if fp.ext == '.cpp':
         binary = fp.chext('.bin')
         if binary.mtime() < fp.mtime() and not self._cpp_compiler(
                 fp, binary):
             return (None, 'Failed to build validator.')
         return (Runnable(binary), 'OK')
     if fp.ext in ['.py', '.py3']:
         return (Runnable('python3', [str(source)]), 'OK')
     if fp.ext == '.py2':
         return (Runnable('python2', [str(source)]), 'OK')
     return (None, 'Not supported source file.')
예제 #7
0
파일: core.py 프로젝트: rodrigoieh/ocimatic
class Statement:
    """Represents a statement. A statement is formed by a latex source and a pdf
    file.
    """
    def __init__(self, directory, num=None, codename=None):
        """
        Args:
            directory (Directory): Directory to search for statement source file.
            num (int): Number of the statement in the contest starting from 0
        """
        assert FilePath(directory, 'statement.tex').exists()
        self._source = FilePath(directory, 'statement.tex')
        self._pdf = self._source.chext('.pdf')
        self._compiler = LatexCompiler()
        self._directory = directory
        self._num = num
        self._codename = codename

    @property
    def pdf(self):
        """Returns path to pdf file and compiles it if necessary.
        Returns:
            Optional[FilePath]: The file path if the binary is present or None
                if the pdf file cannot be generated.
        """
        if self._pdf.mtime() < self._source.mtime():
            (st, _msg) = self.build()
            if not st:
                return None
        return self._pdf

    def __str__(self):
        return str(self._source)

    @ui.work('PDF')
    def build(self, blank_page=False):
        """Compile statement latex source
        Args:
           blank_page (Optional[bool]) if true adds a blank page at the end of the
               problem.
        Returns:
           (bool, msg) a tuple containing status code and result message.

        """
        if self._num is not None:
            os.environ['OCIMATIC_PROBLEM_NUMBER'] = chr(ord('A') + self._num)
        if self._codename:
            os.environ['OCIMATIC_CODENAME'] = self._codename
        if blank_page:
            os.environ['OCIMATIC_BLANK_PAGE'] = 'True'
        st = self._compiler(self._source)
        return (st, 'OK' if st else 'FAILED')

    def io_samples(self):
        """Find sample input data in the satement
        Returns:
            List[FilePath]: list of paths
        """
        latex_file = self._source.open('r')
        samples = set()
        for line in latex_file:
            m = re.match(r'[^%]*\\sampleIO(\[[^\]]*\]){0,2}{([^}]+)}', line)
            if m:
                samples.add(m.group(2))
        latex_file.close()
        return [FilePath(self._directory, s) for s in samples]