Worked Equations and Equations With Units

One of the common refrains in maths, physics and engineering education is to “show your working” and “check your working”.

In a one piece generative production workflow, various tools are available that support the creation of simple worked examples. By using a generative approach, the working is guaranteed to be correct (even if the style of presentation may not be exactly as desired) which provides a great benefit in terms of material production.

In addition, tools are available that also allow dimensions, or units of measurement, to form part of the calculation, as well as providing an important way (through dimensional analysis) of checking that a derived formula does indeed create a quantity of the desired type — with the desired or expected unit of measurement — from the manipulated values.

For the learner, being able to generate a worked example from an arbitrary set-up allows them to check their own working against the worked steps generated automatically / mechanically from an arbitrary set-up.

Once again, sharing the means of production that helps authors create logically correct materials also provides learners with a mechanical tutor at their side to help them check their own work.

handcalcs Equations

The handcalcs package provides a simple way for writing mathematical equations using simple text and then rendering them using LaTeX equation style layout.

If the full power of sympy is not required, handcalcs may provide all the manipulation we need:

import handcalcs.render
from math import pi

We can easily write equations that reference greek letters and subscripted values, expanding on a symbolic equation using some provided magic:

%%render
t = 1
theta = pi / 2
omega_t =  2 * pi / t
\[\begin{split} \begin{aligned} t &= 1 \; \\[10pt] \theta &= \frac{ \pi }{ 2 } = \frac{ 3.142 }{ 2 } &= 1.571 \\[10pt] \omega_{t} &= 2 \cdot \frac{ \pi }{ t } = 2 \cdot \frac{ 3.142 }{ 1 } &= 6.283 \end{aligned} \end{split}\]

We can prevent the magic from evaluating the expression by telling it we want the expression to remain a symbolic one:

%%render symbolic

a = 2
b = 3
c = 2*a + b/3
\[\begin{split} \begin{aligned} a &= 2 \; \\[10pt] b &= 3 \; \\[10pt] c &= 2 \cdot a + \frac{ b }{ 3 } \; \end{aligned} \end{split}\]

If the expression is evaluated, elements will be expanded along a single line, unless we force a “long” format output which splits the output over several lines:

%%render long
a = 2
b = 3
c = 2*a + b/3
\[\begin{split} \begin{aligned} a &= 2 \; \\[10pt] b &= 3 \; \\[10pt] c &= 2 \cdot a + \frac{ b }{ 3 } \\&= 2 \cdot 2 + \frac{ 3 }{ 3 } \\&= 5.0 \\ \end{aligned} \end{split}\]

If the output isn’t to your liking, handcalcs might still help accelerate authoring by providing a draft of some raw laTeX that you could copy and edit by hand and then render by other means.

Note

In single piece generative document workflow terms, the %%tex magic cell could be removed from a rendered version of the notebook and yet still be used to create raw TeX that might be manually copied into, edited and rendered from a %%latex magicked cell with a hidden input.

%%tex long
a = 2
b = 3
c = 2*a + b/3
\[
\begin{aligned}
a &= 2 \; 
\\[10pt]
b &= 3 \; 
\\[10pt]
c &= 2 \cdot a + \frac{ b }{ 3 } \\&= 2 \cdot 2 + \frac{ 3 }{ 3 } \\&= 5.0  \\
\end{aligned}
\]

For example, we might copy the generated LaTeX, edited as required, perhaps with one of the steps omitted, into a %%latex magic cell:

%%latex

\[
\begin{aligned}
a &= 2 \; 
\\[10pt]
b &= 3 \; 
\\[10pt]
c &= 2 \cdot a + \frac{ b }{ 3 } \\&= 5.0  \\
\end{aligned}
\]
\[\begin{split} \begin{aligned} a &= 2 \; \\[10pt] b &= 3 \; \\[10pt] c &= 2 \cdot a + \frac{ b }{ 3 } \\&= 5.0 \\ \end{aligned} \end{split}\]

We can use a decorator rather than magic to expand various expressions contained within a function.

For example, consider the following function:

from math import sqrt
from handcalcs.decorator import handcalc

@handcalc(override='long', jupyter_display=True)
def calc(x, y):
    a = 2 * x / y
    b = 3 * a
    
    return a + b

We can now present the worked solution directly:

calc(1, 4)
\[\begin{split} \begin{aligned} a &= 2 \cdot \frac{ x }{ y } \\&= 2 \cdot \frac{ 1 }{ 4 } \\&= 0.5 \\ \\[10pt] b &= 3 \cdot a \\&= 3 \cdot 0.5 \\&= 1.5 \\ \end{aligned} \end{split}\]
2.0

Working with Dimensions

In some situations, such as physics or engineering calculations, it might be important to make use of dimensioned quantities. The forallpeople package is one of several packages that provides dimensional units. Conveniently, it also works with the handcalcs package.

By default, we can load a particular measurement framework, such as the SI units of measurement. (Alternatives include things like Imperial measurements.)

import forallpeople as si

si.environment('default') #, top_level=True)
# Describes the SI derived units
# Units are created by compounding the base units (e.g. Newton, Pascal, Celsius, Watt, Joule, etc.)

Calculated quantities have a value and a dimension. An appropriate magnitude prefix is determined automatically:

force = 20000 * si.N
area = 2 * si.m**2
pressure = force / area

pressure
10.000 kPa

Small units are also determined correctly:

2e-6 * si.F
2.000 μF

Dimensional values can be associated with terms in expressions rendered using handcalcs magic, with appropriate units being displayed as part of a rendered calculation.

Note

Dimensional analysis can be very useful when checking equation derivations or trying to remember particular formulae: was it \(V=IR\), or \(V=I/R\)? A quick dimensional analysis, if you know your SI units, can help check…

%%render

# We need to bracket the terms to not expand the units equation
I = (3e-3 * si.A) #  set the current
V = (20 * si.V) # set the voltage

R = V/I
# Incorrect omega, issue: https://github.com/connorferster/handcalcs/issues/76
\[\begin{split} \begin{aligned} I &= 3.000\ \text{mA} \; \;\textrm{(set the current)} \\[10pt] V &= 20.000\ \text{V} \; \;\textrm{(set the voltage)} \\[10pt] R &= \frac{ V }{ I } = \frac{ 20.000\ \text{V} }{ 3.000\ \text{mA} } &= 6.667\ \text{k\Omega} \end{aligned} \end{split}\]