3. Decimals diagram - automated

The LaTeX in this section is for a diagram for addition or subtraction of decimals.
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, add_sub_decimals_diagram_maker, when run, will ask for 3 inputs:
Choose the arithmetic process: "Enter 1, 2, or 3 for +, -, random for the process".
Choose the number of integer places: "Enter 1, 2, 3, or 4 for the number of places before the decimal point".
Choose the number of decimal places: "Enter 1, 2, 3, 4, or 5 for the number of decimal places ".
Choose the file name base: "Enter the base filename to be added to the prefix asd_:".
The filename will have β€œ_q” added for the question diagram and β€œ_ans” for the answer diagram.

3.1. A decimals diagram with answers

addition_q

addition_ans

subtraction_q

subtraction_ans


3.2. Splitting the LaTeX and modifying it for python

The LaTeX file is built from 2 templates.
The Document template contains the preamble and the scaffold for the document.
The Diagram template contains the decimal diagram LaTeX.

3.2.1. Document template

The LaTeX document template is below.
1% asd worksheet template
2\documentclass[border = 1mm]{standalone}
3\usepackage{dcolumn}
4    
5\newcolumntype{d}[1]{cD{.}{.}{#1}}
6
7\begin{document}
8    <<diagram>>
9\end{document}
<<diagram>> is placeholder text for the text that python will use to add the LaTeX for the decimals diagram.

3.2.2. Diagram template

The LaTeX decimals diagram template is below.
The placeholders are marked by << >>.
1
2\begin{tabular}{d{<<numip>>.<<numdp>>}}
3     &<<num1>> \tabularnewline
4    $<<process>>$&<<num2>> \tabularnewline
5    \hline
6     &<<answer>> \tabularnewline
7    \hline
8\end{tabular}

3.2.3. Python to create a decimals diagram

The Python to create a decimals 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:

add_sub_decimals_diagram_maker.py

  1from pathlib import Path
  2import subprocess
  3import time
  4import decimals_functions as decf
  5import magick_pdf_to_png
  6
  7
  8currfile_dir = Path(__file__).parent
  9tex_template_path = currfile_dir / "add_sub_decimals_template.tex"
 10texans_template_path = currfile_dir / "add_sub_decimals_template.tex"
 11tex_diagram_template_path = currfile_dir / "add_sub_decimals_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 = ["num1", "num2", "process"]
 44tex_keys_q = ["answer"]
 45
 46
 47def make1_diagram(tex_diagram_template_txt, nump, numip, numdp):
 48    tex_diagram_template_txt_ans = tex_diagram_template_txt
 49    kv = decf.get_add_sub_dec_dict(nump, numip, numdp)
 50
 51    for key, value in kv.items():
 52        tex_diagram_template_txt_ans = tex_diagram_template_txt_ans.replace(
 53            "<<" + key + ">>", value
 54        )
 55
 56    for key, value in kv.items():
 57        if key in tex_keys_q:
 58            tex_diagram_template_txt = tex_diagram_template_txt.replace(
 59                "<<" + key + ">>", ""
 60            )
 61        else:
 62            tex_diagram_template_txt = tex_diagram_template_txt.replace(
 63                "<<" + key + ">>", value
 64            )
 65    tex_diagram_template_txt = tex_diagram_template_txt.replace("<<numip>>", str(numip))
 66    tex_diagram_template_txt = tex_diagram_template_txt.replace("<<numdp>>", str(numdp))
 67    tex_diagram_template_txt_ans = tex_diagram_template_txt_ans.replace("<<numip>>", str(numip))
 68    tex_diagram_template_txt_ans = tex_diagram_template_txt_ans.replace("<<numdp>>", str(numdp))
 69    # return tex_diagram_template_txt
 70    return tex_diagram_template_txt, tex_diagram_template_txt_ans
 71
 72
 73def main():
 74    nump = input("Enter 1, 2, or 3 for +, -, random for the process \n")
 75    if nump.strip().isdigit():
 76        nump = int(nump)
 77        if not nump in [1, 2, 3]:
 78            nump = 3  # random by default
 79    else:
 80        nump = 3  # random by default
 81    #
 82    numip = input("Enter 1, 2, 3, or 4 for the number of places before the decimal point \n")
 83    if numip.strip().isdigit():
 84        numip = int(numip)
 85        if not numip in [1, 2, 3, 4, 5]:
 86            numip = 1  # 1 by default
 87    else:
 88        numip = 1  # 1 by default
 89    #
 90    numdp = input("Enter 1, 2, 3, 4, or 5 for the number of decimal places \n")
 91    if numdp.strip().isdigit():
 92        numdp = int(numdp)
 93        if not numdp in [1, 2, 3, 4, 5]:
 94            numdp = 1  # 1 by default
 95    else:
 96        numdp = 1  # 1 by default
 97    #
 98    filename = input("Enter the base filename to be added to the prefix asd_: \n")
 99    if not filename:
100        filename = "1"  # "asd_1_q and asd_1_ans as default file"
101    # set names of files that are made
102    # questions
103    tex_output_path = currfile_dir / f"asd_{filename}_q.tex"
104    pdf_path = currfile_dir / f"asd_{filename}_q.pdf"
105    png_path = currfile_dir / f"asd_{filename}_q.png"
106    aux_path = currfile_dir / "temp"
107    # answers
108    tex_output_path_ans = currfile_dir / f"asd_{filename}_ans.tex"
109    pdf_path_ans = currfile_dir / f"asd_{filename}_ans.pdf"
110    png_path_ans = currfile_dir / f"asd_{filename}_ans.png"
111
112
113    # Read in the LaTeX template file
114    with open(tex_template_path, "r") as infile:
115        tex_template_txt = infile.read()
116    # Read in the LaTeX template file for answers
117    with open(texans_template_path, "r") as infile:
118        tex_template_txt_ans = infile.read()
119    # Read in the LaTeX diagram template file
120    with open(tex_diagram_template_path, "r") as infile:
121        tex_diagram_template_txt = infile.read()
122
123    # Generate the <<diagram>> replacement tex
124    diagram_text, diagram_text_ans = make1_diagram(tex_diagram_template_txt, nump, numip, numdp)
125    # Replace the <<diagram>> placeholder in the LaTeX template
126    tex_template_txt = tex_template_txt.replace("<<diagram>>", diagram_text)
127    tex_template_txt_ans = tex_template_txt_ans.replace("<<diagram>>", diagram_text_ans)
128    # Write the question diagram tex to an output file
129    with open(tex_output_path, "w") as outfile:
130        outfile.write(tex_template_txt)
131    # Write the answer diagram 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 to pdf
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 to png
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")