使用 `sage` 系列在 PythonTeX 中进行数字格式化

使用 `sage` 系列在 PythonTeX 中进行数字格式化

我正在尝试在家庭中使用一种特殊的数字格式,pythontex但是sage没有效果。

这是一个示例,展示了它应该是什么样子以及我迄今为止尝试过什么。

我怎样才能让它工作?

\documentclass{article}

\usepackage[gobble=auto,usefamily=sage]{pythontex}
\usepackage{xparse}
\usepackage{amsmath}  

\DeclareDocumentCommand{\sageN}{O{} m}
{%
\sage[#1]{str(#2).replace('.',',')}%
}


\DeclareDocumentCommand{\sageR}{O{} m O{2}}
{%
\sage[#1]{str(round(#2,#3)).replace('.',',')}%
}

\begin{pythontexcustomcode}{sage}
def roundIf(a,n):     
    if (type(a) == type(1.2)) | (type(a) == type(sqrt(2).n())):
        return round(a,n)
    else:
        return a
\end{pythontexcustomcode}

\DeclareDocumentCommand{\sageRIF}{O{} m O{2}}
{%
\sage[#1]{str(roundIf(#2,#3)).replace('.',',')}%
}

\usepackage{icomma}
\usepackage{tcolorbox}

\newtcolorbox{example}{}

\begin{document}

\begin{sagecode}[MySession]
a = 3.42000 ## number with trailing zeros
b = sqrt(3) ## symbolic square root
c = 3/7 ## fraction
d = 5 ## integer
e = pi.n() ## First Decimals of pi
\end{sagecode}

\section*{How it should look like}


\begin{example}
\begin{align*}
a &= 3,42\\ 
b &= \sqrt{3}\\ 
c &= \frac{3}{7}\\ 
d &= 5\\
e &= 3,14159
\end{align*}
\end{example}




\section*{Output with sage}

\begin{example}
\begin{align*}
a &= \sage[MySession]{a}\\ 
b &= \sage[MySession]{b}\\ 
c &= \sage[MySession]{c}\\ 
d &= \sage[MySession]{d}\\
e &= \sage[MySession]{e}\\
\end{align*}
\end{example}


\section*{Output with sageN}


\begin{example}
\begin{align*}
a &= \sageN[MySession]{a}\\ 
b &= \sageN[MySession]{b}\\ 
c &= \sageN[MySession]{c}\\ 
d &= \sageN[MySession]{d}\\
e &= \sageN[MySession]{e}\\
\end{align*}
\end{example}

\section*{Output with sageR}


\begin{example}
\begin{align*}
a &= \sageR[MySession]{a}\\ 
b &= \sageR[MySession]{b}\\ 
c &= \sageR[MySession]{c}\\ 
d &= \sageR[MySession]{d}\\
e &= \sageR[MySession]{e}[5]\\
\end{align*}
\end{example}




\section*{Output with sageRIF}

\begin{example}
\begin{align*}
a &= \sageRIF[MySession]{a}\\ 
b &= \sageRIF[MySession]{b}\\ 
c &= \sageRIF[MySession]{c}\\ 
d &= \sageRIF[MySession]{d}\\
e &= \sageRIF[MySession]{e}[5]\\
\end{align*}
\end{example}


\end{document}

在此处输入图片描述

在此处输入图片描述

答案1

pythontex_engines.py正如您在sage 系列文件中看到的,latexsage 函数用于预格式化输出(pytex.formatter):

SubCodeEngine('python', 'sage', language='sage', extension='.sage',
              template=python_template.replace('{future}', ''),
              extend = 'pytex.formatter = latex',
              commands='{sage} {file}.sage')

因此,您的预期输出会被该函数额外修改latex。我认为这是您忽略的一点。

您的代码的可能修改(我仅取最后一个例子)可能如下所示:

\documentclass{article}

\usepackage[gobble=auto,usefamily=sage]{pythontex}
\usepackage{xparse}
\usepackage{amsmath}  


\begin{pythontexcustomcode}{sage}
def roundIf(a,n):     
    if (type(a) == type(1.2)) | (type(a) == type(sqrt(2).n())):
        return LatexExpr(str(round(a,n)).replace('.',','))
    else:
        return a
\end{pythontexcustomcode}

\DeclareDocumentCommand{\sageRIF}{O{} m O{2}}
{%
\sage[#1]{roundIf(#2,#3)}%
}

\usepackage{icomma}
\usepackage{tcolorbox}

\newtcolorbox{example}{}

\begin{document}

\begin{sagecode}[MySession]
a = 3.42000 ## number with trailing zeros
b = sqrt(3) ## symbolic square root
c = 3/7 ## fraction
d = 5 ## integer
e = pi.n() ## First Decimals of pi
\end{sagecode}

\section*{How it should look like}


\begin{example}
\begin{align*}
a &= 3,42\\ 
b &= \sqrt{3}\\ 
c &= \frac{3}{7}\\ 
d &= 5\\
e &= 3,14159
\end{align*}
\end{example}


\section*{Output with sageRIF}

\begin{example}
\begin{align*}
a &= \sageRIF[MySession]{a}\\ 
b &= \sageRIF[MySession]{b}\\ 
c &= \sageRIF[MySession]{c}\\ 
d &= \sageRIF[MySession]{d}\\
e &= \sageRIF[MySession]{e}[5]\\
\end{align*}
\end{example}
\end{document}

输出:

在此处输入图片描述

另一个解决方案可能只是更改格式化程序pythontex_engines.py,但我不知道如何在您的 tex 文件中直接修改它。

答案2

首先,对于一般用途,如果不能用 sqrt (type(a) == type(2**(1/2))代替,则需要进行小的修改(type(a) == type(sqrt(2).n())

第二个扩展用于复数

def roundIf(a,n=16,eps=0):
    if (type(a) == type(1.2)) | (type(a) == type(2**(1/2))):
        return str(round(a,n)).replace('.','{,}')
    elif (type(a) == type(1.2j)) | (type(a) == type((-1)**(1/2))):
        rp=a.real; ip=a.imag
        if (eps>0) & (abs(rp)<eps):
            rp = ''
        elif (eps<0) & (abs(rp)>eps):
            rp = '0.0'
        else:
            rp = str(round(rp,n)).replace('.','{,}')
        if (eps>0) & (abs(ip)<eps):
            ip = ''
        elif (eps<0) & (abs(ip)>eps):
            ip = '0.0\\imath'
        else:
            ip = str(round(ip,n)).replace('.','{,}')+'\\imath'
        if (rp == '') | (ip == ''):
            return rp+ip
        else:
            return rp+'+'+ip
    else:
        return a

如果存在真实或虚构的伪影,则可以决定是否省略它(eps>0)或将其打印为零(eps<0)。

相关内容