2. Coordinates2


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_plot_without_xy"] = format_latex_coordinates_for_plotting_without_xy(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_plotting_without_xy(coord_dict):
54    latex_str = ""
55    for name, (x, y) in coord_dict.items():
56        latex_str += f"\\fill ({x},{y}) circle (4pt);\n"
57        latex_str += f"\\node[xshift=1.9em, yshift=7pt] at ({x},{y}) {{\\small {name}(\\hspace{{0.6cm}},\\hspace{{0.6cm}})}};\n"
58    return latex_str
59
60
61
62
63def format_latex_coordinates_for_plotting(coord_dict):
64    latex_str = ""
65    for name, (x, y) in coord_dict.items():
66        latex_str += f"\\fill ({x},{y}) circle (4pt);\n"
67        latex_str += f"\\node[xshift=1.9em, yshift=7pt] at ({x},{y}) {{\\small {name}({x},{y})}};\n"
68    return latex_str
69
70# 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_plot_without_xy"]
 35ky_keys_q_to_clear = ["points_to_plot"]
 36kv_keys_ans = ["points_to_plot"]
 37ky_keys_ans_to_clear = ["points_to_plot_without_xy"]
 38
 39
 40def make1_diagram(tex_diagram_template_txt, nump):
 41    tex_diagram_template_txt_ans = tex_diagram_template_txt
 42    kv = coordf.get_coordinates_dict(nump)
 43    for key, value in kv.items():
 44        # show answers
 45        if key in kv_keys_ans:
 46            tex_diagram_template_txt_ans = tex_diagram_template_txt_ans.replace(
 47                "<<" + key + ">>", value)
 48        if key in ky_keys_ans_to_clear:
 49               tex_diagram_template_txt_ans = tex_diagram_template_txt_ans.replace(
 50                "<<" + key + ">>", "")
 51    for key, value in kv.items():
 52        # show questions
 53        if key in kv_keys_q:
 54            tex_diagram_template_txt = tex_diagram_template_txt.replace(
 55                "<<" + key + ">>", value)
 56
 57        if key in ky_keys_q_to_clear:
 58            tex_diagram_template_txt = tex_diagram_template_txt.replace(
 59                "<<" + key + ">>", "")
 60    return tex_diagram_template_txt, tex_diagram_template_txt_ans
 61
 62
 63def main():
 64    numq = input("Enter the number of graphs from 1 to 10 \n")
 65    if numq.strip().isdigit():
 66        numq = int(numq)
 67        if not numq in range(1, 11):
 68            numq = 2  #  default
 69    else:
 70        numq = 2  # default
 71    #
 72    nump = input("Enter the number of points to plot from 1 to 20 \n")
 73    if nump.strip().isdigit():
 74        nump = int(nump)
 75        if not nump in range(1, 21):
 76            nump = 5  #  default
 77    else:
 78        nump = 5  # default
 79    #
 80
 81    filename = input(
 82        "Enter the base filename to be added to the prefix coordinates_Bk_: \n"
 83    )
 84    if not filename:
 85        filename = "1"  # "coordinates_Bk_1_q and coordinates_Bk_1_ans as default file"
 86    # set names of files that are made
 87    # questions
 88    tex_output_path = currfile_dir / f"coordinates_Bk_{filename}_q.tex"
 89    pdf_path = currfile_dir / f"coordinates_Bk_{filename}_q.pdf"
 90
 91    # answers
 92    tex_output_path_ans = currfile_dir / f"coordinates_Bk_{filename}_ans.tex"
 93    pdf_path_ans = currfile_dir / f"coordinates_Bk_{filename}_ans.pdf"
 94
 95    # Read in the LaTeX template file
 96    with open(tex_template_path, "r") as infile:
 97        tex_template_txt = infile.read()
 98    # Read in the LaTeX template file for answers
 99    with open(texans_template_path, "r") as infile:
100        tex_template_txt_ans = infile.read()
101    # Read in the LaTeX diagram template file
102    with open(tex_diagram_template_path, "r") as infile:
103        tex_diagram_template_txt = infile.read()
104
105    # Generate the <<diagram>> replacement tex
106    # diagram_text, diagram_text_ans = make1_diagram(tex_diagram_template_txt)
107
108    # <<diagrams>>
109    # generate diagrams text and text for answers
110    diagrams_text = ""
111    diagrams_text_ans = ""
112    # add the headtext; disabled for now using r"" wno needed as numbers in minipage itself
113    posttext = r"\pagebreak ~ \newline ~ \newline"
114    for i in range(1, numq + 1):
115        img_tex, img_tex_ans = make1_diagram(tex_diagram_template_txt, nump)
116
117        diagrams_text += img_tex
118        diagrams_text_ans += img_tex_ans
119        if i < numq:
120            diagrams_text += posttext
121            diagrams_text_ans += posttext
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(
126        "<<diagrams>>", diagrams_text_ans)
127    # Write the question diagrams tex to an output file
128    with open(tex_output_path, "w") as outfile:
129        outfile.write(tex_template_txt)
130    # Write the answer diagrams tex to an output file
131    with open(tex_output_path_ans, "w") as outfile:
132        outfile.write(tex_template_txt_ans)
133
134    # Wait for the files to be created
135    time.sleep(1)
136    # convert to pdf
137    convert_to_pdf(tex_output_path, currfile_dir)
138    convert_to_pdf(tex_output_path_ans, currfile_dir)
139
140    # Wait for the files to be created
141    # time.sleep(1)
142    # convert to png
143    # magick_pdf_to_png.convert_pdf_to_png(pdf_path, png_path)
144    # magick_pdf_to_png.convert_pdf_to_png(pdf_path_ans, png_path_ans)
145
146
147if __name__ == "__main__":
148    print("starting")
149    main()
150    print("finished")

question

answer