handcalcs: Python calculations in Jupyter, as though you wrote them by hand.
handcalcs is a library to render Python calculation code automatically in Latex, but in a manner that mimics how one might format their calculation if it were written with a pencil: write the symbolic formula, followed by numeric substitutions, and then the result.
Because handcalcs shows the numeric substitution, the calculations become significantly easier to check and verify by hand.
handcalcs is intended to be used with either Jupyter Notebook or Jupyter Lab as a cell magic.
First, import the module and run the cell:
importhandcalcs.render
Note: This will import both %%tex and %%render magics in the Jupyter Notebook.
Then, in any cell that you want to render with handcalcs, just use the render cell magic at the top of your cell:
%%render
For example:
%%rendera=2b=3c=2*a+b/3
That is it!
Once rendered, you can then export your notebook as a PDF, provided you have a Latex environment installed on your system. If you are new to working with Latex and would like to install it on your system so you can use this functionality, please see the section Installing Tex, in the wiki.
You can also use the %%tex command to convert any Python code snippet into a valid LaTex. For Example:
First import handcalcs. We are also importing a few properties/functions from math package for the
example below.
Returns a tuple consisting of (latex_code: str, locals: dict), where locals is a dictionary of all variables in the scope of the function namespace.
override is a str representing one of the acceptable override tags (see below)
precision is an int to alter the of decimal precision displayed
left and right are strings that can precede and follow the encoded Latex string, such as \\[ and \\] or $ and $
jupyter_display, when True, will return only the locals dictionary and instead will display the encoded Latex string rendering with display(Latex(latex_code)) from IPython.display. Will return an error if not used within
In your decorated function, everything between def my_calc(...) and a return statement (if any) is now like the code in a Jupyter cell, except it's a standard Python function.
Used in this way, you can use @handcalc() to dynamically generate Latex code for display in Jupyter and non-Jupypter Python environments (e.g. streamlit).
Override tags
handcalcs makes certain assumptions about how you would like your calculation formatted and does not allow for a great deal of customization in this regard. However, there are currently four customizations you can make using # override tags as an argument after the %%render cell magic. Additionally, you can also specify the number of decimals of precision to display. You can only use one override tag per cell but you can combine an override tag with a precision setting.
Override tags can be used with both the Jupyter cell magic and the function decorator. To use a override tag with the decorator, you just supply it as an argument, e.g. @handcalc(override='params', precision=2)
I will compare a basic rendering of the quadratic formula (below) with the change achieved with each override tag.
Basic rendering:
params:
handcalcs renders lines of code vertically, one after the other. However, when you are assigning variables, or displaying resulting variables, you may not want to waste all of that vertical space.
Using the params override tag, your list of parameters will instead render in three columns, thereby saving vertical space. Additionally, onsly the result will be shown, no calculations.
Adjust precision:
The number of decimal places in a cell can be adjusted by providing an integer after %%render to indicate the decimal precision to be displayed. Can be combined with another override tag.
long and short:
To save vertical space, handcalcsattempts to figure out how long your calculation is and, if it is short enough, renders it out fully on one line.
If handcalcs's internal test deems the calculation as being too long to fit onto one line, it breaks it out into multiple lines.
Use the # long or # short override tags to override the length check and display the calculation in the "Long" format or the "Short" format for all calculations in the cell. e.g.
long: Spans multiple lines as though you had a long equation
short: Forced to a single line as though you had a short equation
# Format for "short" calculations (can fit on one line):c=2*a+b/3=2*(2) + (3)/3=5# Format for "long" calculations (requires multi-line format)c=2*a+b/3=2*(2) + (3)/3=5
symbolic
The primary purpose of handcalcs is to render the full calculation with the numeric substitution. This allows for easy traceability and verification of the calculation.
However, there may be instances when it is preferred to simply display calculations symbolically. For example, you can use the symbolic tag to use handcalcs as a fast way to render Latex equations symbolically.
Alternatively, you may prefer to render out all of input parameters in one cell, your formulae symbolically in the following cell, and then all the final values in the last cell, skipping the numeric substitution process entirely.
Keep in mind that even if you use the symbolic tag with your calculations, you still need to declare those variables (by assigning values to them) ahead of time in order for your calculation to be valid Python.
sympy
This is intended to be used only with sympy loaded. Sympy allows for symbolic manipulation, solving, and integration of algebraic expressions. Sympy will render its own objects in Latex without handcalcs.
If you are manipulating a sympy expression or sympy equation for the purpose of calculation, you can use handcalcs to handle the substitution and calculation of your resulting expression.
Note: Re-assigning your symbolic variables to numbers will clobber them as sympy variables. However, you are done with these now, right? So, it's no problem. If you need to work symbolically again, just re-run your notebook cells from the top.
Units Packages Compatibility
handcalcs was designed to be used with the units package, forallpeople (and forallpeople was designed to be compatible with handcalcs). However, it has been recently reported that pint can work to good effect, also.
For potential compatibility with other units packages, please see the wiki.
Features
Quickly display the values of many variables
No more print statements needed. Just plop your variables onto a line and they will all be displayed.
Get Just the Latex Code, without the render
If you just want to generate the rendered Latex code directly to use in your own Latex files, you can use the %%tex cell magic instead:
%%texa=2b=3c=2*a+b/3
Then you can just copy and paste the result into your own LaTeX document.
Subscripts (and sub-subscripts, etc.)
Subscripts in variable names are automatically created when _ is used in the variable name. Sub-subscripts are nested for each separate _ used in series.
Greek symbols
Any variable name that contains a Greek letter (e.g. "pi", "upsilon", "eta", etc.) as a string or substring will be replaced by the appropriate Latex code to represent that Greek letter.
Using lower case letters as your variable name will make a lower case Greek letter.
Using a Capitalized Name for your variable will render it as an upper case Greek letter.
Functions, built-in or custom
If you are using Python functions in your calculation, eg. min() or tan(), they will be replaced with Latex code to represent that function in Latex.
If you are creating your own functions, then they will be rendered in Latex as a custom operator.
If you are using a function with the name sqrt (whether your own custom implementation or from math.sqrt), then it will be rendered as the radical sign.
Rendered in-line Comments
Any comments placed after a line of calculation will be rendered as an inline comment in the Latex.
This makes it convenient to make notes along side your calculations to briefly explain where you may have acquired or derived a particular value.
Skip the substitution
Any calculation entirely wrapped in parentheses, (), will be rendered as just param = result, without the substitution.
This can be convient when you want to calculate a parameter on the fly and not have it be the focus of the calculation.
Conditional statements
Many calculations in the "real world" are dependent on context.
handcalcs allows for the inclusion of some simple conditional statements into its code in a way that makes it easier to understand the context of the calculation.
Note: Multiple "lines" of calculations can be used after the conditional expression provided that they are all on the same line and separated with ";". See Expected Behaviours for more context.
Numeric integration
You can use scipy.quad to perform numeric integration on a pre-defined function and have handcalcs perform a basic rendering of it.
This behaviour is triggered if you use a function with either integrate or quad in the name.
"Prime" notation
Sometimes you need to write "prime" on your variables:
PDF Printing in Jupyter
Note: With nbconvert v6.0, templates are handled in a different manner that is incompatible with the below method. Be sure to use nbconvert v5.6.1 to allow template installation and swapping.
Jupyter Notebooks/Lab are able to print notebooks to PDF through two methods. Both can produce great results with handcalcs:
Export to HTML: Open the exported HTML page in your browser and print to PDF using your system's own PDF printer
Pros: No additional software required, you can include images copy-pasted into your Jupyter notebook, and you can change the scale of the printed PDF in your brower's print window.
Cons: Page breaks can be less graceful on html output and you cannot otherwise customize the output further like you can with a .tex file
Export to PDF (via Latex): Using your previously installed Latex distribution, Jupyter will first export your notebook to a .tex file and then render the file to PDF. This requires you to have a Latex distribution already installed on your system (Instructions: windows, mac os, ubuntu).
Pros: Page breaks tend to work better and you have the ability to customize your output further using the generated .tex file
Cons: Cannot easily rescale the PDF print (e.g. to ensure really long equations fit on the page) and you cannot include images copy/pasted into your Notebook. Images can be used but must be linked in with Markdown and the file must reside in the same directory as your Notebook.
PDF notebooks made with handcalcs tend to look better if the code input cells are suppressed. To make this convenient, handcalcs ships with two modified nbconvert template files that can be installed by running a function in Jupyter before exporting.
swap_in: the name of the handcalcs template file you wish to install. When not provided, the function will print a list of available templates whose names are acceptable inputs for this argument. swap_out: the name of the nbconvert template file you wish to replace (default file is nbconvert's default html or latex template, respectively) restore: when set to True, the function will remove your previously installed template file and restore the default nbconvert template.
Design rationale
While there are methods for manually changing the template that nbconvert uses, this has to be performed on the command line as a separate conversion step. This default template override approach is not available from within the Jupyter GUI interface.
I have found that the easiest and most reliable way to quickly change the default export behaviour is to swap out and replace the default template files. By using this approach, you can export your notebooks directly from the Jupyter GUI menu options and have your notebooks look how you wish without fussing with multiple configuration settings that may or may not take.
Note
When handcalcs installs these templates, they make a semi-permanent change to your templates that will persist for all of your other notebooks that you print from with Jupyter, regardless of whether you are working with handcalcs or not. It does this because it is "physically" swapping out and replacing your nbconvert default template files for your local installation meaning it will persist past the end of your Jupyter session.
This change can be reverted at any time by using the restore = True argument. Additionally, the function will not let you repeatedly install the same template. If you wish to install another template, the function will prompt you to run the function with restore = True before attempting another installation.
In this way, handcalcs can fully manage these template installations for you. However, if you manually alter the file names of an installed handcalcs template in the nbconvert templates directory, there is no guarantee that your original template can be successfully restored.
Example of use
You can perform the same below process using either install_html or install_latex functions.
>>>fromhandcalcs.install_templatesimportinstall_html>>>fromhandcalcs.install_templatesimportinstall_latex>>>install_html() # Use with no arguments to discover available templatesAvailabletemplates:
['full_html_noinputs.tpl']
>>>install_html('full_html_noinputs.tpl') # Select the template you wish to install/usr/Name/path/to/your/nbconvert/templates/dir/html/full.tpl-isnow-/usr/Name/path/to/your/nbconvert/templates/dir/html/full_swapped.tpl/usr/Name/path/to/your/handcalcs/templates/dir/html/full_html_noinputs.tpl-isnow-/usr/Name/path/to/your/nbconvert/templates/dir/html/full.tpl>>>install_html(restore=True) # To revert this change to your template files/user/Name/path/to/your/nbconvert/templates/dir/html/full.tpl-wasrestoredfrom-/user/Name/path/to/your/nbconvert/templates/dir/html/full_swapped.tpl
Expected Behaviours
handcalcs is intended to render arithmetical calculations written in Python code. It is not intended to render arbitrary Python into Latex.
Given that, handcalcs only renders a small subset of Python and there is a lot that will not work, especially anything that happens over multiple lines (e.g. function definitions, for loops, with statements, etc.).
handcalcs works by parsing individual lines of Python within a cell. It does not parse the cell as a whole. Therefore all statements to be rendered must be contained on a single line.
请发表评论