3. Check solutions to equations: 1 step booklet pythonο
The python file to make 1-step check solutions booklets is below.
The required LaTeX files are below.
The python file, check_solution_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 100:
"Enter the number of questions from 1 to 100; with 10 per page"Choose the file name base:
"Enter the base filename to be added to the prefix check_solution_Bk_:".The filename will have β_qβ added for the question diagram and β_ansβ for the answer diagram.
num1 = input(βEnter 1, 2, 3, 4 or 5 for +, -, X, /, random nβ)
3.1. Sample check solution bookletο
3.2. Check solution: pythonο
1from pathlib import Path
2import subprocess
3import os
4import time
5# import magick_pdf_to_png
6import check_solution_functions as chsolf
7
8currfile_dir = Path(__file__).parent
9tex_template_path = currfile_dir / "check_solution_booklet_template.tex"
10texans_template_path = currfile_dir / "check_solution_booklet_ans_template.tex"
11tex_diagram_template_path = currfile_dir / "check_solution_booklet_diagram_template.tex"
12
13q_per_column = 5
14q_per_page = q_per_column * 2
15max_q = 100
16
17
18def convert_to_pdf(tex_path, outputdir):
19 tex_path = Path(tex_path).resolve()
20 outputdir = Path(outputdir).resolve()
21 # for testing
22 # print(f"tex_path: {tex_path}")
23 # print(f"outputdir: {outputdir}")
24 try:
25 # Generate the PDF
26 subprocess.run(["latexmk", "-pdf", "-outdir=" + str(outputdir), str(tex_path)], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
27 # # Clean auxiliary files after successful PDF generation
28 subprocess.run(["latexmk", "-c", "-outdir=" + str(outputdir), str(tex_path)], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
29 # for hosted remove stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL for debugging any errors
30 # Remove the .tex file manually
31 if tex_path.exists():
32 os.remove(tex_path)
33 except subprocess.CalledProcessError as e:
34 print(f"Error: {e}")
35
36
37# % end modify values for check_solution
38# tex_keys = []
39tex_keys_q = ["LHS", "LHSsub", "LHSval", "RHS", "side_equality", "is_a_sol"]
40
41
42def make1_diagram(
43 tex_diagram_template_txt,
44 num1,
45):
46 tex_diagram_template_txt_ans = tex_diagram_template_txt
47 kv = chsolf.get_1step_process_dict(num1)
48 for key, value in kv.items():
49 tex_diagram_template_txt_ans = tex_diagram_template_txt_ans.replace("<<" + key + ">>", value)
50 for key, value in kv.items():
51 if key not in tex_keys_q:
52 tex_diagram_template_txt = tex_diagram_template_txt.replace("<<" + key + ">>", value)
53 else:
54 tex_diagram_template_txt = tex_diagram_template_txt.replace("<<" + key + ">>", kv[f"{key}q"])
55 return tex_diagram_template_txt, tex_diagram_template_txt_ans
56
57
58def main():
59 num1 = input("Enter 1, 2, 3, 4 or 5 for +, -, X, /, random \n")
60 if num1.strip().isdigit():
61 num1 = int(num1)
62 if not num1 in [1, 2, 3, 4, 5]:
63 num1 = 5 # random by default
64 else:
65 num1 = 5 # random by default
66 #
67 numq = input("Enter the number of questions from 1 to 100; with 10 per page \n")
68 if numq.strip().isdigit():
69 numq = int(numq)
70 if not numq in range(1, max_q + 1):
71 numq = max_q # max
72 else:
73 numq = q_per_page # by default fits on one page
74 #
75 filename = input("Enter the base filename to be added to the prefix check_solution_Bk_: \n")
76 if not filename:
77 filename = "1" # "check_solution_Bk_1_q and check_solution_Bk_1_ans as default file"
78 # set names of files that are made
79 # questions
80 tex_output_path = currfile_dir / f"check_solution_Bk_{filename}_q.tex"
81 pdf_path = currfile_dir / f"check_solution_Bk_{filename}_q.pdf"
82
83 # answers
84 tex_output_path_ans = currfile_dir / f"check_solution_Bk_{filename}_ans.tex"
85 pdf_path_ans = currfile_dir / f"check_solution_Bk_{filename}_ans.pdf"
86
87 # Read in the LaTeX template file
88 with open(tex_template_path, "r") as infile:
89 tex_template_txt = infile.read()
90 # Read in the LaTeX template file for answers
91 with open(texans_template_path, "r") as infile:
92 tex_template_txt_ans = infile.read()
93 # Read in the LaTeX diagram template file
94 with open(tex_diagram_template_path, "r") as infile:
95 tex_diagram_template_txt = infile.read()
96
97 # Generate the <<diagram>> replacement tex
98 # diagram_text, diagram_text_ans = make1_diagram(tex_diagram_template_txt, num1)
99
100 # <<diagrams>>
101 # generate diagrams text and text for answers
102 diagrams_text = ""
103 diagrams_text_ans = ""
104 # add the headtext
105 # must have no space in \end{minipage}\columnbreak for column break to occur at correct place.
106 headtext_col = r"""\columnbreak
107 """
108 headtext_page = r"""\newpage
109 """
110 # headtext_page = r'''\newpage ~ \newline ~ \newline# '''
111
112 for i in range(1, numq + 1):
113 img_tex, img_tex_ans = make1_diagram(tex_diagram_template_txt, num1)
114 diagrams_text += img_tex
115 diagrams_text_ans += img_tex_ans
116 if i % q_per_page == 0 and numq + 1 > i:
117 diagrams_text += headtext_page
118 diagrams_text_ans += headtext_page
119 elif i % q_per_column == 0 and i > 1 and numq + 1 > i:
120 diagrams_text += headtext_col
121 diagrams_text_ans += headtext_col
122
123 # Replace the <<diagrams>> placeholder in the LaTeX template
124 tex_template_txt = tex_template_txt.replace("<<diagrams>>", diagrams_text)
125 tex_template_txt_ans = tex_template_txt_ans.replace("<<diagrams>>", diagrams_text_ans)
126 # Replace the <<chsol_filename>> placeholder in the LaTeX template
127 tex_template_txt = tex_template_txt.replace("<<chsol_filename>>", filename)
128 tex_template_txt_ans = tex_template_txt_ans.replace("<<chsol_filename>>", filename)
129
130
131 # Write the question diagrams tex to an output file
132 with open(tex_output_path, "w") as outfile:
133 outfile.write(tex_template_txt)
134 # Write the answer diagrams tex to an output file
135 with open(tex_output_path_ans, "w") as outfile:
136 outfile.write(tex_template_txt_ans)
137
138 # Wait for the files to be created
139 time.sleep(1)
140 # convert to pdf
141 convert_to_pdf(tex_output_path, currfile_dir)
142 convert_to_pdf(tex_output_path_ans, currfile_dir)
143
144 # Wait for the files to be created
145 # time.sleep(1)
146 # convert to png
147 # magick_pdf_to_png.convert_pdf_to_png(pdf_path, png_path)
148 # magick_pdf_to_png.convert_pdf_to_png(pdf_path_ans, png_path_ans)
149
150
151if __name__ == "__main__":
152 print("starting")
153 main()
154 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"""
5
6import random
7
8
9def get_offset():
10 off_numbers = [-3, -2, -1, 1, 2, 3]
11 return random.choice(off_numbers)
12
13
14def get_1step_process_dict(num):
15 if num is None or num == 5:
16 num = random.randint(1, 4)
17 match num:
18 case 1:
19 return add_dict()
20 case 2:
21 return sub_dict()
22 case 3:
23 return times_dict()
24 case 4:
25 return div_dict()
26
27
28def add_dict():
29 # x + nx = na
30 # xsol = x; xval is test val
31 nx = random.randint(1, 10)
32 na = random.randint(1, 10)
33 xsol = na - nx
34 #
35 kv = dict()
36 if random.randint(1, 10) > 6:
37 xval = xsol + get_offset()
38 kv["side_equality"] = r"\neq"
39 kv["is_a_sol"] = "is not "
40 else:
41 xval = xsol
42 kv["side_equality"] = "="
43 kv["is_a_sol"] = "is "
44 #
45 kv["pro_value"] = f"x = {xval}"
46 kv["equation"] = f"x + {nx} = {na}"
47 kv["LHS"] = f"x + {nx}"
48 kv["LHSsub"] = f"{xval} + {nx}"
49 kv["LHSval"] = f"{xval + nx} "
50 kv["LHSq"] = f""
51 kv["LHSsubq"] = f""
52 kv["LHSvalq"] = f""
53 kv["RHS"] = f"{na}"
54 kv["RHSq"] = f""
55 kv["side_equalityq"] = r"\dotuline{\hspace{5mm}}"
56 kv["is_a_solq"] = r"\dotuline{\hspace{12mm}}"
57 return kv
58
59
60"""
61kv["pro_value"] x=4
62kv["equation"] x + 5 = 9
63kv["LHS"]
64kv["LHSsub"]
65kv["LHSval"]
66
67kv["side_equality"]
68kv["is_a_sol"]
69"""
70
71
72def sub_dict():
73 # x - nx = na
74 # xsol = x; xval is test val
75 nx = random.randint(1, 10)
76 na = random.randint(1, 10)
77 xsol = na + nx
78 #
79 kv = dict()
80 if random.randint(1, 10) > 6:
81 xval = xsol + get_offset()
82 kv["side_equality"] = r"\neq"
83 kv["is_a_sol"] = "is not "
84 else:
85 xval = xsol
86 kv["side_equality"] = "="
87 kv["is_a_sol"] = "is "
88 #
89 kv["pro_value"] = f"x = {xval}"
90 kv["equation"] = f"x - {nx} = {na}"
91 kv["LHS"] = f"x - {nx}"
92 kv["LHSsub"] = f"{xval} - {nx}"
93 kv["LHSval"] = f"{xval - nx} "
94 kv["LHSq"] = f""
95 kv["LHSsubq"] = f""
96 kv["LHSvalq"] = f""
97 kv["RHS"] = f"{na}"
98 kv["RHSq"] = f""
99 kv["side_equalityq"] = r"\dotuline{\hspace{5mm}}"
100 kv["is_a_solq"] = r"\dotuline{\hspace{12mm}}"
101 return kv
102
103
104def times_dict():
105 # xsol = x; xval is test val
106 # x * nx = na
107 nx = random.randint(2, 10)
108 xsol = random.randint(2, 10)
109 na = xsol * nx
110 #
111 kv = dict()
112 if random.randint(1, 10) > 6:
113 xval = xsol + get_offset()
114 kv["side_equality"] = r"\neq"
115 kv["is_a_sol"] = "is not "
116 else:
117 xval = xsol
118 kv["side_equality"] = "="
119 kv["is_a_sol"] = "is "
120 #
121 kv["pro_value"] = f"x = {xval}"
122 kv["equation"] = f"{nx}x = {na}"
123 kv["LHS"] = f"{nx}x"
124 kv["LHSsub"] = f"{nx} \\times{xval}"
125 kv["LHSval"] = f"{nx * xval} "
126 kv["LHSq"] = f""
127 kv["LHSsubq"] = f""
128 kv["LHSvalq"] = f""
129 kv["RHS"] = f"{na}"
130 kv["RHSq"] = f""
131 kv["side_equalityq"] = r"\dotuline{\hspace{5mm}}"
132 kv["is_a_solq"] = r"\dotuline{\hspace{12mm}}"
133 return kv
134
135
136def div_dict():
137 # xsol = x; xval is test val
138 # x / nx = na
139 nx = random.randint(2, 10)
140 na = random.randint(2, 10)
141 xsol = na * nx
142 #
143 kv = dict()
144 if random.randint(1, 10) > 6:
145 # offset a multiple such that
146 xval = xsol + (get_offset() * nx)
147 kv["side_equality"] = r"\neq"
148 kv["is_a_sol"] = "is not "
149 if xval % nx == 0:
150 xval_div_nx = int(xval / nx)
151 else:
152 xval_div_nx = round(xval / nx, 3)
153 kv["LHSval"] = f"{xval_div_nx}"
154 else:
155 xval = xsol
156 kv["side_equality"] = "="
157 kv["is_a_sol"] = "is "
158 kv["LHSval"] = f"{na}" # to avoid ".0" for float
159 #
160 kv["pro_value"] = f"x = {xval}"
161 kv["equation"] = f"\\frac{{x}}{{{nx}}} = {na}"
162 kv["LHS"] = f"\\frac{{x}}{{{nx}}}"
163 kv["LHSsub"] = f"\\frac{{{xval}}}{{{nx}}}"
164 # kv["LHSval"] = f"{xval / nx}" # see above
165 kv["LHSq"] = f""
166 kv["LHSsubq"] = f""
167 kv["LHSvalq"] = f""
168 kv["RHS"] = f"{na}"
169 kv["RHSq"] = f""
170 kv["side_equalityq"] = r"\dotuline{\hspace{5mm}}"
171 kv["is_a_solq"] = r"\dotuline{\hspace{12mm}}"
172 return kv
173
174
175# ############################################
176
177
178def val_in_list_exclude(low, high, exclude):
179 # random 2 step: avoid xx, x/, /x, //, ++, --, +-, -+
180 vals = list(range(low, high + 1))
181 if exclude in vals:
182 if exclude in [1, 2]:
183 vals.remove(1)
184 vals.remove(2)
185 elif exclude in [3, 4]:
186 vals.remove(3)
187 vals.remove(4)
188 return random.choice(vals)
189
190
191def get_2step_process_dict(num1, num2):
192 if num1 is None or num1 == 5:
193 num1 = random.randint(1, 4)
194 if num2 is None or num2 == 5:
195 num2 = random.randint(1, 4)
196 # num2 = val_in_list_exclude(1, 4, num1)
197 processes = (num1, num2)
198 # processes = (3,3)
199 match processes:
200 case (1, 1):
201 return add_add_dict()
202 case (1, 2):
203 return add_sub_dict()
204 case (1, 3):
205 return add_times_dict()
206 case (1, 4):
207 return add_div_dict()
208 case (2, 1):
209 return sub_add_dict()
210 case (2, 2):
211 return sub_sub_dict()
212 case (2, 3):
213 return sub_times_dict()
214 case (2, 4):
215 return sub_div_dict()
216 case (3, 1):
217 return times_add_dict()
218 case (3, 2):
219 return times_sub_dict()
220 case (3, 3):
221 return times_times_dict()
222 case (3, 4):
223 return times_div_dict()
224 case (4, 1):
225 return div_add_dict()
226 case (4, 2):
227 return div_sub_dict()
228 case (4, 3):
229 return div_times_dict()
230 case (4, 4):
231 return div_div_dict()
232 case _:
233 return add_add_dict()
234
235
236def add_add_dict():
237 # x + nx + mx = na
238 # xsol = x; xval is test val
239 nx = random.randint(1, 10)
240 mx = random.randint(1, 10)
241 na = random.randint(1, 10)
242 xsol = na - nx - mx
243 #
244 kv = dict()
245 if random.randint(1, 10) > 6:
246 xval = xsol + get_offset()
247 kv["side_equality"] = r"\neq"
248 kv["is_a_sol"] = "is not "
249 else:
250 xval = xsol
251 kv["side_equality"] = "="
252 kv["is_a_sol"] = "is "
253 #
254 kv["pro_value"] = f"x = {xval}"
255 kv["equation"] = f"x + {nx} + {mx} = {na}"
256 kv["LHS"] = f"x + {nx} + {mx}"
257 kv["LHSsub"] = f"{xval} + {nx} + {mx}"
258 kv["LHSval"] = f"{xval + nx + mx} "
259 kv["LHSq"] = f""
260 kv["LHSsubq"] = f""
261 kv["LHSvalq"] = f""
262 kv["RHS"] = f"{na}"
263 kv["RHSq"] = f""
264 kv["side_equalityq"] = r"\dotuline{\hspace{5mm}}"
265 kv["is_a_solq"] = r"\dotuline{\hspace{12mm}}"
266 return kv
267
268
269def add_sub_dict():
270 # bc = nx + na - nb
271 nx = random.randint(1, 10)
272 na = random.randint(1, 10)
273 bb = nx + na
274 if bb > 10:
275 nb = random.randint(1, 10)
276 else:
277 nb = random.randint(1, bb)
278 bc = bb - nb
279
280 # x + nx - mx = na
281 # xsol = x; xval is test val
282 nx = random.randint(1, 10)
283 mx = random.randint(1, 10)
284 na = random.randint(1, 10)
285 xsol = na - nx + mx
286 #
287 kv = dict()
288 if random.randint(1, 10) > 6:
289 xval = xsol + get_offset()
290 kv["side_equality"] = r"\neq"
291 kv["is_a_sol"] = "is not "
292 else:
293 xval = xsol
294 kv["side_equality"] = "="
295 kv["is_a_sol"] = "is "
296 #
297 kv["pro_value"] = f"x = {xval}"
298 kv["equation"] = f"x + {nx} - {mx} = {na}"
299 kv["LHS"] = f"x + {nx} - {mx}"
300 kv["LHSsub"] = f"{xval} + {nx} - {mx}"
301 kv["LHSval"] = f"{xval + nx - mx} "
302 kv["LHSq"] = f""
303 kv["LHSsubq"] = f""
304 kv["LHSvalq"] = f""
305 kv["RHS"] = f"{na}"
306 kv["RHSq"] = f""
307 kv["side_equalityq"] = r"\dotuline{\hspace{5mm}}"
308 kv["is_a_solq"] = r"\dotuline{\hspace{12mm}}"
309 return kv
310
311
312def add_times_dict():
313 # xsol = x; xval is test val
314 # mx * (x + nx) = na
315 nx = random.randint(1, 10)
316 mx = random.randint(2, 10)
317 xsol = random.randint(1, 10)
318 na = mx * (xsol + nx)
319 #
320 kv = dict()
321 if random.randint(1, 10) > 6:
322 xval = xsol + get_offset()
323 kv["side_equality"] = r"\neq"
324 kv["is_a_sol"] = "is not "
325 else:
326 xval = xsol
327 kv["side_equality"] = "="
328 kv["is_a_sol"] = "is "
329 #
330 kv["pro_value"] = f"x = {xval}"
331 kv["equation"] = f"{mx}(x + {nx}) = {na}"
332 kv["LHS"] = f"{mx}(x + {nx})"
333 kv["LHSsub"] = f"{mx} \\times({xval} + {nx})"
334 kv["LHSval"] = f"{mx * (xval + nx)} "
335 kv["LHSq"] = f""
336 kv["LHSsubq"] = f""
337 kv["LHSvalq"] = f""
338 kv["RHS"] = f"{na}"
339 kv["RHSq"] = f""
340 kv["side_equalityq"] = r"\dotuline{\hspace{5mm}}"
341 kv["is_a_solq"] = r"\dotuline{\hspace{12mm}}"
342 return kv
343
344
345def add_div_dict():
346 # xsol = x; xval is test val
347 # (x + nx)/mx = na
348 nx = random.randint(1, 10)
349 mx = random.randint(2, 10)
350 na = random.randint(1, 10)
351 xsol = (na * mx) - nx
352 #
353 kv = dict()
354 if random.randint(1, 10) > 6:
355 xval = xsol + (get_offset() * mx)
356 kv["side_equality"] = r"\neq"
357 kv["is_a_sol"] = "is not "
358 else:
359 xval = xsol
360 kv["side_equality"] = "="
361 kv["is_a_sol"] = "is "
362 #
363 kv["pro_value"] = f"x = {xval}"
364 kv["equation"] = f"\\frac{{x + {nx}}}{{{mx}}} = {na}"
365 kv["LHS"] = f"\\frac{{x + {nx}}}{{{mx}}}"
366 kv["LHSsub"] = f"\\frac{{{xval} + {nx}}}{{{mx}}}"
367 kv["LHSval"] = f"{(xval + nx) / mx}"
368
369 kv["LHSq"] = f""
370 kv["LHSsubq"] = f""
371 kv["LHSvalq"] = f""
372 kv["RHS"] = f"{na}"
373 kv["RHSq"] = f""
374 kv["side_equalityq"] = r"\dotuline{\hspace{5mm}}"
375 kv["is_a_solq"] = r"\dotuline{\hspace{12mm}}"
376 return kv
377
378
379def sub_add_dict():
380 # x - nx + mx = na
381 # xsol = x; xval is test val
382 nx = random.randint(1, 10)
383 mx = random.randint(1, 10)
384 na = random.randint(1, 10)
385 xsol = na + nx - mx
386 #
387 kv = dict()
388 if random.randint(1, 10) > 6:
389 xval = xsol + get_offset()
390 kv["side_equality"] = r"\neq"
391 kv["is_a_sol"] = "is not "
392 else:
393 xval = xsol
394 kv["side_equality"] = "="
395 kv["is_a_sol"] = "is "
396 #
397 kv["pro_value"] = f"x = {xval}"
398 kv["equation"] = f"x - {nx} + {mx} = {na}"
399 kv["LHS"] = f"x - {nx} + {mx}"
400 kv["LHSsub"] = f"{xval} - {nx} + {mx}"
401 kv["LHSval"] = f"{xval - nx + mx} "
402 kv["LHSq"] = f""
403 kv["LHSsubq"] = f""
404 kv["LHSvalq"] = f""
405 kv["RHS"] = f"{na}"
406 kv["RHSq"] = f""
407 kv["side_equalityq"] = r"\dotuline{\hspace{5mm}}"
408 kv["is_a_solq"] = r"\dotuline{\hspace{12mm}}"
409 return kv
410
411
412def sub_sub_dict():
413 # x - nx - mx = na
414 # xsol = x; xval is test val
415 nx = random.randint(1, 10)
416 mx = random.randint(1, 10)
417 na = random.randint(1, 10)
418 xsol = na + nx + mx
419 #
420 kv = dict()
421 if random.randint(1, 10) > 6:
422 xval = xsol + get_offset()
423 kv["side_equality"] = r"\neq"
424 kv["is_a_sol"] = "is not "
425 else:
426 xval = xsol
427 kv["side_equality"] = "="
428 kv["is_a_sol"] = "is "
429 #
430 kv["pro_value"] = f"x = {xval}"
431 kv["equation"] = f"x - {nx} - {mx} = {na}"
432 kv["LHS"] = f"x + {nx} - {mx}"
433 kv["LHSsub"] = f"{xval} - {nx} - {mx}"
434 kv["LHSval"] = f"{xval - nx - mx} "
435 kv["LHSq"] = f""
436 kv["LHSsubq"] = f""
437 kv["LHSvalq"] = f""
438 kv["RHS"] = f"{na}"
439 kv["RHSq"] = f""
440 kv["side_equalityq"] = r"\dotuline{\hspace{5mm}}"
441 kv["is_a_solq"] = r"\dotuline{\hspace{12mm}}"
442 return kv
443
444
445def sub_times_dict():
446 # xsol = x; xval is test val
447 # mx * (x - nx) = na
448 nx = random.randint(1, 10)
449 mx = random.randint(2, 10)
450 xsol = random.randint(1, 10)
451 na = mx * (xsol - nx)
452 #
453 kv = dict()
454 if random.randint(1, 10) > 6:
455 xval = xsol + get_offset()
456 kv["side_equality"] = r"\neq"
457 kv["is_a_sol"] = "is not "
458 else:
459 xval = xsol
460 kv["side_equality"] = "="
461 kv["is_a_sol"] = "is "
462 #
463 kv["pro_value"] = f"x = {xval}"
464 kv["equation"] = f"{mx}(x - {nx}) = {na}"
465 kv["LHS"] = f"{mx}(x - {nx})"
466 kv["LHSsub"] = f"{mx} \\times({xval} - {nx})"
467 kv["LHSval"] = f"{mx * (xval - nx)} "
468 kv["LHSq"] = f""
469 kv["LHSsubq"] = f""
470 kv["LHSvalq"] = f""
471 kv["RHS"] = f"{na}"
472 kv["RHSq"] = f""
473 kv["side_equalityq"] = r"\dotuline{\hspace{5mm}}"
474 kv["is_a_solq"] = r"\dotuline{\hspace{12mm}}"
475 return kv
476
477
478def sub_div_dict():
479 # xsol = x; xval is test val
480 # (x - nx)/mx = na
481 nx = random.randint(1, 10)
482 mx = random.randint(2, 10)
483 na = random.randint(1, 10)
484 xsol = (na * mx) + nx
485 #
486 kv = dict()
487 if random.randint(1, 10) > 6:
488 xval = xsol + (get_offset() * mx)
489 kv["side_equality"] = r"\neq"
490 kv["is_a_sol"] = "is not "
491 else:
492 xval = xsol
493 kv["side_equality"] = "="
494 kv["is_a_sol"] = "is "
495 #
496 kv["pro_value"] = f"x = {xval}"
497 kv["equation"] = f"\\frac{{x - {nx}}}{{{mx}}} = {na}"
498 kv["LHS"] = f"\\frac{{x - {nx}}}{{{mx}}}"
499 kv["LHSsub"] = f"\\frac{{{xval} - {nx}}}{{{mx}}}"
500 kv["LHSval"] = f"{(xval - nx) / mx}"
501
502 kv["LHSq"] = f""
503 kv["LHSsubq"] = f""
504 kv["LHSvalq"] = f""
505 kv["RHS"] = f"{na}"
506 kv["RHSq"] = f""
507 kv["side_equalityq"] = r"\dotuline{\hspace{5mm}}"
508 kv["is_a_solq"] = r"\dotuline{\hspace{12mm}}"
509 return kv
510
511
512def times_add_dict():
513 # xsol = x; xval is test val
514 # (x * nx) + mx = na
515 nx = random.randint(2, 10)
516 mx = random.randint(1, 10)
517 xsol = random.randint(1, 10)
518 na = (xsol * nx) + mx
519 #
520 kv = dict()
521 if random.randint(1, 10) > 6:
522 xval = xsol + get_offset()
523 kv["side_equality"] = r"\neq"
524 kv["is_a_sol"] = "is not "
525 else:
526 xval = xsol
527 kv["side_equality"] = "="
528 kv["is_a_sol"] = "is "
529 #
530 kv["pro_value"] = f"x = {xval}"
531 kv["equation"] = f"{nx}x + {mx} = {na}"
532 kv["LHS"] = f"{nx}x + {mx}"
533 kv["LHSsub"] = f"{nx} \\times{xval} + {mx}"
534 kv["LHSval"] = f"{(xval * nx) + mx } "
535 kv["LHSq"] = f""
536 kv["LHSsubq"] = f""
537 kv["LHSvalq"] = f""
538 kv["RHS"] = f"{na}"
539 kv["RHSq"] = f""
540 kv["side_equalityq"] = r"\dotuline{\hspace{5mm}}"
541 kv["is_a_solq"] = r"\dotuline{\hspace{12mm}}"
542 return kv
543
544
545def times_sub_dict():
546 # xsol = x; xval is test val
547 # (x * nx) - mx = na
548 nx = random.randint(2, 10)
549 mx = random.randint(1, 10)
550 xsol = random.randint(1, 10)
551 na = (xsol * nx) - mx
552 #
553 kv = dict()
554 if random.randint(1, 10) > 6:
555 xval = xsol + get_offset()
556 kv["side_equality"] = r"\neq"
557 kv["is_a_sol"] = "is not "
558 else:
559 xval = xsol
560 kv["side_equality"] = "="
561 kv["is_a_sol"] = "is "
562 #
563 kv["pro_value"] = f"x = {xval}"
564 kv["equation"] = f"{nx}x - {mx} = {na}"
565 kv["LHS"] = f"{nx}x - {mx}"
566 kv["LHSsub"] = f"{nx} \\times{xval} - {mx}"
567 kv["LHSval"] = f"{(xval * nx) - mx } "
568 kv["LHSq"] = f""
569 kv["LHSsubq"] = f""
570 kv["LHSvalq"] = f""
571 kv["RHS"] = f"{na}"
572 kv["RHSq"] = f""
573 kv["side_equalityq"] = r"\dotuline{\hspace{5mm}}"
574 kv["is_a_solq"] = r"\dotuline{\hspace{12mm}}"
575 return kv
576
577
578def times_times_dict():
579 # xsol = x; xval is test val
580 # x * nx * mx = na
581 nx = random.randint(2, 10)
582 mx = random.randint(2, 10)
583 xsol = random.randint(1, 10)
584 na = xsol * nx * mx
585 #
586 kv = dict()
587 if random.randint(1, 10) > 6:
588 xval = xsol + get_offset()
589 kv["side_equality"] = r"\neq"
590 kv["is_a_sol"] = "is not "
591 else:
592 xval = xsol
593 kv["side_equality"] = "="
594 kv["is_a_sol"] = "is "
595 #
596 kv["pro_value"] = f"x = {xval}"
597 kv["equation"] = f"{nx}x \\times {mx} = {na}"
598 kv["LHS"] = f"{nx}x \\times {mx}"
599 kv["LHSsub"] = f"{nx} \\times{xval} \\times {mx}"
600 kv["LHSval"] = f"{xval * nx * mx } "
601 kv["LHSq"] = f""
602 kv["LHSsubq"] = f""
603 kv["LHSvalq"] = f""
604 kv["RHS"] = f"{na}"
605 kv["RHSq"] = f""
606 kv["side_equalityq"] = r"\dotuline{\hspace{5mm}}"
607 kv["is_a_solq"] = r"\dotuline{\hspace{12mm}}"
608 return kv
609
610
611def times_div_dict():
612 # xsol = x; xval is test val
613 # (x * nx)/mx = na
614 nx = random.randint(2, 10)
615 xsol = random.randint(2, 10)
616 mx_candidates = [i for i in range(2, 11) if (xsol * nx) % i == 0]
617 mx = random.choice(mx_candidates)
618 na = (xsol * nx) // mx
619 #
620 kv = dict()
621 if random.randint(1, 10) > 6:
622 xval = xsol + (get_offset() * mx)
623 kv["side_equality"] = r"\neq"
624 kv["is_a_sol"] = "is not "
625 else:
626 xval = xsol
627 kv["side_equality"] = "="
628 kv["is_a_sol"] = "is "
629 #
630 kv["pro_value"] = f"x = {xval}"
631 kv["equation"] = f"\\frac{{{nx}x}}{{{mx}}} = {na}"
632 kv["LHS"] = f"\\frac{{{nx}x}}{{{mx}}}"
633 kv["LHSsub"] = f"\\frac{{{nx} \\times{xval}}}{{{mx}}}"
634 kv["LHSval"] = f"{(xval * nx) / mx}"
635
636 kv["LHSq"] = f""
637 kv["LHSsubq"] = f""
638 kv["LHSvalq"] = f""
639 kv["RHS"] = f"{na}"
640 kv["RHSq"] = f""
641 kv["side_equalityq"] = r"\dotuline{\hspace{5mm}}"
642 kv["is_a_solq"] = r"\dotuline{\hspace{12mm}}"
643 return kv
644
645
646def div_add_dict():
647 # xsol = x; xval is test val
648 # x/nx + mx = na
649 nx = random.randint(2, 10)
650 mx = random.randint(1, 10)
651 na = random.randint(1, 10)
652 xsol = (na - mx) * nx
653 #
654 kv = dict()
655 if random.randint(1, 10) > 6:
656 xval = xsol + (get_offset() * nx)
657 kv["side_equality"] = r"\neq"
658 kv["is_a_sol"] = "is not "
659 else:
660 xval = xsol
661 kv["side_equality"] = "="
662 kv["is_a_sol"] = "is "
663 #
664 kv["pro_value"] = f"x = {xval}"
665 kv["equation"] = f"\\frac{{x}}{{{nx}}} + {mx} = {na}"
666 kv["LHS"] = f"\\frac{{x}}{{{nx}}} + {mx}"
667 kv["LHSsub"] = f"\\frac{{{xval}}}{{{nx}}} + {mx}"
668 kv["LHSval"] = f"{(xval // nx) + mx}"
669
670 kv["LHSq"] = f""
671 kv["LHSsubq"] = f""
672 kv["LHSvalq"] = f""
673 kv["RHS"] = f"{na}"
674 kv["RHSq"] = f""
675 kv["side_equalityq"] = r"\dotuline{\hspace{5mm}}"
676 kv["is_a_solq"] = r"\dotuline{\hspace{12mm}}"
677 return kv
678
679
680def div_sub_dict():
681 # xsol = x; xval is test val
682 # x/nx - mx = na
683 nx = random.randint(2, 10)
684 mx = random.randint(1, 10)
685 na = random.randint(1, 10)
686 xsol = (na + mx) * nx
687 #
688 kv = dict()
689 if random.randint(1, 10) > 6:
690 xval = xsol + (get_offset() * nx)
691 kv["side_equality"] = r"\neq"
692 kv["is_a_sol"] = "is not "
693 else:
694 xval = xsol
695 kv["side_equality"] = "="
696 kv["is_a_sol"] = "is "
697 #
698 kv["pro_value"] = f"x = {xval}"
699 kv["equation"] = f"\\frac{{x}}{{{nx}}} - {mx} = {na}"
700 kv["LHS"] = f"\\frac{{x}}{{{nx}}} - {mx}"
701 kv["LHSsub"] = f"\\frac{{{xval}}}{{{nx}}} - {mx}"
702 kv["LHSval"] = f"{(xval // nx) - mx}"
703
704 kv["LHSq"] = f""
705 kv["LHSsubq"] = f""
706 kv["LHSvalq"] = f""
707 kv["RHS"] = f"{na}"
708 kv["RHSq"] = f""
709 kv["side_equalityq"] = r"\dotuline{\hspace{5mm}}"
710 kv["is_a_solq"] = r"\dotuline{\hspace{12mm}}"
711 return kv
712
713
714def div_times_dict():
715 # xsol = x; xval is test val
716 # (x / nx) * mx = na
717 mx = random.randint(2, 10)
718 xsol = random.randint(2, 10)
719 nx_candidates = [i for i in range(2, 11) if (xsol * mx) % i == 0]
720 nx = random.choice(nx_candidates)
721 na = (xsol * mx) // nx
722 #
723 kv = dict()
724 if random.randint(1, 10) > 6:
725 xval = xsol + (get_offset() * nx)
726 kv["side_equality"] = r"\neq"
727 kv["is_a_sol"] = "is not "
728 else:
729 xval = xsol
730 kv["side_equality"] = "="
731 kv["is_a_sol"] = "is "
732 #
733 kv["pro_value"] = f"x = {xval}"
734 kv["equation"] = f"\\frac{{x}}{{{nx}}} \\times {mx} = {na}"
735 kv["LHS"] = f"\\frac{{x}}{{{nx}}} \\times {mx}"
736 kv["LHSsub"] = f"\\frac{{{xval}}}{{{nx}}} \\times {mx}"
737 kv["LHSval"] = f"{(xval * mx) // nx}"
738
739 kv["LHSq"] = f""
740 kv["LHSsubq"] = f""
741 kv["LHSvalq"] = f""
742 kv["RHS"] = f"{na}"
743 kv["RHSq"] = f""
744 kv["side_equalityq"] = r"\dotuline{\hspace{5mm}}"
745 kv["is_a_solq"] = r"\dotuline{\hspace{12mm}}"
746 return kv
747
748
749def div_div_dict():
750 # bc = (nx / na) / nb
751 # escape {} in f strings by doubling them up {{}}
752 # xsol = x; xval is test val
753 # (x / nx) / mx = na
754 mx = random.randint(2, 7)
755 nx = random.randint(2, 7)
756 na = random.randint(2, 7)
757 xsol = na * mx * nx
758 #
759 kv = dict()
760 if random.randint(1, 10) > 6:
761 xval = xsol + (get_offset() * nx)
762 kv["side_equality"] = r"\neq"
763 kv["is_a_sol"] = "is not "
764 else:
765 xval = xsol
766 kv["side_equality"] = "="
767 kv["is_a_sol"] = "is "
768 #
769 kv["pro_value"] = f"x = {xval}"
770 kv["equation"] = f"\\frac{{x}}{{{nx}}} \\times \\frac{{1}}{{{mx}}} = {na}"
771 kv["LHS"] = f"\\frac{{x}}{{{nx}}} \\times \\frac{{1}}{{{mx}}}"
772 kv["LHSsub"] = f"\\frac{{{xval}}}{{{nx}}} \\times \\frac{{1}}{{{mx}}}"
773 kv["LHSval"] = f"{xval // (mx * nx)}"
774
775 kv["LHSq"] = f""
776 kv["LHSsubq"] = f""
777 kv["LHSvalq"] = f""
778 kv["RHS"] = f"{na}"
779 kv["RHSq"] = f""
780 kv["side_equalityq"] = r"\dotuline{\hspace{5mm}}"
781 kv["is_a_solq"] = r"\dotuline{\hspace{12mm}}"
782 return kv
3.3. Check solution: LaTeXο
1% \begin{enumerate}
2\refstepcounter{minipagecount} % increments the counter minipagecount by one.
3\noindent{(\theminipagecount)}\hspace{0.1mm} % By default, LaTeX indents the first line of a new paragraph, but \noindent overrides this
4% and inserts the current value of the minipagecount counter, enclosed in parentheses
5\begin{minipage}[t]{0.40\textwidth} % The [t] option aligns the top of the minipage with the baseline of the surrounding text.
6
7 \noindent Determine whether \(<<pro_value>>\) is a solution to the equation \(<<equation>>\):
8 \vspace{4pt} % Ensure spacing between problem statement and solution
9
10 \noindent
11 \renewcommand{\arraystretch}{1.3} % Adjust line spacing in the aligned environment
12 \begin{tabular}{@{}p{0.60\linewidth}@{}p{0.40\linewidth}@{}}
13 \(\begin{aligned}
14 \text{LHS} &= <<LHS>> \\
15 &= <<LHSsub>> \\
16 &= <<LHSval>>
17 \end{aligned}\) &
18 \(\begin{aligned}
19 \text{RHS} &= <<RHS>>\\
20 & \\
21 &
22 \end{aligned}\)
23 \end{tabular}
24 \renewcommand{\arraystretch}{1.0} % Adjust line spacing in the aligned environment
25 \vspace{2pt} % Optional spacing
26
27 \noindent \(\therefore\) Since \(\text{LHS} <<side_equality>> \text{RHS}\), \(<<pro_value>>\) <<is_a_sol>> a solution to the equation.
28
29\end{minipage}
30
31 \vspace*{16pt}
1\documentclass[12pt]{article}
2\usepackage{tikz}
3\usepackage{amssymb} % For \therefore symbol
4\usepackage{amsmath}
5% Underlining package
6\usepackage[normalem]{ulem} % [normalem] prevents the package from changing the default behavior of \emph to underline.
7\usepackage[a4paper, portrait, margin=1cm]{geometry}
8\usepackage{multicol}
9\usepackage{fancyhdr}
10\usepackage[none]{hyphenat}
11
12\def \HeadingQuestions {\section*{\Large Name: \underline{\hspace{8cm}} \hfill Date: \underline{\hspace{3cm}}} \vspace{-3mm}
13{<<chsol_filename>> Check Solution: Questions} \vspace{1pt}\hrule}
14
15% \linespread{1.5} % Adjust line spacing factor
16\raggedbottom
17
18% raise footer with page number; no header
19\fancypagestyle{myfancypagestyle}{
20 \fancyhf{}% clear all header and footer fields
21 \renewcommand{\headrulewidth}{0pt} % no rule under header
22 \fancyfoot[C] {\thepage} \setlength{\footskip}{14.5pt} % raise page number allowed min 14.5pt
23}
24\pagestyle{myfancypagestyle} % apply myfancypagestyle
25\newcounter{minipagecount}
26\begin{document}
27\HeadingQuestions
28\vspace{1pt}
29\begin{multicols}{2}
30<<diagrams>>
31\end{multicols}
32\end{document}
1\documentclass[12pt]{article}
2\usepackage{tikz}
3\usepackage{amssymb} % For \therefore symbol
4\usepackage{amsmath}
5% Underlining package
6\usepackage[normalem]{ulem} % [normalem] prevents the package from changing the default behavior of `\\emph` to underline.
7\usepackage[a4paper, portrait, margin=1cm]{geometry}
8\usepackage{multicol}
9\usepackage{fancyhdr}
10\usepackage[none]{hyphenat}
11
12\def \HeadingAnswers {\section*{\Large Name: \underline{\hspace{8cm}} \hfill Date: \underline{\hspace{3cm}}} \vspace{-3mm}
13{<<chsol_filename>> Check Solution: Answers} \vspace{1pt}\hrule}
14
15% \linespread{1.5} % Adjust line spacing factor
16\raggedbottom
17
18% raise footer with page number; no header
19\fancypagestyle{myfancypagestyle}{
20 \fancyhf{}% clear all header and footer fields
21 \renewcommand{\headrulewidth}{0pt} % no rule under header
22 \fancyfoot[C] {\thepage} \setlength{\footskip}{14.5pt} % raise page number allowed min 14.5pt
23}
24\pagestyle{myfancypagestyle} % apply myfancypagestyle
25\newcounter{minipagecount}
26\begin{document}
27\HeadingAnswers
28\vspace{1pt}
29\begin{multicols}{2}
30 <<diagrams>>
31\end{multicols}
32\end{document}