Showing and hiding steps#

Recipes for choosing what appears: which steps of a calculation, which lines, and how long equations are broken. The commands are all listed in Comment commands.

Show only the result of a line#

Asked in #183.

-p shows target = result and skips the formula and the substitution. It suits values whose formula adds nothing, like a section property taken from a table or a unit conversion:

b = 300                    # mm
h = 600                    # mm
A = b * h                  # hc: -p
I_x = b * h**3 / 12
Output (MarkdownRenderer)
\[\begin{aligned} b &= 300 \quad\text{(mm)} \\ h &= 600 \quad\text{(mm)} \\ A &= 180000 \\ I_{x} &= \frac{b \cdot h^{3}}{12} = \frac{300 \cdot 600^{3}}{12} = 5.4 \times 10^{9} \end{aligned}\]
$$\begin{aligned} b &= 300 \quad\text{(mm)} \\ h &= 600 \quad\text{(mm)} \\ A &= 180000 \\ I_{x} &= \frac{b \cdot h^{3}}{12} = \frac{300 \cdot 600^{3}}{12} = 5.4 \times 10^{9} \end{aligned}$$

Show only formulas, or only results, for a whole section#

Asked in #89 and #183.

The mode field picks the steps. "ass sym" shows formulas, as in a design guide:

w = 5
L = 6
# hc: mode = "ass sym"
M = w * L**2 / 8
V = w * L / 2
Output (MarkdownRenderer)
\[\begin{aligned} w &= 5 \\ L &= 6 \end{aligned}\]
\[\begin{aligned} M &= \frac{w \cdot L^{2}}{8} \\ V &= \frac{w \cdot L}{2} \end{aligned}\]
$$\begin{aligned} w &= 5 \\ L &= 6 \end{aligned}$$

$$\begin{aligned} M &= \frac{w \cdot L^{2}}{8} \\ V &= \frac{w \cdot L}{2} \end{aligned}$$

"ass res" shows results, as in a summary table:

w = 5
L = 6
# hc: mode = "ass res"
M = w * L**2 / 8
V = w * L / 2
Output (MarkdownRenderer)
\[\begin{aligned} w &= 5 \\ L &= 6 \end{aligned}\]
\[\begin{aligned} M &= 22.5 \\ V &= 15 \end{aligned}\]
$$\begin{aligned} w &= 5 \\ L &= 6 \end{aligned}$$

$$\begin{aligned} M &= 22.5 \\ V &= 15 \end{aligned}$$

Switch back with # hc: mode = "full". For every calculation in a session: handcalcs.set_option("mode", "ass res").

Hide a line#

Asked in #106 and #226.

-i at the end of a line runs it but leaves it out of the output:

L_mm = 6000
L = L_mm / 1000            # hc: -i
w = 5
M = w * L**2 / 8
Output (MarkdownRenderer)
\[\begin{aligned} L_{\mathrm{mm}} &= 6000 \\ w &= 5 \\ M &= \frac{w \cdot L^{2}}{8} = \frac{5 \cdot 6^{2}}{8} = 22.5 \end{aligned}\]
$$\begin{aligned} L_{\mathrm{mm}} &= 6000 \\ w &= 5 \\ M &= \frac{w \cdot L^{2}}{8} = \frac{5 \cdot 6^{2}}{8} = 22.5 \end{aligned}$$

On its own line, # hc: -i hides every line after it; # hc: ignore = False shows them again:

# hc: -i
a_raw = [3.1, 2.9, 3.0]
a = sum(a_raw) / len(a_raw)
# hc: ignore = False
b = 2 * a
Output (MarkdownRenderer)
\[\begin{aligned} b &= 2 \cdot a = 2 \cdot 3 = 6 \end{aligned}\]
$$\begin{aligned} b &= 2 \cdot a = 2 \cdot 3 = 6 \end{aligned}$$

Hide import lines#

Imports are shown as a line of code. To leave one out, end it with # hc: -i:

