3. Backtracking 1 step diagram - automated

The LaTeX in this section is for one 1-step backtracking diagram.
The values in the diagram can be randomly generated by python.
The required LaTeX and python files are:
The 2 custom python modules required are:
The python file, backtracking_1step_diagram_maker, when run, will ask for 2 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 bt1_:".
The filename will have β€œ_q” added for the question diagram and β€œ_ans” for the answer diagram.
e.g If the user inputs β€œadd1a” the file name will be β€œbt1_add1a_q”.

3.1. A 1-step backtracking diagram with answers

addition_q

addition_ans

subtraction_q

subtraction_ans

multiplication_q

multiplication_ans

division_q

division_ans


3.2. Splitting the LaTeX and modifying it for python

The LaTeX from a single 1-step equation is used as a starting point, split into 2 and modified.
The Document template contains the preamble and the scaffold for the document.
The Diagram template contains the backtacking diagram LaTeX.

3.2.1. Document template

The LaTeX 1-step worksheet template is below.
 1% backtracking worksheet template
 2\documentclass[border = 1mm]{standalone}
 3\usepackage{tikz}
 4\usetikzlibrary{positioning}
 5\usetikzlibrary {arrows.meta}
 6
 7\tikzset{backtrack/.style={rectangle,draw=black,fill=white,
 8inner sep=2pt,minimum height=32pt, minimum width=20mm}}
 9\tikzset{backtrackeq/.style={rectangle,draw=black,fill=white,
10inner sep=2pt,minimum height=12pt, minimum width=20mm}}
11\tikzset{backtrackstep/.style={rectangle,draw=none,fill=white,
12inner sep=2pt,minimum height=12pt, minimum width=20mm}}
13
14\begin{document}
15    <<diagram>>
16\end{document}
<<diagram>> is placeholder text for the text that python will use to add the LaTeX for the backtracking diagram.

3.2.2. Diagram template

The LaTeX 1-step diagram template is below.
 1\begin{tikzpicture}
 2
 3    \node[backtrack] (boxA) at (0, 0) {$<<boxA>>$};
 4    \node[backtrack] (boxB) [right=1cm of boxA] {$<<boxB>>$};
 5 
 6    \node[backtrackeq] (boxAeq) [below=-1pt of boxA] {$=$};
 7    \node[backtrackeq] (boxBeq) [below=-1pt of boxB] {$=$};
 8
 9    \node[backtrack] (boxArev) [below=-1pt of boxAeq] {$<<boxArev>>$};
10    \node[backtrack] (boxBrev) [below=-1pt of boxBeq] {$<<boxBrev>>$};
11
12    \node(boxAr) at ([yshift=24pt,xshift=5mm]boxA) { };
13    \node(boxBl) at ([yshift=24pt,xshift=-5mm]boxB) { };
14    \draw [line width=0.4pt,-{Stealth[length=2mm]}] (boxAr)  --node[backtrackstep, above=3.0pt] {$<<stepAB>>$} (boxBl);
15    
16    \node(boxBrevl) at ([yshift=-24pt,xshift=-5mm]boxBrev) { };
17    \node(boxArevr) at ([yshift=-24pt,xshift=5mm]boxArev) { };
18    \draw [line width=0.4pt,-{Stealth[length=2mm]}] (boxBrevl)  --node[backtrackstep, below=3.0pt] {$<<stepABrev>>$} (boxArevr);
19
20\end{tikzpicture}
21
22
23

3.2.3. Example of a placeholder

The line \node[backtrack] (boxB) [right=1cm of boxA] {$<<boxB>>$} has a placeholder <<boxB>> which is replaced by python.
Other placeholders are marked by << >>.

3.2.4. Python to create a 1 step diagram

The Python to create a 1 step diagram is below.
This script creates a LaTeX file with a diagram and converts it to PDF and PNG formats. It does the following steps:
  • This Python code requires two user inputs: a1 to 4 to choose the arithmetic operation, and the filename to be used.

  • The code reads in three template files: tex_template_path, texans_template_path, and tex_diagram_template_path. The contents of these files are stored in the variables tex_template_txt, tex_template_txt_ans, and tex_diagram_template_txt, respectively.

  • The code then calls the make1_diagram function, passing in tex_diagram_template_txt as an argument. kv = btf.get_1step_process_dict() gets the dictionary containing the values to be placed in the diagram template. The make1_diagram function generates a diagram and returns two values: diagram_text and diagram_text_ans. These values are then used to replace the <<diagram>> placeholder in the tex_template_txt and tex_template_txt_ans variables.

  • The resulting text is then written to two output files: tex_output_path and tex_output_path_ans.

  • The code then waits for 1 second to ensure that the files have been created before calling the convert_to_pdf function to convert these TeX files to PDFs. The PDFs are saved to the paths specified by the pdf_path and pdf_path_ans variables.

  • After waiting for another second, the code calls the magick_pdf_to_png.convert_pdf_to_png function to convert the PDFs to PNGs. The PNGs are saved to the paths specified by the png_path and png_path_ans variables.

  • The script prints β€œstarting” and β€œfinished” messages to indicate when it begins and ends its execution.

python 1step diagram maker

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