def check(process_output, judge_output, judge_input, point_value, submission_source, **kwargs): from dmoj.result import CheckerResult if not process_output: return CheckerResult(False, 0) return CheckerResult(True, point_value, '正しい出力なのです')
def check(process_output, judge_output, judge_input, point_value, execution_time, **kwargs): try: process_lines = process_output.decode("utf-8").split("\n")[:-1] judge_lines = judge_output.decode("utf-8").split("\n")[1:-1] judge_input = judge_input.decode("utf-8").split("\n") id = judge_input[0] n = int(judge_input[1].split()[0]) assert n == len(process_lines), "wrong number of lines {}".format(len(process_lines)) barx = [float(x) for x in judge_lines] try: x = [float(z) for z in process_lines] except: assert False, "illegal output" for y in x: assert not math.isnan(y), "nan detected" assert len(barx) == n, "barx has wrong length {}".format(len(barx)) assert len(x) == n, "x has wrong length {}".format(len(x)) L = getL(judge_input) xDiff = [x[i] - barx[i] for i in range(n)] xDiffNorm = getNorm(n, xDiff, L) xNorm = getNorm(n, barx, L) if xDiffNorm > 0.1 * xNorm: return CheckerResult(False, 0, "norm out of range: xNorm = {}, xDiffNorm = {}, ratio = {}".format(xNorm, xDiffNorm, xDiffNorm / xNorm)) bestTime = 10. ratio = bestTime / execution_time return CheckerResult(True, point_value * ratio**2, "norm in range: xNorm = {}, xDiffNorm = {}, ratio = {}".format(xNorm, xDiffNorm, xDiffNorm / xNorm)) except Exception as e: return CheckerResult(False, 0, "{}".format(e))
def check(process_output, judge_output, **kwargs): subtask = kwargs["batch"] grid = kwargs["judge_input"].decode("utf-8") subtask_id = f"[SUBTASK {subtask}]" process_output = process_output.decode("utf-8") try: ind = process_output.find(subtask_id) + len(subtask_id) endind = process_output[ind:].find("[SUBTASK") if endind == -1: endind = len(process_output) program = process_output[ind : ind + endind] if subtask == 1: result = checkerlib.checkSubtask1(grid, program, use_compile=False) elif subtask == 2: result = checkerlib.checkSubtask2(grid, program, use_compile=False) elif subtask == 3: result = checkerlib.checkSubtask3(grid, program, use_compile=True) elif subtask == 4: result = checkerlib.checkSubtask4(grid, program, use_compile=True) elif subtask == 5: result = checkerlib.checkSubtask5(grid, program, use_compile=True) except Exception: result = (False, "Error while parsing or running program") if result[0] is False: return CheckerResult(False, 0, result[1]) elif result[1] == 1: return True else: return CheckerResult( True, result[1] * kwargs["point_value"], "Partially correct" )
def check(process_output, judge_output, judge_input, point_value, execution_time, **kwargs): try: process_lines = process_output.decode("utf-8").split("\n")[:-1] judge_lines = judge_output.decode("utf-8").split("\n")[1:-1] judge_input = judge_input.decode("utf-8").split("\n") id = judge_input[0] n = int(judge_input[1].split()[0]) if n != len(process_lines): return False barx = [Decimal(x) for x in judge_lines] x = [Decimal(z) for z in process_lines] assert len(barx) == n, "barx has wrong length {}".format(len(barx)) assert len(x) == n, "x has wrong length {}".format(len(x)) L = getL(judge_input) xDiff = [x[i] - barx[i] for i in range(n)] xDiffNorm = getNorm(n, xDiff, L) xNorm = getNorm(n, barx, L) if xDiffNorm > Decimal("0.1") * xNorm: return CheckerResult(False, 0, "norm out of range") bestTime = 10. ratio = bestTime / execution_time return CheckerResult(True, point_value * ratio**2) except Exception as e: return CheckerResult(False, 0, "{}".format(e))
def parse_return_code(cls, proc, executor, point_value, time_limit, memory_limit, feedback, name, stderr): if proc.returncode == cls.AC: return CheckerResult(True, point_value, feedback=feedback) elif proc.returncode == cls.PARTIAL: match = cls.repartial.search(stderr) if not match: raise InternalError('Invalid stderr for partial points: %r' % stderr) points = int(match.group(1)) if not 0 <= points <= point_value: raise InternalError('Invalid partial points: %d' % points) return CheckerResult(True, points, feedback=feedback) elif proc.returncode == cls.WA: return CheckerResult(False, 0, feedback=feedback) elif proc.returncode == cls.PE: return CheckerResult(False, 0, feedback=feedback or 'Presentation Error') elif proc.returncode == cls.IE: raise InternalError('%s failed assertion with message %s' % (name, feedback)) else: parse_helper_file_error(proc, executor, name, stderr, time_limit, memory_limit)
def grade(self, case): result = Result(case) case.input_data() # cache generator data self._current_proc = self.binary.launch(time=self.problem.time_limit, memory=self.problem.memory_limit, pipe_stderr=True, unbuffered=case.config.unbuffered) error = self._interact_with_process(case, result) process = self._current_proc result.max_memory = process.max_memory or 0.0 result.execution_time = process.execution_time or 0.0 result.r_execution_time = process.r_execution_time or 0.0 # checkers might crash if any data is None, so force at least empty string check = case.checker()(result.proc_output or '', case.output_data() or '', submission_source=self.source, judge_input=case.input_data() or '', point_value=case.points) # checkers must either return a boolean (True: full points, False: 0 points) # or a CheckerResult, so convert to CheckerResult if it returned bool if not isinstance(check, CheckerResult): check = CheckerResult(check, case.points if check else 0.0) result.result_flag |= [Result.WA, Result.AC][check.passed] # Translate status codes/process results into Result object for status codes if process.returncode > 0: # print>> sys.stderr, 'Exited with error: %d' % process.returncode result.result_flag |= Result.IR if process.returncode < 0: # None < 0 == True # if process.returncode is not None: # print>> sys.stderr, 'Killed by signal %d' % -process.returncode result.result_flag |= Result.RTE # Killed by signal if process.tle: result.result_flag |= Result.TLE if process.mle: result.result_flag |= Result.MLE if result.result_flag & ~Result.WA: check.points = 0 result.points = check.points result.feedback = (check.feedback or (process.feedback if hasattr(process, 'feedback') else getattr(self.binary, 'get_feedback', lambda x, y: '')(error, result))) if not result.feedback and hasattr(process, 'signal') and process.signal and result.get_main_code() in [Result.IR, Result.RTE]: result.feedback = strsignal(process.signal) return result
def parse_return_code(cls, proc, executor, point_value, time_limit, memory_limit, feedback, name, stderr): if proc.returncode == cls.AC: return CheckerResult(True, point_value, feedback=feedback) elif proc.returncode == cls.WA: return CheckerResult(False, 0, feedback=feedback) else: parse_helper_file_error(proc, executor, name, stderr, time_limit, memory_limit)
def check(process_output, judge_output, judge_input, checker_kwargs, problem_id, point_value=None, **kwargs) -> CheckerResult: # Update checker_kwargs with defaults for key, value in checker_defaults.items(): checker_kwargs.setdefault(key, value) executor = get_executor(checker_kwargs, problem_id) with mktemp(judge_input) as input_file, mktemp( process_output) as output_file, mktemp(judge_output) as judge_file: process = executor.launch(input_file.name, output_file.name, judge_file.name, stdout=subprocess.PIPE, stderr=subprocess.PIPE, memory=checker_kwargs['memory_limit'], time=checker_kwargs['time_limit']) proc_output, error = map(utf8text, process.communicate()) # We use the testlib.h return codes AC = 0 WA = 1 PE = 2 IE = 3 if process.returncode == AC: if checker_kwargs['feedback']: return CheckerResult(True, point_value, feedback=proc_output) else: return CheckerResult(True, point_value) elif process.returncode in (WA, PE): if checker_kwargs['feedback']: return CheckerResult(False, 0, feedback=proc_output) else: return CheckerResult(False, 0, feedback='Presentation Error' if process.returncode == PE else '') else: if process.returncode == IE: error = 'checker failed assertion with message %s' % proc_output else: error = 'checker returned unexpected return code %d with stderr %s' % ( process.returncode, error) raise InternalError(error)
def check(process_output, judge_output, judge_input, problem_id, files, lang, time_limit=env['generator_time_limit'], memory_limit=env['generator_memory_limit'], compiler_time_limit=env['generator_compiler_limit'], feedback=True, point_value=None, **kwargs) -> CheckerResult: executor = get_executor(files, lang, compiler_time_limit, problem_id) with mktemp(judge_input) as input_file, mktemp( process_output) as output_file, mktemp(judge_output) as judge_file: process = executor.launch(input_file.name, output_file.name, judge_file.name, stdout=subprocess.PIPE, stderr=subprocess.PIPE, memory=memory_limit, time=time_limit) proc_output, error = map(utf8text, process.communicate()) # We use the testlib.h return codes AC = 0 WA = 1 PE = 2 IE = 3 if process.returncode == AC: if feedback: return CheckerResult(True, point_value, feedback=proc_output) else: return CheckerResult(True, point_value) elif process.returncode in (WA, PE): if feedback: return CheckerResult(False, 0, feedback=proc_output) else: return CheckerResult(False, 0, feedback='Presentation Error' if process.returncode == PE else '') else: if process.returncode == IE: error = 'checker failed assertion with message %s' % proc_output else: error = 'checker returned unexpected return code %d with stderr %s' % ( process.returncode, error) raise InternalError(error)
def check(process_output: bytes, judge_output: bytes, point_value: float, feedback: bool = True, match: Callable[[bytes, bytes], bool] = lambda p, j: p.strip() == j.strip(), **kwargs) -> Union[CheckerResult, bool]: process_lines = list( filter(None, resplit(b'[\r\n]', utf8bytes(process_output)))) judge_lines = list( filter(None, resplit(b'[\r\n]', utf8bytes(judge_output)))) if len(process_lines) > len(judge_lines): return False if not judge_lines: return True if isinstance(match, str): match = eval(match) cases = [verdict[0]] * len(judge_lines) count = 0 for i, (process_line, judge_line) in enumerate(zip(process_lines, judge_lines)): if match(process_line, judge_line): cases[i] = verdict[1] count += 1 return CheckerResult(count == len(judge_lines), point_value * (1.0 * count / len(judge_lines)), ''.join(cases) if feedback else "")
def check(process_output: bytes, judge_output: bytes, point_value: float = 1, point_distribution: List[int] = [1], filler_lines_required: bool = True, **kwargs) -> Union[CheckerResult, bool]: judge_lines = list( filter(None, resplit(b'[\r\n]', utf8bytes(judge_output)))) if len(judge_lines) != len(point_distribution): raise InternalError( 'point distribution length must equal to judge output length') if sum(point_distribution) == 0: raise InternalError('sum of point distribution must be positive') process_lines = list( filter(None, resplit(b'[\r\n]', utf8bytes(process_output)))) if filler_lines_required and len(process_lines) != len(judge_lines): return False points = 0 for process_line, judge_line, line_points in zip(process_lines, judge_lines, point_distribution): if process_line == judge_line: points += line_points return CheckerResult(points > 0, point_value * (points / sum(point_distribution)))
def check(process_output, judge_output, point_value, feedback=False, match=lambda p, j: p.strip() == j.strip(), **kwargs): process_lines = filter(None, process_output.strip().split("\n")) judge_lines = filter(None, judge_output.strip().split("\n")) if len(process_lines) > len(judge_lines): return False if not judge_lines: return True if isinstance(match, basestring): match = eval(match) cases = [verdict[0]] * len(judge_lines) count = 0 for i, (process_line, judge_line) in enumerate(zip(process_lines, judge_lines)): if match(process_line, judge_line): cases[i] = verdict[1] count += 1 return CheckerResult(count == len(judge_lines), point_value * (1.0 * count / len(judge_lines)), ''.join(cases) if feedback else "")
def parse_return_code(cls, proc, executor, point_value, time_limit, memory_limit, feedback, name, stderr): if proc.returncode == cls.AC: return CheckerResult(True, point_value, feedback=feedback) elif proc.returncode == cls.WA: return CheckerResult(False, 0, feedback=feedback) elif proc.returncode == cls.PE: return CheckerResult(False, 0, feedback=feedback or 'Presentation Error') elif proc.returncode == cls.IE: raise InternalError('%s failed assertion with message %s' % (name, feedback)) else: parse_helper_file_error(proc, executor, name, stderr, time_limit, memory_limit)
def check(process_output: bytes, judge_output: bytes, point_value: float, feedback: bool = True, **kwargs) -> Union[CheckerResult, bool]: process_lines = list( filter(None, resplit(b'[\r\n]', utf8bytes(process_output)))) judge_lines = list( filter(None, resplit(b'[\r\n]', utf8bytes(judge_output)))) if len(process_lines) > len(judge_lines): return False if not judge_lines: return True cases = [verdict[0]] * len(judge_lines) count = 0 for i, (process_line, judge_line) in enumerate(zip(process_lines, judge_lines)): if process_line.strip() == judge_line.strip(): cases[i] = verdict[1] count += 1 return CheckerResult(count == len(judge_lines), point_value * count / len(judge_lines), extended_feedback='Case Feedback:\n' + ''.join(cases) if feedback else '')
def check(process_output, judge_output, point_value, feedback=False, **kwargs): process_lines = filter(None, process_output.strip().split("\n")) judge_lines = filter(None, judge_output.strip().split("\n")) cases = [verdict[0]] * len(judge_lines) count = 0 for i, (process_line, judge_line) in enumerate(zip(process_lines, judge_lines)): if process_line == judge_line: cases[i] = verdict[1] count += 1 if not count or len(process_lines) > len(judge_lines): return CheckerResult(False, 0) return CheckerResult(True, point_value * (1.0 * count / len(judge_lines)), ''.join(cases) if feedback else "")
def check(process_output: bytes, judge_output: bytes, pe_allowed: bool = True, **kwargs) -> Union[CheckerResult, bool]: if judge_output == process_output: return True feedback = None if pe_allowed and standard(utf8bytes(judge_output), utf8bytes(process_output)): # in the event the standard checker would have passed the problem, raise a presentation error feedback = "Presentation Error, check your whitespace" return CheckerResult(False, 0, feedback=feedback)
def check(process_output, judge_output, pe_allowed=True, **kwargs): if judge_output == process_output: return True feedback = None if pe_allowed and standard(utf8bytes(judge_output), utf8bytes(process_output)): # in the event the standard checker would have passed the problem, raise a presentation error feedback = "Presentation Error" return CheckerResult(False, 0, feedback=feedback)
def check(process_output: bytes, judge_output: bytes, **kwargs) -> bool: process_lines = resplit(b'[\r\n]', utf8bytes(process_output)) judge_lines = resplit(b'[\r\n]', utf8bytes(judge_output)) #l'usuari fara una sola linea d'output, el nom del seu fitxer filename = process_lines[0].decode('utf-8') #fitxer esperat passat a caracters utf8 enjin = [x.decode('utf-8') for x in list(filter(None, judge_lines))] strexpected = '\n'.join(map(str, enjin)) print(strexpected) #rescato el nom del fitxer i l'obro myfile = open("/outputfiles/" + filename, "rb").read() file_lines = resplit(b'[\r\n]', utf8bytes(myfile)) #fitxer de l'usuari passat a caracters utf8 enjin = [x.decode('utf-8') for x in list(filter(None, file_lines))] data_to_read = '\n'.join(map(str, enjin)) print(data_to_read) #comparacio print(file_lines) print(judge_lines) #pots esborrar ja el fitxer i que no ocupi memòria (no hi ha risc de fitxer de 3GB, perque donaria MLE) os.remove("/outputfiles/" + filename) if len(file_lines) != len(judge_lines): #print("ep") return CheckerResult(False, 0, "Els fitxers no tenen les mateixes línees", strexpected + "\u2719" + data_to_read) for process_line, judge_line in zip(file_lines, judge_lines): if process_line.rstrip() != judge_line.rstrip(): #print("aaa",process_line.rstrip,judge_line.rstrip()) return CheckerResult(False, 0, "Els fitxers no son iguals", strexpected + "\u2719" + data_to_read) return True
def parse_return_code(cls, proc, executor, point_value, time_limit, memory_limit, feedback, name, stderr): if proc.returncode == cls.AC: return CheckerResult(True, point_value, feedback=feedback) elif proc.returncode == cls.PARTIAL: match = cls.repartial.search(stderr) if not match: raise InternalError('Invalid stderr for partial points: %r' % stderr) points = float(match.group(0)) if not 0 <= points <= 1: raise InternalError('Invalid partial points: %d' % points) ac = (points == 1) return CheckerResult(ac, points * point_value, feedback=feedback) elif proc.returncode == cls.WA: return CheckerResult(False, 0, feedback=feedback) else: parse_helper_file_error(proc, executor, name, stderr, time_limit, memory_limit)
def parse_return_code(cls, proc, executor, point_value, time_limit, memory_limit, feedback, name, stderr): if proc.returncode == cls.PARTIAL: match = cls.repartial.search(stderr) if not match: raise InternalError( 'Invalid stderr for fraction of points: %r' % stderr) percentage = int(match.group(2)) / int(match.group(3)) if not 0.0 <= percentage <= 1.0: raise InternalError('Invalid fraction: %s' % match.group(1)) points = percentage * point_value return CheckerResult(True, points, feedback=feedback) else: return super().parse_return_code(proc, executor, point_value, time_limit, memory_limit, feedback, name, stderr)
def parse_return_code(cls, proc, executor, point_value, time_limit, memory_limit, feedback, name, stderr): if proc.returncode == cls.AC: return True elif proc.returncode == cls.WA: # PEG allows for a ratio of floating points # Scanning for floating points with a regex is impractical, so we loop all lines feedback_lines = feedback.split('\n') for line1, line2 in zip(feedback_lines, feedback_lines[1:]): try: percentage = float(line1) / float(line2) except (ValueError, ZeroDivisionError): pass else: if percentage > 0: # We like to return _AC for partials, vs PEG and WA return CheckerResult(True, point_value * percentage) return False else: parse_helper_file_error(proc, executor, name, stderr, time_limit, memory_limit)
class StandardGrader(BaseGrader): def grade(self, case): result = Result(case) input = case.input_data() # cache generator data self._launch_process(case) error = self._interact_with_process(case, result, input) process = self._current_proc self.populate_result(error, result, process) check = self.check_result(case, result) # checkers must either return a boolean (True: full points, False: 0 points) # or a CheckerResult, so convert to CheckerResult if it returned bool if not isinstance(check, CheckerResult): check = CheckerResult(check, case.points if check else 0.0) result.result_flag |= [Result.WA, Result.AC][check.passed] result.points = check.points result.feedback = check.feedback or result.feedback result.extended_feedback = check.extended_feedback or result.extended_feedback case.free_data() return result def populate_result(self, error, result, process): self.binary.populate_result(error, result, process) def check_result(self, case, result): # If the submission didn't crash and didn't time out, there's a chance it might be AC # We shouldn't run checkers if the submission is already known to be incorrect, because some checkers # might be very computationally expensive. # See https://github.com/DMOJ/judge/issues/170 checker = case.checker() # checker is a `partial` object, NOT a `function` object if not result.result_flag or getattr(checker.func, 'run_on_error', False): try: check = checker( result.proc_output, case.output_data(), submission_source=self.source, judge_input=case.input_data(), point_value=case.points, case_position=case.position, batch=case.batch, submission_language=self.language, binary_data=case.has_binary_data, execution_time=result.execution_time, problem_id=self.problem.id, ) except UnicodeDecodeError: # Don't rely on problemsetters to do sane things when it comes to Unicode handling, so # just proactively swallow all Unicode-related checker errors. return CheckerResult(False, 0, feedback='invalid unicode') else: # Solution is guaranteed to receive 0 points check = False return check
class StandardGrader(BaseGrader): def grade(self, case): result = Result(case) input = case.input_data() # cache generator data self._launch_process(case) error = self._interact_with_process(case, result, input) process = self._current_proc self.populate_result(error, result, process) check = self.check_result(case, result) # checkers must either return a boolean (True: full points, False: 0 points) # or a CheckerResult, so convert to CheckerResult if it returned bool if not isinstance(check, CheckerResult): check = CheckerResult(check, case.points if check else 0.0) result.result_flag |= [Result.WA, Result.AC][check.passed] result.points = check.points result.feedback = check.feedback or result.feedback result.extended_feedback = check.extended_feedback or result.extended_feedback case.free_data() # Where CPython has reference counting and a GC, PyPy only has a GC. This means that while CPython # will have freed any (usually massive) generated data from the line above by reference counting, it might # - and probably still is - in memory by now. We need to be able to fork() immediately, which has a good chance # of failing if there's not a lot of swap space available. # # We don't really have a way to force the generated data to disappear, so calling a gc here is the best # chance we have. if platform.python_implementation() == 'PyPy': gc.collect() return result def populate_result(self, error, result, process): self.binary.populate_result(error, result, process) def check_result(self, case, result): # If the submission didn't crash and didn't time out, there's a chance it might be AC # We shouldn't run checkers if the submission is already known to be incorrect, because some checkers # might be very computationally expensive. # See https://github.com/DMOJ/judge/issues/170 checker = case.checker() # checker is a `partial` object, NOT a `function` object if not result.result_flag or getattr(checker.func, 'run_on_error', False): try: check = checker( result.proc_output, case.output_data(), submission_source=self.source, judge_input=case.input_data(), point_value=case.points, case_position=case.position, batch=case.batch, submission_language=self.language, binary_data=case.has_binary_data, execution_time=result.execution_time, problem_id=self.problem.id, result_flag=result.result_flag, ) except UnicodeDecodeError: # Don't rely on problemsetters to do sane things when it comes to Unicode handling, so # just proactively swallow all Unicode-related checker errors. return CheckerResult(False, 0, feedback='invalid unicode') else: # Solution is guaranteed to receive 0 points check = False return check
class StandardGrader(BaseGrader): def grade(self, case): result = Result(case) input = case.input_data() # cache generator data self._current_proc = self.binary.launch( time=self.problem.time_limit, memory=self.problem.memory_limit, symlinks=case.config.symlinks, pipe_stderr=True, wall_time=case.config.wall_time_factor * self.problem.time_limit) error = self._interact_with_process(case, result, input) process = self._current_proc result.max_memory = process.max_memory or 0.0 result.execution_time = process.execution_time or 0.0 result.r_execution_time = process.r_execution_time or 0.0 # Translate status codes/process results into Result object for status codes self.set_result_flag(process, result) check = self.check_result(case, result) # checkers must either return a boolean (True: full points, False: 0 points) # or a CheckerResult, so convert to CheckerResult if it returned bool if not isinstance(check, CheckerResult): check = CheckerResult(check, case.points if check else 0.0) result.result_flag |= [Result.WA, Result.AC][check.passed] result.points = check.points result.extended_feedback = check.extended_feedback self.update_feedback(check, error, process, result) case.free_data() # Where CPython has reference counting and a GC, PyPy only has a GC. This means that while CPython # will have freed any (usually massive) generated data from the line above by reference counting, it might # - and probably still is - in memory by now. We need to be able to fork() immediately, which has a good chance # of failing if there's not a lot of swap space available. # # We don't really have a way to force the generated data to disappear, so calling a gc here is the best # chance we have. if platform.python_implementation() == 'PyPy': gc.collect() return result def update_feedback(self, check, error, process, result): result.feedback = ( check.feedback or (process.feedback if hasattr(process, 'feedback') else getattr( self.binary, 'get_feedback', lambda x, y, z: '')(error, result, process))) if not result.feedback and result.get_main_code() == Result.RTE: if hasattr(process, 'was_initialized') and not process.was_initialized: # Process may failed to initialize, resulting in a SIGKILL without any prior signals. # See <https://github.com/DMOJ/judge/issues/179> for more details. result.feedback = 'failed initializing' elif hasattr(process, 'signal'): # I suppose generate a SIGKILL message is better when we don't know the signal that caused it. result.feedback = strsignal( process.signal).lower() if process.signal else 'killed' # On Linux we can provide better help messages if hasattr(process, 'protection_fault') and process.protection_fault: syscall, callname, args = process.protection_fault print_protection_fault(process.protection_fault) callname = callname.replace('sys_', '', 1) message = '%s syscall disallowed' % callname result.feedback = message def check_result(self, case, result): # If the submission didn't crash and didn't time out, there's a chance it might be AC # We shouldn't run checkers if the submission is already known to be incorrect, because some checkers # might be very computationally expensive. # See https://github.com/DMOJ/judge/issues/170 checker = case.checker() # checker is a `partial` object, NOT a `function` object if not result.result_flag or getattr(checker.func, 'run_on_error', False): try: # Checkers might crash if any data is None, so force at least empty string check = checker(result.proc_output or b'', case.output_data() or b'', submission_source=self.source, judge_input=case.input_data() or b'', point_value=case.points, case_position=case.position, batch=case.batch, submission_language=self.language, binary_data=case.has_binary_data, execution_time=result.execution_time) except UnicodeDecodeError: # Don't rely on problemsetters to do sane things when it comes to Unicode handling, so # just proactively swallow all Unicode-related checker errors. return CheckerResult(False, 0, feedback='invalid unicode') else: # Solution is guaranteed to receive 0 points check = False return check
def check(process_output: bytes, judge_output: bytes, point_value: float, feedback: bool = True, **kwargs) -> Union[CheckerResult, bool]: judge_input = list( filter(None, resplit(b'[\r\n]', utf8bytes(kwargs["judge_input"])))) process_lines = list( filter(None, resplit(b'[\r\n]', utf8bytes(process_output)))) judge_lines = list( filter(None, resplit(b'[\r\n]', utf8bytes(judge_output)))) wronganswers = "" enjin = [x.decode('utf-8') for x in judge_input] strinput = '\n'.join(map(str, enjin)) print(strinput) if len(process_lines) > len(judge_lines): while len(process_lines) > len(judge_lines): ch = '\u2717' ch = ch.encode('utf-8') judge_lines.append(ch) elif len(process_lines) < len(judge_lines): while len(process_lines) < len(judge_lines): ch = '\u2717' ch = ch.encode('utf-8') process_lines.append(ch) if not judge_lines: return True cases = [verdict[0]] * len(judge_lines) count = 0 for i, (process_line, judge_line) in enumerate(zip(process_lines, judge_lines)): if process_line.strip() == judge_line.strip(): cases[i] = verdict[1] count += 1 else: tmpl = str(i) + "\u2720" + str( judge_line.strip().decode('utf-8')) + "\u2720" + str( process_line.strip().decode('utf-8')) + "\u2721" wronganswers += (tmpl) #Error, so keep the executor exception info if kwargs["result_flag"]: return CheckerResult( count == len(judge_lines), point_value * (1.0 * count / len(judge_lines)), None, strinput + "\u2719" + str(wronganswers) + "\u2719" + str(len(judge_input)) + "\u2719" + str(len(judge_lines))) #Not an error, so use the new ifno else: percent = int((count) * 100 / (len(judge_lines))) return CheckerResult( count == len(judge_lines), point_value * (1.0 * count / len(judge_lines)), str(percent) + "%" if feedback else "", strinput + "\u2719" + str(wronganswers) + "\u2719" + str(len(judge_input)) + "\u2719" + str(len(judge_lines)))