SymEval

Symbolic, unit-aware evaluation of SymPy equations.

Write a SymPy equation, substitute Pint quantities, and SymEval shows how you arrive at the result the way you were taught in school:

1. Formula \rho = \dfrac{m}{V}
2. Formula with substituted quantities (value + unit) \rho = \dfrac{0.998\ \mathrm{kg}}{1\ \mathrm{L}}
3. Result (density of water) \rho = 998\ \dfrac{\mathrm{kg}}{\mathrm{m}^3}

SymEval integrates seamlessly with marimo and Quarto, such that you can make explorable explanationsin Python notebooks or websites, and automate calculation report generation.

Get started GitHub PyPI

Highlights

  • Crystal clear: shows every step. The formula, the values substituted with units, then the result.
  • 🐍 Pure Python: drop into your interactive notebooks and other Python code, no special syntax, no cell magic, no Domain-Specific Language (DSL).
  • 📏 Unit-aware: pint.Quantitys carry units through every step and convert to your chosen output unit.
  • 🧮 SymPy-native: first rearrange or simplify your equation symbolically using SymPy, then evaluate.
  • 📊 DataFrame-ready: use quantity_evalf() to compute a unit-aware column on a DataFrame.
  • 🔄 Reactive: tweak an input in a marimo notebook or on a website, and every dependent symbolic evaluation updates instantly.
  • 🤖 Automatable: render calculation reports with Quarto (HTML, PDF, Word, …) or run marimo notebooks as scripts to regenerate reports whenever inputs change.

Quickstart

SymEval is especially powerful inside Python notebooks, and these docs are opinionated. We strongly recommend marimo rather than Jupyter notebooks, and uv for managing Python.

The only thing you need to create a reproducible marimo notebook, i.e. a notebook that runs anywhere, is uv (installation instructions).

Run the command below to open a marimo notebook called usains_speed.py:

uvx marimo edit --sandbox usains_speed.py

uvx runs a Python package as a tool in a temporary isolated environment, allowing you to run the marimo Command Line Interface (CLI) directly without any manual setup.


When running marimo with the --sandbox flag, marimo:

  1. tracks the packages and versions used by your notebook, saving them in the notebook file as inline script metadata;
  2. runs in an isolated virtual environment (“sandbox”) that only contains the notebook dependencies.

In this way you can share your marimo notebook with anyone, and they’ll be able to run it anywhere. See marimo’s Inlining dependencies guide for more information.

Copy-paste the code below into a Python cell, and click install when prompted in the pop-up. This will install the packages and add them to the inline script metadata, which keeps the notebook reproducible.

from pint import Quantity
from symeval import sym_evalf
from sympy import Equality, Symbol

usains_speed = sym_evalf(
    Equality(Symbol("v"), Symbol("d") / Symbol("t")),
    subs={
        Symbol("d"): Quantity(100, "m"), 
        Symbol("t"): Quantity(9.58, "s")
    },
    output_unit="km/h",     # Play around with the unit!
    n_display=3             # Significant figures, defaults to 4
)
usains_speed

You should now see the symbolic evaluation of Usain Bolt’s world record speed on the 100-meter dash in km/h:

\begin{aligned} v &= \frac{d}{t} \\ &= \frac{100\ \mathrm{m}}{9.58\ \mathrm{s}} \\ v &= 10.4\ \frac{\mathrm{m}}{\mathrm{s}} = 37.6\ \frac{\mathrm{km}}{\mathrm{h}} \end{aligned}

Head to the Getting started tutorial for a live, interactive walkthrough and more advanced SymEval functionality, or read how SymEval works for the ideas behind SymEval.

Have an engineering calculation worth sharing? Contributions of worked example notebooks are welcome, see CONTRIBUTING.

Inspiration

Back to top