junaid0600 commited on
Commit
b4cf41e
Β·
1 Parent(s): 95b11e6

new fixed

Browse files
Files changed (1) hide show
  1. env/graders.py +21 -26
env/graders.py CHANGED
@@ -20,10 +20,10 @@ def _safe_get(payload: dict, key: str, default=None):
20
  def _score_explanation(explanation: str) -> float:
21
  """Score explanation quality by length and keyword richness."""
22
  if not explanation or not isinstance(explanation, str):
23
- return 0.0
24
  explanation = explanation.strip()
25
  if len(explanation) < 10:
26
- return 0.0
27
  if len(explanation) < 30:
28
  return 0.05
29
  if len(explanation) < 80:
@@ -38,7 +38,7 @@ def _score_confidence(confidence) -> float:
38
  return 0.05
39
  except (TypeError, ValueError):
40
  pass
41
- return 0.0
42
 
43
  def _query_similarity(submitted: str, expected: str) -> float:
44
  """
@@ -51,14 +51,14 @@ def _query_similarity(submitted: str, expected: str) -> float:
51
 
52
  # Exact match after normalization
53
  if s == e:
54
- return 1.0
55
 
56
  # Tokenize and check keyword overlap
57
  s_tokens = set(s.split())
58
  e_tokens = set(e.split())
59
 
60
  if not e_tokens:
61
- return 0.0
62
 
63
  overlap = len(s_tokens & e_tokens) / len(e_tokens)
64
 
@@ -68,7 +68,8 @@ def _query_similarity(submitted: str, expected: str) -> float:
68
  critical_score = critical_found / len(critical_keywords) if critical_keywords else 0.0
69
 
70
  # Weighted combination
71
- return round((overlap * 0.4) + (critical_score * 0.6), 4)
 
72
 
73
  def _extract_critical_keywords(query: str) -> list[str]:
74
  """Extract SQL keywords that are critical to correctness."""
@@ -90,7 +91,7 @@ def _extract_critical_keywords(query: str) -> list[str]:
90
  def _score_error_type(submitted_type: str, expected_type: str) -> float:
91
  """Score for correctly identifying the error type."""
92
  if not submitted_type:
93
- return 0.0
94
  s = submitted_type.strip().lower()
95
  e = expected_type.strip().lower()
96
  if s == e:
@@ -104,12 +105,12 @@ def _score_error_type(submitted_type: str, expected_type: str) -> float:
104
  for canonical, aliases in related.items():
105
  if e == canonical and any(alias in s for alias in aliases):
106
  return 0.05
107
- return 0.0
108
 
109
  def _score_error_location(submitted_location: str, expected_location: str) -> float:
110
  """Score for correctly identifying WHERE in the query the error is."""
111
  if not submitted_location or not expected_location:
112
- return 0.0
113
  s = submitted_location.strip().lower()
114
  e = expected_location.strip().lower()
115
  if s == e:
@@ -118,7 +119,7 @@ def _score_error_location(submitted_location: str, expected_location: str) -> fl
118
  e_words = set(e.split())
119
  s_words = set(s.split())
120
  overlap = len(e_words & s_words) / len(e_words) if e_words else 0.0
121
- return round(overlap * 0.10, 4)
122
 
123
 
124
  # GRADERS PER DIFFICULTY
@@ -210,7 +211,7 @@ def grade_medium(action: Action, ground_truth: dict) -> tuple[float, dict, str]:
210
  DETERMINISTIC: same input always returns same score.
211
  """
212
  if action is None or action.payload is None:
213
- return 0.0, {"error": "null_action"}, "No action provided."
214
 
215
  payload = action.payload
216
  score = 0.0
@@ -255,7 +256,7 @@ def grade_medium(action: Action, ground_truth: dict) -> tuple[float, dict, str]:
255
  keywords_to_check = logic_keywords.get(error_type, logic_keywords["logic"])
256
  expl_lower = explanation.lower()
257
  keyword_hits = sum(1 for kw in keywords_to_check if kw in expl_lower)
258
- logic_score = min(keyword_hits * 0.05, 0.20)
259
  score += logic_score
260
  breakdown["logic_flaw_identification"] = round(logic_score, 4)
261
  if logic_score > 0:
@@ -286,7 +287,7 @@ def grade_medium(action: Action, ground_truth: dict) -> tuple[float, dict, str]:
286
  breakdown["impact_analysis"] = 0.05
287
  feedback_parts.append("Impact analysis provided.")
288
  else:
