5. Backtracking 1-step booklet pythonο
The python below requires the following .tex files:
The Python to create a multi page booklet of 1-step backtracking booklets, with 10 backtracking diagrams per page, is below.
The python file, backtracking_1step_booklet_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 number of questions form 1 to 100:
"Enter the number of questions from 1 to 100"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.
The Python to create a multi page booklet of 1-step backtracking booklets, with 10 backtracking diagrams per page, is below.
1from pathlib import Path
2import subprocess
3import os
4import time
5import backtracking_functions as btf
6
7currfile_dir = Path(__file__).parent
8tex_template_path = currfile_dir / "backtrack_1step_booklet_template.tex"
9texans_template_path = currfile_dir / "backtrack_1step_booklet_ans_template.tex"
10tex_diagram_template_path = currfile_dir / "backtrack_1step_booklet_diagram_template.tex"
11
12
13def merge_files(file1, file2, outputname):
14 result = subprocess.run(["pdfunite", file1, file2, outputname])
15
16
17def convert_to_pdf(tex_path, outputdir):
18 tex_path = Path(tex_path).resolve()
19 outputdir = Path(outputdir).resolve()
20 # for testing
21 # print(f"tex_path: {tex_path}")
22 # print(f"outputdir: {outputdir}")
23 try:
24 # Generate the PDF
25 subprocess.run(["latexmk", "-pdf", "-outdir=" + str(outputdir), str(tex_path)], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
26 # # Clean auxiliary files after successful PDF generation
27 subprocess.run(["latexmk", "-c", "-outdir=" + str(outputdir), str(tex_path)], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
28 # for hosted remove stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL for debugging any errors
29 # Remove the .tex file manually
30 if tex_path.exists():
31 os.remove(tex_path)
32 except subprocess.CalledProcessError as e:
33 print(f"Error: {e}")
34
35
36# tex_keys = ['stepAB','stepABrev','boxA','boxB','boxBrev', 'boxArev' ]
37tex_keys_q = ["stepAB", "boxA", "boxBrev"]
38
39
40def make1_diagram(tex_diagram_template_txt, num):
41 tex_diagram_template_txt_ans = tex_diagram_template_txt
42 posttext = r"\vspace{-2pt}"
43 kv = btf.get_1step_process_dict(num)
44
45 for key, value in kv.items():
46 tex_diagram_template_txt_ans = tex_diagram_template_txt_ans.replace("<<" + key + ">>", value)
47
48 for key, value in kv.items():
49 if key in tex_keys_q:
50 tex_diagram_template_txt = tex_diagram_template_txt.replace("<<" + key + ">>", value)
51 else:
52 tex_diagram_template_txt = tex_diagram_template_txt.replace("<<" + key + ">>", "")
53
54 # return tex_diagram_template_txt
55 return tex_diagram_template_txt + posttext, tex_diagram_template_txt_ans + posttext
56
57
58def main():
59 num = input("Enter 1, 2, 3, 4 or 5 for +, -, X, /, random \n")
60 if num.strip().isdigit():
61 num = int(num)
62 if not num in [1, 2, 3, 4, 5]:
63 num = 5 # random by default
64 else:
65 num = 5 # random by default
66 #
67 numq = input("Enter the number of questions from 1 to 100 \n")
68 if numq.strip().isdigit():
69 numq = int(numq)
70 if not numq in range(1, 101):
71 numq = 20 # random by default
72 else:
73 numq = 20 # random by default
74 #
75 filename = input("Enter the base filename to be added to the prefix bt1Bk_: \n")
76 if not filename:
77 filename = "1" # "bt1Bk_1st_q and bt1Bk_1st_ans as default file"
78 # set names of files that are made
79 # questions
80 tex_output_path = currfile_dir / f"bt1Bk_{filename}_q.tex"
81
82 # answers
83 tex_output_path_ans = currfile_dir / f"bt1Bk_{filename}_ans.tex"
84
85 # Read in the LaTeX template file
86 with open(tex_template_path, "r") as infile:
87 tex_template_txt = infile.read()
88 # Read in the LaTeX template file for answers
89 with open(texans_template_path, "r") as infile:
90 tex_template_txt_ans = infile.read()
91 # Read in the LaTeX diagram template file
92 with open(tex_diagram_template_path, "r") as infile:
93 tex_diagram_template_txt = infile.read()
94
95 # <<diagrams>>
96 # generate column text and column text for answers
97 diagram_text = ""
98 diagram_text_ans = ""
99 for _ in range(1, numq + 1):
100 img_tex, img_tex_ans = make1_diagram(tex_diagram_template_txt, num)
101 diagram_text += img_tex
102 diagram_text_ans += img_tex_ans
103
104 # Replace the <<diagrams>> placeholder in the LaTeX template with the generated diagrams
105 tex_template_txt = tex_template_txt.replace("<<diagrams>>", diagram_text)
106 tex_template_txt_ans = tex_template_txt_ans.replace("<<diagrams>>", diagram_text_ans)
107
108 # Write the question tex to an output file
109 with open(tex_output_path, "w") as outfile:
110 outfile.write(tex_template_txt)
111
112 # Write the answer tex to an output file
113 with open(tex_output_path_ans, "w") as outfile:
114 outfile.write(tex_template_txt_ans)
115
116 # Wait for the file to be created
117 time.sleep(1)
118 # Convert the LaTeX files to PDFs
119 convert_to_pdf(tex_output_path, currfile_dir)
120 convert_to_pdf(tex_output_path_ans, currfile_dir)
121
122
123if __name__ == "__main__":
124 print("starting")
125 main()
126 print("finished")
The custom Python module that is required to work out the various texts for the diagrams, is below.
It includes the module functions for 2 step backtracking as well.
1"""
2Module of functions to return diagram dictionary for LaTeX
3"""
4import random
5
6
7def get_1step_process_dict(num):
8 if num is None or num == 5:
9 num = random.randint(1, 4)
10 match num:
11 case 1:
12 return add_dict()
13 case 2:
14 return sub_dict()
15 case 3:
16 return times_dict()
17 case 4:
18 return div_dict()
19
20
21def add_dict():
22 # bb = nx + na
23 nx = random.randint(1, 10)
24 na = random.randint(1, 10)
25 bb = nx + na
26 mod_dict = dict()
27 mod_dict["stepAB"] = f"+{na}"
28 mod_dict["stepABrev"] = f"-{na}"
29
30 mod_dict["boxA"] = f"x"
31 mod_dict["boxB"] = f"x+{na}"
32 mod_dict["boxBrev"] = f"{bb}"
33 mod_dict["boxArev"] = f"{nx}"
34 return mod_dict
35
36
37def sub_dict():
38 # bb = nx - na
39 na = random.randint(1, 10)
40 nx = na + random.randint(1, 10)
41 bb = nx - na
42 mod_dict = dict()
43 mod_dict["stepAB"] = f"-{na}"
44 mod_dict["stepABrev"] = f"+{na}"
45
46 mod_dict["boxA"] = f"x"
47 mod_dict["boxB"] = f"x-{na}"
48 mod_dict["boxBrev"] = f"{bb}"
49 mod_dict["boxArev"] = f"{nx}"
50 return mod_dict
51
52
53def times_dict():
54 # bb = nx * na
55 nx = random.randint(2, 10)
56 na = random.randint(2, 10)
57 bb = nx * na
58 mod_dict = dict()
59 mod_dict["stepAB"] = f"\\times{na}"
60 mod_dict["stepABrev"] = f"\\div{na}"
61
62 mod_dict["boxA"] = f"x"
63 mod_dict["boxB"] = f"{na}x"
64 mod_dict["boxBrev"] = f"{bb}"
65 mod_dict["boxArev"] = f"{nx}"
66 return mod_dict
67
68
69def div_dict():
70 # bb = nx / na; nx = na * bb
71 # escape {} in f strings by doubling them up {{}}
72 na = random.randint(2, 10)
73 nx = na * random.randint(2, 10)
74 bb = int(nx / na)
75 mod_dict = dict()
76 mod_dict["stepAB"] = f"\\div{na}"
77 mod_dict["stepABrev"] = f"\\times{na}"
78
79 mod_dict["boxA"] = f"x"
80 mod_dict["boxB"] = f"\\frac{{x}}{{{na}}}"
81 mod_dict["boxBrev"] = f"{bb}"
82 mod_dict["boxArev"] = f"{nx}"
83 return mod_dict
84
85
86
87# ############################################
88
89def val_in_list_exclude(low, high, exclude):
90 # random 2 step: avoid xx, x/, /x, //, ++, --, +-, -+
91 vals = list(range(low, high + 1))
92 if exclude in vals:
93 if exclude in [1, 2]:
94 vals.remove(1)
95 vals.remove(2)
96 elif exclude in [3, 4]:
97 vals.remove(3)
98 vals.remove(4)
99 return random.choice(vals)
100
101
102def get_2step_process_dict(num1, num2):
103 if num1 is None or num1 == 5:
104 num1 = random.randint(1, 4)
105 if num2 is None or num2 == 5:
106 num2 = val_in_list_exclude(1, 4, num1)
107 processes = (num1, num2)
108 # processes = (3,3)
109 match processes:
110 case (1, 1):
111 return add_add_dict()
112 case (1, 2):
113 return add_sub_dict()
114 case (1, 3):
115 return add_times_dict()
116 case (1, 4):
117 return add_div_dict()
118 case (2, 1):
119 return sub_add_dict()
120 case (2, 2):
121 return sub_sub_dict()
122 case (2, 3):
123 return sub_times_dict()
124 case (2, 4):
125 return sub_div_dict()
126 case (3, 1):
127 return times_add_dict()
128 case (3, 2):
129 return times_sub_dict()
130 case (3, 3):
131 return times_times_dict()
132 case (3, 4):
133 return times_div_dict()
134 case (4, 1):
135 return div_add_dict()
136 case (4, 2):
137 return div_sub_dict()
138 case (4, 3):
139 return div_times_dict()
140 case (4, 4):
141 return div_div_dict()
142 case _:
143 return add_add_dict()
144
145
146def add_add_dict():
147 # bc = nx + na + nb
148 nx = random.randint(1, 10)
149 na = random.randint(1, 10)
150 nb = random.randint(1, 10)
151 bb = nx + na
152 bc = bb + nb
153
154 mod_dict = dict()
155 mod_dict["stepAB"] = f"+{na}"
156 mod_dict["stepABrev"] = f"-{na}"
157 mod_dict["stepBC"] = f"+{nb}"
158 mod_dict["stepBCrev"] = f"-{nb}"
159
160 mod_dict["boxA"] = f"x"
161 mod_dict["boxB"] = f"x+{na}"
162 mod_dict["boxC"] = f"x+{na + nb}"
163 mod_dict["boxCrev"] = f"{bc}"
164 mod_dict["boxBrev"] = f"{bb}"
165 mod_dict["boxArev"] = f"{nx}"
166 return mod_dict
167
168
169def add_sub_dict():
170 # bc = nx + na - nb
171 nx = random.randint(1, 10)
172 na = random.randint(1, 10)
173 bb = nx + na
174 if bb > 10:
175 nb = random.randint(1, 10)
176 else:
177 nb = random.randint(1, bb)
178 bc = bb - nb
179
180 mod_dict = dict()
181 mod_dict["stepAB"] = f"+{na}"
182 mod_dict["stepABrev"] = f"-{na}"
183 mod_dict["stepBC"] = f"-{nb}"
184 mod_dict["stepBCrev"] = f"+{nb}"
185
186 mod_dict["boxA"] = f"x"
187 mod_dict["boxB"] = f"x+{na}"
188 if na - nb > 0:
189 mod_dict["boxC"] = f"x+{na - nb}"
190 else:
191 mod_dict["boxC"] = f"x-{nb - na}"
192 mod_dict["boxCrev"] = f"{bc}"
193 mod_dict["boxBrev"] = f"{bb}"
194 mod_dict["boxArev"] = f"{nx}"
195 return mod_dict
196
197
198def add_times_dict():
199 # bc = nx * na * nb
200 nx = random.randint(1, 10)
201 na = random.randint(1, 10)
202 nb = random.randint(1, 10)
203 bb = nx + na
204 bc = bb * nb
205
206 mod_dict = dict()
207 mod_dict["stepAB"] = f"+{na}"
208 mod_dict["stepABrev"] = f"-{na}"
209 mod_dict["stepBC"] = f"\\times{nb}"
210 mod_dict["stepBCrev"] = f"\\div{nb}"
211
212 mod_dict["boxA"] = f"x"
213 mod_dict["boxB"] = f"x+{na}"
214 mod_dict["boxC"] = f"{nb}(x + {na})"
215 mod_dict["boxCrev"] = f"{bc}"
216 mod_dict["boxBrev"] = f"{bb}"
217 mod_dict["boxArev"] = f"{nx}"
218 return mod_dict
219
220
221def add_div_dict():
222 # bc = (nx + na) / nb
223 # nx = (bc * nb) - na
224 bc = random.randint(1, 10)
225 nb = random.randint(1, 10)
226 bb = bc * nb
227 if bb > 10:
228 na = random.randint(1, 10)
229 else:
230 na = random.randint(1, bb)
231 nx = bb - na
232
233 mod_dict = dict()
234 mod_dict["stepAB"] = f"+{na}"
235 mod_dict["stepABrev"] = f"-{na}"
236 mod_dict["stepBC"] = f"\\div{nb}"
237 mod_dict["stepBCrev"] = f"\\times{nb}"
238
239 mod_dict["boxA"] = f"x"
240 mod_dict["boxB"] = f"x+{na}"
241 mod_dict["boxC"] = f"\\frac{{(x+{na})}}{{{nb}}}"
242 mod_dict["boxCrev"] = f"{bc}"
243 mod_dict["boxBrev"] = f"{bb}"
244 mod_dict["boxArev"] = f"{nx}"
245 return mod_dict
246
247
248def sub_add_dict():
249 # bc = nx - na + nb
250 na = random.randint(1, 10)
251 nx = na + random.randint(1, 10)
252 nb = random.randint(1, 10)
253 bb = nx - na
254 bc = bb + nb
255
256 mod_dict = dict()
257 mod_dict["stepAB"] = f"-{na}"
258 mod_dict["stepABrev"] = f"+{na}"
259 mod_dict["stepBC"] = f"-{nb}"
260 mod_dict["stepBCrev"] = f"+{nb}"
261
262 mod_dict["boxA"] = f"x"
263 mod_dict["boxB"] = f"x-{na}"
264 mod_dict["boxC"] = f"x-{na + nb}"
265 mod_dict["boxCrev"] = f"{bc}"
266 mod_dict["boxBrev"] = f"{bb}"
267 mod_dict["boxArev"] = f"{nx}"
268 return mod_dict
269
270
271def sub_sub_dict():
272 # bc = nx - na - nb
273 # nx = bc + nb + na
274 bc = random.randint(1, 10)
275 na = random.randint(1, 10)
276 nb = random.randint(1, 10)
277 bb = bc + nb
278 nx = bb + na
279
280 mod_dict = dict()
281 mod_dict["stepAB"] = f"-{na}"
282 mod_dict["stepABrev"] = f"+{na}"
283 mod_dict["stepBC"] = f"-{nb}"
284 mod_dict["stepBCrev"] = f"+{nb}"
285
286 mod_dict["boxA"] = f"x"
287 mod_dict["boxB"] = f"x-{na}"
288 mod_dict["boxC"] = f"x-{na + nb}"
289 mod_dict["boxCrev"] = f"{bc}"
290 mod_dict["boxBrev"] = f"{bb}"
291 mod_dict["boxArev"] = f"{nx}"
292 return mod_dict
293
294
295def sub_times_dict():
296 # bc = (nx - na) * nb
297 # nx = (bc + nb) * na
298 na = random.randint(1, 10)
299 nx = na + random.randint(1, 10)
300 nb = random.randint(1, 10)
301 bb = nx - na
302 bc = bb * nb
303
304 mod_dict = dict()
305 mod_dict["stepAB"] = f"-{na}"
306 mod_dict["stepABrev"] = f"+{na}"
307 mod_dict["stepBC"] = f"\\times{nb}"
308 mod_dict["stepBCrev"] = f"\\div{nb}"
309
310 mod_dict["boxA"] = f"x"
311 mod_dict["boxB"] = f"x-{na}"
312 mod_dict["boxC"] = f"{nb}(x-{na})"
313 mod_dict["boxCrev"] = f"{bc}"
314 mod_dict["boxBrev"] = f"{bb}"
315 mod_dict["boxArev"] = f"{nx}"
316 return mod_dict
317
318
319def sub_div_dict():
320 # bc = nx - na / nb
321 # nx = (bc + nb) * na
322 bc = random.randint(1, 10)
323 na = random.randint(1, 10)
324 nb = random.randint(1, 10)
325 bb = bc * nb
326 nx = bb + na
327
328 mod_dict = dict()
329 mod_dict["stepAB"] = f"-{na}"
330 mod_dict["stepABrev"] = f"+{na}"
331 mod_dict["stepBC"] = f"\\div{nb}"
332 mod_dict["stepBCrev"] = f"\\times{nb}"
333
334 mod_dict["boxA"] = f"x"
335 mod_dict["boxB"] = f"x-{na}"
336 mod_dict["boxC"] = f"\\frac{{(x-{na})}}{{{nb}}}"
337 mod_dict["boxCrev"] = f"{bc}"
338 mod_dict["boxBrev"] = f"{bb}"
339 mod_dict["boxArev"] = f"{nx}"
340 return mod_dict
341
342
343def times_add_dict():
344 # bc = nx * na + nb
345 nx = random.randint(2, 10)
346 na = random.randint(2, 10)
347 nb = random.randint(2, 10)
348 bb = nx * na
349 bc = nx * na + nb
350
351 mod_dict = dict()
352 mod_dict["stepAB"] = f"\\times{na}"
353 mod_dict["stepABrev"] = f"\\div{na}"
354 mod_dict["stepBC"] = f"+{nb}"
355 mod_dict["stepBCrev"] = f"-{nb}"
356
357 mod_dict["boxA"] = f"x"
358 mod_dict["boxB"] = f"{na}x"
359 mod_dict["boxC"] = f"{na}x + {nb}"
360 mod_dict["boxCrev"] = f"{bc}"
361 mod_dict["boxBrev"] = f"{bb}"
362 mod_dict["boxArev"] = f"{nx}"
363 return mod_dict
364
365
366def times_sub_dict():
367 # bc = nx * na - nb
368 nx = random.randint(2, 10)
369 na = random.randint(2, 10)
370 bb = nx * na
371 if bb > 10:
372 nb = random.randint(2, 10)
373 else:
374 nb = random.randint(2, bb)
375 bc = bb - nb
376
377 mod_dict = dict()
378 mod_dict["stepAB"] = f"\\times{na}"
379 mod_dict["stepABrev"] = f"\\div{na}"
380 mod_dict["stepBC"] = f"-{nb}"
381 mod_dict["stepBCrev"] = f"+{nb}"
382
383 mod_dict["boxA"] = f"x"
384 mod_dict["boxB"] = f"{na}x"
385 mod_dict["boxC"] = f"{na}x - {nb}"
386 mod_dict["boxCrev"] = f"{bc}"
387 mod_dict["boxBrev"] = f"{bb}"
388 mod_dict["boxArev"] = f"{nx}"
389 return mod_dict
390
391
392def times_times_dict():
393 # bc = nx * na * nb
394 nx = random.randint(2, 10)
395 na = random.randint(2, 10)
396 nb = random.randint(2, 10)
397 bb = nx * na
398 bc = nx * na * nb
399
400 mod_dict = dict()
401 mod_dict["stepAB"] = f"\\times{na}"
402 mod_dict["stepABrev"] = f"\\div{na}"
403 mod_dict["stepBC"] = f"\\times{nb}"
404 mod_dict["stepBCrev"] = f"\\div{nb}"
405
406 mod_dict["boxA"] = f"x"
407 mod_dict["boxB"] = f"{na}x"
408 mod_dict["boxC"] = f"{na * nb}x"
409 mod_dict["boxCrev"] = f"{bc}"
410 mod_dict["boxBrev"] = f"{bb}"
411 mod_dict["boxArev"] = f"{nx}"
412 return mod_dict
413
414
415def times_div_dict():
416 # bc = nx * na / nb
417 nb = random.randint(2, 3)
418 na = nb * random.randint(2, 4)
419 nx = random.randint(2, 10)
420 bb = nx * na
421 bc = int(bb / nb)
422
423 mod_dict = dict()
424 mod_dict["stepAB"] = f"\\times{na}"
425 mod_dict["stepABrev"] = f"\\div{na}"
426 mod_dict["stepBC"] = f"\\div{nb}"
427 mod_dict["stepBCrev"] = f"\\times{nb}"
428
429 mod_dict["boxA"] = f"x"
430 mod_dict["boxB"] = f"{na}x"
431 mod_dict["boxC"] = f"{int(na / nb)}x"
432 mod_dict["boxCrev"] = f"{bc}"
433 mod_dict["boxBrev"] = f"{bb}"
434 mod_dict["boxArev"] = f"{nx}"
435 return mod_dict
436
437
438def div_add_dict():
439 # bc = (nx / na) + nb
440 # nx = (bc - nb) * na
441 na = random.randint(2, 10)
442 nx = na * random.randint(1, 10)
443 nb = random.randint(1, 10)
444 bb = int(nx / na)
445 bc = bb + nb
446
447 mod_dict = dict()
448 mod_dict["stepAB"] = f"\\div{na}"
449 mod_dict["stepABrev"] = f"\\times{na}"
450 mod_dict["stepBC"] = f"+{nb}"
451 mod_dict["stepBCrev"] = f"-{nb}"
452 mod_dict["boxA"] = f"x"
453 mod_dict["boxB"] = f"\\frac{{x}}{{{na}}}"
454 mod_dict["boxC"] = f"\\frac{{x}}{{{na}}} + {nb}"
455 mod_dict["boxCrev"] = f"{bc}"
456 mod_dict["boxBrev"] = f"{bb}"
457 mod_dict["boxArev"] = f"{nx}"
458 return mod_dict
459
460
461def div_sub_dict():
462 # bc = (nx / na) - nb
463 # nx = (bc + nb) * na
464 bc = random.randint(2, 10)
465 na = random.randint(2, 10)
466 nb = random.randint(2, 10)
467 bb = bc + nb
468 nx = bb * na
469
470 mod_dict = dict()
471 mod_dict["stepAB"] = f"\\div{na}"
472 mod_dict["stepABrev"] = f"\\times{na}"
473 mod_dict["stepBC"] = f"-{nb}"
474 mod_dict["stepBCrev"] = f"+{nb}"
475 mod_dict["boxA"] = f"x"
476 mod_dict["boxB"] = f"\\frac{{x}}{{{na}}}"
477 mod_dict["boxC"] = f"\\frac{{x}}{{{na}}} - {nb}"
478 mod_dict["boxCrev"] = f"{bc}"
479 mod_dict["boxBrev"] = f"{bb}"
480 mod_dict["boxArev"] = f"{nx}"
481 return mod_dict
482
483
484def div_times_dict():
485 # bc = (nx / na) * nb
486 na = random.randint(2, 10)
487 nx = na * random.randint(2, 10)
488 nb = random.randint(2, 10)
489 bb = int(nx / na)
490 bc = bb * nb
491
492 mod_dict = dict()
493 mod_dict["stepAB"] = f"\\div{na}"
494 mod_dict["stepABrev"] = f"\\times{na}"
495 mod_dict["stepBC"] = f"\\div{nb}"
496 mod_dict["stepBCrev"] = f"\\times{nb}"
497 mod_dict["boxA"] = f"x"
498 mod_dict["boxB"] = f"\\frac{{x}}{{{na}}}"
499 mod_dict["boxC"] = f"\\frac{{x}}{{{na * nb}}}"
500 mod_dict["boxCrev"] = f"{bc}"
501 mod_dict["boxBrev"] = f"{bb}"
502 mod_dict["boxArev"] = f"{nx}"
503 return mod_dict
504
505
506def div_div_dict():
507 # bc = (nx / na) / nb
508 # escape {} in f strings by doubling them up {{}}
509 bc = random.randint(2, 10)
510 na = random.randint(2, 10)
511 nb = random.randint(2, 10)
512 bb = bc * nb
513 nx = bb * na
514
515 mod_dict = dict()
516 mod_dict["stepAB"] = f"\\div{na}"
517 mod_dict["stepABrev"] = f"\\times{na}"
518 mod_dict["stepBC"] = f"\\div{nb}"
519 mod_dict["stepBCrev"] = f"\\times{nb}"
520 mod_dict["boxA"] = f"x"
521 mod_dict["boxB"] = f"\\frac{{x}}{{{na}}}"
522 mod_dict["boxC"] = f"\\frac{{x}}{{{na * nb}}}"
523 mod_dict["boxCrev"] = f"{bc}"
524 mod_dict["boxBrev"] = f"{bb}"
525 mod_dict["boxArev"] = f"{nx}"
526 return mod_dict