Project Icon

handcalcs

Python 计算代码转手写风格 LaTeX 公式的工具

handcalcs 是一个 Python 库,能将计算代码自动渲染为 LaTeX 格式,呈现手写计算的风格。它展示符号公式、数值替换和结果,便于手动核查。该工具可在 Jupyter 中作为单元魔法使用,也可作为函数装饰器应用。handcalcs 支持多种自定义设置,兼容 forallpeople 等单位包,并具备快速显示变量值、生成 LaTeX 代码等功能,适合工程计算使用。

覆盖率状态


封面设计:Joshua Hoiberg

handcalcs:
在Jupyter中进行Python计算,
就像手写一样。

handcalcs是一个库,可以自动将Python计算代码渲染成Latex,但其方式模仿了用铅笔手写计算的格式:先写出符号公式,然后是数值代入,最后是结果。

由于handcalcs显示了数值代入过程,计算变得更容易通过手工检查和验证。

目录

基本演示

handcalcs演示1

安装

你可以使用pip安装:

pip install handcalcs

要安装可选的nbconvert"无输入"导出器,请使用:

pip install "handcalcs[exporters]"

新功能

从v1.9.0版本开始,handcalcs不再安装"无输入"nbconvert导出器。这是为了减轻handcalcs的安装负担并确保包的适当范围。nbconvert导出器现在"超出范围",并在https://github.com/connorferster/nb-hideinputs单独维护。

