原来试运行走另一台 Judge0:C 是 GCC 9、编译参数也不一样,Python 的语法错误回来的是运行错误, 没有题目的时间内存限制和代码模板,例子上的结果常和提交对不上。现在走本站判题机 (POST /trial-runs),同一套编译命令、这道题的限制和模板,对不对也由判题机比。 - 不落库、不算提交、不进判题队列:api 进程里自己排队,全站同时 TRIAL_CONCURRENCY 批 (服务器 2、机房 4),每人最多两批,排满或等超过 30 秒就请学生过一会儿再点 - 死循环不停打印时判题机回包会很大,超过 16MB 就掐断,告诉学生输出太多、停不下来 - Python 语法错误用和提交一样的说明:第几行、中文标点标红、一键换成英文 - 运行时错误和提交用同一个解析,说清楚第几行、为什么(下标越界、int() 转换失败、段错误……); 比赛里照旧只给按结果码的那一句 - 语法没过、服务没跑成时,标题不再说「N 个例子没对上」 - 后台「生成测试点」一并迁过来,编译警告不会再写进 .out;Judge0 的地址和调用全部删掉 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
8834536135
commit
eb32676de4
27 files changed
+691
-169
No files matched your search
@@ -1,38 +1,79 @@
|
||||
<script setup lang="ts">
|
||||
import { SubmissionStatus } from "utils/constants"
|
||||
import type { StatisticInfo } from "@oj2/contract"
|
||||
import PythonErrorExplain from "./PythonErrorExplain.vue"
|
||||
import RuntimeErrorExplain from "./RuntimeErrorExplain.vue"
|
||||
|
||||
/**
|
||||
* 试跑(Judge0)没跑完时给学生看的中文说明。Judge0 回来的是英文原文(Traceback、
|
||||
* gcc 的报错),学生读不懂,原文收进折叠区。
|
||||
* 试跑没跑完时给学生看的中文说明。判题机回来的是英文原文(Traceback、gcc 的报错),
|
||||
* 学生读不懂,原文收进折叠区。Python 的语法错误是判题机上 CPython 的原文,和提交判出来的
|
||||
* 一样,直接交给 PythonErrorExplain(中文说明 + 编辑器里标出位置 + 一键换中文标点)。
|
||||
*/
|
||||
const props = defineProps<{
|
||||
result: SubmissionStatus
|
||||
output: string
|
||||
language: string
|
||||
/** 调用方给的说明(没跑成的原因、输出太多),有它就不用下面按结果码挑的那句 */
|
||||
note?: string
|
||||
/** 运行时错误的诊断(后端和提交同一个解析),有它就说清楚第几行、为什么 */
|
||||
runtimeError?: NonNullable<StatisticInfo["runtime_error"]> | null
|
||||
/** 跑的那份代码,摆出出错的那一行 */
|
||||
code?: string
|
||||
/**
|
||||
* 比赛里:不给具体到哪一行、什么原因的说明(设计文档第 8 节「运行例子只给对 / 没对上和
|
||||
* 原样输出」;提交那边比赛里也只给判题状态),只留按结果码的那一句
|
||||
*/
|
||||
plain?: boolean
|
||||
}>()
|
||||
|
||||
/** 运行时错误、而且诊断出了东西:用和提交一样的说明卡片(第几行 + 中文原因 + 编辑器标红) */
|
||||
const runtimeExplain = computed(
|
||||
() =>
|
||||
!props.note &&
|
||||
!props.plain &&
|
||||
props.result === SubmissionStatus.runtime_error &&
|
||||
!!props.runtimeError,
|
||||
)
|
||||
|
||||
const pythonSyntaxError = computed(
|
||||
() =>
|
||||
!props.note &&
|
||||
props.result === SubmissionStatus.compile_error &&
|
||||
props.language === "Python" &&
|
||||
!!props.output,
|
||||
)
|
||||
|
||||
const message = computed(() => {
|
||||
if (props.note) return props.note
|
||||
switch (props.result) {
|
||||
case SubmissionStatus.compile_error:
|
||||
return props.language === "Python"
|
||||
? "代码有语法错误,程序一行都没跑。最常见的是用了中文标点(,:()“”)。按「提交」会先检查一遍,告诉你错在哪一行,中文标点能一键换成英文。"
|
||||
? "代码有语法错误,程序一行都没跑。最常见的是用了中文标点(,:()“”)。"
|
||||
: "代码没能编译通过,写法有错误。看看是不是漏了分号、括号没配对、变量没声明。"
|
||||
case SubmissionStatus.runtime_error:
|
||||
return "程序运行到一半出错,停下来了。检查一下输入是怎么读的、下标有没有越界、除数是不是 0。"
|
||||
case SubmissionStatus.cpu_time_limit_exceeded:
|
||||
case SubmissionStatus.real_time_limit_exceeded:
|
||||
return "运行超时了:程序跑了太久还没结束。看看是不是有死循环,或者在等一个例子里没有的输入。"
|
||||
return "运行超时了:程序跑了太久还没结束。看看是不是有死循环(条件一直成立、循环变量忘了改),或者在等一个例子里没有的输入(多写了一个 input)。"
|
||||
case SubmissionStatus.memory_limit_exceeded:
|
||||
return "程序占的内存太多了。通常是列表、数组开得太大,或者在循环里不停地往里加东西、停不下来。"
|
||||
default:
|
||||
return "试跑的服务暂时连不上,稍后再试一次。"
|
||||
}
|
||||
})
|
||||
|
||||
/** 判题机的临时目录名(`/judger/run/<32 位随机串>/`)对学生没有意义,只剩文件名 */
|
||||
const rawOutput = computed(() => props.output.replace(/\/judger\/run\/[^/"]+\//g, ""))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<n-flex vertical :size="8">
|
||||
<n-alert type="error" :show-icon="false">{{ message }}</n-alert>
|
||||
<n-collapse v-if="output">
|
||||
<PythonErrorExplain v-if="pythonSyntaxError" :err-info="output" />
|
||||
<n-flex v-else vertical :size="8">
|
||||
<RuntimeErrorExplain v-if="runtimeExplain" :info="runtimeError!" :code="code ?? ''" />
|
||||
<n-alert v-else type="error" :show-icon="false">{{ message }}</n-alert>
|
||||
<n-collapse v-if="rawOutput">
|
||||
<n-collapse-item title="原始输出(英文)" name="raw">
|
||||
<pre class="raw">{{ output }}</pre>
|
||||
<pre class="raw">{{ rawOutput }}</pre>
|
||||
</n-collapse-item>
|
||||
</n-collapse>
|
||||
</n-flex>
|
||||
|
||||
Reference in new issue
Block a user