Rajan Sharma commited on
Commit
5cf4edb
·
verified ·
1 Parent(s): b5c0f10

Create graders/rule_grader.py

Browse files
Files changed (1) hide show
  1. graders/rule_grader.py +52 -0
graders/rule_grader.py ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ from typing import Dict, Any, List
3
+
4
+ def grade(output: Dict[str, Any], rubric_path: str) -> Dict[str, Any]:
5
+ with open(rubric_path, "r", encoding="utf-8") as f:
6
+ rubric = json.load(f)
7
+
8
+ score = 0
9
+ max_score = 0
10
+ notes: List[str] = []
11
+
12
+ # Exact-set checks
13
+ for check in rubric.get("set_equals", []):
14
+ path = check["path"] # e.g., "prioritization.groups_prioritized"
15
+ expected = set(check["expected"])
16
+ actual = get_path(output, path)
17
+ max_score += 1
18
+ if set(actual) == expected:
19
+ score += 1
20
+ else:
21
+ notes.append(f"Set mismatch at {path}. Expected {list(expected)} got {actual}")
22
+
23
+ # Must-contain strings
24
+ for check in rubric.get("must_contain", []):
25
+ path = check["path"]
26
+ expected_substr = check["substr"].lower()
27
+ actual = str(get_path(output, path)).lower()
28
+ max_score += 1
29
+ if expected_substr in actual:
30
+ score += 1
31
+ else:
32
+ notes.append(f"Missing '{check['substr']}' in {path}")
33
+
34
+ # Numeric equals (tolerance)
35
+ for check in rubric.get("numeric_equals", []):
36
+ path = check["path"]
37
+ expected = float(check["expected"])
38
+ tol = float(check.get("tolerance", 0.0))
39
+ actual = float(get_path(output, path))
40
+ max_score += 1
41
+ if abs(actual - expected) <= tol:
42
+ score += 1
43
+ else:
44
+ notes.append(f"Numeric diff at {path}: expected {expected}±{tol}, got {actual}")
45
+
46
+ return {"score": score, "max_score": max_score, "notes": notes}
47
+
48
+ def get_path(obj, path: str):
49
+ cur = obj
50
+ for part in path.split("."):
51
+ cur = cur[part]
52
+ return cur