Skip to content

Commit ff513a3

Browse files
committed
made tests parallel and time measurements more precise
1 parent 51805ad commit ff513a3

File tree

9 files changed

+95
-36
lines changed

9 files changed

+95
-36
lines changed
Binary file not shown.

py3/easy/roman_to_integer/roman_to_integer.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,13 @@ def romanToInt(self, s):
1818
return num + cache
1919

2020

21-
def main():
22-
a = input()
23-
print(Solution().romanToInt(a))
21+
def get_input(inp):
22+
return inp
2423

2524

26-
if __name__ == "__main__":
27-
main()
25+
def format_output(a):
26+
return str(a)
27+
28+
29+
def main(a):
30+
return Solution().romanToInt(a)
1.59 KB
Binary file not shown.

py3/hard/is_match/is_match.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@ def isMatch(self, s, p):
3333
return self.check_match(s, rg, 0)
3434

3535

36-
def main():
37-
a = input()
38-
b = input()
39-
print(Solution().isMatch(a, b))
36+
def main(a, b):
37+
return Solution().isMatch(a, b)
4038

4139

42-
if __name__ == "__main__":
43-
main()
40+
def get_input(inp):
41+
return inp.split("\n")
42+
43+
44+
def format_output(a):
45+
return str(a)
3.37 KB
Binary file not shown.

py3/hard/median/median.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,17 @@ def findMedianSortedArrays(self, nums1, nums2, desired_place=None, need_two=None
8484
return -1
8585

8686

87-
def main():
88-
a = list(map(int, input().split()))
89-
b = list(map(int, input().split()))
90-
print(Solution().findMedianSortedArrays(a, b))
87+
def main(a, b):
88+
return Solution().findMedianSortedArrays(a, b)
9189

9290

93-
if __name__ == "__main__":
94-
main()
91+
def get_input(inp):
92+
inp = inp.split("\n")
93+
a = list(map(int, inp[0].split()))
94+
b = list(map(int, inp[1].split()))
95+
return a, b
96+
97+
98+
def format_output(a):
99+
return str(a)
100+
669 Bytes
Binary file not shown.

py3/sum/sum.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
1-
def main():
2-
a, b = input().split()
3-
print(int(a) + abs(int(b)))
1+
def solve(a, b):
2+
return a + b
3+
4+
5+
def get_input(inp):
6+
a, b = inp.split()
7+
return int(a), int(b)
8+
9+
10+
def format_output(a):
11+
return str(a)
12+
13+
14+
def main(a, b):
15+
return solve(a, b)
416

517

618
if __name__ == "__main__":
7-
main()
19+
main(*get_input("1 2"))

py3/test.py

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
import sys
66
import time
77
import json
8-
import subprocess
8+
import importlib
9+
from collections import abc
10+
import multiprocessing as mp
911

1012
from collections import namedtuple as nt
1113

@@ -26,34 +28,63 @@ def print_red(text):
2628
print(f"{bcolors.FAIL}{text}{bcolors.ENDC}")
2729

2830

29-
Test = nt("Test", "process output expected name duration")
31+
Test = nt("Test", "solution result test_case name duration")
32+
lock = mp.Lock()
3033

3134

3235
def check_result(test):
33-
out = test.output.decode("ascii").strip()
34-
if test.expected == out:
36+
out = test.solution.format_output(*listify(test.result))
37+
lock.acquire()
38+
if test.test_case["output"] == out:
3539
print_green(f"Test: {test.name} is [OK]\tduration: {test.duration}")
3640
print_green(out)
41+
print("-" * 10)
3742
else:
3843
print_red(f"Test: {test.name} is [FAIL]\tduration: {test.duration}")
39-
print_green(test.expected)
44+
print_red(f"Input:\n{test.test_case['input']}\n---")
45+
print_green(test.test_case["output"])
4046
print_red(out)
4147
print("-" * 10)
48+
lock.release()
49+
50+
51+
def listify(a):
52+
if isinstance(a, str):
53+
return [a.strip()]
54+
if isinstance(a, abc.Iterable):
55+
return a
56+
return [a]
4257

4358

4459
def run_test(program_path, test_path):
4560
with open(test_path, "r") as test:
4661
test_case = json.load(test)
47-
started = time.time()
48-
p = subprocess.Popen(["python3", program_path + "/" + program_path.split("/")[-1] + ".py"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
62+
solution_module_name = ".".join(program_path.split("/")) + "." + program_path.split("/")[-1]
63+
solution = importlib.import_module(solution_module_name)
64+
try:
65+
# each solution should have main() function which returns the result solution
66+
# and get_input() function which accepts the input as str, returns the input in prepared for main format
67+
# and format_output() function which returns string to compare
68+
inp = solution.get_input(test_case["input"])
69+
started = time.time()
70+
res = solution.main(*listify(inp))
71+
except Exception as ex:
72+
lock.acquire()
73+
print_red("{} [FAIL]".format(test_path))
74+
lock.release()
75+
raise ex
4976
finished = time.time()
50-
p = subprocess.Popen(["python3", program_path + "/" + program_path.split("/")[-1] + ".py"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
51-
outp, errs = p.communicate(str(test_case["input"]).encode("ascii"))
52-
if errs:
53-
print_red("[FAIL]")
54-
print(errs)
55-
return
56-
check_result(Test(p, outp, test_case["output"], test_path.split("/")[-1], finished - started))
77+
check_result(Test(solution, res, test_case, test_path.split("/")[-1], finished - started))
78+
79+
80+
SYSTEM_CORES_AMOUNT = 16
81+
82+
83+
def flush_processes(procs):
84+
for p in procs:
85+
p.start()
86+
for p in procs:
87+
p.join()
5788

5889

5990
def main(argv):
@@ -63,10 +94,15 @@ def main(argv):
6394
"""
6495
cwd = os.getcwd()
6596
program_path = os.path.join(cwd, argv[1])
97+
test_processes = []
6698
for test_path in os.listdir(os.path.join(program_path, "test")):
6799
if not re.match(test_path, "_res$") and not re.match(test_path, "_test_res$"):
68100
full_path = os.path.join(program_path, "test", test_path)
69-
run_test(program_path, full_path)
101+
test_processes.append(mp.Process(target=run_test, args=(argv[1], full_path)))
102+
if len(test_processes) == SYSTEM_CORES_AMOUNT:
103+
flush_processes(test_processes)
104+
test_processes = []
105+
flush_processes(test_processes)
70106

71107

72108
if __name__ == "__main__":

0 commit comments

Comments
 (0)