3. Levers tikz

Diagrams of levers can be built using tikz.

3.1. First Class levers mechanical advantage

A First Class lever diagram is shown below.
levers.png
The LaTeX:
 1\documentclass[12pt, varwidth, border={20mm 5mm 5mm 20mm}]{standalone}
 2\usepackage{tikz}
 3\usepackage{amsmath}
 4\usepackage[a4paper, portrait, margin=1cm]{geometry}
 5\begin{document}
 6\section*{First Class Lever mechanical advantage}
 7\begin{minipage}{0.5\textwidth}
 8    \begin{tikzpicture}[scale=0.7,>=stealth]
 9        % First class lever
10        % rod
11        \draw[fill=gray!20] (-0.25,0) rectangle (6,0.1);
12        %fulcrum
13        \draw[fill=black] (0.8,-0.5) -- (1.2,-0.5) node[right] {fulcrum} -- (1.0,0) -- cycle;
14        %load
15        \draw[fill=red] (-0.25,0.1) rectangle (0.25,0.6);
16        \draw[->,thick] (0.0,0.35) -- (0.0,-2.15) node[midway,left,yshift=-0.5cm,align=center] {Load \\\\[-3ex] $F_L = 10N$};
17        %effort
18        \draw[->,thick] (6,0.0) -- (6,-0.5) node[midway,right,align=center] {Effort \\\\[-3ex] $F_E = 2N$};
19
20        % Distance markers
21        \draw[<->] (1,-3.0) -- (6,-3.0) node[midway,below,align=center] {$d_E= 50cm$};
22        \draw[<->] (0,-3.1) -- (1.0,-3.1) node[midway,below,xshift=-0.5cm,align=left] {$d_L = 10cm$};
23    \end{tikzpicture}
24\end{minipage}%
25\hfill
26\begin{minipage}{0.3\textwidth}
27    \begin{align*}
28        % ma
29         m.a.&=\frac{F_L}{F_E}=\frac{10N}{2N}=5 \\\\
30         m.a.&=\frac{d_E}{d_L}=\frac{50cm}{10cm}=5
31    \end{align*}
32\end{minipage}
33\end{document}

3.2. First Class levers Fd=Fd

A question diagram of a First Class lever is shown below with an incomplete force distance calculation.
lever_fcl1_q.png
The LaTeX:
 1\documentclass[12pt, varwidth, border={5mm 5mm 5mm 5mm}]{standalone}
 2\usepackage{tikz}
 3\usepackage{amsmath}
 4% Underlining package
 5\usepackage{ulem}
 6% \usepackage[a4paper, portrait, margin=1cm]{geometry}
 7\begin{document}
 8\section*{First Class Levers}
 9    \begin{minipage}{0.65\textwidth}
10    \begin{tikzpicture}[scale=0.7,>=stealth]
11        % First class lever
12        % rod
13        \draw[fill=gray!20] (-0.25,0) rectangle (6,0.1);
14        %fulcrum
15        \draw[fill=black] (0.8,-0.5) -- (1.2,-0.5) node[below,xshift=2mm] {fulcrum} -- (1.0,0) -- cycle;
16        %load
17        \draw[fill=red] (-0.25,0.1) rectangle (0.25,0.6);
18        \draw[->,thick] (0.0,0.35) -- (0.0,-2.15) node[midway,left,yshift=-0.5cm,align=center] {Load \\\\[-3ex] $F_L = 10N$};
19        %effort
20        \draw[->,thick] (6,0.0) -- (6,-0.5) node[midway,right,align=center] {Effort \\\\[-3ex] $F_E = \dotuline{~~~~~~~}N$};
21
22        % Distance markers
23        \draw[<->] (1.0,-2.5) -- (6,-2.5) node[midway,below,align=center] {$d_E = 50.0cm$};
24        \draw[<->] (0,-2.6) -- (1.0,-2.6) node[midway,below,xshift=-0.5cm,align=left] {$d_L = 10.0cm$};
25    \end{tikzpicture}
26\end{minipage}%
27\hfill
28\begin{minipage}{0.3\textwidth}
29    \begin{align*}
30        F_E \times d_E &= F_L \times d_L \\
31        F_E &= \frac{F_L \times d_L}{d_E} \\
32        F_E &= \frac{\dotuline{~~~~~~~} \times \dotuline{~~~~~~~}}{\dotuline{~~~~~~~}} \\
33        F_E &= \dotuline{~~~~~~~}N
34    \end{align*}
35\end{minipage}
36\end{document}
An answer diagram of a First Class lever is shown below with a completed force distance calculation.
lever_fcl1_ans.png
The LaTeX:
 1\documentclass[12pt, varwidth, border={5mm 5mm 5mm 5mm}]{standalone}
 2\usepackage{tikz}
 3\usepackage{amsmath}
 4% Underlining package
 5\usepackage{ulem}
 6% \usepackage[a4paper, portrait, margin=1cm]{geometry}
 7\begin{document}
 8\section*{First Class Levers}
 9    \begin{minipage}{0.65\textwidth}