289
- breakdown["impact_analysis"] = 0.0
290
 
291
  final_score = round(max(min(score, 0.999), 0.001), 4)
292
  feedback = " ".join(feedback_parts) if feedback_parts else "No valid response provided."
@@ -301,13 +302,7 @@ def grade_hard(action: Action, ground_truth: dict) -> tuple[float, dict, str]:
301
  DETERMINISTIC: same input always returns same score.
302
  """
303
  if action is None or action.payload is None:
304
- return 0.0, {"error": "null_action"}, "No action provided."
305
-
306
- payload = action.payload
307
- score = 0.0
308
- breakdown = {}
309
- feedback_parts = []
310
-
311
  rubric = ground_truth.get("scoring_rubric", {})
312
 
313
  # ── 1. Query correctness (0.30) ──────────────────────────────
@@ -353,11 +348,11 @@ def grade_hard(action: Action, ground_truth: dict) -> tuple[float, dict, str]:
353
  "window function": ["window function", "partition by", "row_number", "subquery filter", "where clause window"]
354
  }
355
 
356
- concept_score = 0.0
357
  for concept, keywords in performance_concept_map.items():
358
  if any(concept_part in issue_type for concept_part in concept.split()):
359
  hits = sum(1 for kw in keywords if kw in combined_text)
360
- concept_score = min(hits * 0.06, 0.30)
361
  break
362
 
363
  score += concept_score
@@ -380,7 +375,7 @@ def grade_hard(action: Action, ground_truth: dict) -> tuple[float, dict, str]:
380
  breakdown["root_cause_analysis"] = 0.10
381
  feedback_parts.append("Root cause analysis provided.")
382
  else:
383
- breakdown["root_cause_analysis"] = 0.0
384
 
385
  # ── 5. Expected improvement (0.10) ────────────────────────────
386
  improvement = str(_safe_get(payload, "expected_improvement", "") or "")
@@ -389,7 +384,7 @@ def grade_hard(action: Action, ground_truth: dict) -> tuple[float, dict, str]:
389
  breakdown["expected_improvement"] = 0.10
390
  feedback_parts.append("Performance improvement estimate provided.")
391
  else:
392
- breakdown["expected_improvement"] = 0.0
393
 
394
  # ── 6. Confidence (0.05) ──────────────────────────────────────
395
  confidence = _safe_get(payload, "confidence", None)
@@ -416,7 +411,7 @@ def grade(action: Action, task_id: str) -> tuple[float, dict, str]:
416
  """
417
  # Edge case: null action
418
  if action is None:
419
- return 0.0, {"error": "null_action"}, "No action provided."
420
 
421
  # Edge case: unknown task
422
  ground_truth = task_manager.get_ground_truth(task_id)
@@ -434,7 +429,7 @@ def grade(action: Action, task_id: str) -> tuple[float, dict, str]:
434
  elif difficulty == "hard":
435
  return grade_hard(action, ground_truth)
436
  else:
437
- return 0.0, {"error": "unknown_difficulty"}, f"Unknown difficulty: {difficulty}"
438
  except Exception as e:
439
  # Never crash β€” return 0.0 with error info
440
  return 0.001, {"error": str(e)}, f"Grader error: {str(e)}"
 
20
  def _score_explanation(explanation: str) -> float:
21
  """Score explanation quality by length and keyword richness."""
22
  if not explanation or not isinstance(explanation, str):
23
+ return 0.001
24
  explanation = explanation.strip()
25
  if len(explanation) < 10:
26
+ return 0.001
27
  if len(explanation) < 30:
28
  return 0.05
29
  if len(explanation) < 80:
 
38
  return 0.05
39
  except (TypeError, ValueError):
40
  pass
41
+ return 0.001
42
 
43
  def _query_similarity(submitted: str, expected: str) -> float:
