fix
This commit is contained in:
@@ -1,10 +1,9 @@
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
from utils.models import JSONField
|
|
||||||
|
|
||||||
from utils.constants import ContestStatus, ContestType
|
|
||||||
from account.models import User
|
from account.models import User
|
||||||
from utils.models import RichTextField
|
from utils.constants import ContestStatus, ContestType
|
||||||
|
from utils.models import JSONField, RichTextField
|
||||||
|
|
||||||
|
|
||||||
class Contest(models.Model):
|
class Contest(models.Model):
|
||||||
|
|||||||
@@ -141,6 +141,8 @@ def build_evaluation_prompt(problem):
|
|||||||
5. Mermaid节点ID由系统生成,不是学生编写内容;不要评价节点ID,不要因节点ID扣分,不要建议修改节点ID
|
5. Mermaid节点ID由系统生成,不是学生编写内容;不要评价节点ID,不要因节点ID扣分,不要建议修改节点ID
|
||||||
6. feedback控制在100字以内,只总结核心优点和主要问题
|
6. feedback控制在100字以内,只总结核心优点和主要问题
|
||||||
7. suggestions最多3条,每条单独一行;重要建议必须以【重点】开头,普通建议不要加前缀
|
7. suggestions最多3条,每条单独一行;重要建议必须以【重点】开头,普通建议不要加前缀
|
||||||
|
- 只针对学生流程图中真实存在的问题给建议;若流程图已符合要求,suggestions 留空字符串,禁止编造或凑数
|
||||||
|
- 不要建议学生去做他已经做对的事(如顺序/分支已正确,就不要再建议调整该顺序/分支)
|
||||||
8. criteria_details 中的 comment 保持简短,每项不超过25字
|
8. criteria_details 中的 comment 保持简短,每项不超过25字
|
||||||
|
|
||||||
评分等级:
|
评分等级:
|
||||||
@@ -149,17 +151,17 @@ def build_evaluation_prompt(problem):
|
|||||||
- B级 (70-79分): 及格,基本正确但存在一些问题
|
- B级 (70-79分): 及格,基本正确但存在一些问题
|
||||||
- C级 (0-69分): 需要改进,存在明显问题
|
- C级 (0-69分): 需要改进,存在明显问题
|
||||||
|
|
||||||
请以JSON格式返回评分结果:
|
请以JSON格式返回评分结果(以下仅为格式示例,feedback/suggestions 的内容必须依据学生实际提交的流程图生成,不要照搬示例文字,尤其不要在没有循环的流程图中提及循环):
|
||||||
{{
|
{{
|
||||||
"score": 85,
|
"score": 85,
|
||||||
"grade": "A",
|
"grade": "A",
|
||||||
"feedback": "整体逻辑清楚,但循环出口表达不够明确。",
|
"feedback": "<根据实际流程图填写,100字以内>",
|
||||||
"suggestions": "【重点】补充循环结束条件\\n完善异常输入分支",
|
"suggestions": "<根据实际问题填写;若无明显问题可留空字符串>",
|
||||||
"criteria_details": {{
|
"criteria_details": {{
|
||||||
"逻辑正确性": {{"score": 35, "max": 40, "comment": "逻辑基本正确"}},
|
"逻辑正确性": {{"score": 35, "max": 40, "comment": "<简短说明>"}},
|
||||||
"完整性": {{"score": 25, "max": 30, "comment": "缺少部分步骤"}},
|
"完整性": {{"score": 25, "max": 30, "comment": "<简短说明>"}},
|
||||||
"规范性": {{"score": 18, "max": 20, "comment": "符号使用规范"}},
|
"规范性": {{"score": 18, "max": 20, "comment": "<简短说明>"}},
|
||||||
"清晰度": {{"score": 8, "max": 10, "comment": "布局清晰"}}
|
"清晰度": {{"score": 8, "max": 10, "comment": "<简短说明>"}}
|
||||||
}}
|
}}
|
||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -124,13 +124,9 @@ class TestCaseAPI(CSRFExemptAPIView, TestCaseZipProcessor):
|
|||||||
with zipfile.ZipFile(file_name, "w") as file:
|
with zipfile.ZipFile(file_name, "w") as file:
|
||||||
for test_case in name_list:
|
for test_case in name_list:
|
||||||
file.write(f"{test_case_dir}/{test_case}", test_case)
|
file.write(f"{test_case_dir}/{test_case}", test_case)
|
||||||
response = StreamingHttpResponse(
|
response = StreamingHttpResponse(FileWrapper(open(file_name, "rb")), content_type="application/octet-stream")
|
||||||
FileWrapper(open(file_name, "rb")), content_type="application/octet-stream"
|
|
||||||
)
|
|
||||||
|
|
||||||
response["Content-Disposition"] = (
|
response["Content-Disposition"] = f"attachment; filename=problem_{problem.id}_test_cases.zip"
|
||||||
f"attachment; filename=problem_{problem.id}_test_cases.zip"
|
|
||||||
)
|
|
||||||
response["Content-Length"] = os.path.getsize(file_name)
|
response["Content-Length"] = os.path.getsize(file_name)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@@ -203,9 +199,7 @@ class ProblemAPI(ProblemBase):
|
|||||||
except Problem.DoesNotExist:
|
except Problem.DoesNotExist:
|
||||||
return self.error("Problem does not exist")
|
return self.error("Problem does not exist")
|
||||||
|
|
||||||
problems = Problem.objects.filter(contest_id__isnull=True).order_by(
|
problems = Problem.objects.filter(contest_id__isnull=True).order_by("-create_time")
|
||||||
"-create_time"
|
|
||||||
)
|
|
||||||
|
|
||||||
author = request.GET.get("author", "")
|
author = request.GET.get("author", "")
|
||||||
if author:
|
if author:
|
||||||
@@ -213,14 +207,10 @@ class ProblemAPI(ProblemBase):
|
|||||||
|
|
||||||
keyword = request.GET.get("keyword", "").strip()
|
keyword = request.GET.get("keyword", "").strip()
|
||||||
if keyword:
|
if keyword:
|
||||||
problems = problems.filter(
|
problems = problems.filter(Q(title__icontains=keyword) | Q(_id__icontains=keyword))
|
||||||
Q(title__icontains=keyword) | Q(_id__icontains=keyword)
|
|
||||||
)
|
|
||||||
if not user.can_mgmt_all_problem():
|
if not user.can_mgmt_all_problem():
|
||||||
problems = problems.filter(created_by=user)
|
problems = problems.filter(created_by=user)
|
||||||
return self.success(
|
return self.success(self.paginate_data(request, problems, ProblemAdminListSerializer))
|
||||||
self.paginate_data(request, problems, ProblemAdminListSerializer)
|
|
||||||
)
|
|
||||||
|
|
||||||
@problem_permission_required
|
@problem_permission_required
|
||||||
@validate_serializer(EditProblemSerializer)
|
@validate_serializer(EditProblemSerializer)
|
||||||
@@ -237,11 +227,7 @@ class ProblemAPI(ProblemBase):
|
|||||||
_id = data["_id"]
|
_id = data["_id"]
|
||||||
if not _id:
|
if not _id:
|
||||||
return self.error("Display ID is required")
|
return self.error("Display ID is required")
|
||||||
if (
|
if Problem.objects.exclude(id=problem_id).filter(_id=_id, contest_id__isnull=True).exists():
|
||||||
Problem.objects.exclude(id=problem_id)
|
|
||||||
.filter(_id=_id, contest_id__isnull=True)
|
|
||||||
.exists()
|
|
||||||
):
|
|
||||||
return self.error("Display ID already exists")
|
return self.error("Display ID already exists")
|
||||||
|
|
||||||
error_info = self.common_checks(request)
|
error_info = self.common_checks(request)
|
||||||
@@ -342,9 +328,7 @@ class ContestProblemAPI(ProblemBase):
|
|||||||
keyword = request.GET.get("keyword")
|
keyword = request.GET.get("keyword")
|
||||||
if keyword:
|
if keyword:
|
||||||
problems = problems.filter(title__contains=keyword)
|
problems = problems.filter(title__contains=keyword)
|
||||||
return self.success(
|
return self.success(self.paginate_data(request, problems, ProblemAdminListSerializer))
|
||||||
self.paginate_data(request, problems, ProblemAdminListSerializer)
|
|
||||||
)
|
|
||||||
|
|
||||||
@validate_serializer(EditContestProblemSerializer)
|
@validate_serializer(EditContestProblemSerializer)
|
||||||
def put(self, request):
|
def put(self, request):
|
||||||
@@ -367,11 +351,7 @@ class ContestProblemAPI(ProblemBase):
|
|||||||
_id = data["_id"]
|
_id = data["_id"]
|
||||||
if not _id:
|
if not _id:
|
||||||
return self.error("Display ID is required")
|
return self.error("Display ID is required")
|
||||||
if (
|
if Problem.objects.exclude(id=problem_id).filter(_id=_id, contest=contest).exists():
|
||||||
Problem.objects.exclude(id=problem_id)
|
|
||||||
.filter(_id=_id, contest=contest)
|
|
||||||
.exists()
|
|
||||||
):
|
|
||||||
return self.error("Display ID already exists")
|
return self.error("Display ID already exists")
|
||||||
|
|
||||||
error_info = self.common_checks(request)
|
error_info = self.common_checks(request)
|
||||||
@@ -500,7 +480,8 @@ class ProblemFlowchartAIGen(APIView):
|
|||||||
},
|
},
|
||||||
{"role": "user", "content": python_code},
|
{"role": "user", "content": python_code},
|
||||||
],
|
],
|
||||||
temperature=1.0,
|
temperature=0,
|
||||||
|
extra_body={"thinking": {"type": "disabled"}},
|
||||||
)
|
)
|
||||||
|
|
||||||
mermaid_code = response.choices[0].message.content
|
mermaid_code = response.choices[0].message.content
|
||||||
@@ -512,11 +493,13 @@ class StuckProblemsAPI(APIView):
|
|||||||
def get(self, request):
|
def get(self, request):
|
||||||
from submission.models import JudgeStatus
|
from submission.models import JudgeStatus
|
||||||
|
|
||||||
failed_q = Q(result__in=[
|
failed_q = Q(
|
||||||
JudgeStatus.WRONG_ANSWER,
|
result__in=[
|
||||||
JudgeStatus.COMPILE_ERROR,
|
JudgeStatus.WRONG_ANSWER,
|
||||||
JudgeStatus.RUNTIME_ERROR,
|
JudgeStatus.COMPILE_ERROR,
|
||||||
])
|
JudgeStatus.RUNTIME_ERROR,
|
||||||
|
]
|
||||||
|
)
|
||||||
rows = (
|
rows = (
|
||||||
Submission.objects.values("problem_id", "problem___id", "problem__title")
|
Submission.objects.values("problem_id", "problem___id", "problem__title")
|
||||||
.annotate(
|
.annotate(
|
||||||
@@ -535,9 +518,7 @@ class StuckProblemsAPI(APIView):
|
|||||||
"total": r["total"],
|
"total": r["total"],
|
||||||
"failed": r["failed"],
|
"failed": r["failed"],
|
||||||
"failed_users": r["failed_users"],
|
"failed_users": r["failed_users"],
|
||||||
"ac_rate": round(r["accepted"] / r["total"] * 100, 1)
|
"ac_rate": round(r["accepted"] / r["total"] * 100, 1) if r["total"] else 0,
|
||||||
if r["total"]
|
|
||||||
else 0,
|
|
||||||
}
|
}
|
||||||
for r in rows
|
for r in rows
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user