10    \begin{tikzpicture}[scale=0.7,>=stealth]
11        % First class lever
12        % rod
13        \draw[fill=gray!20] (-0.25,0) rectangle (6,0.1);
14        %fulcrum
15        \draw[fill=black] (0.8,-0.5) -- (1.2,-0.5) node[below,xshift=2mm] {fulcrum} -- (1.0,0) -- cycle;
16        %load
17        \draw[fill=red] (-0.25,0.1) rectangle (0.25,0.6);
18        \draw[->,thick] (0.0,0.35) -- (0.0,-2.15) node[midway,left,yshift=-0.5cm,align=center] {Load \\\\[-3ex] $F_L = 10.0N$};
19        %effort
20        \draw[->,thick] (6,0.0) -- (6,-0.5) node[midway,right,align=center] {Effort \\\\[-3ex] $F_E = 2.0N$};
21
22        % Distance markers
23        \draw[<->] (1.0,-2.5) -- (6,-2.5) node[midway,below,align=center] {$d_E = 50.0cm$};
24        \draw[<->] (0,-2.6) -- (1.0,-2.6) node[midway,below,xshift=-0.5cm,align=left] {$d_L = 10.0cm$};
25    \end{tikzpicture}
26\end{minipage}%
27\hfill
28\begin{minipage}{0.3\textwidth}
29    \begin{align*}
30        F_E \times d_E &= F_L \times d_L \\
31        F_E &= \frac{F_L \times d_L}{d_E} \\
32        F_E &= \frac{10.0 \times 10.0}{50.0} \\
33        F_E &= 2.0N
34    \end{align*}
35\end{minipage}
36\end{document}

3.3. Booklet: First Class levers Fd=Fd

A booklet of random first class levers can be created.

Questions  pdf Questions tex

Answers pdf Answerstex


3.4. Maker files

The python below requires the following .tex files:

