5. Backtracking 1-step worksheet python

The 2 custom python modules required are:
The Python code that creates a 1 step worksheet, with 10 backtracking diagrams on one page, is below.
The python file, backtracking_1step_worksheet_maker.py, when run, will ask for these inputs:
  • Choose the arithmetic process: "Enter 1, 2, 3, 4 or 5 for +, -, X, /, random".

  • Choose the file name base: "Enter the base filename to be added to the prefix bt1Bk_:". The filename will have β€œ_q” added for the question booklet and β€œ_ans” for the answer booklet.

  1from pathlib import Path
  2import subprocess
  3import time
  4import random
  5import magick_pdf_to_png
  6import backtracking_functions as btf
  7
  8currfile_dir = Path(__file__).parent
  9tex_template_path = currfile_dir / "backtrack_1step_worksheet_template.tex"
 10texans_template_path = currfile_dir / "backtrack_1step_worksheet_ans_template.tex"
 11tex_diagram_template_path = (
 12    currfile_dir / "backtrack_1step_worksheet_diagram_template.tex"
 13)
 14
 15
 16def convert_to_pdf(tex_path, currfile_dir, aux_path):
 17    """
 18    Converts a TeX file to PDF format using pdfLaTeX.
 19
 20    Args:
 21        tex_path (str): The path to the TeX file.
 22        currfile_dir (str): The path to the directory where the TeX file is located.
 23        aux_path (str): The path to the directory where auxiliary files will be stored.
 24
 25    Returns:
 26        subprocess.CompletedProcess: A subprocess.CompletedProcess object containing information about the completed process.
 27
 28    Raises:
 29        FileNotFoundError: If the TeX file does not exist.
 30        subprocess.CalledProcessError: If pdfLaTeX returns a non-zero exit code.
 31    """
 32    result = subprocess.run(
 33        [
 34            "pdfLaTeX",
 35            tex_path,
 36            "-output-directory",
 37            currfile_dir,
 38            "-aux-directory",
 39            aux_path,
 40        ],
 41        stdout=subprocess.PIPE,
 42    )
 43
 44
 45# tex_keys = ['stepAB','stepABrev','boxA','boxB','boxBrev', 'boxArev' ]
 46tex_keys_q = ["stepAB", "boxA", "boxBrev"]
 47
 48
 49def make1_diagram(tex_diagram_template_txt, num):
 50    tex_diagram_template_txt_ans = tex_diagram_template_txt
 51    posttext = r"\vspace{-2pt}"
 52    kv = btf.get_1step_process_dict(num)
 53    for key, value in kv.items():
 54        tex_diagram_template_txt_ans = tex_diagram_template_txt_ans.replace(
 55            "<<" + key + ">>", value
 56        )
 57    for key, value in kv.items():
 58        if key in tex_keys_q:
 59            tex_diagram_template_txt = tex_diagram_template_txt.replace(
 60                "<<" + key + ">>", value
 61            )
 62        else:
 63            tex_diagram_template_txt = tex_diagram_template_txt.replace(
 64                "<<" + key + ">>", ""
 65            )
 66    # return tex_diagram_template_txt
 67    return tex_diagram_template_txt + posttext, tex_diagram_template_txt_ans + posttext
 68
 69
 70def main():
 71    num = input("Enter 1, 2, 3, 4 or 5 for +, -, X, /, random \n")
 72    if num.strip().isdigit():
 73        num = int(num)
 74        if not num in [1, 2, 3, 4, 5]:
 75            num = 5  # random by default
 76    else:
 77        num = 5  # random by default
 78    filename = input("Enter the base filename to be added to the prefix bt1WS_: \n")
 79    if not filename:
 80        filename = "1"  # "bt1_1_q and bt1_1_ans as default file"
 81    # set names of files that are made
 82    # questions
 83    tex_output_path = currfile_dir / f"bt1WS_{filename}_q.tex"
 84    pdf_path = currfile_dir / f"bt1WS_{filename}_q.pdf"
 85    png_path = currfile_dir / f"bt1WS_{filename}_q.png"
 86    aux_path = currfile_dir / "temp"
 87    # answers
 88    tex_output_path_ans = currfile_dir / f"bt1WS_{filename}_ans.tex"
 89    pdf_path_ans = currfile_dir / f"bt1WS_{filename}_ans.pdf"
 90    png_path_ans = currfile_dir / f"bt1WS_{filename}_ans.png"
 91
 92    # Read in the LaTeX template file
 93    with open(tex_template_path, "r") as infile:
 94        tex_template_txt = infile.read()
 95    # Read in the LaTeX template file for answers
 96    with open(texans_template_path, "r") as infile:
 97        tex_template_txt_ans = infile.read()
 98    # Read in the LaTeX diagram template file
 99    with open(tex_diagram_template_path, "r") as infile:
100        tex_diagram_template_txt = infile.read()
101
102    # <<col1>>
103    # generate column 1 text and column 1 text for answers
104    col1_text = ""
105    col1_text_ans = ""
106    for i in range(1, 6):
107        img_tex, img_tex_ans = make1_diagram(tex_diagram_template_txt, num)
108        col1_text += img_tex
109        col1_text_ans += img_tex_ans
110
111    # Replace the <<col1>> placeholder in the LaTeX template with the generated diagrams
112    tex_template_txt = tex_template_txt.replace("<<col1>>", col1_text)
113    tex_template_txt_ans = tex_template_txt_ans.replace("<<col1>>", col1_text_ans)
114
115    # generate column 2 text and column 2 text for answers
116    col2_text = ""
117    col2_text_ans = ""
118    for i in range(6, 11):
119        img_tex, img_tex_ans = make1_diagram(tex_diagram_template_txt, num)
120        col2_text += img_tex
121        col2_text_ans += img_tex_ans
122
123    # Replace the <<col2>> placeholder in the LaTeX template with the generated diagrams
124    tex_template_txt = tex_template_txt.replace("<<col2>>", col2_text)
125    tex_template_txt_ans = tex_template_txt_ans.replace("<<col2>>", col2_text_ans)
126
127    # Write the question tex to an output file
128    with open(tex_output_path, "w") as outfile:
129        outfile.write(tex_template_txt)
130
131    # Write the answer tex to an output file
132    with open(tex_output_path_ans, "w") as outfile:
133        outfile.write(tex_template_txt_ans)
134
135    # Wait for the files to be created
136    time.sleep(1)
137    # Convert the LaTeX files to PDFs
138    convert_to_pdf(tex_output_path, currfile_dir, aux_path)
139    convert_to_pdf(tex_output_path_ans, currfile_dir, aux_path)
140
141    # Wait for the files to be created
142    time.sleep(1)
143    # Convert the PDFs to PNGs
144    magick_pdf_to_png.convert_pdf_to_png(pdf_path, png_path)
145    magick_pdf_to_png.convert_pdf_to_png(pdf_path_ans, png_path_ans)
146
147
148if __name__ == "__main__":
149    print("starting")
150    main()
151    print("finished")