2. Equations 2 step diagramsο
The python file to make a 2-step invop diagram is below.
The python file, invop_2step_diagram_maker.py, when run, will ask for these inputs:
Choose the arithmetic process:
"Enter 1, 2, 3, 4 or 5 for +, -, X, /, random for the 1st process"Choose the arithmetic process:
"Enter 1, 2, 3, 4 or 5 for +, -, X, /, random for the 2nd process"Choose the file name base:
"Enter the base filename to be added to the prefix :"The prefix will be βinvop2β for standard operations.
The filename will have β_qβ added for the question diagram and β_ansβ for the answer diagram.
2.1. Example 2-step invop diagramο
2.2. 2-step invop diagram: pythonο
1from pathlib import Path
2import subprocess
3import os
4import time
5import magick_pdf_to_png
6import invop_functions as iof
7
8
9currfile_dir = Path(__file__).parent
10tex_template_path = currfile_dir / "invop_2step_template.tex"
11texans_template_path = currfile_dir / "invop_2step_template.tex"
12tex_diagram_template_path = currfile_dir / "invop_2step_diagram_template.tex"
13
14
15def convert_to_pdf(tex_path, outputdir):
16 tex_path = Path(tex_path).resolve()
17 outputdir = Path(outputdir).resolve()
18 # for testing
19 # print(f"tex_path: {tex_path}")
20 # print(f"outputdir: {outputdir}")
21 try:
22 # Generate the PDF
23 subprocess.run(["latexmk", "-pdf", "-outdir=" + str(outputdir), str(tex_path)], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
24 # # Clean auxiliary files after successful PDF generation
25 subprocess.run(["latexmk", "-c", "-outdir=" + str(outputdir), str(tex_path)], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
26 # for hosted remove stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL for debugging any errors
27 # Remove the .tex file manually
28 if tex_path.exists():
29 os.remove(tex_path)
30 except subprocess.CalledProcessError as e:
31 print(f"Error: {e}")
32
33
34# % end modify values for invop
35# ['line1_LHS', 'line2_LHS', 'line2_LHSq', 'line3_LHS', 'line4_LHS', 'line4_LHSq', 'line5_LHS', 'line1_RHS', 'line2_RHS', 'line2_RHSq', 'line3_RHS', 'line3_RHSq', 'line4_RHS', 'line4_RHSq', 'line5_RHS', 'line5_RHSq']
36# get the full keys above then get those with q, then delete the q
37tex_keys_q = ["line2_LHS", "line4_LHS", "line2_RHS", "line3_RHS", "line4_RHS", "line5_RHS"]
38
39
40def make1_diagram(tex_diagram_template_txt, num1, num2):
41 tex_diagram_template_txt_ans = tex_diagram_template_txt
42 kv = iof.get_2step_process_dict(num1, num2)
43 # do ans sheet
44 for key, value in kv.items():
45 tex_diagram_template_txt_ans = tex_diagram_template_txt_ans.replace("<<" + key + ">>", value)
46 # do q sheet
47 for key, value in kv.items():
48 if key not in tex_keys_q:
49 tex_diagram_template_txt = tex_diagram_template_txt.replace("<<" + key + ">>", value)
50 else:
51 tex_diagram_template_txt = tex_diagram_template_txt.replace("<<" + key + ">>", kv[f"{key}q"])
52 return tex_diagram_template_txt, tex_diagram_template_txt_ans
53
54
55def main():
56 num1 = input("Enter 1, 2, 3, 4 or 5 for +, -, X, /, random for the 1st process \n")
57 if num1.strip().isdigit():
58 num1 = int(num1)
59 if not num1 in [1, 2, 3, 4, 5]:
60 num1 = 5 # random by default
61 else:
62 num1 = 5 # random by default
63 #
64 num2 = input("Enter 1, 2, 3, 4 or 5 for +, -, X, /, random for the 2nd process \n")
65 if num2.strip().isdigit():
66 num2 = int(num2)
67 if not num2 in [1, 2, 3, 4, 5]:
68 num2 = 5 # random by default
69 else:
70 num2 = 5 # random by default
71 #
72 filename = input("Enter the base filename to be added to the prefix invop2_: \n")
73 if not filename:
74 filename = "1" # "invop2_1_q and invop2_1_ans as default file"
75 # set names of files that are made
76 # questions
77 tex_output_path = currfile_dir / f"invop2_{filename}_q.tex"
78 pdf_path = currfile_dir / f"invop2_{filename}_q.pdf"
79 png_path = currfile_dir / f"invop2_{filename}_q.png"
80
81 # answers
82 tex_output_path_ans = currfile_dir / f"invop2_{filename}_ans.tex"
83 pdf_path_ans = currfile_dir / f"invop2_{filename}_ans.pdf"
84 png_path_ans = currfile_dir / f"invop2_{filename}_ans.png"
85
86 # Read in the LaTeX template file
87 with open(tex_template_path, "r") as infile:
88 tex_template_txt = infile.read()
89 # Read in the LaTeX template file for answers
90 with open(texans_template_path, "r") as infile:
91 tex_template_txt_ans = infile.read()
92 # Read in the LaTeX diagram template file
93 with open(tex_diagram_template_path, "r") as infile:
94 tex_diagram_template_txt = infile.read()
95
96 # Generate the <<diagram>> replacement tex
97 diagram_text, diagram_text_ans = make1_diagram(tex_diagram_template_txt, num1, num2)
98 # Replace the <<diagram>> placeholder in the LaTeX template
99 tex_template_txt = tex_template_txt.replace("<<diagram>>", diagram_text)
100 tex_template_txt_ans = tex_template_txt_ans.replace("<<diagram>>", diagram_text_ans)
101 # Write the question diagram tex to an output file
102 with open(tex_output_path, "w") as outfile:
103 outfile.write(tex_template_txt)
104 # Write the answer diagram tex to an output file
105 with open(tex_output_path_ans, "w") as outfile:
106 outfile.write(tex_template_txt_ans)
107
108 # Wait for the files to be created
109 time.sleep(1)
110 # convert to pdf
111 convert_to_pdf(tex_output_path, currfile_dir)
112 convert_to_pdf(tex_output_path_ans, currfile_dir)
113
114 # Wait for the files to be created
115 time.sleep(1)
116 # convert to png
117 magick_pdf_to_png.convert_pdf_to_png(pdf_path, png_path)
118 magick_pdf_to_png.convert_pdf_to_png(pdf_path_ans, png_path_ans)
119
120
121if __name__ == "__main__":
122 print("starting")
123 main()
124 print("finished")
The custom python module:
1"""
2Module of functions to return diagram dictionary for LaTeX
3# escape {} in f strings by doubling them up {{}}
4"""
5import random
6
7gap = r'\dotuline{\hspace{5mm}}'
8
9def get_1step_process_dict(num):
10 if num is None or num == 5:
11 num = random.randint(1, 4)
12 match num:
13 case 1:
14 return add_dict()
15 case 2:
16 return sub_dict()
17 case 3:
18 return times_dict()
19 case 4:
20 return div_dict()
21
22
23
24def add_dict():
25 # x + nx = na
26 nx = random.randint(1, 10)
27 na = random.randint(1, 10)
28 xval = na - nx
29 kv = dict()
30 kv["line1_LHS"] = f"x + {nx}"
31 kv["line2_LHS"] = f"x + {nx} - {nx}"
32 kv["line2_LHSq"] = f"x + {nx} - {gap}"
33 kv["line3_LHS"] = f"x"
34 kv["line1_RHS"] = f"{na}"
35 kv["line2_RHS"] = f"{na} - {nx}"
36 kv["line2_RHSq"] = f"{na} - {gap}"
37 kv["line3_RHS"] = f"{xval}"
38 kv["line3_RHSq"] = f"{gap}"
39 return kv
40
41
42def sub_dict():
43 # x - nx = na
44 nx = random.randint(1, 10)
45 na = random.randint(1, 10)
46 xval = na + nx
47 kv = dict()
48 kv["line1_LHS"] = f"x - {nx}"
49 kv["line2_LHS"] = f"x - {nx} + {nx}"
50 kv["line2_LHSq"] = f"x - {nx} + {gap}"
51 kv["line3_LHS"] = f"x"
52 kv["line1_RHS"] = f"{na}"
53 kv["line2_RHS"] = f"{na} + {nx}"
54 kv["line2_RHSq"] = f"{na} + {gap}"
55 kv["line3_RHS"] = f"{xval}"
56 kv["line3_RHSq"] = f"{gap}"
57 return kv
58
59
60def times_dict():
61 # x * nx = na
62 nx = random.randint(2, 10)
63 na = nx * random.randint(2, 10)
64 xval = int(na / nx)
65 kv = dict()
66 kv["line1_LHS"] = f"{nx}x"
67 kv["line2_LHS"] = f"\\frac{{{nx}x}}{{{nx}}}"
68 kv["line2_LHSq"] = f"\\frac{{{nx}x}}{{{gap}}}"
69 kv["line3_LHS"] = f"x"
70 kv["line1_RHS"] = f"{na}"
71 kv["line2_RHS"] = f"\\frac{{{na}}}{{{nx}}}"
72 kv["line2_RHSq"] = f"\\frac{{{na}}}{{{gap}}}"
73 kv["line3_RHS"] = f"{xval}"
74 kv["line3_RHSq"] = f"{gap}"
75 return kv
76
77
78def div_dict():
79 # x / nx = na
80 nx = random.randint(2, 10)
81 na = random.randint(2, 10)
82 xval = na * nx
83 kv = dict()
84 kv["line1_LHS"] = f"\\frac{{x}}{{{nx}}}"
85 kv["line2_LHS"] = f"\\frac{{x}}{{{nx}}} \\times{nx}"
86 kv["line2_LHSq"] = f"\\frac{{x}}{{{nx}}} \\times{{{gap}}}"
87 kv["line3_LHS"] = f"x"
88 kv["line1_RHS"] = f"{na}"
89 kv["line2_RHS"] = f"{na} \\times{nx}"
90 kv["line2_RHSq"] = f"{na} \\times{{{gap}}}"
91 kv["line3_RHS"] = f"{xval}"
92 kv["line3_RHSq"] = f"{gap}"
93 return kv
94
95
96
97# ############################################
98
99def val_in_list_exclude(low, high, exclude):
100 # random 2 step: avoid xx, x/, /x, //, ++, --, +-, -+
101 vals = list(range(low, high + 1))
102 if exclude in vals:
103 if exclude in [1, 2]:
104 vals.remove(1)
105 vals.remove(2)
106 elif exclude in [3, 4]:
107 vals.remove(3)
108 vals.remove(4)
109 return random.choice(vals)
110
111
112def get_2step_process_dict(num1, num2):
113 if num1 is None or num1 == 5:
114 num1 = random.randint(1, 4)
115 if num2 is None or num2 == 5:
116 num2 = val_in_list_exclude(1, 4, num1)
117 processes = (num1, num2)
118 # processes = (3,3)
119 match processes:
120 case (1, 1):
121 return add_add_dict()
122 case (1, 2):
123 return add_sub_dict()
124 case (1, 3):
125 return add_times_dict()
126 case (1, 4):
127 return add_div_dict()
128 case (2, 1):
129 return sub_add_dict()
130 case (2, 2):
131 return sub_sub_dict()
132 case (2, 3):
133 return sub_times_dict()
134 case (2, 4):
135 return sub_div_dict()
136 case (3, 1):
137 return times_add_dict()
138 case (3, 2):
139 return times_sub_dict()
140 case (3, 3):
141 return times_times_dict()
142 case (3, 4):
143 return times_div_dict()
144 case (4, 1):
145 return div_add_dict()
146 case (4, 2):
147 return div_sub_dict()
148 case (4, 3):
149 return div_times_dict()
150 case (4, 4):
151 return div_div_dict()
152 case _:
153 return add_add_dict()
154
155
156def add_add_dict():
157 # x + nx + mx = na
158 nx = random.randint(1, 10)
159 mx = random.randint(1, 10)
160 na = random.randint(1, 10)
161 xval = na - nx - mx
162
163 kv = dict()
164 kv["line1_LHS"] = f"x + {nx} + {mx}"
165 kv["line2_LHS"] = f"x + {nx} - {nx} + {mx}"
166 kv["line2_LHSq"] = f"x + {nx} - {gap} + {mx}"
167 kv["line3_LHS"] = f"x + {mx}"
168 kv["line4_LHS"] = f"x + {mx} - {mx}"
169 kv["line4_LHSq"] = f"x + {mx} - {gap}"
170 kv["line5_LHS"] = f"x"
171
172 kv["line1_RHS"] = f"{na}"
173 kv["line2_RHS"] = f"{na} - {nx}"
174 kv["line2_RHSq"] = f"{na} - {gap}"
175 kv["line3_RHS"] = f"{na - nx}"
176 kv["line3_RHSq"] = f"{gap}"
177 kv["line4_RHS"] = f"{na - nx} - {mx}"
178 kv["line4_RHSq"] = f"{gap} - {gap}"
179 kv["line5_RHS"] = f"{xval}"
180 kv["line5_RHSq"] = f"{gap}"
181 return kv
182
183
184def add_sub_dict():
185 # x + nx - mx = na
186 nx = random.randint(1, 10)
187 mx = random.randint(1, 10)
188 na = random.randint(1, 10)
189 xval = na - nx + mx
190
191 kv = dict()
192 kv["line1_LHS"] = f"x + {nx} - {mx}"
193 kv["line2_LHS"] = f"x + {nx} - {nx} - {mx}"
194 kv["line2_LHSq"] = f"x + {nx} - {gap} - {mx}"
195 kv["line3_LHS"] = f"x - {mx}"
196 kv["line4_LHS"] = f"x - {mx} + {mx}"
197 kv["line4_LHSq"] = f"x - {mx} + {gap}"
198 kv["line5_LHS"] = f"x"
199
200 kv["line1_RHS"] = f"{na}"
201 kv["line2_RHS"] = f"{na} - {nx}"
202 kv["line2_RHSq"] = f"{na} - {gap}"
203 kv["line3_RHS"] = f"{na - nx}"
204 kv["line3_RHSq"] = f"{gap}"
205 kv["line4_RHS"] = f"{na - nx} + {mx}"
206 kv["line4_RHSq"] = f"{gap} + {gap}"
207 kv["line5_RHS"] = f"{xval}"
208 kv["line5_RHSq"] = f"{gap}"
209 return kv
210
211
212def add_times_dict():
213 # (x + nx) * mx = na
214 xval = random.randint(1, 10)
215 nx = random.randint(1, 10)
216 mx = random.randint(2, 10)
217 na = (xval + nx) * mx
218
219 kv = dict()
220 kv["line1_LHS"] = f"{mx}(x + {nx})"
221 kv["line2_LHS"] = f"\\frac{{{mx}(x+{nx})}}{{{mx}}}"
222 kv["line2_LHSq"] = f"\\frac{{{mx}(x+{nx})}}{{{gap}}}"
223 kv["line3_LHS"] = f"x + {nx}"
224 kv["line4_LHS"] = f"x + {nx} - {nx}"
225 kv["line4_LHSq"] = f"x + {nx} - {gap}"
226 kv["line5_LHS"] = f"x"
227
228 kv["line1_RHS"] = f"{na}"
229 kv["line2_RHS"] = f"\\frac{{{na}}}{{{mx}}}"
230 kv["line2_RHSq"] = f"\\frac{{{na}}}{{{gap}}}"
231 kv["line3_RHS"] = f"{int(na / mx)}"
232 kv["line3_RHSq"] = f"{gap}"
233 kv["line4_RHS"] = f"{int(na / mx)} - {nx}"
234 kv["line4_RHSq"] = f"{gap} - {gap}"
235 kv["line5_RHS"] = f"{xval}"
236 kv["line5_RHSq"] = f"{gap}"
237 return kv
238
239
240def add_div_dict():
241 # (x + nx) / mx = na
242 nx = random.randint(1, 10)
243 mx = random.randint(2, 10)
244 na = random.randint(1, 10)
245 xval = na * mx - nx
246
247 kv = dict()
248 kv["line1_LHS"] = f"\\frac{{x + {nx}}}{{{mx}}}"
249 kv["line2_LHS"] = f"\\frac{{x + {nx}}}{{{mx}}} \\times{mx}"
250 kv["line2_LHSq"] = f"\\frac{{x + {nx}}}{{{mx}}} \\times{gap}"
251 kv["line3_LHS"] = f"x + {nx}"
252 kv["line4_LHS"] = f"x + {nx} - {nx}"
253 kv["line4_LHSq"] = f"x + {nx} - {gap}"
254 kv["line5_LHS"] = f"x"
255
256 kv["line1_RHS"] = f"{na}"
257 kv["line2_RHS"] = f"{na} \\times{mx}"
258 kv["line2_RHSq"] = f"{na} \\times{gap}"
259 kv["line3_RHS"] = f"{na * mx}"
260 kv["line3_RHSq"] = f"{gap}"
261 kv["line4_RHS"] = f"{na * mx} - {nx}"
262 kv["line4_RHSq"] = f"{gap} - {gap}"
263 kv["line5_RHS"] = f"{xval}"
264 kv["line5_RHSq"] = f"{gap}"
265 return kv
266
267
268
269def sub_add_dict():
270 # x - nx + mx = na
271 nx = random.randint(1, 10)
272 mx = random.randint(1, 10)
273 na = random.randint(1, 10)
274 xval = na - nx + mx
275
276 kv = dict()
277 kv["line1_LHS"] = f"x - {nx} + {mx}"
278 kv["line2_LHS"] = f"x - {nx} + {nx} + {mx}"
279 kv["line2_LHSq"] = f"x - {nx} + {gap} + {mx}"
280 kv["line3_LHS"] = f"x + {mx}"
281 kv["line4_LHS"] = f"x + {mx} - {mx}"
282 kv["line4_LHSq"] = f"x + {mx} - {gap}"
283 kv["line5_LHS"] = f"x"
284
285 kv["line1_RHS"] = f"{na}"
286 kv["line2_RHS"] = f"{na} + {nx}"
287 kv["line2_RHSq"] = f"{na} + {gap}"
288 kv["line3_RHS"] = f"{na + nx}"
289 kv["line3_RHSq"] = f"{gap}"
290 kv["line4_RHS"] = f"{na + nx} - {mx}"
291 kv["line4_RHSq"] = f"{gap} - {gap}"
292 kv["line5_RHS"] = f"{xval}"
293 kv["line5_RHSq"] = f"{gap}"
294 return kv
295
296def sub_sub_dict():
297 # x - nx - mx = na
298 nx = random.randint(1, 10)
299 mx = random.randint(1, 10)
300 na = random.randint(1, 10)
301 xval = na + nx + mx
302
303 kv = dict()
304 kv["line1_LHS"] = f"x - {nx} - {mx}"
305 kv["line2_LHS"] = f"x - {nx} + {nx} - {mx}"
306 kv["line2_LHSq"] = f"x - {nx} + {gap} - {mx}"
307 kv["line3_LHS"] = f"x - {mx}"
308 kv["line4_LHS"] = f"x - {mx} + {mx}"
309 kv["line4_LHSq"] = f"x - {mx} + {gap}"
310 kv["line5_LHS"] = f"x"
311
312 kv["line1_RHS"] = f"{na}"
313 kv["line2_RHS"] = f"{na} + {nx}"
314 kv["line2_RHSq"] = f"{na} + {gap}"
315 kv["line3_RHS"] = f"{na + nx}"
316 kv["line3_RHSq"] = f"{gap}"
317 kv["line4_RHS"] = f"{na + nx} + {mx}"
318 kv["line4_RHSq"] = f"{gap} + {gap}"
319 kv["line5_RHS"] = f"{xval}"
320 kv["line5_RHSq"] = f"{gap}"
321 return kv
322
323def sub_times_dict():
324 # (x - nx) * mx = na
325 xval = random.randint(1, 10)
326 nx = random.randint(1, 10)
327 mx = random.randint(2, 10)
328 na = (xval - nx) * mx
329
330 kv = dict()
331 kv["line1_LHS"] = f"{mx}(x - {nx})"
332 kv["line2_LHS"] = f"\\frac{{{mx}(x-{nx})}}{{{mx}}}"
333 kv["line2_LHSq"] = f"\\frac{{{mx}(x-{nx})}}{{{gap}}}"
334 kv["line3_LHS"] = f"x - {nx}"
335 kv["line4_LHS"] = f"x - {nx} + {nx}"
336 kv["line4_LHSq"] = f"x - {nx} + {gap}"
337 kv["line5_LHS"] = f"x"
338
339 kv["line1_RHS"] = f"{na}"
340 kv["line2_RHS"] = f"\\frac{{{na}}}{{{mx}}}"
341 kv["line2_RHSq"] = f"\\frac{{{na}}}{{{gap}}}"
342 kv["line3_RHS"] = f"{int(na / mx)}"
343 kv["line3_RHSq"] = f"{gap}"
344 kv["line4_RHS"] = f"{int(na / mx)} + {nx}"
345 kv["line4_RHSq"] = f"{gap} + {gap}"
346 kv["line5_RHS"] = f"{xval}"
347 kv["line5_RHSq"] = f"{gap}"
348 return kv
349
350def sub_div_dict():
351 # (x - nx) / mx = na
352 nx = random.randint(1, 10)
353 mx = random.randint(2, 10)
354 na = random.randint(1, 10)
355 xval = na * mx + nx
356
357 kv = dict()
358 kv["line1_LHS"] = f"\\frac{{x - {nx}}}{{{mx}}}"
359 kv["line2_LHS"] = f"\\frac{{x - {nx}}}{{{mx}}} \\times{mx}"
360 kv["line2_LHSq"] = f"\\frac{{x - {nx}}}{{{mx}}} \\times{gap}"
361 kv["line3_LHS"] = f"x - {nx}"
362 kv["line4_LHS"] = f"x - {nx} + {nx}"
363 kv["line4_LHSq"] = f"x - {nx} + {gap}"
364 kv["line5_LHS"] = f"x"
365
366 kv["line1_RHS"] = f"{na}"
367 kv["line2_RHS"] = f"{na} \\times{mx}"
368 kv["line2_RHSq"] = f"{na} \\times{gap}"
369 kv["line3_RHS"] = f"{na * mx}"
370 kv["line3_RHSq"] = f"{gap}"
371 kv["line4_RHS"] = f"{na * mx} + {nx}"
372 kv["line4_RHSq"] = f"{gap} + {gap}"
373 kv["line5_RHS"] = f"{xval}"
374 kv["line5_RHSq"] = f"{gap}"
375 return kv
376
377
378def times_add_dict():
379 # nx * x + mx = na
380 xval = random.randint(1, 10)
381 nx = random.randint(2, 10)
382 mx = random.randint(1, 10)
383 na = (xval * nx) + mx
384
385 kv = dict()
386 kv["line1_LHS"] = f"{nx}x + {mx}"
387 kv["line2_LHS"] = f"{nx}x + {mx} - {mx}"
388 kv["line2_LHSq"] = f"{nx}x + {mx} - {gap}"
389 kv["line3_LHS"] = f"{nx}x"
390 kv["line4_LHS"] = f"\\frac{{{nx}x}}{{{nx}}}"
391 kv["line4_LHSq"] = f"\\frac{{{nx}x}}{{{gap}}}"
392 kv["line5_LHS"] = f"x"
393
394 kv["line1_RHS"] = f"{na}"
395 kv["line2_RHS"] = f"{na} - {mx}"
396 kv["line2_RHSq"] = f"{na} - {gap}"
397 kv["line3_RHS"] = f"{na - mx}"
398 kv["line3_RHSq"] = f"{gap}"
399 kv["line4_RHS"] = f"\\frac{{{na - mx}}}{{{nx}}}"
400 kv["line4_RHSq"] = f"\\frac{{{gap}}}{{{gap}}}"
401 kv["line5_RHS"] = f"{xval}"
402 kv["line5_RHSq"] = f"{gap}"
403 return kv
404
405
406def times_sub_dict():
407 # nx * x - mx = na
408 xval = random.randint(1, 10)
409 nx = random.randint(2, 10)
410 mx = random.randint(1, 10)
411 na = (xval * nx) - mx
412
413 kv = dict()
414 kv["line1_LHS"] = f"{nx}x - {mx}"
415 kv["line2_LHS"] = f"{nx}x - {mx} + {mx}"
416 kv["line2_LHSq"] = f"{nx}x - {mx} + {gap}"
417 kv["line3_LHS"] = f"{nx}x"
418 kv["line4_LHS"] = f"\\frac{{{nx}x}}{{{nx}}}"
419 kv["line4_LHSq"] = f"\\frac{{{nx}x}}{{{gap}}}"
420 kv["line5_LHS"] = f"x"
421
422 kv["line1_RHS"] = f"{na}"
423 kv["line2_RHS"] = f"{na} + {mx}"
424 kv["line2_RHSq"] = f"{na} + {gap}"
425 kv["line3_RHS"] = f"{na + mx}"
426 kv["line3_RHSq"] = f"{gap}"
427 kv["line4_RHS"] = f"\\frac{{{na + mx}}}{{{nx}}}"
428 kv["line4_RHSq"] = f"\\frac{{{gap}}}{{{gap}}}"
429 kv["line5_RHS"] = f"{xval}"
430 kv["line5_RHSq"] = f"{gap}"
431 return kv
432
433
434def times_times_dict():
435 # nx * x * mx = na
436 xval = random.randint(1, 10)
437 nx = random.randint(2, 10)
438 mx = random.randint(2, 10)
439 na = xval * nx * mx
440
441 kv = dict()
442 kv["line1_LHS"] = f"{nx}x \\times{mx}"
443 kv["line2_LHS"] = f"\\frac{{{nx}x \\times{mx}}}{{{mx}}}"
444 kv["line2_LHSq"] = f"\\frac{{{nx}x \\times{mx}}}{{{gap}}}"
445 kv["line3_LHS"] = f"{nx}x"
446 kv["line4_LHS"] = f"\\frac{{{nx}x}}{{{nx}}}"
447 kv["line4_LHSq"] = f"\\frac{{{nx}x}}{{{gap}}}"
448 kv["line5_LHS"] = f"x"
449
450 kv["line1_RHS"] = f"{na}"
451 kv["line2_RHS"] = f"\\frac{{{na}}}{{{mx}}}"
452 kv["line2_RHSq"] = f"\\frac{{{na}}}{{{gap}}}"
453 kv["line3_RHS"] = f"{int(na / mx)}"
454 kv["line3_RHSq"] = f"{gap}"
455 kv["line4_RHS"] = f"\\frac{{{int(na / mx)}}}{{{nx}}}"
456 kv["line4_RHSq"] = f"\\frac{{{gap}}}{{{gap}}}"
457 kv["line5_RHS"] = f"{xval}"
458 kv["line5_RHSq"] = f"{gap}"
459 return kv
460
461def times_div_dict():
462 # (nx * x) / mx = na
463 xval = random.randint(1, 10)
464 mx = random.randint(2, 4)
465 nx = mx * random.randint(2, 5)
466 na = int((nx * xval) / mx)
467
468 kv = dict()
469 kv["line1_LHS"] = f"\\frac{{{nx}x}}{{{mx}}}"
470 kv["line2_LHS"] = f"\\frac{{{nx}x}}{{{mx}}} \\times{mx}"
471 kv["line2_LHSq"] = f"\\frac{{{nx}x}}{{{mx}}} \\times{gap}"
472 kv["line3_LHS"] = f"{nx}x"
473 kv["line4_LHS"] = f"\\frac{{{nx}x}}{{{nx}}}"
474 kv["line4_LHSq"] = f"\\frac{{{nx}x}}{{{gap}}}"
475 kv["line5_LHS"] = f"x"
476
477 kv["line1_RHS"] = f"{na}"
478 kv["line2_RHS"] = f"{na}\\times{mx}"
479 kv["line2_RHSq"] = f"{na}\\times{gap}"
480 kv["line3_RHS"] = f"{na * mx}"
481 kv["line3_RHSq"] = f"{gap}"
482 kv["line4_RHS"] = f"\\frac{{{na * mx}}}{{{nx}}}"
483 kv["line4_RHSq"] = f"\\frac{{{gap}}}{{{gap}}}"
484 kv["line5_RHS"] = f"{xval}"
485 kv["line5_RHSq"] = f"{gap}"
486 return kv
487
488
489
490def div_add_dict():
491 # (x / nx) + mx = na
492 nx = random.randint(2, 10)
493 xval = nx * random.randint(2, 10)
494 mx = random.randint(1, 10)
495 na = int(xval / nx) + mx
496
497 kv = dict()
498 kv["line1_LHS"] = f"\\frac{{x}}{{{nx}}} + {mx}"
499 kv["line2_LHS"] = f"\\frac{{x}}{{{nx}}} + {mx} - {mx}"
500 kv["line2_LHSq"] = f"\\frac{{x}}{{{nx}}} + {mx} - {gap}"
501 kv["line3_LHS"] = f"\\frac{{x}}{{{nx}}}"
502 kv["line4_LHS"] = f"\\frac{{x}}{{{nx}}} \\times{nx}"
503 kv["line4_LHSq"] = f"\\frac{{x}}{{{nx}}} \\times{gap}"
504 kv["line5_LHS"] = f"x"
505
506 kv["line1_RHS"] = f"{na}"
507 kv["line2_RHS"] = f"{na} - {mx}"
508 kv["line2_RHSq"] = f"{na} - {gap}"
509 kv["line3_RHS"] = f"{na - mx}"
510 kv["line3_RHSq"] = f"{gap}"
511 kv["line4_RHS"] = f"{na - mx} \\times{nx}"
512 kv["line4_RHSq"] = f"{gap} \\times{gap}"
513 kv["line5_RHS"] = f"{xval}"
514 kv["line5_RHSq"] = f"{gap}"
515 return kv
516
517
518def div_sub_dict():
519 # (x / nx) - mx = na
520 nx = random.randint(2, 10)
521 xval = nx * random.randint(2, 10)
522 mx = random.randint(1, 10)
523 na = int(xval / nx) - mx
524
525 kv = dict()
526 kv["line1_LHS"] = f"\\frac{{x}}{{{nx}}} - {mx}"
527 kv["line2_LHS"] = f"\\frac{{x}}{{{nx}}} - {mx} + {mx}"
528 kv["line2_LHSq"] = f"\\frac{{x}}{{{nx}}} - {mx} + {gap}"
529 kv["line3_LHS"] = f"\\frac{{x}}{{{nx}}}"
530 kv["line4_LHS"] = f"\\frac{{x}}{{{nx}}} \\times{nx}"
531 kv["line4_LHSq"] = f"\\frac{{x}}{{{nx}}} \\times{gap}"
532 kv["line5_LHS"] = f"x"
533
534 kv["line1_RHS"] = f"{na}"
535 kv["line2_RHS"] = f"{na} + {mx}"
536 kv["line2_RHSq"] = f"{na} + {gap}"
537 kv["line3_RHS"] = f"{na + mx}"
538 kv["line3_RHSq"] = f"{gap}"
539 kv["line4_RHS"] = f"{na + mx} \\times{nx}"
540 kv["line4_RHSq"] = f"{gap} \\times{gap}"
541 kv["line5_RHS"] = f"{xval}"
542 kv["line5_RHSq"] = f"{gap}"
543 return kv
544
545
546def div_times_dict():
547 # (x / nx) * mx = na
548 nx = random.randint(2, 10)
549 xval = nx * random.randint(2, 10)
550 mx = random.randint(2, 10)
551 na = int((xval / nx) * mx)
552
553 kv = dict()
554 kv["line1_LHS"] = f"\\frac{{x}}{{{nx}}} \\times{mx}"
555 kv["line2_LHS"] = f"\\frac{{\\frac{{x}}{{{nx}}} \\times{mx}}}{{{mx}}}"
556 kv["line2_LHSq"] = f"\\frac{{\\frac{{x}}{{{nx}}} \\times{mx}}}{{{gap}}}"
557 kv["line3_LHS"] = f"\\frac{{x}}{{{nx}}}"
558 kv["line4_LHS"] = f"\\frac{{x}}{{{nx}}} \\times{nx}"
559 kv["line4_LHSq"] = f"\\frac{{x}}{{{nx}}} \\times{gap}"
560 kv["line5_LHS"] = f"x"
561
562 kv["line1_RHS"] = f"{na}"
563 kv["line2_RHS"] = f"\\frac{{{na}}}{{{mx}}}"
564 kv["line2_RHSq"] = f"\\frac{{{na}}}{{{gap}}}"
565 kv["line3_RHS"] = f"{int(na / mx)}"
566 kv["line3_RHSq"] = f"{gap}"
567 kv["line4_RHS"] = f"{int(na / mx)}\\times{nx}"
568 kv["line4_RHSq"] = f"{int(na / mx)}\\times{gap}"
569 kv["line5_RHS"] = f"{xval}"
570 kv["line5_RHSq"] = f"{gap}"
571 return kv
572
573
574def div_div_dict():
575 # (x / nx) / mx = na
576 nx = random.randint(2, 5)
577 mx = random.randint(2, 6)
578 na = random.randint(2, 5)
579 xval = na * nx * mx
580
581 kv = dict()
582 kv["line1_LHS"] = f"\\frac{{\\frac{{x}}{{{nx}}}}}{{{mx}}}"
583 kv["line2_LHS"] = f"\\frac{{\\frac{{x}}{{{nx}}}}}{{{mx}}} \\times {mx}"
584 kv["line2_LHSq"] = f"\\frac{{\\frac{{x}}{{{nx}}}}}{{{mx}}} \\times {gap}"
585 kv["line3_LHS"] = f"\\frac{{x}}{{{nx}}}"
586 kv["line4_LHS"] = f"\\frac{{x}}{{{nx}}} \\times{nx}"
587 kv["line4_LHSq"] = f"\\frac{{x}}{{{nx}}} \\times{gap}"
588 kv["line5_LHS"] = f"x"
589
590 kv["line1_RHS"] = f"{na}"
591 kv["line2_RHS"] = f"{na}\\times{mx}"
592 kv["line2_RHSq"] = f"{na}\\times{gap}"
593 kv["line3_RHS"] = f"{na * mx}"
594 kv["line3_RHSq"] = f"{gap}"
595 kv["line4_RHS"] = f"{na * mx}\\times{nx}"
596 kv["line4_RHSq"] = f"{na * mx}\\times{gap}"
597 kv["line5_RHS"] = f"{xval}"
598 kv["line5_RHSq"] = f"{gap}"
599 return kv
2.3. 2-step invop diagram: LaTeXο
1% inv op template
2\documentclass[varwidth]{standalone}
3\usepackage{amsmath}
4\usepackage[normalem]{ulem} % [normalem] prevents the package from changing the default behavior of `\\emph` to underline.
5\usepackage[active,tightpage]{preview}
6\PreviewEnvironment{align*}
7
8\begin{document}
9 <<diagram>>
10\end{document}
1\begin{varwidth}{0.25\paperwidth}
2 \begin{align*}
3 <<line1_LHS>> &= <<line1_RHS>>\\
4 <<line2_LHS>> &= <<line2_RHS>>\\
5 <<line3_LHS>> &= <<line3_RHS>>\\
6 <<line4_LHS>> &= <<line4_RHS>>\\
7 <<line5_LHS>> &= <<line5_RHS>>\\
8\end{align*}
9\end{varwidth}