File size: 1,408 Bytes
c5c7c2a
 
 
 
 
0b1e995
 
 
c5c7c2a
081c6ca
 
 
 
 
 
 
 
c5c7c2a
0b1e995
081c6ca
0b1e995
081c6ca
0b1e995
081c6ca
 
 
 
0b1e995
 
081c6ca
 
 
 
 
 
 
 
 
 
 
0b1e995
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
"""
Programmatic Grader — The Master Grader
Orchestrates easy, medium, and hard components into a single report.
"""
from typing import Any
from graders.easy_grader import grade_easy
from graders.medium_grader import grade_medium
from graders.hard_grader import grade_hard

def get_letter_grade(score: float) -> str:
    if score >= 0.90: return "A+"
    if score >= 0.80: return "A"
    if score >= 0.70: return "B"
    if score >= 0.60: return "C"
    if score >= 0.50: return "D"
    return "F"

def grade_episode(history: list[dict]) -> dict[str, Any]:
    if not history:
        return {"error": "No history provided", "score": 0.0, "grade": "F"}
    
    easy_score   = grade_easy(history)
    medium_score = grade_medium(history)
    hard_score   = grade_hard(history)
    
    final_score = hard_score
    grade       = get_letter_grade(final_score)
    
    return {
        "overall_score": round(final_score, 4),
        "letter_grade":  grade,
        "summary":       f"Episode completed with {len(history)} turns. Final score: {final_score}.",
        "metrics": {
            "easy":   easy_score,
            "medium": medium_score,
            "hard":   hard_score,
            "turns":  len(history),
            "unique_strategies": len(set(h.get("strategy_type") for h in history)),
            "unique_categories": len(set(h.get("target_category") for h in history)),
        }
    }