from typing import Dict import ast MIN_TASK_SCORE = 0.01 MAX_TASK_SCORE = 0.99 def get_task() -> Dict: return { "id": "hard", "difficulty": "hard", "name": "refactor_types", "objective": "Preserve core structure and add meaningful type annotations.", "description": "Refactor code and add type hints.", "grader_name": "grade", "score_range": [MIN_TASK_SCORE, MAX_TASK_SCORE], } def _count_type_hints(tree: ast.AST) -> int: count = 0 for node in ast.walk(tree): if isinstance(node, ast.AnnAssign): count += 1 elif isinstance(node, ast.FunctionDef): if node.returns is not None: count += 1 for arg in node.args.args: if arg.annotation is not None: count += 1 return count def _count_defs(tree: ast.AST) -> int: return sum( isinstance(node, (ast.FunctionDef, ast.ClassDef)) for node in ast.walk(tree) ) def grade(candidate_code: str) -> float: """ Score breakdown: - Structural preservation (defs exist) → +0.5 - Type hints present → +0.5 """ try: tree = ast.parse(candidate_code) except SyntaxError: return MIN_TASK_SCORE score = 0.0 if _count_defs(tree) > 0: score += 0.5 if _count_type_hints(tree) > 0: score += 0.5 score = round(score, 2) score = max(MIN_TASK_SCORE, min(MAX_TASK_SCORE, score)) return score