The 2 custom python modules required are:
The Python code that creates a booklet of 5 lever diagrams and calculations per page is:
The python file, lever_booklet_diagram_maker.py, when run, will ask for these inputs:
  • Choose the lever class: "Enter 1, 2, 3 or 4 for 1st, 2nd, 3rd class levers or random ".

  • Choose the numnber of questions: "- Choose the numnber of questions: "

  • Choose the file name base: "Enter the base filename to be added to the prefix lever_Bk_:".

  • The filename will have β€œ_q” added for the question booklet and β€œ_ans” for the answer booklet.

  1from pathlib import Path
  2import subprocess
  3import time
  4# import magick_pdf_to_png
  5import lever_functions as levf
  6
  7currfile_dir = Path(__file__).parent
  8tex_template_path = currfile_dir / "lever_booklet_template.tex"
  9texans_template_path = currfile_dir / "lever_booklet_ans_template.tex"
 10tex_diagram_template_path = currfile_dir / "lever_booklet_diagram_template.tex"
 11
 12
 13def convert_to_pdf(tex_path, currfile_dir, aux_path):
 14    """
 15    Converts a TeX file to PDF format using pdfLaTeX.
 16
 17    Args:
 18        tex_path (str): The path to the TeX file.
 19        currfile_dir (str): The path to the directory where the TeX file is located.
 20        aux_path (str): The path to the directory where auxiliary files will be stored.
 21
 22    Returns:
 23        subprocess.CompletedProcess: A subprocess.CompletedProcess object containing information about the completed process.
 24
 25    Raises:
 26        FileNotFoundError: If the TeX file does not exist.
 27        subprocess.CalledProcessError: If pdfLaTeX returns a non-zero exit code.
 28    """
 29    result = subprocess.run(
 30        [
 31            "pdfLaTeX",
 32            tex_path,
 33            "-output-directory",
 34            currfile_dir,
 35            "-aux-directory",
 36            aux_path,
 37        ],
 38        stdout=subprocess.PIPE,
 39    )
 40
 41
 42# % end modify values for lever 
 43# tex_keys = ['ans_force_l','ans_force_e','ans_dist_l', 'ans_dist_e', 'effort_vector','fulc_c', 'fulc_l', 'fulc_r' ]
 44tex_keys_q = ["force_l", "force_e", "dist_l", "dist_e", 'effort_vector','fulc_c', 'fulc_l', 'fulc_r']
 45
 46
 47def make1_diagram(tex_diagram_template_txt, num1,):
 48    tex_diagram_template_txt_ans = tex_diagram_template_txt
 49    kv = levf.get_lever_dict(num1)
 50    for key, value in kv.items():
 51        tex_diagram_template_txt_ans = tex_diagram_template_txt_ans.replace(
 52            "<<" + key + ">>", value
 53        )
 54    for key, value in kv.items():
 55        if key in tex_keys_q:
 56            tex_diagram_template_txt = tex_diagram_template_txt.replace(
 57                "<<" + key + ">>", value
 58            )
 59        else:
 60            tex_diagram_template_txt = tex_diagram_template_txt.replace(
 61                "<<" + key + ">>", "\dotuline{~~~~~~~}"  # non breaking spaces for gaps
 62            )
 63    return tex_diagram_template_txt, tex_diagram_template_txt_ans
 64
 65
 66def main():
 67    num1 = input("Enter 1, 2, 3 or 4 for 1st, 2nd, 3rd class levers or random \n")
 68    if num1.strip().isdigit():
 69        num1 = int(num1)
 70        if num1 not in [1, 2, 3, 4]:
 71            num1 = 4  # random by default
 72    else:
 73        num1 = 4  # random by default
 74    #
 75    numq = input("Enter the number of questions from 1 to 20 \n")
 76    if numq.strip().isdigit():
 77        numq = int(numq)
 78        if not numq in range(1,21):
 79            numq = 6  # random by default
 80    else:
 81        numq = 6  # random by default
 82    #
 83    filename = input("Enter the base filename to be added to the prefix lever_Bk_: \n")
 84    if not filename:
 85        filename = "1"  # "lever_Bk_1_q and lever_Bk_1_ans as default file"
 86    # set names of files that are made
 87    # questions
 88    tex_output_path = currfile_dir / f"lever_Bk_{filename}_q.tex"
 89    pdf_path = currfile_dir / f"lever_Bk_{filename}_q.pdf"
 90    aux_path = currfile_dir / "temp"
 91    # answers
 92    tex_output_path_ans = currfile_dir / f"lever_Bk_{filename}_ans.tex"
 93    pdf_path_ans = currfile_dir / f"lever_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, num1)
107
108    # <<diagrams>>
109    # generate diagrams text and text for answers
110    diagrams_text = ""
111    diagrams_text_ans = ""
112    # add the headtext
113    headtext = r"\pagebreak ~ \newline ~ \newline"
114    rmax = numq + 1
115    for i in range(1, rmax):
116        img_tex, img_tex_ans = make1_diagram(tex_diagram_template_txt, num1)
117        if i > 5 and i % 5 == 1:
118            diagrams_text += headtext
119            diagrams_text_ans += headtext
120        diagrams_text += img_tex
121        diagrams_text_ans += img_tex_ans
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    # Write the question diagrams tex to an output file
127    with open(tex_output_path, "w") as outfile:
128        outfile.write(tex_template_txt)
129    # Write the answer diagrams tex to an output file
130    with open(tex_output_path_ans, "w") as outfile:
131        outfile.write(tex_template_txt_ans)
132
133    # Wait for the files to be created
134    time.sleep(1)
135    # convert to pdf
136    convert_to_pdf(tex_output_path, currfile_dir, aux_path)
137    convert_to_pdf(tex_output_path_ans, currfile_dir, aux_path)
138
139    # Wait for the files to be created
140    # time.sleep(1)
141    # convert to png
142    # magick_pdf_to_png.convert_pdf_to_png(pdf_path, png_path)
143    # magick_pdf_to_png.convert_pdf_to_png(pdf_path_ans, png_path_ans)
144
145
146if __name__ == "__main__":
147    print("starting")
148    main()
149    print("finished")