Skip to content
This repository was archived by the owner on Oct 23, 2023. It is now read-only.

Commit f4a995d

Browse files
committed
Added to_dict to IOITask and to TerryTask
1 parent 715e0ec commit f4a995d

3 files changed

Lines changed: 74 additions & 16 deletions

File tree

python/formats/__init__.py

Lines changed: 72 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@
33
import os.path
44
from abc import ABC, abstractmethod
55
from enum import Enum
6-
from typing import List, Dict, Optional, Union, Any
7-
86
from task_maker.config import Config
9-
from task_maker.task_maker_frontend import Frontend
10-
from task_maker.source_file import SourceFile
117
from task_maker.languages import GraderInfo, LanguageManager, Dependency, \
128
Language
9+
from task_maker.source_file import SourceFile
10+
from task_maker.task_maker_frontend import Frontend
11+
from typing import List, Dict, Optional, Union, Any
1312

1413
# Name of the input file on disk when doing the validation process
1514
VALIDATION_INPUT_NAME = "tm_input_file"
@@ -42,6 +41,7 @@ class Constraint:
4241
"""
4342
Defines a CONSTRAINT in a cases.gen file (TM-format).
4443
"""
44+
4545
def __init__(self, name: str, lower_bound: Optional[float],
4646
upper_bound: Optional[float], more_or_equal: bool,
4747
less_or_equal: bool):
@@ -88,22 +88,24 @@ class Generator:
8888
a specific SourceFile. Optionally can contain a specification about its
8989
parameters (the names of them, in order).
9090
"""
91+
9192
def __init__(self, name: str, source_file: Optional[SourceFile],
9293
args_spec: Optional[List[str]]):
9394
self.name = name
9495
self.args_spec = args_spec
9596
self.source_file = source_file
9697

9798
def __repr__(self):
98-
return "<Generator %s [%s]>" % (self.name,
99-
" ".join(self.args_spec or []))
99+
return "<Generator %s [%s]>" % (self.name, " ".join(self.args_spec
100+
or []))
100101

101102

102103
class Validator:
103104
"""
104105
Defines a validator of testcases. Like Generator it's composed of a name, a
105106
SourceFile and optionally a list with the names of the parameters
106107
"""
108+
107109
def __init__(self, name: str, source_file: SourceFile,
108110
args_spec: Optional[List[str]]):
109111
self.name = name
@@ -140,6 +142,7 @@ class TestCase:
140142
the path of where to write the files to disk.
141143
Note that a generator and a static file cannot be specified together.
142144
"""
145+
143146
def __init__(self, generator: Optional[Generator],
144147
validator: Optional[Validator], generator_args: List[str],
145148
extra_deps: List[Dependency], input_file: Optional[str],
@@ -169,6 +172,7 @@ class Subtask:
169172
ScoreMode is used with a max_score parameter. With TM-format it's also
170173
possible to specify some constraints for the problem variables.
171174
"""
175+
172176
def __init__(self, name: str, description: str, score_mode: ScoreMode,
173177
max_score: float, testcases: Dict[int, TestCase],
174178
constraints: List[Constraint]):
@@ -188,6 +192,7 @@ class Task(ABC):
188192
Abstract class of a Task, each task format should derive from this base
189193
class.
190194
"""
195+
191196
def __init__(self, name: str, title: str):
192197
self.name = name
193198
self.title = title
@@ -208,6 +213,7 @@ class IOITask(Task):
208213
The subtasks are 0-based numbered, the testcases as well but their numbers
209214
wont reset at each subtask. The time limit is expressed in seconds.
210215
"""
216+
211217
def __init__(self, name: str, title: str, subtasks: Dict[int, Subtask],
212218
official_solution: Optional["SourceFile"],
213219
grader_map: Dict[Language, GraderInfo],
@@ -228,6 +234,44 @@ def __init__(self, name: str, title: str, subtasks: Dict[int, Subtask],
228234
self.default_gen = None # type: Optional[Generator]
229235
self.default_val = None # type: Optional[Validator]
230236

237+
def to_dict(self):
238+
return {
239+
"name":
240+
self.name,
241+
"title":
242+
self.title,
243+
"subtasks": {
244+
st_num: {
245+
"name": subtask.name,
246+
"max_score": subtask.max_score,
247+
"cases": {
248+
tc_num: {
249+
"generator": testcase.generator.name,
250+
"generator_path":
251+
testcase.generator.source_file.path,
252+
"args": testcase.generator_args
253+
}
254+
for tc_num, testcase in subtask.testcases.items()
255+
}
256+
}
257+
for st_num, subtask in self.subtasks.items()
258+
},
259+
"official_solution":
260+
self.official_solution.name if self.official_solution else None,
261+
"checker":
262+
self.checker.name if self.checker else None,
263+
"time_limit":
264+
self.time_limit,
265+
"memory_limit":
266+
self.memory_limit_kb,
267+
"input_file":
268+
self.input_file,
269+
"output_file":
270+
self.output_file,
271+
"task_type":
272+
self.task_type.name
273+
}
274+
231275
def __repr__(self):
232276
return "<Task name=%s title=%s>" % (self.name, self.title)
233277

@@ -241,6 +285,7 @@ class TerryTask(Task):
241285
An official solution can be provided, it will be compiled and put alongside
242286
the checker.
243287
"""
288+
244289
def __init__(self, name: str, title: str, max_score: float):
245290
super().__init__(name, title)
246291
self.max_score = max_score
@@ -249,6 +294,24 @@ def __init__(self, name: str, title: str, max_score: float):
249294
self.official_solution = None # type: Optional[SourceFile]
250295
self.checker = None # type: SourceFile
251296

297+
def to_dict(self):
298+
return {
299+
"name":
300+
self.name,
301+
"title":
302+
self.title,
303+
"max_score":
304+
self.max_score,
305+
"generator":
306+
self.generator.path if self.generator else None,
307+
"validator":
308+
self.validator.path if self.validator else None,
309+
"official_solution":
310+
self.official_solution.path if self.official_solution else None,
311+
"checker":
312+
self.checker.path if self.checker else None,
313+
}
314+
252315
def __repr__(self):
253316
return "<TerryTask name={} title={}>".format(self.name, self.title)
254317

@@ -259,6 +322,7 @@ class TaskFormat(ABC):
259322
should derive from this class. The main function will call one of those
260323
abstract methods to do the action associated to this format.
261324
"""
325+
262326
@staticmethod
263327
@abstractmethod
264328
def evaluate_task(frontend: Frontend, config: Config):
@@ -430,8 +494,8 @@ def get_solutions(solutions: List[str], directory: str,
430494
paths.append("{}{}*".format(directory, sol))
431495
solutions = list_files(paths)
432496
else:
433-
solutions = list_files(
434-
[directory + "*"], exclude=graders + [directory + "__init__.py"])
497+
solutions = list_files([directory + "*"],
498+
exclude=graders + [directory + "__init__.py"])
435499
solutions = list(
436500
filter(lambda s: not s.startswith(directory + "."), solutions))
437501
return solutions

python/uis/ioi_finish_ui_json.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,7 @@ def __init__(self, config: Config, interface: IOIUIInterface):
6969
def print(self):
7070
res = {
7171
"action": "result",
72-
"task": {
73-
"name": self.task.name,
74-
"title": self.task.title
75-
},
72+
"task": self.task.to_dict(),
7673
"subtasks": self._get_subtasks(),
7774
"solutions": get_compilations(self.interface.solutions),
7875
"non_solutions": get_compilations(self.interface.non_solutions),

python/uis/terry_finish_ui_json.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,7 @@ def __init__(self, config: Config, interface: TerryUIInterface):
4040
def print(self):
4141
res = {
4242
"action": "result",
43-
"task": {
44-
"name": self.task.name,
45-
"title": self.task.title
46-
},
43+
"task": self.task.to_dict(),
4744
"solutions": get_compilations(self.interface.solutions),
4845
"non_solutions": get_compilations(self.interface.non_solutions),
4946
"testing": self._get_testing()

0 commit comments

Comments
 (0)