2. Backtracking 2 step diagrams
The python file to make a 2-step backtracking diagram is below.
The required LaTeX files are below.
The python file, backtracking_2step_diagram_maker.py, when run, will ask for these inputs:
Choose the type of diagrams:
"Enter 1, 2, 3, 4, 5 or 6 for standard, 1 row build expression, 1 row inverse operations, 1 row from expression, solve from expression, blank "
Choose the first arithmetic process:
"Enter 1, 2, 3, 4 or 5 for +, -, X, /, random for 1st process"
Choose the second arithmetic process:
"Enter 1, 2, 3, 4 or 5 for +, -, X, /, random for 2nd process"
Choose the file name base:
"Enter the base filename to be added to the prefix :"
The prefix will be “bt2” for standard; “bt2_build” for 1 row build expression; or “bt2_invop” for 1 row inverse operations.
The prefix will be “bt2_fromexp” for 1 row from expression; “bt2_solvefromexp” for solve from expression; or “bt2_blank” for blank.
The filename will have “_q” added for the question diagram and “_ans” for the answer diagram.
2.1. Example 2-step backtracking diagram
2.2. Example 2-step backtracking diagram: 1 row; building the expression
2.3. Example 2-step backtracking diagram: 1 row; inverse operations
2.4. Example 2-step backtracking diagram: 1 row; from the expression
2.5. Example 2-step backtracking diagram: solve from the expression
2.6. Example 2-step backtracking diagram: blank
2.7. 2-step backtracking diagram: python
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_2step_template.tex"
10texans_template_path = currfile_dir / "backtrack_2step_template.tex"
11
12tex_diagram_standard_template_path = (
13 currfile_dir / "backtrack_2step_diagram_template.tex"
14)
15tex_diagram_buildexp_template_path = (
16 currfile_dir / "backtrack_2step_diagram_template_1buildexp.tex"
17)
18tex_diagram_invop_template_path = (
19 currfile_dir / "backtrack_2step_diagram_template_1invop.tex"
20)
21tex_diagram_fromexp_template_path = (
22 currfile_dir / "backtrack_2step_diagram_template_1invop.tex"
23)
24tex_diagram_solvefromexp_template_path = (
25 currfile_dir / "backtrack_2step_diagram_template.tex"
26)
27tex_diagram_blank_template_path = (
28 currfile_dir / "backtrack_2step_diagram_template_blank.tex"
29)
30
31
32def convert_to_pdf(tex_path, currfile_dir, aux_path):
33 """
34 Converts a TeX file to PDF format using pdfLaTeX.
35
36 Args:
37 tex_path (str): The path to the TeX file.
38 currfile_dir (str): The path to the directory where the TeX file is located.
39 aux_path (str): The path to the directory where auxiliary files will be stored.
40
41 Returns:
42 subprocess.CompletedProcess: A subprocess.CompletedProcess object containing information about the completed process.
43
44 Raises:
45 FileNotFoundError: If the TeX file does not exist.
46 subprocess.CalledProcessError: If pdfLaTeX returns a non-zero exit code.
47 """
48 result = subprocess.run(
49 [
50 "pdfLaTeX",
51 tex_path,
52 "-output-directory",
53 currfile_dir,
54 "-aux-directory",
55 aux_path,
56 ],
57 stdout=subprocess.PIPE,
58 )
59
60
61# % end modify values for backtracking
62# tex_keys = ['stepAB','stepABrev','stepBC', 'stepBCrev', boxA','boxB', 'boxC', 'boxCrev, 'boxBrev', 'boxArev' ]
63# used by standard, build expression, inverse operations
64tex_keys_q = ["stepAB", "stepBC", "boxA", "boxCrev"]
65# used by from expression
66tex_keys_q_fromexp = ["boxC"]
67# used by from expression
68tex_keys_q_solvefromexp = ["boxC", "boxCrev"]
69
70
71def make1_diagram(tex_diagram_template_txt, num1, num2, tex_keys_q):
72 tex_diagram_template_txt_ans = tex_diagram_template_txt
73 kv = btf.get_2step_process_dict(num1, num2)
74 for key, value in kv.items():
75 tex_diagram_template_txt_ans = tex_diagram_template_txt_ans.replace(
76 "<<" + key + ">>", value
77 )
78 for key, value in kv.items():
79 if key in tex_keys_q:
80 tex_diagram_template_txt = tex_diagram_template_txt.replace(
81 "<<" + key + ">>", value
82 )
83 else:
84 tex_diagram_template_txt = tex_diagram_template_txt.replace(
85 "<<" + key + ">>", ""
86 )
87 return tex_diagram_template_txt, tex_diagram_template_txt_ans
88
89
90def main():
91 input_str = (
92 "Enter 1, 2, 3, 4, 5 or 6 for standard, 1 row build expression, "
93 + "1 row inverse operations, 1 row from expression, solve from expression, blank \n"
94 )
95 bt_type = input(input_str)
96 if bt_type.strip().isdigit():
97 bt_type = int(bt_type)
98 if not bt_type in [1, 2, 3, 4, 5, 6]:
99 bt_type = 1 # standard by default
100 else:
101 bt_type = 1 # standard by default
102 #
103 if bt_type in [1, 2, 3, 4, 5]:
104 num1 = input("Enter 1, 2, 3, 4 or 5 for +, -, X, /, random for 1st process \n")
105 if num1.strip().isdigit():
106 num1 = int(num1)
107 if num1 not in [1, 2, 3, 4, 5]:
108 num1 = 5 # random by default
109 else:
110 num1 = 5 # random by default
111 #
112 num2 = input("Enter 1, 2, 3, 4 or 5 for +, -, X, /, random for 2nd process \n")
113 if num2.strip().isdigit():
114 num2 = int(num2)
115 if num2 not in [1, 2, 3, 4, 5]:
116 num2 = 5 # random by default
117 else:
118 num2 = 5 # random by default
119 else:
120 # use as placeholders for sake of call below; will end up returning + + dictionary but not used.
121 num1, num2 = None, None
122
123 match bt_type:
124 case 1:
125 tex_diagram_template_path = tex_diagram_standard_template_path
126 fileprefix = "bt2"
127 q_parts_to_fill = tex_keys_q
128 case 2:
129 tex_diagram_template_path = tex_diagram_buildexp_template_path
130 fileprefix = "bt2_build"
131 q_parts_to_fill = tex_keys_q
132 case 3:
133 tex_diagram_template_path = tex_diagram_invop_template_path
134 fileprefix = "bt2_invop"
135 q_parts_to_fill = tex_keys_q
136 case 4:
137 tex_diagram_template_path = tex_diagram_fromexp_template_path
138 fileprefix = "bt2_fromexp"
139 q_parts_to_fill = tex_keys_q_fromexp
140 case 5:
141 tex_diagram_template_path = tex_diagram_solvefromexp_template_path
142 fileprefix = "bt2_solvefromexp"
143 q_parts_to_fill = tex_keys_q_solvefromexp
144 case 6:
145 tex_diagram_template_path = tex_diagram_blank_template_path
146 fileprefix = "bt2_blank"
147 q_parts_to_fill = tex_keys_q
148 #
149 filename = input(
150 f"Enter the base filename to be added to the prefix {fileprefix}_: \n"
151 )
152 if not filename:
153 filename = "1" # "bt2_1_q and bt2_1_ans as default file"
154 #
155 # set names of files that are made
156 # questions
157 tex_output_path = currfile_dir / f"{fileprefix}_{filename}_q.tex"
158 pdf_path = currfile_dir / f"{fileprefix}_{filename}_q.pdf"
159 png_path = currfile_dir / f"{fileprefix}_{filename}_q.png"
160 aux_path = currfile_dir / "temp"
161 # answers
162 tex_output_path_ans = currfile_dir / f"{fileprefix}_{filename}_ans.tex"
163 pdf_path_ans = currfile_dir / f"{fileprefix}_{filename}_ans.pdf"
164 png_path_ans = currfile_dir / f"{fileprefix}_{filename}_ans.png"
165
166 # Read in the LaTeX template file
167 with open(tex_template_path, "r") as infile:
168 tex_template_txt = infile.read()
169 # Read in the LaTeX template file for answers
170 with open(texans_template_path, "r") as infile:
171 tex_template_txt_ans = infile.read()
172 # Read in the LaTeX diagram template file
173 with open(tex_diagram_template_path, "r") as infile:
174 tex_diagram_template_txt = infile.read()
175
176 # Generate the <<diagram>> replacement tex
177 diagram_text, diagram_text_ans = make1_diagram(
178 tex_diagram_template_txt, num1, num2, q_parts_to_fill
179 )
180 # Replace the <<diagram>> placeholder in the LaTeX template
181 tex_template_txt = tex_template_txt.replace("<<diagram>>", diagram_text)
182 tex_template_txt_ans = tex_template_txt_ans.replace("<<diagram>>", diagram_text_ans)
183 # Write the question diagram tex to an output file
184 with open(tex_output_path, "w") as outfile:
185 outfile.write(tex_template_txt)
186 # Write the answer diagram tex to an output file
187 if bt_type in [1, 2, 3, 4, 5]:
188 with open(tex_output_path_ans, "w") as outfile:
189 outfile.write(tex_template_txt_ans)
190
191 # Wait for the files to be created
192 time.sleep(1)
193 # convert to pdf
194 convert_to_pdf(tex_output_path, currfile_dir, aux_path)
195 if bt_type in [1, 2, 3, 4, 5]:
196 convert_to_pdf(tex_output_path_ans, currfile_dir, aux_path)
197
198 # Wait for the files to be created
199 time.sleep(1)
200 # convert to png
201 magick_pdf_to_png.convert_pdf_to_png(pdf_path, png_path)
202 if bt_type in [1, 2, 3, 4, 5]:
203 magick_pdf_to_png.convert_pdf_to_png(pdf_path_ans, png_path_ans)
204
205
206if __name__ == "__main__":
207 print("starting")
208 main()
209 print("finished")