如何在 LaTeX 中的 \ifnum 中使用 pycode 方法的返回值?

如何在 LaTeX 中的 \ifnum 中使用 pycode 方法的返回值?

我正在尝试使用 TikZ 结合 pythontex 和 cancel 包来绘制有理数平面(的剪辑),其中所有 gcd 不等于 1 的有理数都被划掉。

这是我的代码迄今为止:

\documentclass{article}
\usepackage{tikz}
\usepackage[makeroom]{cancel}
\usepackage{amsmath,amsthm,amssymb}
\usepackage{pythontex}
\usetikzlibrary{intersections,positioning,arrows.meta}

\begin{pycode}
def ggt(a,b):
    r=a%b
    i=0
    erg=1
    while r:
        a=b
        b=r
        r=a%b
    return b
\end{pycode}

\begin{document}

\begin{tikzpicture}

    \draw[-Stealth] (0,-.5) -- (0,6) node [above] {$n\in \mathbb{N}$};
    \draw[-Stealth] (-5.5,0) -- (5.5,0) node [right] {$m\in\mathbb{Z}$};
    
    \foreach \m in {-4,...,4}
        \foreach \n in {1,...,5}{
            \ifnum\py{ggt(\m,\n)}=1 {
            
                \node (\m-\n) at (\m,\n) [circle, draw, inner sep=0, minimum size=0.6 cm, fill=white] {$\frac{\m}{\n}$};}
            \else {
                
                \node (\m-\n) at (\m,\n) [circle, inner sep=0, minimum size=0.6 cm, fill=white] {$\xcancel{\frac{\m}{\n}}$};
            }\fi
        }
    
\end{tikzpicture}

\end{document}

问题:!缺失数字,视为零。“我认为,这是在\ifnum语句中引起的,在该语句中我调用了\py{ggt(\m,\n)},但显然它没有被视为数字。

我的问题:有没有办法让 LaTeX 将我的 python 方法的返回值读取为“数字”?或者有没有完全不使用 pythontex 的方法?任何帮助都非常感谢!另外,我对 LaTeX 还很陌生,所以如果我犯了任何明显或愚蠢的错误,我深表歉意。

答案1

由于您还要求提供替代方法:

您已经使用了tikz能够进行大量数学计算的包。因此,您只需使用 PGF 函数即可gcd()。您可以使用 调用相关计算\pgfmathparse{gcd(\m,\n)},然后将结果存储在名为 的宏中,\pgfmathresult您可以在子句中使用该宏\if

\documentclass{article}
\usepackage{tikz}
\usepackage[makeroom]{cancel}
\usepackage{amsmath,amsthm,amssymb}
\usetikzlibrary{intersections,positioning,arrows.meta}

\begin{document}

\begin{tikzpicture}

    \draw[-Stealth] (0,-.5) -- (0,6) node [above] {$n\in \mathbb{N}$};
    \draw[-Stealth] (-5.5,0) -- (5.5,0) node [right] {$m\in\mathbb{Z}$};
    
    \foreach \m in {-4,...,4}
        \foreach \n in {1,...,5}{
            \pgfmathparse{gcd(\m,\n)}
            \ifnum\pgfmathresult=1 {
            
                \node (\m-\n) at (\m,\n) [circle, draw, inner sep=0, minimum size=0.6 cm, fill=white] {$\frac{\m}{\n}$};}
            \else {
                
                \node (\m-\n) at (\m,\n) [circle, inner sep=0, minimum size=0.6 cm, fill=white] {$\xcancel{\frac{\m}{\n}}$};
            }\fi
        }
    
\end{tikzpicture}

\end{document}

还有一个名为的包calculator,它提供了一个宏\GCD,允许您动态计算最大公约数并将其存储在单独的宏中,然后您可以在子句中使用它\if,如下所示:

\documentclass{article}
\usepackage{tikz}
\usepackage[makeroom]{cancel}
\usepackage{amsmath,amsthm,amssymb}
\usepackage{calculator}
\usetikzlibrary{intersections,positioning,arrows.meta}

\begin{document}

