it's a click cli now, and PDF output is working as an option
This commit is contained in:
@@ -1 +1 @@
|
||||
BEGIN_ANSWERS_TOKEN = "*BEGIN ANSWERS*"
|
||||
BEGIN_ANSWERS_TOKEN = "\n*BEGIN ANSWERS*\n"
|
||||
|
||||
51
app/main.py
51
app/main.py
@@ -1,19 +1,37 @@
|
||||
import sys
|
||||
|
||||
import click
|
||||
from click import ClickException
|
||||
|
||||
from app.generate import generate_answers, generate_problems
|
||||
from config import BEGIN_ANSWERS_TOKEN
|
||||
from app.config import BEGIN_ANSWERS_TOKEN
|
||||
from app.pdf import make_pdf
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 3:
|
||||
print(
|
||||
"please supply the number of bits and the number of exercises you'd like, "
|
||||
"space-separated, like so:\n\n $ binary 8 100\n"
|
||||
@click.command()
|
||||
@click.argument("bits", type=click.INT)
|
||||
@click.argument("num-problems", type=click.INT)
|
||||
@click.option("--pdf", default=False, is_flag=True)
|
||||
@click.option("--silent", default=False, is_flag=True)
|
||||
@click.option("--include-answers", default=True, is_flag=True)
|
||||
@click.option("--output-filepath")
|
||||
def main(
|
||||
bits: int,
|
||||
num_problems: int,
|
||||
pdf: bool = False,
|
||||
silent: bool = False,
|
||||
include_answers: bool = True,
|
||||
output_filepath: str = None,
|
||||
) -> None:
|
||||
|
||||
if pdf and silent:
|
||||
raise ClickException(
|
||||
"please specify either `pdf` or `silent`, not both (otherwise there "
|
||||
"won't be any outcome of running the app!"
|
||||
)
|
||||
sys.exit()
|
||||
|
||||
bits = int(sys.argv[1])
|
||||
num_problems = int(sys.argv[2])
|
||||
if pdf and output_filepath and not output_filepath.endswith("pdf"):
|
||||
raise ClickException("Please include an output filepath ending in '.pdf'")
|
||||
|
||||
problems = generate_problems(bits, num_problems)
|
||||
answers = generate_answers(problems)
|
||||
@@ -23,5 +41,16 @@ def main():
|
||||
[f"{problem} | {answer} " for problem, answer in zip(problems, answers)]
|
||||
)
|
||||
|
||||
sys.stdout.write(BEGIN_ANSWERS_TOKEN.join((problems_string, answers_string)))
|
||||
return problems_string, answers_string
|
||||
if pdf:
|
||||
make_pdf(
|
||||
problems=problems_string,
|
||||
answers=answers_string,
|
||||
output_path=output_filepath or "problems.pdf",
|
||||
include_answers=include_answers,
|
||||
)
|
||||
|
||||
if not silent:
|
||||
if include_answers:
|
||||
click.echo(BEGIN_ANSWERS_TOKEN.join((problems_string, answers_string)))
|
||||
else:
|
||||
click.echo(problems_string)
|
||||
|
||||
39
app/pdf.py
Normal file
39
app/pdf.py
Normal file
@@ -0,0 +1,39 @@
|
||||
import os
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
|
||||
def make_pdf(
|
||||
problems: str, answers: str, output_path: str, include_answers: bool
|
||||
) -> None:
|
||||
if include_answers:
|
||||
pdf_jobs = (("problems", problems), ("answers", answers))
|
||||
else:
|
||||
pdf_jobs = ("problems", problems)
|
||||
|
||||
for job_name, job in pdf_jobs:
|
||||
|
||||
if job_name == "answers":
|
||||
path, filename = os.path.split(output_path)
|
||||
new_filename = f"{filename.split('.pdf')[0]}-answers.pdf"
|
||||
output_path = os.path.join(path, new_filename)
|
||||
|
||||
with tempfile.NamedTemporaryFile(mode="w") as txt_file:
|
||||
txt_file.write(job)
|
||||
txt_file.flush()
|
||||
|
||||
command = (
|
||||
f"enscript --columns=4 --no-header --output=tempfile.ps {txt_file.name}"
|
||||
)
|
||||
print(f"command: '{command}'")
|
||||
|
||||
output = subprocess.check_output(command, shell=True)
|
||||
print(output)
|
||||
|
||||
command = f"ps2pdf tempfile.ps {output_path}"
|
||||
print(f"command: '{command}'")
|
||||
|
||||
output = subprocess.check_output(command, shell=True)
|
||||
print(output)
|
||||
print("made pdf", output_path)
|
||||
os.unlink("tempfile.ps")
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
from app.generate import generate, generate_problems
|
||||
from app.check import check
|
||||
|
||||
@@ -6,9 +5,9 @@ from app.check import check
|
||||
def test_generate():
|
||||
first_problem = generate(bits=5)
|
||||
assert len(first_problem) == 5
|
||||
assert all(char in ('1', '0') for char in first_problem)
|
||||
assert '1' in first_problem
|
||||
assert '0' in first_problem
|
||||
assert all(char in ("1", "0") for char in first_problem)
|
||||
assert "1" in first_problem
|
||||
assert "0" in first_problem
|
||||
|
||||
|
||||
def test_generate_problems():
|
||||
@@ -16,14 +15,12 @@ def test_generate_problems():
|
||||
first_problem = problems[0]
|
||||
assert len(problems) == 100
|
||||
assert len(first_problem) == 5
|
||||
assert all(char in ('1', '0') for char in first_problem)
|
||||
assert '1' in first_problem
|
||||
assert '0' in first_problem
|
||||
assert all(char in ("1", "0") for char in first_problem)
|
||||
|
||||
|
||||
def test_check():
|
||||
assert check('110') == 6
|
||||
assert check('000') == 0
|
||||
assert check('001') == 1
|
||||
assert check('011') == 3
|
||||
assert check('010') == 2
|
||||
assert check("110") == 6
|
||||
assert check("000") == 0
|
||||
assert check("001") == 1
|
||||
assert check("011") == 3
|
||||
assert check("010") == 2
|
||||
|
||||
Reference in New Issue
Block a user