1. Coordinates


The custom python module required is:
 1"""
 2Module of functions to return diagram dictionary for LaTeX
 3"""
 4
 5import random
 6
 7
 8def get_coordinates_dict(num=None):
 9    coord_dict = get_points_dict(num)
10    coords_sections_dict = dict()
11    coords_sections_dict["points_to_list"] = format_latex_coordinates_for_listing(coord_dict)
12    coords_sections_dict["points_to_plot"] = format_latex_coordinates_for_plotting(coord_dict)
13    return coords_sections_dict
14
15
16
17def get_points_dict(num=None):
18    # limit to max of 20
19    if num is None or num > 20:
20        num = random.randint(5, 20)  # Randomly choose how many points to generate
21    coord_labels_list = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
22    coord_dict = {}
23    used_x_values = set()  # Track used x-values
24    used_y_values = set()  # Track used y-values
25    for i in range(num):
26        label = coord_labels_list[i]  # Get the next available letter
27        x, y = random_coordinate(used_x_values, used_y_values)  # Ensure unique values
28        coord_dict[label] = (x, y)
29    return coord_dict
30
31
32def random_coordinate(used_x_values, used_y_values):
33    while True:
34        x = random.randint(-10, 10)
35        y = random.randint(-10, 10)
36        # Check constraints
37        if y == -1:  # Avoid y = -1
38            continue
39        if y % 2 == 0 and (x == -1 or x == -2):  # Avoid x = 1 or -2 when y is even
40            continue
41        if y in used_y_values:  # Avoid reused y-values
42            continue
43        if x in used_x_values:  # Avoid reused x-values
44            continue
45
46        # If valid, mark x and y as used
47        used_x_values.add(x)
48        used_y_values.add(y)
49        break
50    return x, y
51
52
53def format_latex_coordinates_for_listing(coord_dict):
54    latex_str = r"\[" + "\n"
55    latex_str += r"\begin{array}{lllll}" + "\n"  # Define 5 columns
56    # Create list of formatted points
57    items = [f"{key}({x}, {y})" for key, (x, y) in coord_dict.items()]
58    # Split items into rows of 5 points
59    rows = [items[i : i + 5] for i in range(0, len(items), 5)]
60    # Add rows to LaTeX string with `\quad` spacing
61    for row in rows:
62        latex_str += " \quad & ".join(row) + r" \\" + "\n"
63    latex_str += r"\end{array}" + "\n"
64    latex_str += r"\]"
65    return latex_str
66
67
68
69def format_latex_coordinates_for_plotting(coord_dict):
70    latex_str = ""
71    for name, (x, y) in coord_dict.items():
72        latex_str += f"\\fill ({x},{y}) circle (4pt);\n"
73        latex_str += f"\\node[xshift=1.9em, yshift=7pt] at ({x},{y}) {{\\small {name}({x},{y})}};\n"
74    return latex_str
75
76# print(get_coordinates_dict(20)["points_to_plot"])
The Python to create booklets of questions involving coordinates, is below.
  1from pathlib import Path
  2import subprocess
  3import os
  4import time
  5
  6# import magick_pdf_to_png
  7import coordinates_functions as coordf
  8
  9currfile_dir = Path(__file__).parent
 10tex_template_path = currfile_dir / "coordinates_booklet_template.tex"
 11texans_template_path = currfile_dir / "coordinates_booklet_ans_template.tex"
 12tex_diagram_template_path = currfile_dir / "coordinates_booklet_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
 34kv_keys_q = ["points_to_list"]
 35kv_keys_ans = ["points_to_list", "points_to_plot"]
 36ky_keys_to_clear = ["points_to_plot"]
 37
 38
 39def make1_diagram(tex_diagram_template_txt, nump):
 40    tex_diagram_template_txt_ans = tex_diagram_template_txt
 41    kv = coordf.get_coordinates_dict(nump)
 42    for key, value in kv.items():
 43        # show answers
 44        if key in kv_keys_ans:
 45            tex_diagram_template_txt_ans = tex_diagram_template_txt_ans.replace(
 46                "<<" + key + ">>", value)
 47    for key, value in kv.items():
 48        # don't show answers
 49        if key in kv_keys_q:
 50            tex_diagram_template_txt = tex_diagram_template_txt.replace(
 51                "<<" + key + ">>", value)
 52
 53        if key in ky_keys_to_clear:
 54            tex_diagram_template_txt = tex_diagram_template_txt.replace(
 55                "<<" + key + ">>", "")
 56    return tex_diagram_template_txt, tex_diagram_template_txt_ans
 57
 58
 59def main():
 60    numq = input("Enter the number of graphs from 1 to 10 \n")
 61    if numq.strip().isdigit():
 62        numq = int(numq)
 63        if not numq in range(1, 11):
 64            numq = 2  #  default
 65    else:
 66        numq = 2  # default
 67    #
 68    nump = input("Enter the number of points to plot from 1 to 20 \n")
 69    if nump.strip().isdigit():
 70        nump = int(nump)
 71        if not nump in range(1, 21):
 72            nump = 5  #  default
 73    else:
 74        nump = 5  # default
 75    #
 76
 77    filename = input(
 78        "Enter the base filename to be added to the prefix coordinates_Bk_: \n"
 79    )
 80    if not filename:
 81        filename = "1"  # "coordinates_Bk_1_q and coordinates_Bk_1_ans as default file"
 82    # set names of files that are made
 83    # questions
 84    tex_output_path = currfile_dir / f"coordinates_Bk_{filename}_q.tex"
 85    pdf_path = currfile_dir / f"coordinates_Bk_{filename}_q.pdf"
 86
 87    # answers
 88    tex_output_path_ans = currfile_dir / f"coordinates_Bk_{filename}_ans.tex"
 89    pdf_path_ans = currfile_dir / f"coordinates_Bk_{filename}_ans.pdf"
 90
 91    # Read in the LaTeX template file
 92    with open(tex_template_path, "r") as infile:
 93        tex_template_txt = infile.read()
 94    # Read in the LaTeX template file for answers
 95    with open(texans_template_path, "r") as infile:
 96        tex_template_txt_ans = infile.read()
 97    # Read in the LaTeX diagram template file
 98    with open(tex_diagram_template_path, "r") as infile:
 99        tex_diagram_template_txt = infile.read()