\begin{tikzpicture}

    \draw[-Stealth] (0,-.5) -- (0,6) node [above] {$n\in \mathbb{N}$};
    \draw[-Stealth] (-5.5,0) -- (5.5,0) node [right] {$m\in\mathbb{Z}$};
    
    \foreach \m in {-4,...,4}
        \foreach \n in {1,...,5}{
            \GCD{\m}{\n}{\thisgcd}
            \ifnum\thisgcd=1 {
            
                \node (\m-\n) at (\m,\n) [circle, draw, inner sep=0, minimum size=0.6 cm, fill=white] {$\frac{\m}{\n}$};}
            \else {
                
                \node (\m-\n) at (\m,\n) [circle, inner sep=0, minimum size=0.6 cm, fill=white] {$\xcancel{\frac{\m}{\n}}$};
            }\fi
        }
    
\end{tikzpicture}

\end{document}

另外,你也可以用 Lua 来执行这样的计算。我找到了一个用 Lua 计算最大公约数的脚本在这个很好的答案中。请注意,您需要使用 LuaLaTeX 而不是 PDFLaTeX 来编译您的文档才能使其正常工作:

\documentclass{article}
\usepackage{tikz}
\usepackage[makeroom]{cancel}
\usepackage{amsmath,amsthm,amssymb}
\usepackage{luacode}
\usetikzlibrary{intersections,positioning,arrows.meta}

\begin{luacode}
function gcd(a,b)
    if b ~= 0 then
        return gcd(b, a % b)
    else
        return math.abs(a)
    end
end
\end{luacode}