from math import sqrt  # hc: -i
a = 3
b = 4
c = sqrt(a**2 + b**2)
Output (MarkdownRenderer)
\[\begin{aligned} a &= 3 \\ b &= 4 \\ c &= \sqrt{a^{2} + b^{2}} = \sqrt{3^{2} + 4^{2}} = 5 \end{aligned}\]
$$\begin{aligned} a &= 3 \\ b &= 4 \\ c &= \sqrt{a^{2} + b^{2}} = \sqrt{3^{2} + 4^{2}} = 5 \end{aligned}$$

To never show imports, register a handler on your renderer that renders nothing for import nodes:

"""Per-instance customization: one MarkdownRenderer that hides import lines."""
from handcalcs.renderers import MarkdownRenderer


def hide_import(renderer, node, base_context):
    return ""


def make_renderer():
    renderer = MarkdownRenderer()
    renderer.register_handler("import", hide_import)
    return renderer
from math import sqrt
a = 3
b = 4
c = sqrt(a**2 + b**2)
Output (MarkdownRenderer)
\[\begin{aligned} a &= 3 \\ b &= 4 \\ c &= \sqrt{a^{2} + b^{2}} = \sqrt{3^{2} + 4^{2}} = 5 \end{aligned}\]
$$\begin{aligned} a &= 3 \\ b &= 4 \\ c &= \sqrt{a^{2} + b^{2}} = \sqrt{3^{2} + 4^{2}} = 5 \end{aligned}$$

Lay out inputs in a grid#

A row of short parameter assignments takes up a lot of vertical space. Separate them with ; to put them on one row:

b = 300; h = 600; c = 40
Output (MarkdownRenderer)
\[\begin{aligned} b &= 300 \; &h &= 600 \; &c &= 40 \; \end{aligned}\]
$$\begin{aligned} b &= 300 \; &h &= 600 \; &c &= 40 \; \end{aligned}$$

or put # hc: -h above a group of assignments to lay them out in a grid, -c N columns wide, with their comments:

# hc: -h -c 2
f_c = 30     # Concrete strength, MPa
f_y = 400    # Rebar yield, MPa
b = 300      # Width, mm
d = 540      # Effective depth, mm
Output (MarkdownRenderer)
\[\begin{aligned} f_{c} &= 30 \; \text{(Concrete strength, MPa)} \qquad &f_{y} &= 400 \; \text{(Rebar yield, MPa)} \\ b &= 300 \; \text{(Width, mm)} \qquad &d &= 540 \; \text{(Effective depth, mm)} \end{aligned}\]
$$\begin{aligned} f_{c} &= 30 \; \text{(Concrete strength, MPa)} \qquad &f_{y} &= 400 \; \text{(Rebar yield, MPa)} \\ b &= 300 \; \text{(Width, mm)} \qquad &d &= 540 \; \text{(Effective depth, mm)} \end{aligned}$$

Break a long equation over several lines#

Asked in #199, #181, #149 and #259.

-m puts each step (formula, substitution, result) on its own line:

E = 200000; I_y = 160e6; G = 77e3; J = 133e3; C_w = 200e9; L = 6000
M_u = pi / L * sqrt(E * I_y * G * J + (pi * E / L)**2 * I_y * C_w)  # hc: -m
Output (MarkdownRenderer)
\[\begin{aligned} E &= 200000 \; &I_{y} &= 1.6 \times 10^{8} \; &G &= 77000 \; \\ J &= 1.33 \times 10^{5} \; &C_{w} &= 2 \times 10^{11} \; &L &= 6000 \; \end{aligned}\]
\[\begin{aligned} M_{u} &= \frac{\pi}{L} \cdot \sqrt{E \cdot I_{y} \cdot G \cdot J + \left(\frac{\pi \cdot E}{L}\right)^{2} \cdot I_{y} \cdot C_{w}} \\ &= \frac{3.1416}{6000} \cdot \sqrt{200000 \cdot 1.6 \times 10^{8} \cdot 77000 \cdot 1.33 \times 10^{5} + \left(\frac{3.1416 \cdot 200000}{6000}\right)^{2} \cdot 1.6 \times 10^{8} \cdot 2 \times 10^{11}} \\ &= 4.3134 \times 10^{8} \end{aligned}\]
$$\begin{aligned} E &= 200000 \; &I_{y} &= 1.6 \times 10^{8} \; &G &= 77000 \; \\ J &= 1.33 \times 10^{5} \; &C_{w} &= 2 \times 10^{11} \; &L &= 6000 \; \end{aligned}$$