44
  """
 
51
 
52
  # Exact match after normalization
53
  if s == e:
54
+ return 0.999
55
 
56
  # Tokenize and check keyword overlap
57
  s_tokens = set(s.split())
58
  e_tokens = set(e.split())
59
 
60
  if not e_tokens:
61
+ return 0.001
62
 
63
  overlap = len(s_tokens & e_tokens) / len(e_tokens)
64
 
 
68
  critical_score = critical_found / len(critical_keywords) if critical_keywords else 0.0
69
 
70
  # Weighted combination
71
+ similarity = round((overlap * 0.4) + (critical_score * 0.6), 4)
72
+ return max(min(similarity, 0.999), 0.001)
73
 
74
  def _extract_critical_keywords(query: str) -> list[str]:
75
  """Extract SQL keywords that are critical to correctness."""
 
91
  def _score_error_type(submitted_type: str, expected_type: str) -> float:
92
  """Score for correctly identifying the error type."""
93
  if not submitted_type:
94
+ return 0.001
95
  s = submitted_type.strip().lower()
96
  e = expected_type.strip().lower()
97
  if s == e:
 
105
  for canonical, aliases in related.items():
106
  if e == canonical and any(alias in s for alias in aliases):
107
  return 0.05
108
+ return 0.001
109
 
110
  def _score_error_location(submitted_location: str, expected_location: str) -> float:
111
  """Score for correctly identifying WHERE in the query the error is."""
112
  if not submitted_location or not expected_location:
113
+ return 0.001
114
  s = submitted_location.strip().lower()
115
  e = expected_location.strip().lower()
116
  if s == e:
 
119
  e_words = set(e.split())
120
  s_words = set(s.split())
121
  overlap = len(e_words & s_words) / len(e_words) if e_words else 0.0
122
+ return max(round(overlap * 0.10, 4), 0.001)
123
 
124
 
125
  # GRADERS PER DIFFICULTY
 
211
  DETERMINISTIC: same input always returns same score.
212
  """
213
  if action is None or action.payload is None:
214
+ return 0.001, {"error": "null_action"}, "No action provided."
215
 
216
  payload = action.payload
217
  score = 0.0
 
256
  keywords_to_check = logic_keywords.get(error_type, logic_keywords["logic"])
257
  expl_lower = explanation.lower()
258
  keyword_hits = sum(1 for kw in keywords_to_check if kw in expl_lower)
259
+ logic_score = max(min(keyword_hits * 0.05, 0.20), 0.001)
260
  score += logic_score
261
  breakdown["logic_flaw_identification"] = round(logic_score, 4)
262
  if logic_score > 0:
 
287
  breakdown["impact_analysis"] = 0.05
288
  feedback_parts.append("Impact analysis provided.")
289
  else:
290
+ breakdown["impact_analysis"] = 0.001
291
 
292
  final_score = round(max(min(score, 0.999), 0.001), 4)
293
  feedback = " ".join(feedback_parts) if feedback_parts else "No valid response provided."
 
302
  DETERMINISTIC: same input always returns same score.
303
  """
304
  if action is None or action.payload is None:
305
+ return 0.001, {"error": "null_action"}, "No action provided."
 
 
 
 
 
 
306
  rubric = ground_truth.get("scoring_rubric", {})
307
 
308
  # ── 1. Query correctness (0.30) ──────────────────────────────
 
348
  "window function": ["window function", "partition by", "row_number", "subquery filter", "where clause window"]
349
  }
350
 
351
+ concept_score = 0.001
352
  for concept, keywords in performance_concept_map.items():
353
  if any(concept_part in issue_type for concept_part in concept.split()):
354
  hits = sum(1 for kw in keywords if kw in combined_text)
355
+ concept_score = max(min(hits * 0.06, 0.30), 0.001)
356
  break
357
 
358
  score += concept_score
 
375
  breakdown["root_cause_analysis"] = 0.10
376
  feedback_parts.append("Root cause analysis provided.")
377
  else:
378
+ breakdown["root_cause_analysis"] = 0.001
379
 
380
  # ── 5. Expected improvement (0.10) ────────────────────────────
381
  improvement = str(_safe_get(payload, "expected_improvement", "") or "")
 
384
  breakdown["expected_improvement"] = 0.10
385
  feedback_parts.append("Performance improvement estimate provided.")
386
  else:
387
+ breakdown["expected_improvement"] = 0.001
388
 
389
  # ── 6. Confidence (0.05) ──────────────────────────────────────
390
  confidence = _safe_get(payload, "confidence", None)
 
411
  """
412
  # Edge case: null action
413
  if action is None:
414
+ return 0.001, {"error": "null_action"}, "No action provided."
415
 
416
  # Edge case: unknown task
417
  ground_truth = task_manager.get_ground_truth(task_id)
 
429
  elif difficulty == "hard":
430
  return grade_hard(action, ground_truth)
431
  else:
432
+ return 0.001, {"error": "unknown_difficulty"}, f"Unknown difficulty: {difficulty}"
433
  except Exception as e:
434
  # Never crash β€” return 0.0 with error info
435
  return 0.001, {"error": str(e)}, f"Grader error: {str(e)}"