基本用法1:作为Jupyter单元格魔法命令(%%render

handcalcs旨在与Jupyter Notebook或Jupyter Lab一起使用,作为一个_单元格魔法命令_。

首先,导入模块并运行单元格:

import handcalcs.render

注意:这将在Jupyter Notebook中导入%%tex%%render魔法命令。

然后,在任何你想用handcalcs渲染的单元格中,只需在单元格顶部使用render单元格魔法命令:

%%render

例如:

%%render
a = 2
b = 3
c = 2*a + b/3

就是这样!

渲染后,如果你的系统上安装了Latex环境,你就可以将笔记本导出为PDF。如果你是Latex新手,想在系统上安装它以使用此功能,请参阅wiki中的安装Tex部分。

你还可以使用%%tex命令将任何Python代码片段转换为有效的LaTex。例如:

首先导入handcalcs。我们还从__math__包中导入了一些属性/函数,用于下面的示例。

import handcalcs.render
from math import sqrt, pi

现在,你也可以使用%%tex魔法命令!

%%tex
a = 2 / 3 * sqrt(pi)

这将产生如下LaTeX输出:

\[
\begin{aligned}
a &= \frac{ 2 }{ 3 } \cdot \sqrt{ \pi } = \frac{ 2 }{ 3 } \cdot \sqrt{ 3.142 } &= 1.182
\end{aligned}
\]

基本用法2:作为函数的装饰器,@handcalc()

感谢@eriknw开发innerscope并主动将其集成到handcalcs中。谢谢!

首先导入@handcalc()装饰器:

from handcalcs.decorator import handcalc

@handcalc([override: str = "", precision: int = 3, left: str = "", right: str = "", jupyter_display: bool = False])

返回一个由 (latex_code: str, locals: dict) 组成的元组,其中 locals 是函数命名空间内所有变量的字典。

  • override 是表示可接受的覆盖标签之一的字符串(见下文)
  • precision 是一个整数,用于改变显示的小数精度
  • leftright 是可以在编码后的 Latex 字符串前后添加的字符串,如 \\[\\]$$
  • jupyter_display 为 True 时,将只返回 locals 字典,而会使用 IPython.display 中的 display(Latex(latex_code)) 显示编码后的 Latex 字符串渲染。如果不在 Jupyter 环境中使用,将会返回错误
  • record 为 True 时,将激活 HandcalcsCallRecorder 以允许函数"回溯"先前的输出(见下文)v1.8.0 新功能

在你装饰的函数中,从 def my_calc(...) 到 return 语句(如果有)之间的所有内容现在就像 Jupyter 单元格中的代码,只不过它是一个标准的 Python 函数。

以这种方式使用时,你可以使用 @handcalc() 来动态生成 Latex 代码,以在 Jupyter 和非 Jupyter Python 环境(如 streamlit)中显示。

HandcalcsCallRecorder(v1.8.0 新功能)

HandcalcsCallRecorder 是一种新的函数包装器,可以通过 @handcalc 装饰器使用。要激活它,请在装饰器函数的参数中选择 record=True

其预期用例是在迭代过程中。在工程中,通常需要在表格或 DataFrame 中计算大量值。表格本身包含计算结果,但不一定显示计算步骤。HandcalcsCallRecorder 允许你显示已由装饰函数处理的计算迭代之一的计算过程,如下例所示:

全局配置选项(v1.6.0 新功能)

这是 handcalcs 的一个重要新版本,引入了全局配置功能。这允许用户控制 handcalcs 工作方式的多个选项。配置选项及其默认值如下:

  • decimal_separator = "."
  • latex_block_start = "\\["
  • latex_block_end = "\\]"
  • math_environment_start = "aligned"
  • math_environment_end = "aligned"
  • line_break = "\\\\[10pt]"
  • use_scientific_notation = False
  • display_precision = 3
  • underscore_subscripts = True
  • greek_exclusions = []
  • param_columns = 3
  • preferred_string_formatter = "L"
  • custom_symbols = {}

配置 API

import handcalcs.render

handcalcs.set_option("display_precision", 4)
handcalcs.set_option("param_columns", 5) 
handcalcs.set_option("line_break", "\\\\[20pt]") 
handcalcs.set_option("greek_exclusions", ["psi"]) # 等等...

这些更改现在会影响当前会话中渲染的所有单元格。如果你想永久更新 config.json 文件以保存这些更改(这样 handcalcs 在下次启动时就会使用这些选项),你可以调用 handcalcs.save_config(),这些更改将被保存(并在下一个会话中立即可用)。

自定义符号(v1.7.0 新功能)

你现在可以向全局配置添加自定义符号,以处理 handcalcs 未考虑到的所有情况。

例如:

handcalcs.set_option("custom_symbols", {"V_dot": "\\dot{V}", "N_star": "N^{*}"})

现在将允许这种渲染:

handcalcs.set_option() 函数的文档字符串展示了可用的选项及其取值。

覆盖标签

handcalcs 对你希望如何格式化计算做出了某些假设,在这方面不允许进行大量定制。然而,目前有四种定制可以使用 # override tags 作为 %%render 单元格魔术后的参数来实现。此外,你还可以指定要显示的小数精度。每个单元格只能使用一个覆盖标签,但你可以将覆盖标签与精度设置结合使用。

覆盖标签可以与 Jupyter 单元格魔术和函数装饰器一起使用。要在装饰器中使用覆盖标签,只需将其作为参数提供,例如 @handcalc(override='params', precision=2)

我将比较二次方程公式的基本渲染(如下)与每个覆盖标签实现的变化。

params

handcalcs 垂直渲染代码行,一行接一行。然而,当你分配变量或显示结果变量时,你可能不想浪费所有的垂直空间。

使用 params 覆盖标签,你的参数列表将改为以三列渲染,从而节省垂直空间。此外,只会显示结果,不会显示计算过程。 参数覆盖示例


调整精度:

单元格中的小数位数可以通过在%%render后提供一个整数来调整,以指示要显示的小数精度。可以与其他覆盖标签组合使用。

精度覆盖示例


longshort

为了节省垂直空间,handcalcs会尝试判断计算的长度,如果足够短,就会将其完整地呈现在一行上。

如果handcalcs的内部测试认为计算太长而无法放在一行上,它会将其分成多行。

使用# long# short覆盖标签可以覆盖长度检查,并以"长"格式或"短"格式显示单元格中的所有计算。例如:

long:跨多行展示,就像你有一个长方程一样

长覆盖示例

short:强制显示在单行上,就像你有一个短方程一样

    # "短"计算的格式(可以放在一行中):
    c = 2*a + b/3 = 2*(2) + (3)/3 = 5

    # "长"计算的格式(需要多行格式)
    c = 2*a + b/3
      = 2*(2) + (3)/3
      = 5

短覆盖示例


symbolic

handcalcs的主要目的是渲染完整的计算过程,包括数值替换。这允许轻松地追踪和验证计算。

然而,在某些情况下,可能更希望以符号形式显示计算。例如,你可以使用symbolic标签将handcalcs作为一种快速渲染符号形式Latex方程的方法。

或者,你可能更喜欢在一个单元格中渲染所有输入参数,在下一个单元格中以符号形式渲染公式,然后在最后一个单元格中渲染所有最终值,完全跳过数值替换过程。

请记住,即使你在计算中使用symbolic标签,你仍然需要提前声明这些变量(通过给它们赋值)以使你的计算成为有效的Python代码。

短覆盖示例


sympy

这个标签仅适用于已加载sympy的情况。Sympy允许对代数表达式进行符号操作、求解和积分。Sympy会自行将其对象渲染为Latex,无需handcalcs。

如果你正在操作sympy表达式或方程以进行计算,可以使用handcalcs来处理结果表达式的替换和计算。

注意:将符号变量重新赋值为数字会覆盖它们作为sympy变量的性质。不过,你现在已经完成了这些操作,对吧?所以这不是问题。如果你需要再次进行符号运算,只需从头重新运行你的notebook单元格即可。

Sympy演示


单位包兼容性

handcalcs设计时考虑了与单位包forallpeople的兼容性(而forallpeople也设计为与handcalcs兼容)。然而,最近有报告称pint也可以很好地工作。

显示变量演示

关于与其他单位包的潜在兼容性,请参阅wiki


特性

快速显示多个变量的值

不再需要print语句。只需将你的变量放在一行上,它们就会全部显示出来。

显示变量演示

仅获取Latex代码,不渲染

如果你只想直接生成渲染后的Latex代码以在自己的Latex文件中使用,可以使用%%tex单元格魔法:

%%tex
a = 2
b = 3
c = 2*a + b/3

然后你可以直接复制结果并粘贴到你自己的LaTeX文档中。

tex单元格魔法演示


下标(以及子下标等)

当变量名中使用_时,会自动创建下标。连续使用多个_会创建嵌套的子下标。

下标演示

希腊符号

任何包含希腊字母(如"pi"、"upsilon"、"eta"等)作为字符串或子字符串的变量名将被替换为表示该希腊字母的适当Latex代码。

符号替换符号替换
alphaαAlphaΑ
betaβBetaΒ
gammaγGammaΓ
deltaδDeltaΔ
epsilon, varepsilonϵ, εEpsilonΕ
zetaζZetaΖ
etaηEtaΗ
theta, varthetaθ, ϑThetaΘ
iotaιIotaΙ
kappaκKappaΚ
lambλLambΛ
muμMuΜ
nuνNuN
xiξXiΞ
omicronοOmicronΟ
pi, varpiπ, ϖPiΠ
rho, varrhoρ, ϱRhoΡ
sigma, varsigmaσ, ςSigmaΣ
tauτTauΤ
upsilonυUpsilonΥ
phi, varphiφ, ϕPhiΦ
chiχChiΧ
psiψPsiΨ
omegaωOmegaΩ
  • 使用小写字母作为变量名将生成小写希腊字母。

  • 使用大写字母开头的变量名将生成大写希腊字母。

希腊符号演示


函数,内置或自定义

如果你在计算中使用Python函数,例如min()tan(),它们将被替换为表示该函数的Latex代码。

如果你创建自己的函数,它们将在Latex中被渲染为自定义运算符。

如果你使用名为sqrt的函数(无论是你自己的自定义实现还是来自math.sqrt),它将被渲染为根号符号。

函数


渲染行内注释

放在计算行后的任何注释都将在Latex中被渲染为行内注释。

这使得在计算旁边添加注释变得方便,可以简要解释你可能获得或推导出某个特定值的来源。

注释


跳过替换

完全包裹在括号()中的任何计算将仅渲染为param = result,而不进行替换。

当你想即时计算一个参数但不希望它成为计算的焦点时,这会很方便。

跳过替换


条件语句

现实世界中的许多计算都依赖于具体情况。

handcalcs允许以一种更容易理解计算上下文的方式在其代码中包含一些简单的条件语句。

条件计算

注意:条件表达式后可以使用多个"行"的计算,只要它们都在同一行上并用";"分隔。更多背景信息请参见预期行为


数值积分

你可以使用scipy.quad对预定义函数进行数值积分,并让handcalcs对其进行基本渲染。

如果你使用名称中包含integratequad的函数,就会触发这种行为。

数值积分


"Prime"记号

有时你需要在变量上写"prime":

Prime记号


Jupyter中的PDF打印

注意:自 nbconvert v6.0 起,不再需要安装模板(如旧版 YouTube 视频所示)。安装 handcalcs 时会同时安装适用于 Jupyter Notebook/Lab 的 Exporter,为您提供两个新的"文件 -> 保存并导出为"选项:

  1. 导出 HTML_NoInput
  2. 导出 LaTeX_NoInput
  3. 导出 PDF_NoInput

这些选项会隐藏所有输入单元格,使您在 Jupyter 笔记本中只能看到渲染后的输出。

通过使用这三个选项,您可以通过 HTML(然后从浏览器打印 PDF)或通过 LaTeX(直接或通过您自己的 LaTeX 环境)创建 PDF 导出。


预期行为

handcalcs 旨在渲染用 Python 代码编写的算术计算。它并非用于将任意 Python 代码渲染为 LaTeX。

鉴于此,handcalcs 仅渲染 Python 的一小部分子集,许多内容无法正常工作,尤其是跨多行的内容(如函数定义、for 循环、with 语句等)。

handcalcs 通过解析单元格内的单独 Python 行来工作。它不会将单元格作为一个整体进行解析。因此,所有要渲染的语句必须包含在单行内。

接受的数据类型

handcalcs 会尝试渲染所有数据类型。然而,它目前还不能渲染所有基于"集合"的数据类型,如 list 和 dict。如果您使用集合来保存参数函数,例如 sum((23, 123, 45)),请使用元组以确保正确渲染。或者,您可以在 handcalcs 中使用一维 numpy 数组(向量)。

对象通过两种主要方法渲染为 LaTeX:

  1. 如果对象定义了 repr_latex() 方法,则使用该方法。

    a) 如果对象有其他将自身渲染为 LaTeX 代码的方法,如 .latex() 或 .to_latex(),也会尝试使用。

    为了正确渲染表示,对象的 LaTeX 表示必须使用 MathJax 和/或 KaTeX 实现的命令。

  2. 如果对象没有 LaTeX 方法,则使用 str()。

