Add newline to results' dictionaries

This commit is contained in:
David Doblas Jiménez 2023-04-01 21:26:56 +02:00
parent 48eede9ade
commit 1d0b05c0d3

View File

@ -1,28 +1,25 @@
import os import functools
import json
from pathlib import Path from pathlib import Path
from subprocess import run from subprocess import run
import pytablewriter as ptw
from pytablereader import MarkdownTableFileLoader
from pytablewriter import MarkdownTableWriter from pytablewriter import MarkdownTableWriter
from pytablewriter.style import Style from pytablewriter.style import Style
def read_md(): def read_md(f):
""" loader = MarkdownTableFileLoader(f)
Read README.md for table_data in loader.load():
""" return ptw.dumps_tabledata(table_data)
with open("../README.md", "r") as f:
md = [line.strip() for line in f.readlines() if line.strip() != ""][1:]
return md
def write_md(results): def write_md(results):
"""
Write to README.md
"""
initial_message = ( initial_message = (
f"Having a bit of fun trying to solve the problems from " "Having a bit of fun trying to solve the problems from "
f"https://projecteuler.net/archives using different programming " "https://projecteuler.net/archives using different programming "
f"languages for learning purposes.\n\n" "languages for learning purposes.\n\n"
) )
with open("../README.md", "w") as f: with open("../README.md", "w") as f:
f.write(initial_message) f.write(initial_message)
@ -30,71 +27,101 @@ def write_md(results):
results.write_table() results.write_table()
def _file_stem(f): def cache_and_save_results(func):
return f[-5:] @functools.wraps(func)
@functools.lru_cache(maxsize=None)
def wrapper(script_number):
cache_file_name = f"{func.__name__.split('_')[1]}.json"
num = int(script_number[-6:-3])
if Path(cache_file_name).exists():
with open(cache_file_name, "r") as f:
cache = json.load(f)
else:
cache = {}
if str(num) not in cache:
try:
tim, res = func(script_number)
result = f"Result is {res.split(': ')[1]} and took {tim.split(': ')[1]}"
except IndexError:
tim = "Took: --"
res = "Result is: --"
result = "Result is -- and took --"
cache[str(num)] = result
with open(cache_file_name, "w") as f:
json.dump(cache, f, indent=2, ensure_ascii=False)
else:
result = cache[str(num)]
tim = f"Took: {' '.join(result.split(' ')[-2:])}"
res = f"Result is: {result.split(' ')[2]}"
return tim, res
return wrapper
def get_problems(path=None, ext=None): def get_problems(path, ext=None):
wd = os.getcwd()
os.chdir(Path(path))
scripts = sorted( scripts = sorted(
[script.as_posix() for script in Path(".").rglob(f"*[0-9].{ext}")], [script.as_posix() for script in path.rglob(f"*[0-9].{ext}")],
key=_file_stem, key=lambda x: x[-5:],
) )
os.chdir(wd)
return scripts return scripts
def timing_Python(path=None, exec_only=1): @cache_and_save_results
wd = os.getcwd() def timing_Python(script_number):
scripts = get_problems(path=path, ext="py") _run = run(
os.chdir(Path(path)) ["python3", f"{script_number}"], capture_output=True, text=True
python_timings, python_results = [], [] ).stdout.split("\n")
for script in scripts[:exec_only]:
_res = run(
["python3", f"{script}"], capture_output=True, text=True
).stdout.split("\n")
python_timings.append(_res[0])
python_results.append(_res[2])
os.chdir(wd) return _run[0], _run[2]
return python_timings, python_results
def timing_Julia(path=None, exec_only=1): @cache_and_save_results
wd = os.getcwd() def timing_Julia(script_number):
scripts = get_problems(path="Julia", ext="jl") _run = run(
os.chdir(Path(path)) ["julia", f"{script_number}"], capture_output=True, text=True
julia_problem_numbers, julia_timings, julia_results = [], [], [] ).stdout.split("\n")
for script in scripts[:exec_only]:
_res = run(["julia", f"{script}"], capture_output=True, text=True).stdout.split(
"\n"
)
julia_problem_numbers.append(_res[0])
julia_timings.append(_res[1].split("(")[0])
julia_results.append(_res[3])
os.chdir(wd) tim = " ".join([_run[0], " ".join(_run[1].split(" ")[2:4])])
return julia_problem_numbers, julia_timings, julia_results
return tim, _run[3]
def execute(combine_columns=True, nproblems=-1): def execute(combine_columns=True, nproblems=None):
""" """
Execute scripts and return md formatted table Execute scripts and return md formatted table
""" """
python_timings, python_results = timing_Python(path="Python", exec_only=nproblems) python_path = Path.cwd() / "Python"
julia_n_problem, julia_timings, julia_results = timing_Julia( pscripts = get_problems(python_path, ext="py")
path="Julia", exec_only=nproblems
)
assert len(python_timings) == len(julia_timings) julia_path = Path.cwd() / "Julia"
jscripts = get_problems(julia_path, ext="jl")
ptimings, presults = [], []
jtimings, jresults = [], []
for problem, _ in enumerate(pscripts[:nproblems]):
try:
ptim, pres = timing_Python(pscripts[problem])
ptimings.append(ptim)
presults.append(pres)
except KeyError:
ptimings.append("Took: --")
presults.append(f"Result for problem {problem:0>3}: --")
try:
jtim, jres = timing_Julia(jscripts[problem])
jtimings.append(jtim)
jresults.append(jres)
except IndexError:
jtimings.append("Took: --")
jresults.append(f"Result for problem {problem:0>3}: --")
not_equal = [] not_equal = []
for nproblem, (python_res, julia_res) in enumerate( for npb, (pres, jres) in enumerate(zip(presults, jresults), start=1):
zip(python_results, julia_results), start=1 if not pres.split(" ")[-1] == jres.split(" ")[-1]:
): not_equal.append([npb, pres.split(" ")[-1], jres.split(" ")[-1]])
if not int(python_res[22:]) == int(julia_res[23:]):
not_equal.append([nproblem, int(python_res[22:]), int(julia_res[23:])])
if combine_columns: if combine_columns:
headers = [ headers = [
@ -103,19 +130,25 @@ def execute(combine_columns=True, nproblems=-1):
"T_exec (Python)", "T_exec (Python)",
"T_exec (Julia)", "T_exec (Julia)",
] ]
type_hints = ["str", "int", "str", "str"]
value_matrix = [ value_matrix = [
[f"{int(t_python[25:28]):03d}", int(r_python[22:]), t_python[29:], t_julia] [
for t_python, r_python, t_julia in zip( f"{idx:0>3}",
python_timings, python_results, julia_timings int(r_python.split(" ")[-1]),
t_python.split(": ")[1],
t_julia.split(": ")[1],
]
for idx, (r_python, t_python, t_julia) in enumerate(
zip(presults, ptimings, jtimings), start=1
) )
] ]
discrepancies = [ discrepancies = [
f"\nDiscrepancies in problem {npb}. " f" - Problem {npb}: Python result is {py_r} and in Julia is {jl_r}"
f"Python result is {py_r} and in Julia is {jl_r}."
for npb, py_r, jl_r in not_equal for npb, py_r, jl_r in not_equal
] ]
writer_comb = MarkdownTableWriter( writer_comb = MarkdownTableWriter(
table_name="\n".join(discrepancies), table_name="\nDiscrepancies in:\n" + "\n".join(discrepancies) + "\n",
type_hints=type_hints,
headers=headers, headers=headers,
value_matrix=value_matrix, value_matrix=value_matrix,
column_styles=[ column_styles=[
@ -136,22 +169,35 @@ def execute(combine_columns=True, nproblems=-1):
for lang in languages: for lang in languages:
if lang == "Python": if lang == "Python":
headers = ["Problem #", "Result", "T_exec (Python)"] headers = ["Problem #", "Result", "T_exec (Python)"]
type_hints = ["str", "int", "str"]
value_matrix = [ value_matrix = [
[f"{int(t_python[25:28]):03d}", int(r_python[22:]), t_python[29:]] [
for t_python, r_python in zip(python_timings, python_results) f"{idx:0>3}",
int(r_python.split(" ")[-1]),
t_python.split(": ")[1],
]
for idx, (r_python, t_python) in enumerate(
zip(presults, ptimings), start=1
) # noqa: E501
] ]
elif lang == "Julia": elif lang == "Julia":
headers = ["Problem #", "Result", "T_exec (Julia)"] headers = ["Problem #", "Result", "T_exec (Julia)"]
type_hints = ["str", "int", "str"]
value_matrix = [ value_matrix = [
[f"{int(p_julia[-5:-1]):03d}", int(r_julia[23:]), t_julia] [
for p_julia, r_julia, t_julia in zip( f"{idx:0>3}",
julia_n_problem, julia_results, julia_timings int(r_julia.split(" ")[-1]),
) t_julia.split(": ")[1],
]
for idx, (r_julia, t_julia) in enumerate(
zip(jresults, jtimings), start=1
) # noqa: E501
] ]
writer = MarkdownTableWriter( writer = MarkdownTableWriter(
table_name=f"Results for {lang}", table_name=f"Results for {lang}",
headers=headers, headers=headers,
type_hints=type_hints,
value_matrix=value_matrix, value_matrix=value_matrix,
column_styles=[ column_styles=[
Style(align="center"), Style(align="center"),
@ -165,8 +211,7 @@ def execute(combine_columns=True, nproblems=-1):
if __name__ == "__main__": if __name__ == "__main__":
# md = read_md() # md = read_md("../README.md")
# print(md) # print(md)
res = execute(combine_columns=True, nproblems=-1) res = execute(combine_columns=True, nproblems=-1)
# print(res)
write_md(res) write_md(res)