我正在尝试创建一个可以生成复三项式的宏。
我编写的代码在 80% 的情况下都能按预期编译,但在 20% 的情况下会给出一大堆错误消息。你可以在此 ShareLaTeX 链接。如果您多次按下“重新编译”,您会发现它有时会编译,有时则不会。
错误包括:
- 缺失数字视为零
- 非法计量单位
- 额外\其他
- 缺少结束 \csname
- 额外的 \endcsname
- 未定义的控制序列
- 失控的论点
即在 15% 的时间内无法编译,一大堆事情会同时出错。
我的代码有什么问题?我猜想这与随机数/项目/列表未正确编码有关,但我不确定。
\documentclass{article}
\usepackage[margin=1cm]{geometry}
\usepackage{ifthen}
\usepackage{pgf}
\usepackage{pgffor}
\setlength{\parindent}{0pt}
\pagestyle{empty}
\pgfmathsetseed{\number\pdfrandomseed}
\newcommand{\InitVariablesCTPP}
{%
% I want the equation to be in the form (ax+b)(cx+d)=Ax^2+Bx+C.
%but I want there to be NO common factors.
%So, these lists mean that if, say, c=2, then d is selected randomly from 1,3,5, or 7.... at least that was the intention.
\pgfmathdeclarerandomlist{IfOne}{{1}{2}{3}{4}{5}{6}{7}}
\pgfmathdeclarerandomlist{IfTwo}{{1}{3}{5}{7}}
\pgfmathdeclarerandomlist{IfThree}{{1}{2}{4}{5}{7}}
\pgfmathdeclarerandomlist{IfFour}{{1}{3}{5}{7}}
\pgfmathdeclarerandomlist{IfFive}{{1}{2}{3}{4}{6}{7}}
\pgfmathsetmacro{\a}{int(random(1,5))}
\ifcase\a\relax%
\or \pgfmathrandomitem{\b}{IfOne}
\or \pgfmathrandomitem{\b}{IfTwo}
\or \pgfmathrandomitem{\b}{IfThree}
\or \pgfmathrandomitem{\b}{IfFour}
\or \pgfmathrandomitem{\b}{IfFive} \fi
\pgfmathsetmacro{\c}{int(random(2,5))}
\ifcase\c\relax%
\or \pgfmathrandomitem{\d}{}
\or \pgfmathrandomitem{\d}{IfTwo}
\or \pgfmathrandomitem{\d}{IfThree}
\or \pgfmathrandomitem{\d}{IfFour}
\or \pgfmathrandomitem{\d}{IfFive}
\fi
\pgfmathsetmacro{\A}{int(\a*\c)}
\pgfmathsetmacro{\B}{int(\a*\d+\b*\c)}
\pgfmathsetmacro{\C}{int(\b*\d)}
}
\newcommand{\ManyCTPP}[1]
{%
\foreach \x in {1,2,3,...,#1}
{
\InitVariablesCTPP
a=\a\\
b=\b\\
c=\c\\
d=\d\\
A=\A =\a * \c \\
B=\B =\a * \d + \b * \c\\
C=\C =\b * \d\\
\(({\a}x+{\b})({\c}x+{\d})={\A}x^2+{\B}x+{\C}\)
\\
\vspace{1cm}}
}
\begin{document}
\section{Complex Trinomials}
\ManyCTPP{5}
\end{document}
答案1
什么出现会发生这种情况,您正在选择两个随机列表元素\b
和\d
,当您要使用它们时,随机列表的最后一个“索引”用于和\b
。\d
这是有问题的,因为,例如,如果\d
正在使用列表项编号 6 并且\b
是列表中的一个项目,IfTwo
那么您会得到一个missing number
,因为IfTwo
没有项目 6。
解决该问题的一种方法是强制 \b
,并\d
在定义时使用类似以下内容进行扩展:
\xdef\b{\b}
您的代码还存在一些其他问题:
- 用于
\a, \b, \c, \d, \A, \B, \C, \x
宏/变量名称并不是一个好主意,因为其中一些与 latex 使用的内部宏相冲突 - 正如 David 在评论中指出的那样,这
\pgfmathrandomitem{\d}{}
行是错误的。应该是\pgfmathrandomitem{\d}{IfOne}
。(好吧,因为\c
介于之间2
,并且5
此代码永远不会执行...) - 你只需要定义一次随机列表,因此你应该
\pgfmathdeclarerandomlist
从 Init 宏中删除这些行 - 除了使用之外,
\pgfmathsetmacro{\a}{int(random(1,5))}
您还可以使用\pgfmathrandominteger{\a}{1}{5}
- 而
\foreach \x in {1,2,3,...,#1}
不是写\foreach \x in {1,...,#1}
\\
是一个糟糕的结束方式...
考虑到这些要点,您的代码将变为:
\documentclass{article}
\usepackage[margin=1cm]{geometry}
\usepackage{ifthen}
\usepackage{pgf}
\usepackage{pgffor}
\setlength{\parindent}{0pt}
\pagestyle{empty}
\pgfmathsetseed{\number\pdfrandomseed}
% I want the equation to be in the form (ax+b)(cx+d)=Ax^2+Bx+C.
%but I want there to be NO common factors.
%So, these lists mean that if, say, c=2, then d is selected randomly from 1,3,5, or 7.... at least that was the intention.
\pgfmathdeclarerandomlist{IfOne}{{1}{2}{3}{4}{5}{6}{7}}
\pgfmathdeclarerandomlist{IfTwo}{{1}{3}{5}{7}}
\pgfmathdeclarerandomlist{IfThree}{{1}{2}{4}{5}{7}}
\pgfmathdeclarerandomlist{IfFour}{{1}{3}{5}{7}}
\pgfmathdeclarerandomlist{IfFive}{{1}{2}{3}{4}{6}{7}}
\newcommand{\InitVariablesCTPP}{
\pgfmathrandominteger{\avar}{1}{5}
\ifcase\avar\relax%
\or \pgfmathrandomitem{\bvar}{IfOne}
\or \pgfmathrandomitem{\bvar}{IfTwo}
\or \pgfmathrandomitem{\bvar}{IfThree}
\or \pgfmathrandomitem{\bvar}{IfFour}
\or \pgfmathrandomitem{\bvar}{IfFive}
\fi
\xdef\bvar{\bvar}
\pgfmathrandominteger{\cvar}{2}{5}
\ifcase\cvar\relax%
\or \pgfmathrandomitem{\dvar}{IfOne}
\or \pgfmathrandomitem{\dvar}{IfTwo}
\or \pgfmathrandomitem{\dvar}{IfThree}
\or \pgfmathrandomitem{\dvar}{IfFour}
\or \pgfmathrandomitem{\dvar}{IfFive}
\fi
\xdef\dvar{\dvar}
\pgfmathsetmacro{\Avar}{int(\avar*\cvar)}
\pgfmathsetmacro{\Bvar}{int(\avar*\dvar+\bvar*\cvar)}
\pgfmathsetmacro{\Cvar}{int(\bvar*\dvar)}
}
\newcommand{\ManyCTPP}[1]
{%
\foreach \x in {1,...,#1}
{
\InitVariablesCTPP
a=\avar\\
b=\bvar\\
c=\cvar\\
d=\dvar\\
A=\Avar =\avar * \cvar\relax \\
B=\Bvar =\avar * \dvar + \bvar * \cvar\relax\\
C=\Cvar =\bvar * \dvar\relax\\
\(({\avar}x+{\bvar})({\cvar}x+{\dvar})={\Avar}x^2+{\Bvar}x+{\Cvar}\)
\\
\vspace{1cm}}
}
\begin{document}
\section{Complex Trinomials}
\ManyCTPP{5}
\end{document}
上面的代码确实解决了问题,但是我对问题所在的看法却有点可疑,因为如果我是对的,那么下面的代码有时会导致错误,但它总是可以编译而没有任何问题:
\documentclass{article}
\usepackage{pgf}
\usepackage{pgffor}
\pgfmathdeclarerandomlist{one}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}
\pgfmathdeclarerandomlist{two}{{1}{2}{3}{4}}
\pgfmathdeclarerandomlist{three}{{1}{2}{3}{4}{5}{6}}
\begin{document}
% test case
\foreach \n in {1,...,100} {
\pgfmathrandomitem{\oneval}{one}
\pgfmathrandomitem{\twoval}{two}
\pgfmathrandomitem{\threeval}{three}
\pgfmathparse{int(\oneval*\threeval+\oneval)}
\n: \pgfmathresult
}
\end{document}
我应该小心地将 OP 代码减少到 MWE,但我还有工作要做......