如果您使用的对象类型具有渲染为 <MyObject: value=34> 的 str 方法,那么 LaTeX 解释器将看到并尝试渲染这个内容。

算术运算符

    • 渲染为 +
    • 渲染为 -
    • 渲染为"点运算符"(LaTeX:\cdot)
  • / 始终渲染为分数
  • ** 渲染为上标
  • % 渲染为"模函数"(LaTeX:\mod)

目前不支持渲染 //,但您可以使用 math.floor 函数作为替代(作为 floor)。

for 循环和其他迭代

目前不支持显示渲染后的迭代。预期用法是在不渲染的单元格中执行迭代,然后在单独的单元格中渲染迭代产生的最终结果值。

注意事项

由于 handcalcs 设计用于 Jupyter 环境,且 Jupyter 单元格可以乱序运行,如果您在整个笔记本中重复使用变量名,可能会导致一堆渲染精美但完全错误的计算结果。

handcalcs 使用笔记本的用户命名空间字典来查找命名空间中所有变量的值。如果您的计算在整个笔记本中重复使用变量名,那么当您以非预期顺序运行单元格时,该名称的字典条目可能与您想象的不同。

如果单元格按正确顺序运行(从上到下更容易),您可以在整个笔记本中有效地重复使用变量名。

关于这一点:如果您使用 handcalcs 进行可能成为法律文件的报告(如设计工程计算),确保结果符合您的预期是您的责任。handcalcs 是免费开源软件,作者不对使用它而导致的错误计算负责。

