# Writing calculations
A handcalcs calculation is ordinary Python plus comments. This page covers the pieces you
use to turn a block of code into a readable calculation. The examples use the Markdown
renderer (the Jupyter default); every built-in renderer supports the same features.
## Headings and prose
A comment starting with `##` is a heading. `##` is the top level, `###` the next, and so
on. Other comment lines are prose; consecutive comment lines join into one paragraph.
```{hc-example}
## Beam design
### Loads
# The beam carries a uniformly distributed load from the floor above.
# Self-weight is included in w.
w = 12.5 # kN/m
```
## Naming variables
A variable's name is typeset as a math symbol, so name variables the way you'd write them
on paper:
| You write | Shown as | Rule |
|---|---|---|
| `I_y` | *I*y | `_` starts a subscript |
| `N_pl_Rd` | Npl,Rd | each further `_` adds a subscript, separated by a comma |
| `sigma_max`, `Gamma` | σmax, Γ | a Greek letter's name becomes the letter (`lamb` or `lambda_` for λ) |
| `ΔH`, `σ_R` | ΔH, σR | Unicode Greek letters work too |
| `DeltaH`, `gammaM0`, `alpha2` | ΔH, γM0, α2 | a Greek name followed by an uppercase letter or a digit |
| `x_hat`, `x_bar`, `V_dot`, `x_ddot` | x̂, x̄, V̇, ẍ | accents over the part before them |
| `x̄`, `ŷ_2`, `σ̂` | x̄, ŷ2, σ̂ | Unicode letters with a combining accent (hat, bar, dot, double dot) |
| `f_prime_c`, `M_star` | f′c, M* | a prime, a superscript `*` |
| `Annual__Rate` | Annual Rate | `__` is a space |
| `a___b` | a_b | `___` is a literal underscore |
A lowercase continuation never splits off a Greek letter: `metal`, `beta` and `Pin` stay
as they are. A subscript of more than one letter is set upright.
```{hc-example}
N_pl_Rd = 1250 # kN
gammaM0 = 1.0
DeltaT = 35 # K
f_prime_c = 30 # MPa
```
### Nested subscripts
handcalcs v1 nested each further subscript (`x_a_b` → xab). To get
that back, set the `subscripts` option to `"nested"`, either for the rest of the calculation
with a comment command or for the session with `set_option`:
```{hc-example}
# hc: subscripts = "nested"
x_a_b = 2
```
```python
import handcalcs
handcalcs.set_option("subscripts", "nested")
```
### Display symbols
When a name can't express the symbol you want, map the variable to a display spec with
the `symbols` option. The spec uses a small TeX-like syntax that every renderer
understands:
```{hc-example}
# hc: symbols = {"N_plRd": "N_{pl,Rd}", "V_flow": "dot(V)", "dH": "ΔH^{*}"}
N_plRd = 1250 # kN
V_flow = 2.5 # m³/s
dH = 4.2 # kJ
```
| Spec | Meaning |
|---|---|
| `N_{pl,Rd}` | subscripts in braces, separated by commas; `N_Rd` takes the run after `_` |
| `M^{*}`, `x^2` | superscripts, the same way |
| `x_{a_{b}}` | a subscript with its own subscript |
| `Delta H`, `ΔH`, `sigma_{c}` | spaces separate words; Greek names or Unicode letters |
| `hat(x)`, `bar(x)_{m}`, `dot(V)`, `ddot(x)` | an accent over the base |
| `f'_c` | a prime |
Set `symbols` for the whole session with `handcalcs.set_option("symbols", {...})`. A spec
that can't be parsed raises an error that says where.
## Indexing
An index or key lookup shows the element it looks up in the substitution. A name indexed
by integers, short strings or other names is set with the index as a subscript, the way a
hand calculation numbers its values:
```{hc-example}
M_Ed = [90, 120, 140] # kNm, load cases
loads = {"dead": 5.0, "live": 3.0} # kN/m
i = 2
eta = M_Ed[i] / 150
w = 1.25 * loads["dead"] + 1.5 * loads["live"]
```
Each index follows the name's own subscripts (`M_Ed[i]` → MEd,i), and
`A[i, j]` gives Ai,j. Other lookups, such as slices (`xs[1:3]`) and indexes
that are expressions (`xs[i + 1]`), are shown in brackets. The ASCII renderer always uses
brackets.
handcalcs finds the element without running any code again: the index must be a literal,
a name or an attribute (or a slice or tuple of those), and the container a list, tuple,
string, dict, numpy array, pandas object or units-library quantity. Otherwise the
substitution shows the lookup with its index substituted (`xs[2 + 1]`), followed by the
result. To show every lookup in brackets, see [the recipe](../customizing/symbols-and-functions.md#indexes-in-brackets).
## Several targets
Tuple unpacking and chained assignment are shown as written, with their values:
```{hc-example}
:renderer: ascii
x = [3.0, 4.0]
a, b = x
c = d = a * b
```
## Inline comments
A comment at the end of a line is shown next to that line. Use it for units, sources or
short notes:
```{hc-example}
L = 6000 # Span, in mm (drawing S-201)
E = 200000 # MPa
```
## Values inside comments
Comments (headings, prose and inline comments) are [Jinja](https://jinja.palletsprojects.com/)
templates. Put a variable name in `{{ }}` to insert its value, and use Jinja filters to
format it:
```{hc-example}
:renderer: ascii
F = 12.3456
# The applied force is {{ F|round(1) }} kN.
check = F < 15 # F = {{ "%.2f"|format(F) }} kN, below the 15 kN limit
```
```{note}
Values in `{{ }}` are inserted as they are, without the
[number format](formatting-numbers.md). Use a Jinja filter such as `round` or `format`
to control them.
```
## Parameter grids
Long lists of inputs take up a lot of vertical space. Put several assignments on one line,
separated by `;`, and they are laid out as a grid, three per row:
```{hc-example}
b = 200; d = 450; c_c = 40; f_c = 30; f_y = 400
```
To keep inline comments, use a `# hc: -h` command instead. The assignments that follow
go into the grid, each with its comment, until a blank line, a comment line or a
statement that is not an assignment. Each cell shows only *target = result*:
```{hc-example}
# hc: -h
b = 200 # mm
d = 450 # mm
f_c = 30 # MPa
f_y = 400 # MPa
```
Change the number of columns with `# hc: -c N`:
```{hc-example}
# hc: -c 2
b = 200; d = 450; f_c = 30; f_y = 400
```
```{note}
A standalone command such as `# hc: -c 2` stays in effect for the rest of the
calculation. See [scope](comment-commands.md#scope).
```
## Long equations
A long expression is broken at the same places as your source code. Continue the line
with a `\`, before or after an operator, and each continued piece starts a new row,
indented under the expression above, in both the symbolic and the substituted step:
```{hc-example}
:renderer: ascii
a = 1.5
b = 2.25
c = 3.125
total = a * b \
+ b * c \
+ a * c
```
Only breaks between the terms of the expression itself are kept. A break inside brackets
or a fraction can't be, so that calculation is shown on one line. Brackets around the
*whole* expression show only the result, as for any [bracketed expression](how-it-works.md#skipping-the-substitution).
To break between the steps of a calculation (symbolic, substituted, result) instead, use
[`# hc: -m`](comment-commands.md).
## Expressions
A line that is only an expression, such as `2 * a`, shows its result:
```{hc-example}
:renderer: ascii
a = 3
2 * a + 1
```
An expression that calls a function or has a side effect isn't evaluated again, so it is
shown without a result.
## Conditionals
`if` / `elif` / `else` blocks show the condition that was true, first symbolically and
then with values, followed by the lines in that branch. Branches that did not run are not
shown, so the output reads as the reasoning that applies to *these* inputs:
```{hc-example}
:setup: from math import sqrt
b_t = 8.5
F_y = 350
if b_t <= 145 / sqrt(F_y):
section_class = 1
elif b_t <= 170 / sqrt(F_y):
section_class = 2
else:
section_class = 3
```
Blocks can be nested; each level is indented.
## Loops
A `for` loop is shown as a line describing the iteration, followed by its body. The body
is shown once, with the values of the **last** pass through the loop:
```{hc-example}
:renderer: ascii
total = 0
for load in (1.2, 3.4, 5.6):
factored = 1.25 * load
```
To show a calculation for every case in a table of inputs, render one representative
case, or call a renderer once per case from a script (see
[the object-oriented interface](../interfaces/object-oriented.md)).
## Spacing
`# hc: -b` inserts a blank line (vertical space) at that point:
```{hc-example}
:renderer: ascii
a = 2
# hc: -b
b = a * 3
```
## Hiding a line
Some lines are needed for the calculation but are not interesting to the reader, such as
setting up a unit system. Add `# hc: -i` to run the line but leave it out of the output:
```{hc-example}
:renderer: ascii
a = 2
scale = 1000 # hc: -i
b = a * scale
```
**Next:** [Comment commands](comment-commands.md) lists every command.