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