from keecas import (
show_eqn, # main function to generate expression block
check, # main function for verification
symbols, # to create symbols (from sympy)
u, # unit registry (from pint)
pc, # pipe commands
generate_unique_label, # label generator
config, # configuration options
)
# Init the global dict
params = {}
eqn = {}Quick Start
This guide will get you up and running with Keecas in just a few minutes.
Your First Calculation
Let’s start with a simple engineering calculation - computing stress from force and area.
1. Import Keecas
2. Define Symbols
Use LaTeX notation with subscripts for comprehensive display:
# Define symbols with LaTeX notation
F_d, A_load, sigma = symbols(r"F_{d}, A_{load}, \sigma")3. Set Up Parameters
Define your parameters with units:
# Cell-local parameters
_p = {
F_d: 10 * u.kN, # Force in kilonewtons
A_load: 50 * u.cm**2, # Area in square centimeters
}
params.update(_p)4. Define Expressions
Create symbolic expressions:
# Cell-local expressions
_e = {
sigma: "F_d / A_load" | pc.parse_expr
}
eqn.update(_e)5. Create Descriptions and Labels
Add descriptions for documentation and generate labels1 for cross-references:
# Descriptions
_d = {
F_d: "design force",
A_load: "loaded area",
sigma: "normal stress",
}
# Labels (for Quarto cross-references)
_l = generate_unique_label(_d)6. Evaluate and Display
Compute values and display the results:
# Evaluate expressions
_v = {
k: v | pc.subs(eqn|params) | pc.convert_to([u.MPa]) | pc.N
for k, v in _e.items()
}
# Display equations
show_eqn([_p | _e, _v, _d], label=_l)\[\begin{align} F_{d} & = 10{\,}\text{kN} & & \quad\text{design force} \label{eq-1kv2lsa6} \\[8pt] A_{load} & = 50{\,}\text{cm}^{2} & & \quad\text{loaded area} \label{eq-1qnugots} \\[8pt] \sigma & = \dfrac{F_{d}}{A_{load}} & = 2.0{\,}\text{MPa} & \quad\text{normal stress} \label{eq-27myzkyp} \end{align}\]
This will produce beautiful LaTeX output showing both the symbolic equation and numerical result.
Understanding the Pattern
As convention Keecas uses dict prepended by _ as cell-local containers (e.g. _p), while not prepended as global containers (e.g. params) that carry across cells.
Using pc.subs is recommended to pass a dict as union of the global dicts (e.g. eqn|params), because it contains all the necessary values and expression defined in the notebook.
Dictionary Conventions
| Dict | Purpose | Example |
|---|---|---|
_p |
Cell-local parameters | _p = {F_d: 10*u.kN} |
_e |
Cell-local expressions | _e = {sigma: "F_d/A_load" \| pc.parse_expr} |
_v |
Cell-local values | Evaluated results |
_d |
Cell-local descriptions | _d = {F_d: "design force"} |
_l |
Cell-local labels | _l = generate_unique_label(_d) |
Pipe Operations
Keecas uses pipe operators (|) for functional composition:
# Chain operations together
result = expression | pc.subs(parameters) | pc.convert_to(units) | pc.NCommon pipe commands:
pc.parse_expr- Parse string expressionspc.subs(dict)- Substitute valuespc.convert_to(units)- Convert unitspc.N- Numerical evaluation
Symbol Dependency Ordering
Keecas automatically handles out-of-order symbol definitions. You can define expressions before their dependencies:
a, b, intermediate, result = symbols(r"a, b, intermediate, result")
_e = {
result: "sqrt(a^2 + b^2) / intermediate" | pc.parse_expr, # Uses intermediate
intermediate: "a * b" | pc.parse_expr, # Defined after result
}
_p = {a: 3, b: 4}
_v = {k: v | pc.subs(_e | _p) | pc.N for k, v in _e.items()}
show_eqn([_p | _e, _v])\[\begin{align} a & = 3 & \\[8pt] b & = 4 & \\[8pt] result & = \dfrac{\sqrt{a^{2} + b^{2}}}{intermediate} & = 0.416666666666667 \\[8pt] intermediate & = a{\,}b & = 12.0 \end{align}\]
Keecas resolves dependencies automatically - no manual ordering required.
Common Pitfalls
- Use LaTeX notation for symbol definitions - Prefer
symbols(r"\sigma_{Sd}")oversymbols("sigma_Sd"). Symbols are compared by their string representation, so these create different objects:
# Two different symbols even though they render similarly
display(sigma_latex := symbols(r"\sigma_{Sd}"))
display(sigma_plain := symbols("sigma_Sd"))\(\displaystyle \sigma_{Sd}\)
\(\displaystyle \sigma_{Sd}\)
# They are NOT equal
sigma_latex == sigma_plain # FalseFalse
Using LaTeX notation ensures proper rendering and avoids unexpected symbol mismatches.
- Be careful with
valsdict inpc.subs- While maintaining a globalvalsdict for evaluated results can be useful, passing it topc.subswill overwrite expressions with already evaluated values, preventing recalculation when parameters change.
Example showing the problem:
# Initial setup
x, y, z = symbols(r"x, y, z")
params = {}
eqn = {}
vals = {}
_p = {x: 2}
params.update(_p)
_e = {
y: "x + 1" | pc.parse_expr, # y depends on x
z: "y^2" | pc.parse_expr, # z depends on y (and indirectly on x)
}
eqn.update(_e)
_v = {k: v | pc.subs(eqn|params) for k, v in _e.items()}
vals.update(_v)
show_eqn([_p | _e, _v])\[\begin{align} x & = 2 & \\[8pt] y & = x + 1 & = 3 \\[8pt] z & = y^{2} & = 9 \end{align}\]
# Update parameter and recalculate
_p = {x: 3} # Changed value
params.update(_p)
expr_to_recalc = [y, z]
# INCORRECT: passing vals overwrites expressions with old evaluated values
_v_incorrect = {
k: eqn[k] | pc.subs(eqn|params|vals) for k in expr_to_recalc
}
# CORRECT: don't pass vals
_v_correct = {
k: eqn[k] | pc.subs(eqn|params) for k in expr_to_recalc
}
# Verify the difference using check()
from keecas import check
from sympy import Eq
_c = {
k: check(_v_incorrect[k], _v_correct[k], Eq) for k in expr_to_recalc
}
show_eqn([_p | _e, _v_incorrect, _c])\[\begin{align} x & = 3 & & \\[8pt] y & = x + 1 & = 4 & \quad\text{$\textcolor{green}{\left[=4\quad \textbf{VERIFIED}\right]}$} \\[8pt] z & = y^{2} & = 9 & \quad\text{$\textcolor{red}{\left[\neq16\quad \textbf{NOT VERIFIED}\right]}$} \end{align}\]
Only pass vals to pc.subs if you’re certain no dependent expressions need updating.
Configuration
Set up basic configuration for your document:
# Configuration for LaTeX output
config.display.katex = False # KaTeX compatibility
config.latex.eq_prefix = "eq-PREFIX" # Equation label prefix
config.language.language = 'en' # Language/localeMulti-Step Calculations
For complex calculations spanning multiple cells:
# Setup cell (run once)
params = {} # Global parameters
eqn = {} # Global expressions
# First calculation cell
F_d, A_load, sigma_d = symbols(r"F_{d}, A_{load}, \sigma_{d}")
_p = {
F_d: 10 * u.kN,
A_load: 5 * u.cm**2,
}
params.update(_p) # Save to global
_e = {
sigma_d: "F_d / A_load" | pc.parse_expr,
}
eqn.update(_e) # Save to global
_v = {
k: v | pc.subs(eqn | params) | pc.convert_to([u.MPa]) | pc.N for k, v in _e.items()
}
show_eqn([_p | _e, _v])\[\begin{align} F_{d} & = 10{\,}\text{kN} & \\[8pt] A_{load} & = 5{\,}\text{cm}^{2} & \\[8pt] \sigma_{d} & = \dfrac{F_{d}}{A_{load}} & = 20.0{\,}\text{MPa} \end{align}\]
# Second calculation cell (uses previous results)
sigma_Rk, sigma_Rd, gamma_M0 = symbols(r"\sigma_{Rk}, \sigma_{Rd}, \gamma_{M0}")
_p = {
sigma_Rk: 275 * u.MPa,
gamma_M0: 1.05, # Safety factor
}
params.update(_p)
_e = {
sigma_Rd: "sigma_Rk / gamma_M0" | pc.parse_expr,
}
eqn.update(_e)
_v = {
k: v | pc.subs(eqn | params) | pc.convert_to([u.MPa]) | pc.N for k, v in _e.items()
}
show_eqn([_p | _e, _v], float_format=":.2f")\[\begin{align} \sigma_{Rk} & = 275{\,}\text{MPa} & \\[8pt] \gamma_{M0} & = 1.05 & \\[8pt] \sigma_{Rd} & = \dfrac{\sigma_{Rk}}{\gamma_{M0}} & = 261.90{\,}\text{MPa} \end{align}\]
Verification and Checks
Check if calculated values meet criteria:
from keecas import check
# Check if stress is within allowable limits
# calculate the value
_v = {
k: k | pc.subs(eqn|params) | pc.convert_to([u.N, u.mm]) | pc.N for k in [sigma_d/sigma_Rd]
}
# check is the expression is less than 1 (default)
_c = {
k: check(v, 1) for k, v in _v.items()
}
show_eqn([_v, _c], float_format=":.3f")\[\begin{align} \dfrac{\sigma_{d}}{\sigma_{Rd}} & = 0.076 & \quad\text{$\textcolor{green}{\left[\le1\quad \textbf{VERIFIED}\right]}$} \end{align}\]
CLI Quick Start
Use the Keecas CLI for quick setup:
# Create a temporary session
keecas edit --temp
# Create a new notebook with template
keecas edit my_calculation.ipynb --template quickstart
# Launch JupyterLab in current directory
keecas edit --dir .
# Show available templates
keecas edit --list-templatesComplete Examples
For comprehensive real-world usage, check out the example notebooks:
- hello_world.ipynb - Basic usage patterns and simple calculations
- quarto_example - Complete engineering document with PDF/HTML rendering
Next Steps
- Learn more about Configuration for customizing Keecas behavior
- Review the API Reference for complete function documentation
- Explore the CLI Reference for command-line tools
Footnotes
labels can be automatically generated, or manually specified↩︎