databoysu commited on
Commit
e70f466
·
1 Parent(s): 7266968

3 tasks just for grader

Browse files
Files changed (4) hide show
  1. openenv.yaml +3 -3
  2. task1_easy.py +140 -0
  3. task2_medium.py +140 -0
  4. task3_hard.py +140 -0
openenv.yaml CHANGED
@@ -8,12 +8,12 @@ tasks:
8
  - id: valid_parentheses_wrong_mapping
9
  name: valid_parentheses_wrong_mapping
10
  description: "Debug the is_valid function so it passes all tests."
11
- grader: "server.graders:grade_valid_parentheses_wrong_mapping"
12
  - id: binary_search_off_by_one
13
  name: binary_search_off_by_one
14
  description: "Debug the binary_search function so it passes all tests."
15
- grader: "server.graders:grade_binary_search_off_by_one"
16
  - id: reverse_string_returns_original
17
  name: reverse_string_returns_original
18
  description: "Debug the reverse_string function so it passes all tests."
19
- grader: "server.graders:grade_reverse_string_returns_original"
 
8
  - id: valid_parentheses_wrong_mapping
9
  name: valid_parentheses_wrong_mapping
10
  description: "Debug the is_valid function so it passes all tests."
11
+ grader: "task1_easy:grade"
12
  - id: binary_search_off_by_one
13
  name: binary_search_off_by_one
14
  description: "Debug the binary_search function so it passes all tests."
15
+ grader: "task2_medium:grade"
16
  - id: reverse_string_returns_original
17
  name: reverse_string_returns_original
18
  description: "Debug the reverse_string function so it passes all tests."