\newcommand\findgcd[1]{\directlua{tex.sprint(gcd(#1))}}

\begin{document}

\begin{tikzpicture}

    \draw[-Stealth] (0,-.5) -- (0,6) node [above] {$n\in \mathbb{N}$};
    \draw[-Stealth] (-5.5,0) -- (5.5,0) node [right] {$m\in\mathbb{Z}$};
    
    \foreach \m in {-4,...,4}
        \foreach \n in {1,...,5}{
            \ifnum\findgcd{\m,\n}=1 {
            
                \node (\m-\n) at (\m,\n) [circle, draw, inner sep=0, minimum size=0.6 cm, fill=white] {$\frac{\m}{\n}$};}
            \else {
                
                \node (\m-\n) at (\m,\n) [circle, inner sep=0, minimum size=0.6 cm, fill=white] {$\xcancel{\frac{\m}{\n}}$};
            }\fi
        }
    
\end{tikzpicture}

\end{document}

所有上述方法都将输出以下内容:

在此处输入图片描述

答案2

这里有两个问题。(都需要理解 TeX 才能理解解决方法。)

\py没有扩展其论点。

(类型 3 的我对嵌套宏的回答。 也可以看看如何在 pythontex 中将章节编号传递给 python? - TeX - LaTeX Stack Exchange——没有学习 TeX 编程就没有完全自动化的解决方案然而

这里的一个解决方案是使用\expanded(参见下面代码中插入的代码)。替代方案包括 edef、ExpandArgs、exp_args:Nx 等。(另请参阅上面链接的答案中链接的问题)

警告:\expanded 可能不是每次都能达到你想要的效果. 确保您理解代码的作用,以便修改它。

\py不可扩展。

(类型 2 的我的答案如下

该问题已记录在 pythontex 手册中。

(我在这里附上了一张截图。如果您想阅读文本,请阅读手册。)

pythontex 文档截图

一种解决方法是遵循这一点,并定义一个打印出整个外部内容的 Python 函数。

\documentclass{article}
\usepackage{tikz}
\usepackage[makeroom]{cancel}
\usepackage{amsmath,amsthm,amssymb}
\usepackage{pythontex}
\usetikzlibrary{intersections,positioning,arrows.meta}

\begin{pycode}
def ggt(a,b):
    r=a%b
    i=0
    erg=1
    while r:
        a=b
        b=r
        r=a%b
    return b

def print_my_command(m, n):
    print(
            r'\ifnum' + str(ggt(m, n)) + r'''=1 {
            
                \node (\m-\n) at (\m,\n) [circle, draw, inner sep=0, minimum size=0.6 cm, fill=white] {$\frac{\m}{\n}$};}
            \else {
                
                \node (\m-\n) at (\m,\n) [circle, inner sep=0, minimum size=0.6 cm, fill=white] {$\xcancel{\frac{\m}{\n}}$};
            }\fi'''
            )

\end{pycode}

\begin{document}

\begin{tikzpicture}

    \draw[-Stealth] (0,-.5) -- (0,6) node [above] {$n\in \mathbb{N}$};
    \draw[-Stealth] (-5.5,0) -- (5.5,0) node [right] {$m\in\mathbb{Z}$};
    
    \foreach \m in {-4,...,4}
        \foreach \n in {1,...,5}{
            \expanded{\pyc{print_my_command(\m,\n)}}
        }
    
\end{tikzpicture}

\end{document}

虽然如果你这样做,你最好在 Python 中检查一下。print_my_command

def print_my_command(m, n):
    if ggt(m, n)==1:
        print(r""" \node (\m-\n) at (\m,\n) [circle, draw, inner sep=0, minimum size=0.6 cm, fill=white] {$\frac{\m}{\n}$}; """)
    else:
        print(r""" \node (\m-\n) at (\m,\n) [circle, inner sep=0, minimum size=0.6 cm, fill=white] {$\xcancel{\frac{\m}{\n}}$}; """)

您还可以在 Python 端将 替换\m为 的值。m


另一种解决方法,这个需要更多的 TeX 知识,是使用临时变量,如我上面链接的答案中所述。

\documentclass{article}
\usepackage{tikz}
\usepackage[makeroom]{cancel}
\usepackage{amsmath,amsthm,amssymb}
\usepackage{pythontex}
\usetikzlibrary{intersections,positioning,arrows.meta}

\begin{pycode}
def ggt(a,b):
    r=a%b
    i=0
    erg=1
    while r:
        a=b
        b=r
        r=a%b
    return b

def my_set_ggt(m, n):
    print(r"\def\mytmpggt{" + str(ggt(m, n)) + "}")
\end{pycode}

\begin{document}

\begin{tikzpicture}

    \draw[-Stealth] (0,-.5) -- (0,6) node [above] {$n\in \mathbb{N}$};
    \draw[-Stealth] (-5.5,0) -- (5.5,0) node [right] {$m\in\mathbb{Z}$};
    
    \foreach \m in {-4,...,4}
        \foreach \n in {1,...,5}{
            \def\mytmpggt{0}
            \expanded{\pyc{my_set_ggt(\m,\n)}}
            \ifnum\mytmpggt=1 {
            
                \node (\m-\n) at (\m,\n) [circle, draw, inner sep=0, minimum size=0.6 cm, fill=white] {$\frac{\m}{\n}$};}
            \else {
                
                \node (\m-\n) at (\m,\n) [circle, inner sep=0, minimum size=0.6 cm, fill=white] {$\xcancel{\frac{\m}{\n}}$};
            }\fi
        }
    
\end{tikzpicture}

\end{document}

边注,括号内的内容\ifnum与你想象的并不一样。如果你想学习,请阅读 TeXbook(或 TeX by Topic,TeX in a nutshell)。

答案3

既然您要求替代方法:

您可以替换pythontexpyluatex.
你必须使用 LuaLaTeX 进行编译:lualatex -shell-escape <yourfile.tex>

\documentclass{article}
\usepackage{tikz}
\usepackage[makeroom]{cancel}
\usepackage{amsmath,amsthm,amssymb}
\usepackage{pyluatex}                % <--- changed
\usetikzlibrary{intersections,positioning,arrows.meta}

\begin{python}                       % <--- changed
def ggt(a,b):
    r=a%b
    i=0
    erg=1
    while r:
        a=b
        b=r
        r=a%b
    return b
\end{python}                         % <--- changed

\begin{document}

\begin{tikzpicture}

    \draw[-Stealth] (0,-.5) -- (0,6) node [above] {$n\in \mathbb{N}$};
    \draw[-Stealth] (-5.5,0) -- (5.5,0) node [right] {$m\in\mathbb{Z}$};
    
    \foreach \m in {-4,...,4}
        \foreach \n in {1,...,5}{
            \ifnum\py{ggt(\m,\n)}=1 {
            
                \node (\m-\n) at (\m,\n) [circle, draw, inner sep=0, minimum size=0.6 cm, fill=white] {$\frac{\m}{\n}$};}
            \else {
                
                \node (\m-\n) at (\m,\n) [circle, inner sep=0, minimum size=0.6 cm, fill=white] {$\xcancel{\frac{\m}{\n}}$};
            }\fi
        }
    
\end{tikzpicture}

\end{document}

然后你甚至可以使用以下\pyif命令:

\pyif{ggt(\m,\n) == 1}{
    \node (\m-\n) at (\m,\n) [circle, draw, inner sep=0, minimum size=0.6 cm, fill=white] {$\frac{\m}{\n}$};
}{
    \node (\m-\n) at (\m,\n) [circle, inner sep=0, minimum size=0.6 cm, fill=white] {$\xcancel{\frac{\m}{\n}}$};
}

相关内容