-
Notifications
You must be signed in to change notification settings - Fork 0
/
case_generator.py
114 lines (89 loc) · 3.65 KB
/
case_generator.py
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
from typing import *
from zipfile import ZipFile
from abc import abstractmethod
from time import perf_counter
from os import mkdir
from os import listdir
from os.path import exists
from os.path import isfile
from os.path import isdir
from os.path import join
from re import findall
from re import sub
from json import dump
from json import load
from logging import warning
def calculate_time(func) -> Callable:
def inner(*args, **kwargs) -> Any:
begin = perf_counter()
data = func(*args, **kwargs)
delta_time = perf_counter() - begin
warning("Total time taken in: %s %s", func.__qualname__, f"{delta_time:.5f}s!")
return data
return inner
def safely_create_sub_path(directory: str):
directory = directory.split("/")
for index in range(len(directory)):
sub_directory = "/".join(directory[:index + 1])
if not exists(sub_directory):
mkdir(sub_directory)
def get_files(directory: str) -> List[str]:
return [file for file in listdir(directory) if isfile(join(directory, file))]
def get_sub_directories(directory: str) -> List[str]:
return [sub_directory for sub_directory in listdir(directory) if isdir(join(directory, sub_directory))]
def get_json_data(directory: str) -> Any:
with open(directory, "r", encoding="utf-8") as file:
return load(file)
def save_json_data(directory: str, data: dict):
with open(directory, "w", encoding="utf-8") as file:
dump(data, file, indent=2, ensure_ascii=False)
def get_file_data(directory: str) -> Any:
with open(directory, "r", encoding="utf-8") as file:
return file.read()
def save_file_data(directory: str, data: str):
with open(directory, "w", encoding="utf-8") as file:
file.write(str(data))
class CaseGenerator:
def __init__(
self,
name: str = None,
number_of_testcases: int = 10,
syntax: List[str] = None
):
self.name = name or self.__class__.__name__
self.syntax = syntax or ["%1_id_1%.in", "%1_id_1%.out"]
self.number_of_testcases = number_of_testcases
@abstractmethod
def algorithm(self, input_string: str) -> str:
...
@abstractmethod
def input_generator(self, case_index: int) -> str:
...
def generate(self, zip_all_file: bool = False):
path = f"problems/{self.name}/testcase"
safely_create_sub_path(path)
regex_id_syntax = r"%([0-9]+)_id_([0-9]+)%"
start_input, zero_fill_input = map(int, findall(regex_id_syntax, self.syntax[0])[0])
start_output, zero_fill_output = map(int, findall(regex_id_syntax, self.syntax[1])[0])
if start_input != start_output:
raise Exception("Start Input Number does not match Start Output Number.")
testcase_range = range(start_input, start_input + self.number_of_testcases)
for index in testcase_range:
input_file_name = sub(regex_id_syntax, str(index).zfill(zero_fill_input), self.syntax[0])
output_file_name = sub(regex_id_syntax, str(index).zfill(zero_fill_output), self.syntax[1])
input_data = str(calculate_time(self.input_generator)(index))
output_data = str(calculate_time(self.algorithm)(input_data))
if input_data:
save_file_data(f"problems/{self.name}/testcase/{input_file_name}", input_data)
if output_data:
save_file_data(f"problems/{self.name}/testcase/{output_file_name}", output_data)
if zip_all_file:
self.zip()
@calculate_time
def zip(self):
with ZipFile(f"problems/{self.name}/{self.name}.zip", "w") as zip:
for file in get_files(f"problems/{self.name}/testcase"):
zip.write(
filename=f"problems/{self.name}/testcase/{file}",
arcname=file
)