3. Equations 1-step booklet pythonο
The python file to make 1-step invop booklets is below.
The required LaTeX files are below.
The python file, invop_booklet_maker.py, when run, will ask for these inputs:
Choose the first arithmetic process:
"Enter 1, 2, 3, 4 or 5 for +, -, X, /, random.Choose the number of questions from 1 to 96:
"Enter the number of questions from 1 to 96"Choose the file name base:
"Enter the base filename to be added to the prefix invop_Bk_:". The filename will have β_qβ added for the question booklet and β_ansβ for the answer booklet.3.1. Sample 1-step invop bookletο
3.2. 1-step invop: pythonο
1from pathlib import Path
2import subprocess
3import os
4import time
5
6# import magick_pdf_to_png
7import invop_functions as iof
8
9currfile_dir = Path(__file__).parent
10tex_template_path = currfile_dir / "invop_booklet_template.tex"
11texans_template_path = currfile_dir / "invop_booklet_ans_template.tex"
12tex_diagram_template_path = currfile_dir / "invop_booklet_diagram_template.tex"
13
14q_per_column = 8
15q_per_page = q_per_column * 2
16max_q = 96
17
18
19def convert_to_pdf(tex_path, outputdir):
20 tex_path = Path(tex_path).resolve()
21 outputdir = Path(outputdir).resolve()
22 # for testing
23 # print(f"tex_path: {tex_path}")
24 # print(f"outputdir: {outputdir}")
25 try:
26 # Generate the PDF
27 subprocess.run(["latexmk", "-pdf", "-outdir=" + str(outputdir), str(tex_path)], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
28 # # Clean auxiliary files after successful PDF generation
29 subprocess.run(["latexmk", "-c", "-outdir=" + str(outputdir), str(tex_path)], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
30 # for hosted remove stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL for debugging any errors
31 # Remove the .tex file manually
32 if tex_path.exists():
33 os.remove(tex_path)
34 except subprocess.CalledProcessError as e:
35 print(f"Error: {e}")
36
37
38# % end modify values for invop
39# tex_keys_q = ['line1_LHS', 'line1_RHS', 'line2_LHSq', 'line2_RHSq', 'line3_LHS', 'line3_RHSq']
40# keys without q are in template
41tex_keys_q = ["line2_LHS", "line2_RHS", "line3_RHS"]
42
43
44def make1_diagram(
45 tex_diagram_template_txt,
46 num1,
47):
48 tex_diagram_template_txt_ans = tex_diagram_template_txt
49 kv = iof.get_1step_process_dict(num1)
50 for key, value in kv.items():
51 tex_diagram_template_txt_ans = tex_diagram_template_txt_ans.replace("<<" + key + ">>", value)
52 for key, value in kv.items():
53 if key not in tex_keys_q:
54 tex_diagram_template_txt = tex_diagram_template_txt.replace("<<" + key + ">>", value)
55 else:
56 tex_diagram_template_txt = tex_diagram_template_txt.replace("<<" + key + ">>", kv[f"{key}q"])
57 return tex_diagram_template_txt, tex_diagram_template_txt_ans
58
59
60def main():
61 num1 = input("Enter 1, 2, 3, 4 or 5 for +, -, X, /, random \n")
62 if num1.strip().isdigit():
63 num1 = int(num1)
64 if not num1 in [1, 2, 3, 4, 5]:
65 num1 = 5 # random by default
66 else:
67 num1 = 5 # random by default
68 #
69 numq = input("Enter the number of questions from 1 to 96, with 16 per page \n")
70 if numq.strip().isdigit():
71 numq = int(numq)
72 if not numq in range(1, max_q + 1):
73 numq = max_q # max
74 else:
75 numq = q_per_page # by default fits on one page
76 #
77 filename = input("Enter the base filename to be added to the prefix invop_Bk_: \n")
78 if not filename:
79 filename = "1" # "invop_Bk_1_q and invop_Bk_1_ans as default file"
80 # set names of files that are made
81 # questions
82 tex_output_path = currfile_dir / f"invop_Bk_{filename}_q.tex"
83 pdf_path = currfile_dir / f"invop_Bk_{filename}_q.pdf"
84
85 # answers
86 tex_output_path_ans = currfile_dir / f"invop_Bk_{filename}_ans.tex"
87 pdf_path_ans = currfile_dir / f"invop_Bk_{filename}_ans.pdf"
88
89 # Read in the LaTeX template file
90 with open(tex_template_path, "r") as infile:
91 tex_template_txt = infile.read()
92 # Read in the LaTeX template file for answers
93 with open(texans_template_path, "r") as infile:
94 tex_template_txt_ans = infile.read()
95 # Read in the LaTeX diagram template file
96 with open(tex_diagram_template_path, "r") as infile:
97 tex_diagram_template_txt = infile.read()
98
99 # Generate the <<diagram>> replacement tex
100 # diagram_text, diagram_text_ans = make1_diagram(tex_diagram_template_txt, num1)
101
102 # <<diagrams>>
103 # generate diagrams text and text for answers
104 diagrams_text = ""
105 diagrams_text_ans = ""
106 # add the headtext
107 # must have no space in \end{minipage}\columnbreak for column break to occur at correct place.
108 headtext_col = r"""\columnbreak
109 """
110 headtext_page = r"""\newpage
111 """
112 # headtext_page = r'''\newpage ~ \newline ~ \newline'''
113
114 for i in range(1, numq + 1):
115 img_tex, img_tex_ans = make1_diagram(tex_diagram_template_txt, num1)
116 diagrams_text += img_tex
117 diagrams_text_ans += img_tex_ans
118 if i % q_per_page == 0 and numq + 1 > i:
119 diagrams_text += headtext_page
120 diagrams_text_ans += headtext_page
121 elif i % q_per_column == 0 and i > 1 and numq + 1 > i:
122 diagrams_text += headtext_col
123 diagrams_text_ans += headtext_col
124
125 # Replace the <<diagrams>> placeholder in the LaTeX template
126 tex_template_txt = tex_template_txt.replace("<<diagrams>>", diagrams_text)
127 tex_template_txt_ans = tex_template_txt_ans.replace("<<diagrams>>", diagrams_text_ans)
128 # Write the question diagrams tex to an output file
129 with open(tex_output_path, "w") as outfile:
130 outfile.write(tex_template_txt)
131 # Write the answer diagrams 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)
139 convert_to_pdf(tex_output_path_ans, currfile_dir)
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")
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
7
8def get_1step_process_dict(num):
9 if num is None or num == 5:
10 num = random.randint(1, 4)
11 match num:
12 case 1:
13 return add_dict()
14 case 2:
15 return sub_dict()
16 case 3:
17 return times_dict()
18 case 4:
19 return div_dict()
20
21
22
23def add_dict():
24 # x + nx = na
25 nx = random.randint(1, 10)
26 na = random.randint(1, 10)
27 xval = na - nx
28 kv = dict()
29 kv["line1_LHS"] = f"x + {nx}"
30 kv["line2_LHS"] = f"x + {nx} - {nx}"
31 kv["line2_LHSq"] = f"x + {nx} - {r'\dotuline{\hspace{5mm}}'}"
32 kv["line3_LHS"] = f"x"
33 kv["line1_RHS"] = f"{na}"
34 kv["line2_RHS"] = f"{na} - {nx}"
35 kv["line2_RHSq"] = f"{na} - {r'\dotuline{\hspace{5mm}}'}"
36 kv["line3_RHS"] = f"{xval}"
37 kv["line3_RHSq"] = f"{r'\dotuline{\hspace{5mm}}'}"
38 return kv
39
40
41def sub_dict():
42 # x - nx = na
43 nx = random.randint(1, 10)
44 na = random.randint(1, 10)
45 xval = na + nx
46 kv = dict()
47 kv["line1_LHS"] = f"x - {nx}"
48 kv["line2_LHS"] = f"x - {nx} + {nx}"
49 kv["line2_LHSq"] = f"x - {nx} + {r'\dotuline{\hspace{5mm}}'}"
50 kv["line3_LHS"] = f"x"
51 kv["line1_RHS"] = f"{na}"
52 kv["line2_RHS"] = f"{na} + {nx}"
53 kv["line2_RHSq"] = f"{na} + {r'\dotuline{\hspace{5mm}}'}"
54 kv["line3_RHS"] = f"{xval}"
55 kv["line3_RHSq"] = f"{r'\dotuline{\hspace{5mm}}'}"
56 return kv
57
58
59def times_dict():
60 # x * nx = na
61 nx = random.randint(2, 10)
62 xval = random.randint(2, 10)
63 na = xval * nx
64
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}}{{{r'\dotuline{\hspace{5mm}}'}}}"
69
70 kv["line2_LHSq"] = f"\\frac{{{nx}x}}{{{r'\dotuline{\hspace{5mm}}'}}}"
71 kv["line3_LHS"] = f"x"
72 kv["line1_RHS"] = f"{na}"
73 kv["line2_RHS"] = f"\\frac{{{na}}}{{{nx}}}"
74 kv["line2_RHSq"] = f"\\frac{{{na}}}{{{r'\dotuline{\hspace{5mm}}'}}}"
75 kv["line3_RHS"] = f"{xval}"
76 kv["line3_RHSq"] = f"{r'\dotuline{\hspace{5mm}}'}"
77 return kv
78
79
80def div_dict():
81 # x / nx = na
82 nx = random.randint(2, 10)
83 na = random.randint(2, 10)
84 xval = na * nx
85
86 kv = dict()
87 kv["line1_LHS"] = f"\\frac{{x}}{{{nx}}}"
88 kv["line2_LHS"] = f"\\frac{{x}}{{{nx}}} \\times{nx}"
89 kv["line2_LHSq"] = f"\\frac{{x}}{{{nx}}} \\times{{{r'\dotuline{\hspace{5mm}}'}}}"
90 kv["line3_LHS"] = f"x"
91 kv["line1_RHS"] = f"{na}"
92 kv["line2_RHS"] = f"{na} \\times{nx}"
93 kv["line2_RHSq"] = f"{na} \\times{{{r'\dotuline{\hspace{5mm}}'}}}"
94 kv["line3_RHS"] = f"{xval}"
95 kv["line3_RHSq"] = f"{r'\dotuline{\hspace{5mm}}'}"
96 return kv
97
98
99
100# ############################################
101
102def val_in_list_exclude(low, high, exclude):
103 # random 2 step: avoid xx, x/, /x, //, ++, --, +-, -+
104 vals = list(range(low, high + 1))
105 if exclude in vals:
106 if exclude in [1, 2]:
107 vals.remove(1)
108 vals.remove(2)
109 elif exclude in [3, 4]:
110 vals.remove(3)
111 vals.remove(4)
112 return random.choice(vals)
113
114
115def get_2step_process_dict(num1, num2):
116 if num1 is None or num1 == 5:
117 num1 = random.randint(1, 4)
118 if num2 is None or num2 == 5:
119 num2 = val_in_list_exclude(1, 4, num1)
120 processes = (num1, num2)
121 # processes = (3,3)
122 match processes:
123 case (1, 1):
124 return add_add_dict()
125 case (1, 2):
126 return add_sub_dict()
127 case (1, 3):
128 return add_times_dict()
129 case (1, 4):
130 return add_div_dict()
131 case (2, 1):
132 return sub_add_dict()
133 case (2, 2):
134 return sub_sub_dict()
135 case (2, 3):
136 return sub_times_dict()
137 case (2, 4):
138 return sub_div_dict()
139 case (3, 1):
140 return times_add_dict()
141 case (3, 2):
142 return times_sub_dict()
143 case (3, 3):
144 return times_times_dict()
145 case (3, 4):
146 return times_div_dict()
147 case (4, 1):
148 return div_add_dict()
149 case (4, 2):
150 return div_sub_dict()
151 case (4, 3):
152 return div_times_dict()
153 case (4, 4):
154 return div_div_dict()
155 case _:
156 return add_add_dict()
157
158
159def add_add_dict():
160 # bc = nx + na + nb
161 nx = random.randint(1, 10)
162 na = random.randint(1, 10)
163 nb = random.randint(1, 10)
164 bb = nx + na
165 bc = bb + nb
166
167 kv = dict()
168 kv["stepAB"] = f"+{na}"
169 kv["stepABrev"] = f"-{na}"
170 kv["stepBC"] = f"+{nb}"
171 kv["stepBCrev"] = f"-{nb}"
172
173 kv["boxA"] = f"x"
174 kv["boxB"] = f"x+{na}"
175 kv["boxC"] = f"x+{na + nb}"
176 kv["boxCrev"] = f"{bc}"
177 kv["boxBrev"] = f"{bb}"
178 kv["boxArev"] = f"{nx}"
179 return kv
180
181
182def add_sub_dict():
183 # bc = nx + na - nb
184 nx = random.randint(1, 10)
185 na = random.randint(1, 10)
186 bb = nx + na
187 if bb > 10:
188 nb = random.randint(1, 10)
189 else:
190 nb = random.randint(1, bb)
191 bc = bb - nb
192
193 kv = dict()
194 kv["stepAB"] = f"+{na}"
195 kv["stepABrev"] = f"-{na}"
196 kv["stepBC"] = f"-{nb}"
197 kv["stepBCrev"] = f"+{nb}"
198
199 kv["boxA"] = f"x"
200 kv["boxB"] = f"x+{na}"
201 if na - nb > 0:
202 kv["boxC"] = f"x+{na - nb}"
203 else:
204 kv["boxC"] = f"x-{nb - na}"
205 kv["boxCrev"] = f"{bc}"
206 kv["boxBrev"] = f"{bb}"
207 kv["boxArev"] = f"{nx}"
208 return kv
209
210
211def add_times_dict():
212 # bc = nx * na * nb
213 nx = random.randint(1, 10)
214 na = random.randint(1, 10)
215 nb = random.randint(1, 10)
216 bb = nx + na
217 bc = bb * nb
218
219 kv = dict()
220 kv["stepAB"] = f"+{na}"
221 kv["stepABrev"] = f"-{na}"
222 kv["stepBC"] = f"\\times{nb}"
223 kv["stepBCrev"] = f"\\div{nb}"
224
225 kv["boxA"] = f"x"
226 kv["boxB"] = f"x+{na}"
227 kv["boxC"] = f"{nb}(x + {na})"
228 kv["boxCrev"] = f"{bc}"
229 kv["boxBrev"] = f"{bb}"
230 kv["boxArev"] = f"{nx}"
231 return kv
232
233
234def add_div_dict():
235 # bc = (nx + na) / nb
236 # nx = (bc * nb) - na
237 bc = random.randint(1, 10)
238 nb = random.randint(1, 10)
239 bb = bc * nb
240 if bb > 10:
241 na = random.randint(1, 10)
242 else:
243 na = random.randint(1, bb)
244 nx = bb - na
245
246 kv = dict()
247 kv["stepAB"] = f"+{na}"
248 kv["stepABrev"] = f"-{na}"
249 kv["stepBC"] = f"\\div{nb}"
250 kv["stepBCrev"] = f"\\times{nb}"
251
252 kv["boxA"] = f"x"
253 kv["boxB"] = f"x+{na}"
254 kv["boxC"] = f"\\frac{{(x+{na})}}{{{nb}}}"
255 kv["boxCrev"] = f"{bc}"
256 kv["boxBrev"] = f"{bb}"
257 kv["boxArev"] = f"{nx}"
258 return kv
259
260
261def sub_add_dict():
262 # bc = nx - na + nb
263 na = random.randint(1, 10)
264 nx = na + random.randint(1, 10)
265 nb = random.randint(1, 10)
266 bb = nx - na
267 bc = bb + nb
268
269 kv = dict()
270 kv["stepAB"] = f"-{na}"
271 kv["stepABrev"] = f"+{na}"
272 kv["stepBC"] = f"-{nb}"
273 kv["stepBCrev"] = f"+{nb}"
274
275 kv["boxA"] = f"x"
276 kv["boxB"] = f"x-{na}"
277 kv["boxC"] = f"x-{na + nb}"
278 kv["boxCrev"] = f"{bc}"
279 kv["boxBrev"] = f"{bb}"
280 kv["boxArev"] = f"{nx}"
281 return kv
282
283
284def sub_sub_dict():
285 # bc = nx - na - nb
286 # nx = bc + nb + na
287 bc = random.randint(1, 10)
288 na = random.randint(1, 10)
289 nb = random.randint(1, 10)
290 bb = bc + nb
291 nx = bb + na
292
293 kv = dict()
294 kv["stepAB"] = f"-{na}"
295 kv["stepABrev"] = f"+{na}"
296 kv["stepBC"] = f"-{nb}"
297 kv["stepBCrev"] = f"+{nb}"
298
299 kv["boxA"] = f"x"
300 kv["boxB"] = f"x-{na}"
301 kv["boxC"] = f"x-{na + nb}"
302 kv["boxCrev"] = f"{bc}"
303 kv["boxBrev"] = f"{bb}"
304 kv["boxArev"] = f"{nx}"
305 return kv
306
307
308def sub_times_dict():
309 # bc = (nx - na) * nb
310 # nx = (bc + nb) * na
311 na = random.randint(1, 10)
312 nx = na + random.randint(1, 10)
313 nb = random.randint(1, 10)
314 bb = nx - na
315 bc = bb * nb
316
317 kv = dict()
318 kv["stepAB"] = f"-{na}"
319 kv["stepABrev"] = f"+{na}"
320 kv["stepBC"] = f"\\times{nb}"
321 kv["stepBCrev"] = f"\\div{nb}"
322
323 kv["boxA"] = f"x"
324 kv["boxB"] = f"x-{na}"
325 kv["boxC"] = f"{nb}(x-{na})"
326 kv["boxCrev"] = f"{bc}"
327 kv["boxBrev"] = f"{bb}"
328 kv["boxArev"] = f"{nx}"
329 return kv
330
331
332def sub_div_dict():
333 # bc = nx - na / nb
334 # nx = (bc + nb) * na
335 bc = random.randint(1, 10)
336 na = random.randint(1, 10)
337 nb = random.randint(1, 10)
338 bb = bc * nb
339 nx = bb + na
340
341 kv = dict()
342 kv["stepAB"] = f"-{na}"
343 kv["stepABrev"] = f"+{na}"
344 kv["stepBC"] = f"\\div{nb}"
345 kv["stepBCrev"] = f"\\times{nb}"
346
347 kv["boxA"] = f"x"
348 kv["boxB"] = f"x-{na}"
349 kv["boxC"] = f"\\frac{{(x-{na})}}{{{nb}}}"
350 kv["boxCrev"] = f"{bc}"
351 kv["boxBrev"] = f"{bb}"
352 kv["boxArev"] = f"{nx}"
353 return kv
354
355
356def times_add_dict():
357 # bc = nx * na + nb
358 nx = random.randint(2, 10)
359 na = random.randint(2, 10)
360 nb = random.randint(2, 10)
361 bb = nx * na
362 bc = nx * na + nb
363
364 kv = dict()
365 kv["stepAB"] = f"\\times{na}"
366 kv["stepABrev"] = f"\\div{na}"
367 kv["stepBC"] = f"+{nb}"
368 kv["stepBCrev"] = f"-{nb}"
369
370 kv["boxA"] = f"x"
371 kv["boxB"] = f"{na}x"
372 kv["boxC"] = f"{na}x + {nb}"
373 kv["boxCrev"] = f"{bc}"
374 kv["boxBrev"] = f"{bb}"
375 kv["boxArev"] = f"{nx}"
376 return kv
377
378
379def times_sub_dict():
380 # bc = nx * na - nb
381 nx = random.randint(2, 10)
382 na = random.randint(2, 10)
383 bb = nx * na
384 if bb > 10:
385 nb = random.randint(2, 10)
386 else:
387 nb = random.randint(2, bb)
388 bc = bb - nb
389
390 kv = dict()
391 kv["stepAB"] = f"\\times{na}"
392 kv["stepABrev"] = f"\\div{na}"
393 kv["stepBC"] = f"-{nb}"
394 kv["stepBCrev"] = f"+{nb}"
395
396 kv["boxA"] = f"x"
397 kv["boxB"] = f"{na}x"
398 kv["boxC"] = f"{na}x - {nb}"
399 kv["boxCrev"] = f"{bc}"
400 kv["boxBrev"] = f"{bb}"
401 kv["boxArev"] = f"{nx}"
402 return kv
403
404
405def times_times_dict():
406 # bc = nx * na * nb
407 nx = random.randint(2, 10)
408 na = random.randint(2, 10)
409 nb = random.randint(2, 10)
410 bb = nx * na
411 bc = nx * na * nb
412
413 kv = dict()
414 kv["stepAB"] = f"\\times{na}"
415 kv["stepABrev"] = f"\\div{na}"
416 kv["stepBC"] = f"\\times{nb}"
417 kv["stepBCrev"] = f"\\div{nb}"
418
419 kv["boxA"] = f"x"
420 kv["boxB"] = f"{na}x"
421 kv["boxC"] = f"{na * nb}x"
422 kv["boxCrev"] = f"{bc}"
423 kv["boxBrev"] = f"{bb}"
424 kv["boxArev"] = f"{nx}"
425 return kv
426
427
428def times_div_dict():
429 # bc = nx * na / nb
430 nb = random.randint(2, 3)
431 na = nb * random.randint(2, 4)
432 nx = random.randint(2, 10)
433 bb = nx * na
434 bc = int(bb / nb)
435
436 kv = dict()
437 kv["stepAB"] = f"\\times{na}"
438 kv["stepABrev"] = f"\\div{na}"
439 kv["stepBC"] = f"\\div{nb}"
440 kv["stepBCrev"] = f"\\times{nb}"
441
442 kv["boxA"] = f"x"
443 kv["boxB"] = f"{na}x"
444 kv["boxC"] = f"{int(na / nb)}x"
445 kv["boxCrev"] = f"{bc}"
446 kv["boxBrev"] = f"{bb}"
447 kv["boxArev"] = f"{nx}"
448 return kv
449
450
451def div_add_dict():
452 # bc = (nx / na) + nb
453 # nx = (bc - nb) * na
454 na = random.randint(2, 10)
455 nx = na * random.randint(1, 10)
456 nb = random.randint(1, 10)
457 bb = int(nx / na)
458 bc = bb + nb
459
460 kv = dict()
461 kv["stepAB"] = f"\\div{na}"
462 kv["stepABrev"] = f"\\times{na}"
463 kv["stepBC"] = f"+{nb}"
464 kv["stepBCrev"] = f"-{nb}"
465 kv["boxA"] = f"x"
466 kv["boxB"] = f"\\frac{{x}}{{{na}}}"
467 kv["boxC"] = f"\\frac{{x}}{{{na}}} + {nb}"
468 kv["boxCrev"] = f"{bc}"
469 kv["boxBrev"] = f"{bb}"
470 kv["boxArev"] = f"{nx}"
471 return kv
472
473
474def div_sub_dict():
475 # bc = (nx / na) - nb
476 # nx = (bc + nb) * na
477 bc = random.randint(2, 10)
478 na = random.randint(2, 10)
479 nb = random.randint(2, 10)
480 bb = bc + nb
481 nx = bb * na
482
483 kv = dict()
484 kv["stepAB"] = f"\\div{na}"
485 kv["stepABrev"] = f"\\times{na}"
486 kv["stepBC"] = f"-{nb}"
487 kv["stepBCrev"] = f"+{nb}"
488 kv["boxA"] = f"x"
489 kv["boxB"] = f"\\frac{{x}}{{{na}}}"
490 kv["boxC"] = f"\\frac{{x}}{{{na}}} - {nb}"
491 kv["boxCrev"] = f"{bc}"
492 kv["boxBrev"] = f"{bb}"
493 kv["boxArev"] = f"{nx}"
494 return kv
495
496
497def div_times_dict():
498 # bc = (nx / na) * nb
499 na = random.randint(2, 10)
500 nx = na * random.randint(2, 10)
501 nb = random.randint(2, 10)
502 bb = int(nx / na)
503 bc = bb * nb
504
505 kv = dict()
506 kv["stepAB"] = f"\\div{na}"
507 kv["stepABrev"] = f"\\times{na}"
508 kv["stepBC"] = f"\\div{nb}"
509 kv["stepBCrev"] = f"\\times{nb}"
510 kv["boxA"] = f"x"
511 kv["boxB"] = f"\\frac{{x}}{{{na}}}"
512 kv["boxC"] = f"\\frac{{x}}{{{na * nb}}}"
513 kv["boxCrev"] = f"{bc}"
514 kv["boxBrev"] = f"{bb}"
515 kv["boxArev"] = f"{nx}"
516 return kv
517
518
519def div_div_dict():
520 # bc = (nx / na) / nb
521 # escape {} in f strings by doubling them up {{}}
522 bc = random.randint(2, 10)
523 na = random.randint(2, 10)
524 nb = random.randint(2, 10)
525 bb = bc * nb
526 nx = bb * na
527
528 kv = dict()
529 kv["stepAB"] = f"\\div{na}"
530 kv["stepABrev"] = f"\\times{na}"
531 kv["stepBC"] = f"\\div{nb}"
532 kv["stepBCrev"] = f"\\times{nb}"
533 kv["boxA"] = f"x"
534 kv["boxB"] = f"\\frac{{x}}{{{na}}}"
535 kv["boxC"] = f"\\frac{{x}}{{{na * nb}}}"
536 kv["boxCrev"] = f"{bc}"
537 kv["boxBrev"] = f"{bb}"
538 kv["boxArev"] = f"{nx}"
539 return kv
3.3. 1-step invop: LaTeXο
1\refstepcounter{minipagecount} % increments the counter minipagecount by one.
2\noindent{(\theminipagecount)}\hspace{0.1mm} % By default, LaTeX indents the first line of a new paragraph, but \noindent overrides this
3% and inserts the current value of the minipagecount counter, enclosed in parentheses
4\begin{minipage}[t]{0.45\textwidth} % The [t] option aligns the top of the minipage with the baseline of the surrounding text.
5 \vspace{-26pt} % moves the content of the minipage up, reducing the space between the minipage content and the preceding text.
6 \raggedright % the text lines up on the left side, but the right side will be ragged.
7 \begin{align*} % The * align environment does not number the equations- Each line is aligned at the & symbol
8 <<line1_LHS>> &= <<line1_RHS>>\\
9 <<line2_LHS>> &= <<line2_RHS>>\\
10 <<line3_LHS>> &= <<line3_RHS>>\\
11 \end{align*}
12\end{minipage}
1\documentclass[12pt]{article}
2\usepackage{tikz}
3\usepackage{amsmath}
4% Underlining package
5\usepackage[normalem]{ulem} % [normalem] prevents the package from changing the default behavior of \emph to underline.
6\usepackage[a4paper, portrait, margin=1cm]{geometry}
7\usepackage{multicol}
8\usepackage{fancyhdr}
9
10\def \HeadingQuestions {\section*{\Large Name: \underline{\hspace{8cm}} \hfill Date: \underline{\hspace{3cm}}} \vspace{-3mm}
11{Inverse operations: Questions} \vspace{1pt}\hrule}
12
13% only in Q due to increased line height with dotted underline
14\linespread{0.9} % Adjust line spacing factor to 0.9 if needed to fit 5 in column for 2 div steps
15
16% raise footer with page number; no header
17\fancypagestyle{myfancypagestyle}{
18 \fancyhf{}% clear all header and footer fields
19 \renewcommand{\headrulewidth}{0pt} % no rule under header
20 \fancyfoot[C] {\thepage} \setlength{\footskip}{14.5pt} % raise page number allowed min 14.5pt
21}
22\pagestyle{myfancypagestyle} % apply myfancypagestyle
23\newcounter{minipagecount}
24\begin{document}
25\HeadingQuestions
26\vspace{8mm}
27\begin{multicols}{2}
28<<diagrams>>
29\end{multicols}
30\end{document}
1\documentclass[12pt]{article}
2\usepackage{tikz}
3\usepackage{amsmath}
4% Underlining package
5\usepackage[normalem]{ulem} % [normalem] prevents the package from changing the default behavior of `\\emph` to underline.
6\usepackage[a4paper, portrait, margin=1cm]{geometry}
7\usepackage{multicol}
8\usepackage{fancyhdr}
9
10\def \HeadingAnswers {\section*{\Large Name: \underline{\hspace{8cm}} \hfill Date: \underline{\hspace{3cm}}} \vspace{-3mm}
11{Inverse operations: Answers} \vspace{1pt}\hrule}
12
13% raise footer with page number; no header
14\fancypagestyle{myfancypagestyle}{
15 \fancyhf{}% clear all header and footer fields
16 \renewcommand{\headrulewidth}{0pt} % no rule under header
17 \fancyfoot[C] {\thepage} \setlength{\footskip}{14.5pt} % raise page number allowed min 14.5pt
18}
19\pagestyle{myfancypagestyle} % apply myfancypagestyle
20\newcounter{minipagecount}
21\begin{document}
22\HeadingAnswers
23\vspace{8mm}
24\begin{multicols}{2}
25 <<diagrams>>
26\end{multicols}
27\end{document}