$$\begin{aligned} M_{u} &= \frac{\pi}{L} \cdot \sqrt{E \cdot I_{y} \cdot G \cdot J + \left(\frac{\pi \cdot E}{L}\right)^{2} \cdot I_{y} \cdot C_{w}} \\ &= \frac{3.1416}{6000} \cdot \sqrt{200000 \cdot 1.6 \times 10^{8} \cdot 77000 \cdot 1.33 \times 10^{5} + \left(\frac{3.1416 \cdot 200000}{6000}\right)^{2} \cdot 1.6 \times 10^{8} \cdot 2 \times 10^{11}} \\ &= 4.3134 \times 10^{8} \end{aligned}$$

A formula that is still too wide can be broken where you break it in the source. A line continuation, either \ or an open bracket, starts a new row in the output:

a = 2; b = 3; c = 4
y = (a + b)**2 \
    + 3 * a * c \
    - b / c
Output (MarkdownRenderer)
\[\begin{aligned} a &= 2 \; &b &= 3 \; &c &= 4 \; \end{aligned}\]
\[\begin{aligned} y &= \left(a + b\right)^{2}{} \\ & \quad {}+ 3 \cdot a \cdot c{} \\ & \quad {}- \frac{b}{c} \\ &= \left(2 + 3\right)^{2}{} \\ & \quad {}+ 3 \cdot 2 \cdot 4{} \\ & \quad {}- \frac{3}{4} \\ &= 48.25 \end{aligned}\]
$$\begin{aligned} a &= 2 \; &b &= 3 \; &c &= 4 \; \end{aligned}$$

$$\begin{aligned} y &= \left(a + b\right)^{2}{} \\ & \quad {}+ 3 \cdot a \cdot c{} \\ & \quad {}- \frac{b}{c} \\ &= \left(2 + 3\right)^{2}{} \\ & \quad {}+ 3 \cdot 2 \cdot 4{} \\ & \quad {}- \frac{3}{4} \\ &= 48.25 \end{aligned}$$

There is no automatic wrapping: you decide where a long formula breaks.

Render one line in a notebook#

Asked in #179.

In Jupyter, %render (one %) runs and renders a single line, so a cell of ordinary code can show just the equation that matters:

b = 300
h = 600
%render I_x = b * h**3 / 12

See %render.

Show the result of an expression#

Asked in #54.

A line that is only an expression (no =) is shown with its result, like a calculator:

x = 3
2 * x + 1
x**2 > 5
Output (MarkdownRenderer)
\[\begin{aligned} x &= 3 \\ 2 \cdot x + 1 &= 2 \cdot 3 + 1 = 7 \\ x^{2} \gt 5 &= 3^{2} \gt 5 = \mathrm{True} \end{aligned}\]
$$\begin{aligned} x &= 3 \\ 2 \cdot x + 1 &= 2 \cdot 3 + 1 = 7 \\ x^{2} \gt 5 &= 3^{2} \gt 5 = \mathrm{True} \end{aligned}$$

handcalcs evaluates such a line again to find its result, but only when that is safe: arithmetic, built-ins, and math and numpy functions. A call to your own function is never run twice, so it is shown without a result (f(a) = f(2)). To show its result, assign it: y = f(a).

Add space between parts#

# hc: -b on its own line adds vertical space, to separate groups of results:

a = 2
b = 3
# hc: -b
c = a * b
Output (MarkdownRenderer)
\[\begin{aligned} a &= 2 \\ b &= 3 \end{aligned}\]

 

\[\begin{aligned} c &= a \cdot b = 2 \cdot 3 = 6 \end{aligned}\]
$$\begin{aligned} a &= 2 \\ b &= 3 \end{aligned}$$

 

$$\begin{aligned} c &= a \cdot b = 2 \cdot 3 = 6 \end{aligned}$$

Next: Checks and decisions.