100
101    # Generate the <<diagram>> replacement tex
102    # diagram_text, diagram_text_ans = make1_diagram(tex_diagram_template_txt)
103
104    # <<diagrams>>
105    # generate diagrams text and text for answers
106    diagrams_text = ""
107    diagrams_text_ans = ""
108    # add the headtext; disabled for now using r"" wno needed as numbers in minipage itself
109    posttext = r"\pagebreak ~ \newline ~ \newline"
110    for i in range(1, numq + 1):
111        img_tex, img_tex_ans = make1_diagram(tex_diagram_template_txt, nump)
112
113        diagrams_text += img_tex
114        diagrams_text_ans += img_tex_ans
115        if i < numq:
116            diagrams_text += posttext
117            diagrams_text_ans += posttext
118
119    # Replace the <<diagrams>> placeholder in the LaTeX template
120    tex_template_txt = tex_template_txt.replace("<<diagrams>>", diagrams_text)
121    tex_template_txt_ans = tex_template_txt_ans.replace(
122        "<<diagrams>>", diagrams_text_ans)
123    # Write the question diagrams tex to an output file
124    with open(tex_output_path, "w") as outfile:
125        outfile.write(tex_template_txt)
126    # Write the answer diagrams tex to an output file
127    with open(tex_output_path_ans, "w") as outfile:
128        outfile.write(tex_template_txt_ans)
129
130    # Wait for the files to be created
131    time.sleep(1)
132    # convert to pdf
133    convert_to_pdf(tex_output_path, currfile_dir)
134    convert_to_pdf(tex_output_path_ans, currfile_dir)
135
136    # Wait for the files to be created
137    # time.sleep(1)
138    # convert to png
139    # magick_pdf_to_png.convert_pdf_to_png(pdf_path, png_path)
140    # magick_pdf_to_png.convert_pdf_to_png(pdf_path_ans, png_path_ans)
141
142
143if __name__ == "__main__":
144    print("starting")
145    main()
146    print("finished")

question

answer