project-euler/src/update_results_table.py

173 lines
5.3 KiB
Python

import os
from pathlib import Path
from subprocess import run
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 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"
)
with open("../README.md", "w") as f:
f.write(initial_message)
results.stream = f
results.write_table()
def _file_stem(f):
return f[-5:]
def get_problems(path=None, ext=None):
wd = os.getcwd()
os.chdir(Path(path))
scripts = sorted(
[script.as_posix() for script in Path(".").rglob(f"*[0-9].{ext}")],
key=_file_stem,
)
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])
os.chdir(wd)
return python_timings, python_results
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])
os.chdir(wd)
return julia_problem_numbers, julia_timings, julia_results
def execute(combine_columns=True, nproblems=-1):
"""
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
)
assert len(python_timings) == len(julia_timings)
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:])])
if combine_columns:
headers = [
"Problem #",
"Result",
"T_exec (Python)",
"T_exec (Julia)",
]
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
)
]
discrepancies = [
f"\nDiscrepancies in problem {npb}. "
f"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),
headers=headers,
value_matrix=value_matrix,
column_styles=[
Style(align="center"),
Style(align="right", thousand_separator="_"),
Style(align="right"),
Style(align="right"),
], # specify styles for each column
margin=1, # add a whitespace for both sides of each cell
)
writer_comb.set_indent_level(3)
return writer_comb
else:
languages = ["Python", "Julia"]
for lang in languages:
if lang == "Python":
headers = ["Problem #", "Result", "T_exec (Python)"]
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)
]
elif lang == "Julia":
headers = ["Problem #", "Result", "T_exec (Julia)"]
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
)
]
writer = MarkdownTableWriter(
table_name=f"Results for {lang}",
headers=headers,
value_matrix=value_matrix,
column_styles=[
Style(align="center"),
Style(align="right", thousand_separator="_"),
Style(align="right"),
], # specify styles for each column
margin=1, # add a whitespace for both sides of each cell
)
return writer
if __name__ == "__main__":
# md = read_md()
# print(md)
res = execute(combine_columns=True, nproblems=-1)
# print(res)
write_md(res)