yearning
12 小时以前 3f96c9c6502243b06efd4bb34a189e72e3a5557c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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