Jupyter: %%render#

The Jupyter interface renders a notebook cell in place.

import handcalcs

Importing handcalcs inside a running IPython kernel registers the render magic (as a cell magic and a line magic) and two settings magics:

Magic

Does

%%render

Runs the cell, then displays it as a calculation.

%%render inputs=case

Runs and displays the cell with the values in case (inputs).

%render LINE

Runs one line, then displays it as a calculation.

%hc_default_renderer NAME

Chooses the renderer %%render uses for this session.

%hc_format_code CODE

Sets the default number format for this session.

%%render#

%%render
## Section properties
b = 300  # mm
h = 600  # mm
I_x = b * h**3 / 12

What happens:

  1. The cell runs in the notebook’s namespace, exactly as it would without the magic. Variables it defines are available to later cells. Anything the cell prints is suppressed. If the cell raises an error, the error is shown as usual and nothing is rendered.

  2. handcalcs parses the cell and renders it with the session’s renderer, reading values from the notebook namespace.

  3. The output is displayed with the IPython display class that matches the renderer.

Formatting is controlled with comment commands inside the cell. The first line takes only the inputs arguments; words without = after %%render (such as v1’s params) are ignored.

Warning

If the cell raises an exception, %%render displays nothing, and the traceback is not shown. If a rendered cell comes up empty, remove %%render and run it again to see the error.

Rendering with inputs#

%%render inputs=case renders the cell with the values in the dict case in place of the values the cell assigns them, the same way as HandCalcs(..., inputs=...) does for a script:

case = {"w": 6.2, "L": 8}
%%render inputs=case
w = 4.5 * kN / m
L = 6 * m
M_f = w * L**2 / 8

This runs and renders as w = 6.2 kN/m, L = 8 m, and M_f is computed from them. A number keeps the cell’s units; a quantity is converted to them. Later cells see the values the cell computed with the inputs.

The arguments are keyword arguments, separated by commas, and are evaluated in the notebook’s namespace, so any expression works: %%render inputs=cases[2], strict=False.

Argument

Does

inputs

A dict of names and values. Required when any argument is given.

strict=False

Ignore inputs the cell never assigns, instead of raising a KeyError.

allow_computed=True

Let an input replace a computed line (b = 2 * a), instead of raising a ValueError.

A misspelled input name or an input on a computed line raises its error before the cell runs, so its traceback is shown. A quantity whose units don’t match the line’s raises while the cell runs, so, as the warning above says, nothing is displayed.

%render: one line#

%render runs the rest of its line in the notebook’s namespace and renders just that line. Use it for the one equation that matters in a cell of ordinary code:

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

The line can carry an inline comment or comment command (%render M = w * L**2 / 8  # hc: -f .1f). %render with no code is an error, and so is %render inside a function, because the line would run in the notebook’s namespace instead of the function’s; use @handcalc there.

Choosing the renderer#

%%render uses the Markdown renderer by default: Markdown prose with LaTeX math, which Jupyter typesets with MathJax. To switch:

%hc_default_renderer latex

Name

Displayed as

markdown (default)

IPython.display.Markdown

latex

IPython.display.Latex

html

IPython.display.HTML

ascii

IPython.display.Pretty

The setting lasts for the session. To make it permanent, save it to the configuration:

handcalcs.set_option("jupyter_renderer", "html")
handcalcs.save_config()

%hc_default_renderer only changes %%render; a bare HandCalcs() uses the separate default_renderer option.

Custom renderers#

Any renderer with a name can be selected once its class has been defined or imported:

from my_package import MyRenderer   # name = "mine"
%hc_default_renderer mine

A custom renderer is displayed with the display class of the built-in renderer it inherits from: a subclass of HTMLRenderer is shown as HTML, a subclass of MarkdownRenderer as Markdown, and so on. See Publishing a renderer.

Exporting a notebook#

To share a notebook of rendered calculations without the code, export it with the input cells hidden. The nb-hideinputs package (pip install "handcalcs[exporters]") adds “no input” HTML, LaTeX and PDF export options to Jupyter.

Source#

src/handcalcs/interfaces/jupyter.py