def judge(data_input, problem_id): server = Foo.choose_judge_server() submission = data_input problem = Problem.objects.get(id=problem_id) language = submission['language'] sub_config = list( filter(lambda item: language == item["name"], languages))[0] spj_config = {} if problem.spj_code: for lang in spj_languages: if lang["name"] == problem.spj_language: spj_config = lang["spj"] break if language in problem.template: template = parse_problem_template(problem.template[language]) code = f"{template['prepend']}\n{submission['code']}\n{template['append']}" else: code = submission['code'] data = { "language_config": sub_config["config"], "src": code, "max_cpu_time": problem.time_limit, "max_memory": 1024 * 1024 * problem.memory_limit, "test_case_id": problem.test_case_id, "output": True, "spj_version": problem.spj_version, "spj_config": spj_config.get("config"), "spj_compile_config": spj_config.get("compile"), "spj_src": problem.spj_code } resp = Foo._request(urljoin(server.service_url, "/judge"), data=data) if resp["err"]: resp['result'] = JudgeStatus.COMPILE_ERROR return resp else: resp["data"].sort(key=lambda x: int(x["test_case"])) error_test_case = list( filter(lambda case: case["result"] != 0, resp["data"])) if not error_test_case: result = JudgeStatus.ACCEPTED elif problem.rule_type == ProblemRuleType.ACM or len( error_test_case) == len(resp["data"]): result = error_test_case[0]["result"] else: result = JudgeStatus.PARTIALLY_ACCEPTED num = resp['data'] su = num[0] output = {"result": result} output['data'] = su['output'] return output
def judge(self): server = self.choose_judge_server() if not server: data = {"submission_id": self.submission.id, "problem_id": self.problem.id} cache.lpush(CacheKey.waiting_queue, json.dumps(data)) return language = self.submission.language sub_config = list(filter(lambda item: language == item["name"], languages))[0] spj_config = {} if self.problem.spj_code: for lang in spj_languages: if lang["name"] == self.problem.spj_language: spj_config = lang["spj"] break if language in self.problem.template: template = parse_problem_template(self.problem.template[language]) code = f"{template['prepend']}\n{self.submission.code}\n{template['append']}" else: code = self.submission.code data = { "language_config": sub_config["config"], "src": code, "max_cpu_time": self.problem.time_limit, "max_memory": 1024 * 1024 * self.problem.memory_limit, "test_case_id": self.problem.test_case_id, "output": False, "spj_version": self.problem.spj_version, "spj_config": spj_config.get("config"), "spj_compile_config": spj_config.get("compile"), "spj_src": self.problem.spj_code } Submission.objects.filter(id=self.submission.id).update(result=JudgeStatus.JUDGING) resp = self._request(urljoin(server.service_url, "/judge"), data=data) if resp["err"]: self.submission.result = JudgeStatus.COMPILE_ERROR self.submission.statistic_info["err_info"] = resp["data"] self.submission.statistic_info["score"] = 0 else: resp["data"].sort(key=lambda x: int(x["test_case"])) self.submission.info = resp self._compute_statistic_info(resp["data"]) error_test_case = list(filter(lambda case: case["result"] != 0, resp["data"])) # ACM模式下,多个测试点全部正确则AC,否则取第一个错误的测试点的状态 # OI模式下, 若多个测试点全部正确则AC, 若全部错误则取第一个错误测试点状态,否则为部分正确 if not error_test_case: self.submission.result = JudgeStatus.ACCEPTED elif self.problem.rule_type == ProblemRuleType.ACM or len(error_test_case) == len(resp["data"]): self.submission.result = error_test_case[0]["result"] else: self.submission.result = JudgeStatus.PARTIALLY_ACCEPTED self.submission.save() self.release_judge_server(server.id) if self.contest_id: if self.contest.status != ContestStatus.CONTEST_UNDERWAY or \ User.objects.get(id=self.submission.user_id).is_contest_admin(self.contest): logger.info( "Contest debug mode, id: " + str(self.contest_id) + ", submission id: " + self.submission.id) return self.update_contest_problem_status() self.update_contest_rank() else: if self.last_result: self.update_problem_status_rejudge() else: self.update_problem_status() # 至此判题结束,尝试处理任务队列中剩余的任务 process_pending_task()
def judge(self): server = self.choose_judge_server() if not server: data = { "submission_id": self.submission.id, "problem_id": self.problem.id } cache.lpush(CacheKey.waiting_queue, json.dumps(data)) return language = self.submission.language sub_config = list( filter(lambda item: language == item["name"], languages))[0] spj_config = {} if self.problem.spj_code: for lang in spj_languages: if lang["name"] == self.problem.spj_language: spj_config = lang["spj"] break if language in self.problem.template: template = parse_problem_template(self.problem.template[language]) code = f"{template['prepend']}\n{self.submission.code}\n{template['append']}" else: code = self.submission.code data = { "language_config": sub_config["config"], "src": code, "max_cpu_time": self.problem.time_limit, "max_memory": 1024 * 1024 * self.problem.memory_limit, "test_case_id": self.problem.test_case_id, "output": False, "spj_version": self.problem.spj_version, "spj_config": spj_config.get("config"), "spj_compile_config": spj_config.get("compile"), "spj_src": self.problem.spj_code } Submission.objects.filter(id=self.submission.id).update( result=JudgeStatus.JUDGING) service_url = server.service_url # not set service_url, it should be a linked container if not service_url: service_url = settings.DEFAULT_JUDGE_SERVER_SERVICE_URL resp = self._request(urljoin(service_url, "/judge"), data=data) if resp["err"]: self.submission.result = JudgeStatus.COMPILE_ERROR self.submission.statistic_info["err_info"] = resp["data"] self.submission.statistic_info["score"] = 0 else: resp["data"].sort(key=lambda x: int(x["test_case"])) self.submission.info = resp self._compute_statistic_info(resp["data"]) error_test_case = list( filter(lambda case: case["result"] != 0, resp["data"])) # ACM模式下,多个测试点全部正确则AC,否则取第一个错误的测试点的状态 # OI模式下, 若多个测试点全部正确则AC, 若全部错误则取第一个错误测试点状态,否则为部分正确 if not error_test_case: self.submission.result = JudgeStatus.ACCEPTED elif self.problem.rule_type == ProblemRuleType.ACM or len( error_test_case) == len(resp["data"]): self.submission.result = error_test_case[0]["result"] else: self.submission.result = JudgeStatus.PARTIALLY_ACCEPTED self.submission.save() self.release_judge_server(server.id) if self.contest_id: self.update_contest_problem_status() self.update_contest_rank() else: self.update_problem_status() # 至此判题结束,尝试处理任务队列中剩余的任务 process_pending_task()
def judge(self): language = self.submission.language sub_config = list( filter(lambda item: language == item["name"], SysOptions.languages))[0] spj_config = {} if self.problem.spj_code: for lang in SysOptions.spj_languages: if lang["name"] == self.problem.spj_language: spj_config = lang["spj"] break if language in self.problem.template: template = parse_problem_template(self.problem.template[language]) code = f"{template['prepend']}\n{self.submission.code}\n{template['append']}" else: code = self.submission.code data = { "language_config": sub_config["config"], "src": code, "max_cpu_time": self.problem.time_limit, "max_memory": 1024 * 1024 * self.problem.memory_limit, "test_case_id": self.problem.test_case_id, "output": True, "spj_version": self.problem.spj_version, "spj_config": spj_config.get("config"), "spj_compile_config": spj_config.get("compile"), "spj_src": self.problem.spj_code, "io_mode": self.problem.io_mode, "output_description": self.problem.output_description, "input_str": self.problem.input_str } with ChooseJudgeServer() as server: if not server: data = { "submission_id": self.submission.id, "problem_id": self.problem.id } cache.lpush(CacheKey.waiting_queue, json.dumps(data)) return Submission.objects.filter(id=self.submission.id).update( result=JudgeStatus.JUDGING) resp = self._request(urljoin(server.service_url, "/judge"), data=data) if not resp: Submission.objects.filter(id=self.submission.id).update( result=JudgeStatus.SYSTEM_ERROR) return if resp["err"]: self.submission.result = JudgeStatus.COMPILE_ERROR self.submission.statistic_info["err_info"] = resp["data"] self.submission.statistic_info["score"] = 0 else: resp["data"].sort(key=lambda x: int(x["test_case"])) self.submission.info = resp self._compute_statistic_info(resp["data"]) error_test_case = list( filter(lambda case: case["result"] != 0, resp["data"])) # ACM模式下,多个测试点全部正确则AC,否则取第一个错误的测试点的状态 # OI模式下, 若多个测试点全部正确则AC, 若全部错误则取第一个错误测试点状态,否则为部分正确 if not error_test_case: self.submission.result = JudgeStatus.ACCEPTED elif self.problem.rule_type == ProblemRuleType.ACM or len( error_test_case) == len(resp["data"]): self.submission.result = error_test_case[0]["result"] else: self.submission.result = JudgeStatus.PARTIALLY_ACCEPTED self.submission.save() if self.contest_id: if self.contest.status != ContestStatus.CONTEST_UNDERWAY or \ User.objects.get(id=self.submission.user_id).is_contest_admin(self.contest): logger.info("Contest debug mode, id: " + str(self.contest_id) + ", submission id: " + self.submission.id) return with transaction.atomic(): self.update_contest_problem_status() self.update_contest_rank() else: if self.last_result: self.update_problem_status_rejudge() else: self.update_problem_status() # 至此判题结束,尝试处理任务队列中剩余的任务 process_pending_task()
def judge(self): # 先选择评测机 server = self.choose_judge_server() if not server: # 没有Server说明现在被用完,需要等一下 data = { "submission_id": self.submission.id, "problem_id": self.problem.id } # 缓存存放等待任务,返回 cache.lpush(CacheKey.waiting_queue, json.dumps(data)) return # 提交代码所选择的语言 language = self.submission.language # 提交信息配置sub_config和特殊评判信息配置spj_config # 过滤各项名字为系统的选项语言,并保存在语言language,形成一个列表,取到第一项(下标为0) sub_config = list( filter(lambda item: language == item["name"], SysOptions.languages))[0] spj_config = {} # 需要进行特殊评判:配置评判语言 if self.problem.spj_code: for lang in SysOptions.spj_languages: if lang["name"] == self.problem.spj_language: spj_config = lang["spj"] break # 如果提交的语言包含在问题的模板里面,解析模板,重新拼接成新的代码,否则就直接选取配置代码 if language in self.problem.template: template = parse_problem_template(self.problem.template[language]) code = f"{template['prepend']}\n{self.submission.code}\n{template['append']}" else: code = self.submission.code # 提交数据信息 data = { "language_config": sub_config["config"], "src": code, "max_cpu_time": self.problem.time_limit, "max_memory": 1024 * 1024 * self.problem.memory_limit, "test_case_id": self.problem.test_case_id, "output": False, "spj_version": self.problem.spj_version, "spj_config": spj_config.get("config"), "spj_compile_config": spj_config.get("compile"), "spj_src": self.problem.spj_code } # 将对应ID的提交信息更新到提交信息数据表,状态由waiting_queue--->JUDGING Submission.objects.filter(id=self.submission.id).update( result=JudgeStatus.JUDGING) # 评判请求发起------->>>>请求后台评判机 resp = self._request(urljoin(server.service_url, "/judge"), data=data) # 根据返回的评测结果信息设置提交信息表字段并保存到数据库表 if resp["err"]: self.submission.result = JudgeStatus.COMPILE_ERROR self.submission.statistic_info["err_info"] = resp["data"] self.submission.statistic_info["score"] = 0 else: # 成功后,将返回的数据按照test_case顺序排序 resp["data"].sort(key=lambda x: int(x["test_case"])) # 更具响应信息设置提交信息,统计返回的信息 self.submission.info = resp self._compute_statistic_info(resp["data"]) # 过滤resp["data"]中未通过的测试案例到list,并赋值给error_test_case error_test_case = list( filter(lambda case: case["result"] != 0, resp["data"])) # ACM模式下,多个测试点全部正确则AC,否则取第一个错误的测试点的状态 # OI模式下, 若多个测试点全部正确则AC, 若全部错误则取第一个错误测试点状态,否则为部分正确 if not error_test_case: self.submission.result = JudgeStatus.ACCEPTED elif self.problem.rule_type == ProblemRuleType.ACM or len( error_test_case) == len(resp["data"]): self.submission.result = error_test_case[0]["result"] else: self.submission.result = JudgeStatus.PARTIALLY_ACCEPTED # 保存提交信息,并释放Server self.submission.save() self.release_judge_server(server.id) if self.contest_id: # 如果当前不是正在进行比赛 或者 当前的提交信息对应的用户是比赛的创建者(当前用户是管理员), # 日志中记录管理员是在进行调试:显示contest_id和submission.id if self.contest.status != ContestStatus.CONTEST_UNDERWAY or \ User.objects.get(id=self.submission.user_id).is_contest_admin(self.contest): logger.info("Contest debug mode, id: " + str(self.contest_id) + ", submission id: " + self.submission.id) return # 否则说明是普通用户在进行比赛,更新比赛问题状态和排名 self.update_contest_problem_status() self.update_contest_rank() else: # 最近的判题(上一次返回的判题)结果不空,就是说评测机Judge Server有信息返回,说明你上一次提交了一次(AC/not AC),这次再提交(往往是没AC时候) # 否则就刷新问题状态(例如有一道题被ac,则此题的被ac率应该更新) if self.last_result: self.update_problem_status_rejudge() else: self.update_problem_status() # 至此判题结束,尝试处理任务队列中剩余的任务 process_pending_task()
def judge(self): language = self.submission.language sub_config = list( filter(lambda item: language == item["name"], SysOptions.languages))[0] spj_config = {} if self.problem.spj_code: for lang in SysOptions.spj_languages: if lang["name"] == self.problem.spj_language: spj_config = lang["spj"] break if language in self.problem.template: template = parse_problem_template(self.problem.template[language]) code = f"{template['prepend']}\n{self.submission.code}\n{template['append']}" else: code = self.submission.code data = { "language_config": sub_config["config"], "src": code, "max_cpu_time": self.problem.time_limit, "max_memory": 1024 * 1024 * self.problem.memory_limit, "test_case_id": self.problem.test_case_id, "output": False, "spj_version": self.problem.spj_version, "spj_config": spj_config.get("config"), "spj_compile_config": spj_config.get("compile"), "spj_src": self.problem.spj_code, "io_mode": self.problem.io_mode } with ChooseJudgeServer() as server: if not server: data = { "submission_id": self.submission.id, "problem_id": self.problem.id } cache.lpush(CacheKey.waiting_queue, json.dumps(data)) return Submission.objects.filter(id=self.submission.id).update( result=JudgeStatus.JUDGING) resp = self._request(urljoin(server.service_url, "/judge"), data=data) if not resp: Submission.objects.filter(id=self.submission.id).update( result=JudgeStatus.SYSTEM_ERROR) return if resp["err"]: self.submission.result = JudgeStatus.COMPILE_ERROR self.submission.statistic_info["err_info"] = resp["data"] self.submission.statistic_info["score"] = 0 else: resp["data"].sort(key=lambda x: int(x["test_case"])) self.submission.info = resp self._compute_statistic_info(resp["data"]) error_test_case = list( filter(lambda case: case["result"] != 0, resp["data"])) # In ACM mode, if multiple test points are all correct, then AC, # otherwise, take the status of the first wrong test point # In OI mode, if multiple test points are all correct, AC is used, # if all test points are wrong, the first test point state is taken as the first error, # otherwise it is partially correct if not error_test_case: self.submission.result = JudgeStatus.ACCEPTED elif self.problem.rule_type == ProblemRuleType.ACM or len( error_test_case) == len(resp["data"]): self.submission.result = error_test_case[0]["result"] else: self.submission.result = JudgeStatus.PARTIALLY_ACCEPTED self.submission.save() if self.contest_id: if self.contest.status != ContestStatus.CONTEST_UNDERWAY or \ User.objects.get(id=self.submission.user_id).is_contest_admin(self.contest): logger.info("Contest debug mode, id: " + str(self.contest_id) + ", submission id: " + self.submission.id) return with transaction.atomic(): self.update_contest_problem_status() self.update_contest_rank() else: if self.last_result: self.update_problem_status_rejudge() else: self.update_problem_status() # At this point, the judgment is over, try to process the remaining tasks in the task queue process_pending_task()