话虽如此,handcalcs 渲染数学的方式的目的就是让手动确认和验证计算变得非常容易。

YouTube 教程

handcalcs 入门(假设零 Python 知识)

https://www.youtube.com/watch?v=ZNFhLCWqA_g

工程计算:handcalcs-on-Jupyter vs. Excel

https://www.youtube.com/watch?v=n9Uzy3Eb-XI

应用和与其他人的包的兼容性

**请查看wiki,了解 handcalcs 在教育和工程中的应用,以及与其他 Python 库(如 streamlitpapermill)一起使用 handcalcs 的示例。

项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

白日梦AI

白日梦AI提供专注于AI视频生成的多样化功能,包括文生视频、动态画面和形象生成等,帮助用户快速上手,创造专业级内容。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

讯飞绘镜

讯飞绘镜是一个支持从创意到完整视频创作的智能平台,用户可以快速生成视频素材并创作独特的音乐视频和故事。平台提供多样化的主题和精选作品,帮助用户探索创意灵感。

Project Cover

讯飞文书

讯飞文书依托讯飞星火大模型,为文书写作者提供从素材筹备到稿件撰写及审稿的全程支持。通过录音智记和以稿写稿等功能,满足事务性工作的高频需求,帮助撰稿人节省精力,提高效率,优化工作与生活。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号