From 3f96c9c6502243b06efd4bb34a189e72e3a5557c Mon Sep 17 00:00:00 2001
From: yearning <10538594+wangweifeng1999@user.noreply.gitee.com>
Date: 星期一, 28 九月 2026 19:24:55 +0800
Subject: [PATCH] 复制项目

---
 backend/app/grading.py |   69 ++++++++++++++++++++++++++++++++++
 1 files changed, 69 insertions(+), 0 deletions(-)

diff --git a/backend/app/grading.py b/backend/app/grading.py
new file mode 100644
index 0000000..7241828
--- /dev/null
+++ b/backend/app/grading.py
@@ -0,0 +1,69 @@
+import json
+import re
+from typing import Any
+
+
+def normalize_answer(raw: str, item_type: int | None) -> str:
+    if not raw:
+        return ""
+    s = raw.strip().upper()
+    if item_type == 288:
+        letters = re.findall(r"[A-Z]", s.replace(",", ""))
+        return "".join(sorted(set(letters)))
+    return s.replace(",", "").strip()
+
+
+def normalize_reference(ref: str, item_type: int | None) -> str:
+    if not ref:
+        return ""
+    s = ref.strip().upper()
+    if item_type == 288:
+        letters = re.findall(r"[A-Z]", s)
+        return "".join(sorted(set(letters)))
+    return s
+
+
+def get_correct_mark(answer_rules: str | None, default: float = 1.0) -> float:
+    if not answer_rules:
+        return default
+    try:
+        rules = json.loads(answer_rules)
+        return float(rules.get("correctMark", default))
+    except (json.JSONDecodeError, TypeError, ValueError):
+        return default
+
+
+def grade_item(
+    user_answer: str,
+    reference_answer: str,
+    answer_rules: str | None,
+    item_type: int | None,
+    max_score: float | None,
+) -> tuple[bool, float]:
+    ua = normalize_answer(user_answer, item_type)
+    ra = normalize_reference(reference_answer, item_type)
+    if not ra and answer_rules:
+        try:
+            rules = json.loads(answer_rules)
+            ra = normalize_reference(str(rules.get("reference", "")), item_type)
+        except json.JSONDecodeError:
+            pass
+    mark = get_correct_mark(answer_rules, max_score or 1.0)
+    ok = ua == ra and bool(ra)
+    return ok, (mark if ok else 0.0)
+
+
+def answers_json_to_map(answers_json: str) -> dict[str, str]:
+    try:
+        arr = json.loads(answers_json)
+    except json.JSONDecodeError:
+        return {}
+    out: dict[str, str] = {}
+    if isinstance(arr, list):
+        for item in arr:
+            if isinstance(item, dict):
+                iid = item.get("itemId") or item.get("item_id")
+                ans = item.get("answer", "")
+                if iid:
+                    out[str(iid)] = str(ans) if ans is not None else ""
+    return out

--
Gitblit v1.8.0