19
+ grader: "task3_hard:grade"
task1_easy.py ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Submission task grader for valid_parentheses_wrong_mapping."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Mapping, Sequence
6
+ from typing import Any, Optional
7
+
8
+ from core.sandbox import run_code_with_tests
9
+ from tasks.tasks import TASK_VP_WRONG_MAPPING
10
+
11
+
12
+ MIN_SCORE = 0.01
13
+ MAX_SCORE = 0.98
14
+
15
+
16
+ def _clamp(score: float) -> float:
17
+ return round(min(max(score, MIN_SCORE), MAX_SCORE), 4)
18
+
19
+
20
+ def _as_mapping(value: Any) -> Optional[Mapping[str, Any]]:
21
+ if isinstance(value, Mapping):
22
+ return value
23
+ if hasattr(value, "model_dump"):
24
+ try:
25
+ dumped = value.model_dump()
26
+ except Exception:
27
+ return None
28
+ if isinstance(dumped, Mapping):
29
+ return dumped
30
+ if hasattr(value, "dict"):
31
+ try:
32
+ dumped = value.dict()
33
+ except Exception:
34
+ return None
35
+ if isinstance(dumped, Mapping):
36
+ return dumped
37
+ return None
38
+
39
+
40
+ def _extract_final_observation(payload: Any) -> Any:
41
+ if payload is None:
42
+ return None
43
+
44
+ mapping = _as_mapping(payload)
45
+ if mapping is not None:
46
+ for key in ("final_observation", "observation", "state", "last_observation"):
47
+ if key in mapping:
48
+ candidate = mapping.get(key)
49
+ if candidate is not None:
50
+ nested = _extract_final_observation(candidate)
51
+ if nested is not None:
52
+ return nested
53
+ if "trajectory" in mapping:
54
+ return _extract_final_observation(mapping.get("trajectory"))
55
+ return payload
56
+
57
+ if isinstance(payload, Sequence) and not isinstance(payload, (str, bytes, bytearray)):
58
+ if not payload:
59
+ return None
60
+ last_item = payload[-1]
61
+ if isinstance(last_item, Sequence) and not isinstance(last_item, (str, bytes, bytearray)) and len(last_item) >= 2:
62
+ return _extract_final_observation(last_item[1])
63
+ if isinstance(last_item, Mapping) or hasattr(last_item, "model_dump") or hasattr(last_item, "dict"):
64
+ return _extract_final_observation(last_item)
65
+ return last_item
66
+
67
+ return payload
68
+
69
+
70
+ def _observation_to_source(observation: Any) -> Optional[str]:
71
+ if observation is None:
72
+ return None
73
+
74
+ mapping = _as_mapping(observation)
75
+ if mapping is not None:
76
+ source = mapping.get("source")
77
+ if isinstance(source, str) and source.strip():
78
+ return source
79
+
80
+ code_lines = mapping.get("code_lines") or mapping.get("code")
81
+ if isinstance(code_lines, Sequence) and not isinstance(code_lines, (str, bytes, bytearray)):
82
+ return "\n".join(str(line) for line in code_lines)
83
+
84
+ code_dict = mapping.get("code_dict")
85
+ if isinstance(code_dict, Mapping) and code_dict:
86
+ ordered_lines: list[tuple[int, str]] = []
87
+ for key, value in code_dict.items():
88
+ try:
89
+ line_no = int(key)
90
+ except Exception:
91
+ continue
92
+ ordered_lines.append((line_no, str(value)))
93
+ if ordered_lines:
94
+ ordered_lines.sort(key=lambda item: item[0])
95
+ return "\n".join(line for _, line in ordered_lines)
96
+
97
+ for attr in ("source", "code", "code_lines", "code_dict"):
98
+ if hasattr(observation, attr):
99
+ value = getattr(observation, attr)
100
+ if isinstance(value, str) and value.strip():
101
+ return value
102
+ if isinstance(value, Sequence) and not isinstance(value, (str, bytes, bytearray)):
103
+ return "\n".join(str(line) for line in value)
104
+ if isinstance(value, Mapping) and value:
105
+ ordered_lines = []
106
+ for key, line in value.items():
107
+ try:
108
+ ordered_lines.append((int(key), str(line)))
109
+ except Exception:
110
+ continue
111
+ if ordered_lines:
112
+ ordered_lines.sort(key=lambda item: item[0])
113
+ return "\n".join(line for _, line in ordered_lines)
114
+
115
+ return None
116
+
117
+
118
+ def grade(payload: Any = None, *args: Any, **kwargs: Any) -> float:
119
+ final_payload = payload if payload is not None else (args[0] if args else kwargs)
120
+ final_observation = _extract_final_observation(final_payload)
121
+ source = _observation_to_source(final_observation)
122
+ if not source or not source.strip():
123
+ return MIN_SCORE
124
+
125
+ try:
126
+ _, results, syntax_err = run_code_with_tests(
127
+ source=source,
128
+ test_callables=TASK_VP_WRONG_MAPPING["tests"],
129
+ )
130
+ except Exception:
131
+ return MIN_SCORE
132
+
133
+ if syntax_err:
134
+ return MIN_SCORE
135
+ if results and all(test_result.passed for test_result in results):
136
+ return MAX_SCORE
137
+ return MIN_SCORE
138
+
139
+
140
+ __all__ = ["grade"]
task2_medium.py ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Submission task grader for binary_search_off_by_one."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Mapping, Sequence
6
+ from typing import Any, Optional
7
+
8
+ from core.sandbox import run_code_with_tests
9
+ from tasks.tasks import TASK_BS_OFF_BY_ONE
10
+
11
+
12
+ MIN_SCORE = 0.01
13
+ MAX_SCORE = 0.98
14
+
15
+
16
+ def _clamp(score: float) -> float:
17
+ return round(min(max(score, MIN_SCORE), MAX_SCORE), 4)
18
+
19
+
20
+ def _as_mapping(value: Any) -> Optional[Mapping[str, Any]]:
21
+ if isinstance(value, Mapping):
22
+ return value
23
+ if hasattr(value, "model_dump"):
24
+ try:
25
+ dumped = value.model_dump()
26
+ except Exception:
27
+ return None
28
+ if isinstance(dumped, Mapping):
29
+ return dumped
30
+ if hasattr(value, "dict"):
31
+ try:
32
+ dumped = value.dict()
33
+ except Exception:
34
+ return None
35
+ if isinstance(dumped, Mapping):
36
+ return dumped
37
+ return None
38
+
39
+
40
+ def _extract_final_observation(payload: Any) -> Any:
41
+ if payload is None:
42
+ return None
43
+
44
+ mapping = _as_mapping(payload)
45
+ if mapping is not None:
46
+ for key in ("final_observation", "observation", "state", "last_observation"):
47
+ if key in mapping:
48
+ candidate = mapping.get(key)
49
+ if candidate is not None:
50
+ nested = _extract_final_observation(candidate)
51
+ if nested is not None:
52
+ return nested
53
+ if "trajectory" in mapping:
54
+ return _extract_final_observation(mapping.get("trajectory"))
55
+ return payload
56
+
57
+ if isinstance(payload, Sequence) and not isinstance(payload, (str, bytes, bytearray)):
58
+ if not payload:
59
+ return None
60
+ last_item = payload[-1]
61
+ if isinstance(last_item, Sequence) and not isinstance(last_item, (str, bytes, bytearray)) and len(last_item) >= 2:
62
+ return _extract_final_observation(last_item[1])
63
+ if isinstance(last_item, Mapping) or hasattr(last_item, "model_dump") or hasattr(last_item, "dict"):
64
+ return _extract_final_observation(last_item)
65
+ return last_item
66
+
67
+ return payload
68
+
69
+
70
+ def _observation_to_source(observation: Any) -> Optional[str]:
71
+ if observation is None:
72
+ return None
73
+
74
+ mapping = _as_mapping(observation)
75
+ if mapping is not None:
76
+ source = mapping.get("source")
77
+ if isinstance(source, str) and source.strip():
78
+ return source
79
+
80
+ code_lines = mapping.get("code_lines") or mapping.get("code")
81
+ if isinstance(code_lines, Sequence) and not isinstance(code_lines, (str, bytes, bytearray)):
82
+ return "\n".join(str(line) for line in code_lines)
83
+
84
+ code_dict = mapping.get("code_dict")
85
+ if isinstance(code_dict, Mapping) and code_dict:
86
+ ordered_lines: list[tuple[int, str]] = []
87
+ for key, value in code_dict.items():
88
+ try:
89
+ line_no = int(key)
90
+ except Exception:
91
+ continue
92
+ ordered_lines.append((line_no, str(value)))
93
+ if ordered_lines:
94
+ ordered_lines.sort(key=lambda item: item[0])
95
+ return "\n".join(line for _, line in ordered_lines)
96
+
97
+ for attr in ("source", "code", "code_lines", "code_dict"):
98
+ if hasattr(observation, attr):
99
+ value = getattr(observation, attr)
100
+ if isinstance(value, str) and value.strip():
101
+ return value
102
+ if isinstance(value, Sequence) and not isinstance(value, (str, bytes, bytearray)):
103
+ return "\n".join(str(line) for line in value)
104
+ if isinstance(value, Mapping) and value:
105
+ ordered_lines = []
106
+ for key, line in value.items():
107
+ try:
108
+ ordered_lines.append((int(key), str(line)))
109
+ except Exception:
110
+ continue
111
+ if ordered_lines:
112
+ ordered_lines.sort(key=lambda item: item[0])
113
+ return "\n".join(line for _, line in ordered_lines)
114
+
115
+ return None
116
+
117
+
118
+ def grade(payload: Any = None, *args: Any, **kwargs: Any) -> float:
119
+ final_payload = payload if payload is not None else (args[0] if args else kwargs)
120
+ final_observation = _extract_final_observation(final_payload)
121
+ source = _observation_to_source(final_observation)
122
+ if not source or not source.strip():
123
+ return MIN_SCORE
124
+
125
+ try:
126
+ _, results, syntax_err = run_code_with_tests(
127
+ source=source,
128
+ test_callables=TASK_BS_OFF_BY_ONE["tests"],
129
+ )
130
+ except Exception:
131
+ return MIN_SCORE
132
+
133
+ if syntax_err:
134
+ return MIN_SCORE
135
+ if results and all(test_result.passed for test_result in results):
136
+ return MAX_SCORE
137
+ return MIN_SCORE
138
+
139
+
140
+ __all__ = ["grade"]
task3_hard.py ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Submission task grader for reverse_string_returns_original."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Mapping, Sequence
6
+ from typing import Any, Optional
7
+
8
+ from core.sandbox import run_code_with_tests
9
+ from tasks.tasks import TASK_REVERSE_NO_REVERSE
10
+
11
+
12
+ MIN_SCORE = 0.01
13
+ MAX_SCORE = 0.98
14
+
15
+
16
+ def _clamp(score: float) -> float:
17
+ return round(min(max(score, MIN_SCORE), MAX_SCORE), 4)
18
+
19
+
20
+ def _as_mapping(value: Any) -> Optional[Mapping[str, Any]]:
21
+ if isinstance(value, Mapping):
22
+ return value
23
+ if hasattr(value, "model_dump"):
24
+ try:
25
+ dumped = value.model_dump()
26
+ except Exception:
27
+ return None
28
+ if isinstance(dumped, Mapping):
29
+ return dumped
30
+ if hasattr(value, "dict"):
31
+ try:
32
+ dumped = value.dict()
33
+ except Exception:
34
+ return None
35
+ if isinstance(dumped, Mapping):
36
+ return dumped
37
+ return None
38
+
39
+
40
+ def _extract_final_observation(payload: Any) -> Any:
41
+ if payload is None:
42
+ return None
43
+
44
+ mapping = _as_mapping(payload)
45
+ if mapping is not None:
46
+ for key in ("final_observation", "observation", "state", "last_observation"):
47
+ if key in mapping:
48
+ candidate = mapping.get(key)
49
+ if candidate is not None:
50
+ nested = _extract_final_observation(candidate)
51
+ if nested is not None:
52
+ return nested
53
+ if "trajectory" in mapping:
54
+ return _extract_final_observation(mapping.get("trajectory"))
55
+ return payload
56
+
57
+ if isinstance(payload, Sequence) and not isinstance(payload, (str, bytes, bytearray)):
58
+ if not payload:
59
+ return None
60
+ last_item = payload[-1]
61
+ if isinstance(last_item, Sequence) and not isinstance(last_item, (str, bytes, bytearray)) and len(last_item) >= 2:
62
+ return _extract_final_observation(last_item[1])
63
+ if isinstance(last_item, Mapping) or hasattr(last_item, "model_dump") or hasattr(last_item, "dict"):
64
+ return _extract_final_observation(last_item)
65
+ return last_item
66
+
67
+ return payload
68
+
69
+
70
+ def _observation_to_source(observation: Any) -> Optional[str]:
71
+ if observation is None:
72
+ return None
73
+
74
+ mapping = _as_mapping(observation)
75
+ if mapping is not None:
76
+ source = mapping.get("source")
77
+ if isinstance(source, str) and source.strip():
78
+ return source
79
+
80
+ code_lines = mapping.get("code_lines") or mapping.get("code")
81
+ if isinstance(code_lines, Sequence) and not isinstance(code_lines, (str, bytes, bytearray)):
82
+ return "\n".join(str(line) for line in code_lines)
83
+
84
+ code_dict = mapping.get("code_dict")
85
+ if isinstance(code_dict, Mapping) and code_dict:
86
+ ordered_lines: list[tuple[int, str]] = []
87
+ for key, value in code_dict.items():
88
+ try:
89
+ line_no = int(key)
90
+ except Exception:
91
+ continue
92
+ ordered_lines.append((line_no, str(value)))
93
+ if ordered_lines:
94
+ ordered_lines.sort(key=lambda item: item[0])
95
+ return "\n".join(line for _, line in ordered_lines)
96
+
97
+ for attr in ("source", "code", "code_lines", "code_dict"):
98
+ if hasattr(observation, attr):
99
+ value = getattr(observation, attr)
100
+ if isinstance(value, str) and value.strip():
101
+ return value
102
+ if isinstance(value, Sequence) and not isinstance(value, (str, bytes, bytearray)):
103
+ return "\n".join(str(line) for line in value)
104
+ if isinstance(value, Mapping) and value:
105
+ ordered_lines = []
106
+ for key, line in value.items():
107
+ try:
108
+ ordered_lines.append((int(key), str(line)))
109
+ except Exception:
110
+ continue
111
+ if ordered_lines:
112
+ ordered_lines.sort(key=lambda item: item[0])
113
+ return "\n".join(line for _, line in ordered_lines)
114
+
115
+ return None
116
+
117
+
118
+ def grade(payload: Any = None, *args: Any, **kwargs: Any) -> float:
119
+ final_payload = payload if payload is not None else (args[0] if args else kwargs)
120
+ final_observation = _extract_final_observation(final_payload)
121
+ source = _observation_to_source(final_observation)
122
+ if not source or not source.strip():
123
+ return MIN_SCORE
124
+
125
+ try:
126
+ _, results, syntax_err = run_code_with_tests(
127
+ source=source,
128
+ test_callables=TASK_REVERSE_NO_REVERSE["tests"],
129
+ )
130
+ except Exception:
131
+ return MIN_SCORE
132
+
133
+ if syntax_err:
134
+ return MIN_SCORE
135
+ if results and all(test_result.passed for test_result in results):
136
+ return MAX_SCORE
137
+ return MIN_SCORE
138
+
139
+
140
+ __all__ = ["grade"]