![把随机问题和答案分成不同的页面](https://linux22.com/image/453146/%E6%8A%8A%E9%9A%8F%E6%9C%BA%E9%97%AE%E9%A2%98%E5%92%8C%E7%AD%94%E6%A1%88%E5%88%86%E6%88%90%E4%B8%8D%E5%90%8C%E7%9A%84%E9%A1%B5%E9%9D%A2.png)
我可以创建简单的随机加法问题,但是当我尝试将问题和答案分成两个独立的页面时,我认为因为它是一个随机生成器,所以答案表与问题表并不相同。
\documentclass{article}
%AdditionCode
\usepackage{amsmath}
\usepackage{mathtools}
\usepackage{enumitem}
\usepackage{tikz}
\pgfmathsetseed{\number\pdfrandomseed}
\usepackage{xlop}
\usepackage{fancyhdr}
\newcommand*{\DifficultyOne}{999}%
\newcommand*{\DifficultyTwo}{99}%
%---------------------------------------%
\newcommand{\AddQuestion}[1]{
\foreach \i in {1,...,#1}{%
\pgfmathtruncatemacro{\AddOnea}{random(\DifficultyOne)}%
\pgfmathtruncatemacro{\AddTwoa}{random(\DifficultyTwo)}
question one
\opadd[carryadd=false, voperator=bottom, resultstyle=\color{white}]{\AddOnea} {\AddTwoa} \\
~\newline
Answer two
\opadd[carryadd=true, voperator=bottom, resultstyle=\color{black}]{\AddOnea} {\AddTwoa} \\
}%
}%
\begin{document}
\AddQuestion{2}
\end{document}
这不是工作表的完整代码,只是不想发布大量代码。
答案1
您可能可以使用该包参考值:
以下示例可以作为起点:
在所有 latex 运行中,从 zref 标签中检索伪随机变量的值。
在第一次 latex 运行中,通过伪随机生成器为伪随机变量创建值。
在连续的 latex 运行中,从 zref 标签中获取伪随机变量的值。
在所有 latex 运行中,将伪随机变量的值存储在 zref 标签中。
为了确保一切正确,您需要至少编译两次,且在 latex 运行之间不删除辅助文件。
和脫位对结果/进位/操作数/中间数/余数的每个字符应用相应样式宏的实例。
因此,在第一次运行 LaTeX 时,由于 zref 标签尚未定义,
- style-macros
\undefinedstyle
/\undefinedcarrystyle
用于传递问号。 \zref@extractdefault
将所有内容默认为 0,以便操作数和计算/结果都产生 0,即由单个字符组成的数字序列,因此仅应用相应问号传递样式宏的一个实例。
在连续的 LaTeX 运行中,定义 zref 标签,并且应正确检索伪随机变量的值。
在连续的 LaTeX 运行中,答案是不需要的,resultstyle=\phantom
而是使用 ,并且进位也通过resultstyle=\color{white}
完成。 我不太确定这是否是个好主意。但这样,结果就不会出现在 pdf 文件中不应看到的地方,因此人们不能盲目地从这些地方复制粘贴结果/不能使用 GhostScript 技巧使结果在这些地方可见。\phantom
carrystyle=\phantomcarrystyle
\documentclass{article}
\usepackage{amsmath}
\usepackage{mathtools}
\usepackage{enumitem}
\usepackage{tikz}
\pgfmathsetseed{\number\pdfrandomseed}
\usepackage{xlop}
\usepackage{zref}
\makeatletter
\zref@newprop{AddOnea}{0}%
\zref@newprop{AddTwoa}{0}%
\zref@newprop{range}{0}%
\newcommand\PassFirstToSecond[2]{#2{#1}}%
\newcommand\Exchange[2]{#2#1}%
\makeatother
\usepackage{fancyhdr}
\newcommand*{\DifficultyOne}{999}%
\newcommand*{\DifficultyTwo}{99}%
%---------------------------------------%
\makeatletter
\newcommand\undefinedstyle[1]{\nfss@text{\reset@font\bfseries ??}}%
\newcommand\undefinedcarrystyle[1]{{\nfss@text{\reset@font\scriptsize\bfseries ??}}}%
\newcommand\phantomcarrystyle[1]{\phantom{\scriptsize{#1}}}%
\newcommand{\AddQuestions}[2]{%
\zref@setcurrent{range}{#1}%
\zref@labelbyprops{#2}{range}%
\foreach \i in {1,...,#1}{%
\par\ifnum\i=1 \else\medskip\fi\noindent\hbox{Question \i: }%
\zref@ifrefundefined{#2.\i}{%
\pgfmathtruncatemacro{\AddOnea}{random(\DifficultyOne)}%
\pgfmathtruncatemacro{\AddTwoa}{random(\DifficultyTwo)}%
\expandafter\PassFirstToSecond\expandafter{\AddOnea}{\zref@setcurrent{AddOnea}}%
\expandafter\PassFirstToSecond\expandafter{\AddTwoa}{\zref@setcurrent{AddTwoa}}%
}{%
\expandafter\expandafter\expandafter\PassFirstToSecond
\expandafter\expandafter\expandafter{%
\zref@extractdefault{#2.\i}{AddOnea}{0}%
}{\zref@setcurrent{AddOnea}}%
\expandafter\expandafter\expandafter\PassFirstToSecond
\expandafter\expandafter\expandafter{%
\zref@extractdefault{#2.\i}{AddTwoa}{0}%
}{\zref@setcurrent{AddTwoa}}%
}%
\zref@labelbyprops{#2.\i}{AddOnea, AddTwoa}%
\zref@refused{#2.\i}%
\zref@ifrefundefined{#2.\i}{%
% actually setting carrystyle is not needed as there are no carries with defaults 0, but ...
\opadd[carryadd=true, voperator=bottom, resultstyle=\undefinedstyle, operandstyle=\undefinedstyle, carrystyle=\undefinedcarrystyle]%
}{%
% Only operands shall be seen, so turn everything else into \phantom
\opadd[carryadd=true, voperator=bottom, resultstyle=\phantom, carrystyle=\phantomcarrystyle]%
}%
{\zref@extractdefault{#2.\i}{AddOnea}{0}}%
{\zref@extractdefault{#2.\i}{AddTwoa}{0}}%
}%
\par
}%
\newcommand{\AddAnswers}[1]{%
\zref@ifrefundefined{#1}{%
\zref@refused{#1}%
\par\noindent
{\normalfont\bfseries [Question-series ``#1'' undefined, probably re-run latex, see messages on console/in .log-file]}%
\par
}{%
\expandafter\PassFirstToSecond\expandafter{%
\romannumeral0%
\expandafter\expandafter\expandafter\Exchange
\expandafter\expandafter\expandafter{%
\zref@extractdefault{#1}{range}{1}%
}{ 1,...,}%
}{\foreach \i in }{%
\par\ifnum\i=1 \else\medskip\fi\noindent\hbox{\rlap{Answer \i: }\phantom{Question \i: }}%
\zref@refused{#1.\i}%
\opadd[carryadd=true, voperator=bottom]%
{\zref@extractdefault{#1.\i}{AddOnea}{0}}%
{\zref@extractdefault{#1.\i}{AddTwoa}{0}}%
}%
}%
\par
}%
\makeatother
\begin{document}
\noindent Here come the questions with answers:
\AddAnswers{This question-series label}%
\newpage
\noindent Here come the questions without answers:
\AddQuestions{10}{This question-series label}%
\newpage
\noindent Here come the questions with answers again:
\AddAnswers{This question-series label}%
\end{document}
例如,如果您希望有 20 张试卷,每张试卷包含另一组 15 个随机生成的练习,则可以将上述内容与循环结合起来,以将一组标记复制 k 次:
\DoKtimes{⟨TeX-number-quantity of value K⟩}{⟨tokens⟩}
在控制台和.log文件中遵循消息
LaTeX Warning: Label(s) may have changed. Rerun to get cross-references right.
,即,根据需要进行编译,而不删除latex运行之间的辅助文件,因为该消息不再出现。
\documentclass{article}
\usepackage{amsmath}
\usepackage{mathtools}
\usepackage{enumitem}
\usepackage{tikz}
\pgfmathsetseed{\number\pdfrandomseed}
\usepackage{xlop}
\usepackage[user]{zref}
\usepackage{fancyhdr}
\makeatletter
%%=============================================================================
%% \DoKtimes{<TeX-number-quantity of value K>}{<tokens>}
%%=============================================================================
\newcommand\UD@Exchange[2]{#2#1}%
\newcommand\UD@PassFirstToSecond[2]{#2{#1}}%
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
\@ifdefinable\UD@stopromannumeral{\chardef\UD@stopromannumeral=`\^^00}%
%%-----------------------------------------------------------------------------
%% Check whether argument is empty:
%%.............................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is empty>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
\newcommand\UD@CheckWhetherNull[1]{%
\romannumeral\expandafter\UD@secondoftwo\string{\expandafter
\UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
\UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
\UD@secondoftwo\string}\expandafter\UD@stopromannumeral\UD@secondoftwo}{%
\expandafter\UD@stopromannumeral\UD@firstoftwo}%
}%
%%-----------------------------------------------------------------------------
\newcommand\DoKtimes[2]{%
\romannumeral
\expandafter\DoKtimesloop\expandafter{\romannumeral\number\number#1 000}{#2}{}%
}%
\newcommand\DoKtimesloop[3]{%
\UD@CheckWhetherNull{#1}{\UD@stopromannumeral#3}{%
\expandafter\DoKtimesloop\expandafter{\UD@firstoftwo{}#1}{#2}{#3#2}%
}%
}%
%%=============================================================================
\zref@newprop{AddOnea}{0}%
\zref@newprop{AddTwoa}{0}%
\zref@newprop{range}{0}%
\newcommand\undefinedstyle[1]{\nfss@text{\reset@font\bfseries ??}}%
\newcommand\undefinedcarrystyle[1]{{\nfss@text{\reset@font\scriptsize\bfseries ??}}}%
\newcommand\phantomcarrystyle[1]{\phantom{\scriptsize{#1}}}%
\newcommand{\AddQuestions}[2]{%
\zref@setcurrent{range}{#1}%
\zref@labelbyprops{#2}{range}%
\foreach \i in {1,...,#1}{%
\par\ifnum\i=1 \else\medskip\fi\noindent\hbox{Question \i: }%
\zref@ifrefundefined{#2.\i}{%
\pgfmathtruncatemacro{\AddOnea}{random(\DifficultyOne)}%
\pgfmathtruncatemacro{\AddTwoa}{random(\DifficultyTwo)}%
\expandafter\UD@PassFirstToSecond\expandafter{\AddOnea}{\zref@setcurrent{AddOnea}}%
\expandafter\UD@PassFirstToSecond\expandafter{\AddTwoa}{\zref@setcurrent{AddTwoa}}%
}{%
\expandafter\expandafter\expandafter\UD@PassFirstToSecond
\expandafter\expandafter\expandafter{%
\zref@extractdefault{#2.\i}{AddOnea}{0}%
}{\zref@setcurrent{AddOnea}}%
\expandafter\expandafter\expandafter\UD@PassFirstToSecond
\expandafter\expandafter\expandafter{%
\zref@extractdefault{#2.\i}{AddTwoa}{0}%
}{\zref@setcurrent{AddTwoa}}%
}%
\zref@labelbyprops{#2.\i}{AddOnea, AddTwoa}%
\zref@refused{#2.\i}%
\zref@ifrefundefined{#2.\i}{%
% actually setting carrystyle is not needed as there are no carries with defaults 0, but ...
\opadd[carryadd=true, voperator=bottom, resultstyle=\undefinedstyle, operandstyle=\undefinedstyle, carrystyle=\undefinedcarrystyle]%
}{%
% Only operands shall be seen, so turn everything else into \phantom
\opadd[carryadd=true, voperator=bottom, resultstyle=\phantom, carrystyle=\phantomcarrystyle]%
}%
{\zref@extractdefault{#2.\i}{AddOnea}{0}}%
{\zref@extractdefault{#2.\i}{AddTwoa}{0}}%
}%
\par
}%
\newcommand{\AddAnswers}[1]{%
\zref@ifrefundefined{#1}{%
\zref@refused{#1}%
\par\noindent
{\normalfont\bfseries [Question-series ``#1'' undefined, probably re-run latex, see messages on console/in .log-file]}%
\par
}{%
\expandafter\UD@PassFirstToSecond\expandafter{%
\romannumeral
\expandafter\expandafter\expandafter\UD@Exchange
\expandafter\expandafter\expandafter{%
\zref@extractdefault{#1}{range}{1}%
}{\UD@stopromannumeral 1,...,}%
}{\foreach \i in }{%
\par\ifnum\i=1 \else\medskip\fi\noindent\hbox{\rlap{Answer \i: }\phantom{Question \i: }}%
\zref@refused{#1.\i}%
\opadd[carryadd=true, voperator=bottom]%
{\zref@extractdefault{#1.\i}{AddOnea}{0}}%
{\zref@extractdefault{#1.\i}{AddTwoa}{0}}%
}%
}%
\par
}%
\newcommand*{\DifficultyOne}{999}%
\newcommand*{\DifficultyTwo}{99}%
%%=============================================================================
%% A dirty hack for resetting page-numbers with each sheet
\newcommand\resetpagezreflabelnamenumber{0}%
\newcommand\resetpage{%
\newpage
\xdef\resetpagezreflabelnamenumber{\number\numexpr\resetpagezreflabelnamenumber+1\relax}%
\zref@labelbyprops{pagereset-\resetpagezreflabelnamenumber}{page}%
}%
\newcommand\obtainlastresetpage{%
\zref@extractdefault{pagereset-\resetpagezreflabelnamenumber}{page}{0}%
}%
\newcommand\ps@resetableplain{%
\let\@mkboth\@gobbletwo
\let\@oddhead\@empty
\def\@oddfoot{\reset@font\hfil\@arabic{\number\numexpr\value{page}-\obtainlastresetpage+1\relax}\hfil}%
\let\@evenhead\@empty
\let\@evenfoot\@oddfoot
}%
\makeatother
\pagestyle{resetableplain}
\begin{document}
%%%%%%%
%% Create 20 sheets of paper, each holding 15 randomly generated exercises without answers:
% Initialize the macro for counting sheets to 0:
\newcommand\sheetNumber{0}%
\DoKtimes{20}{%
\resetpage
% Increment \sheetNumber
\edef\sheetNumber{\number\numexpr\sheetNumber+1\relax}%
\section*{Question sheet \sheetNumber (without answers)}
\AddQuestions{15}{This question-series-sheet-\sheetNumber-label}%
}%
%%%%%%%
%% Re-create the 20 sheets of paper from above, this time with answers:
% Initialize the macro for counting sheets to 0:
\renewcommand\sheetNumber{0}%
\DoKtimes{20}{%
\resetpage
% Increment \sheetNumber
\edef\sheetNumber{\number\numexpr\sheetNumber+1\relax}%
\section*{Question sheet \sheetNumber (with answers)}
\AddAnswers{This question-series-sheet-\sheetNumber-label}%
}%
\end{document}
如果您希望个性化表格,例如,包含考生的姓名,您可以定义一个循环,该循环在未限定的参数列表上进行迭代,从每个名称定义一个宏并执行⟨代币⟩:
\DefineVariableWithEachAndDo{⟨(already defined) macro holding list of undelimited arguments⟩}%
{⟨macro (to be (re)defined in each iteration) holding current element of list⟩}%
{⟨tokens⟩}
在控制台和.log文件中遵循消息
LaTeX Warning: Label(s) may have changed. Rerun to get cross-references right.
,即,根据需要进行编译,而不删除latex运行之间的辅助文件,因为该消息不再出现。
\documentclass{article}
\usepackage{amsmath}
\usepackage{mathtools}
\usepackage{enumitem}
\usepackage{tikz}
\pgfmathsetseed{\number\pdfrandomseed}
\usepackage{xlop}
\usepackage[user]{zref}
\usepackage{fancyhdr}
\makeatletter
%%=============================================================================
%% \DefineVariableWithEachAndDo{<macro holding list of undelimited arguments>}%
%% {<macro holding current element of list>}%
%% {<tokens>}
%%=============================================================================
\newcommand\UD@Exchange[2]{#2#1}%
\newcommand\UD@PassFirstToSecond[2]{#2{#1}}%
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
\@ifdefinable\UD@stopromannumeral{\chardef\UD@stopromannumeral=`\^^00}%
\newcommand\DefineVariableWithEachAndDo[3]{%
\romannumeral
\expandafter\UD@Exchange
\expandafter{#1}{\DefineVariableWithEachAndDoloop{#2}{#3}{}}{\relax}%
}%
\newcommand\DefineVariableWithEachAndDoloop[4]{%
\ifx\relax#4\expandafter\UD@firstoftwo\else\expandafter\UD@secondoftwo\fi
{\UD@stopromannumeral#3}{%
\DefineVariableWithEachAndDoloop{#1}{#2}{#3\def#1{#4}#2}%
}%
}%
%%=============================================================================
\zref@newprop{AddOnea}{0}%
\zref@newprop{AddTwoa}{0}%
\zref@newprop{range}{0}%
\newcommand\undefinedstyle[1]{\nfss@text{\reset@font\bfseries ??}}%
\newcommand\undefinedcarrystyle[1]{{\nfss@text{\reset@font\scriptsize\bfseries ??}}}%
\newcommand\phantomcarrystyle[1]{\phantom{\scriptsize{#1}}}%
\newcommand{\AddQuestions}[2]{%
\zref@setcurrent{range}{#1}%
\zref@labelbyprops{#2}{range}%
\foreach \i in {1,...,#1}{%
\par\ifnum\i=1 \else\medskip\fi\noindent\hbox{Question \i: }%
\zref@ifrefundefined{#2.\i}{%
\pgfmathtruncatemacro{\AddOnea}{random(\DifficultyOne)}%
\pgfmathtruncatemacro{\AddTwoa}{random(\DifficultyTwo)}%
\expandafter\UD@PassFirstToSecond\expandafter{\AddOnea}{\zref@setcurrent{AddOnea}}%
\expandafter\UD@PassFirstToSecond\expandafter{\AddTwoa}{\zref@setcurrent{AddTwoa}}%
}{%
\expandafter\expandafter\expandafter\UD@PassFirstToSecond
\expandafter\expandafter\expandafter{%
\zref@extractdefault{#2.\i}{AddOnea}{0}%
}{\zref@setcurrent{AddOnea}}%
\expandafter\expandafter\expandafter\UD@PassFirstToSecond
\expandafter\expandafter\expandafter{%
\zref@extractdefault{#2.\i}{AddTwoa}{0}%
}{\zref@setcurrent{AddTwoa}}%
}%
\zref@labelbyprops{#2.\i}{AddOnea, AddTwoa}%
\zref@refused{#2.\i}%
\zref@ifrefundefined{#2.\i}{%
% actually setting carrystyle is not needed as there are no carries with defaults 0, but ...
\opadd[carryadd=true, voperator=bottom, resultstyle=\undefinedstyle, operandstyle=\undefinedstyle, carrystyle=\undefinedcarrystyle]%
}{%
% Only operands shall be seen, so turn everything else into \phantom
\opadd[carryadd=true, voperator=bottom, resultstyle=\phantom, carrystyle=\phantomcarrystyle]%
}%
{\zref@extractdefault{#2.\i}{AddOnea}{0}}%
{\zref@extractdefault{#2.\i}{AddTwoa}{0}}%
}%
\par
}%
\newcommand{\AddAnswers}[1]{%
\zref@ifrefundefined{#1}{%
\zref@refused{#1}%
\par\noindent
{\normalfont\bfseries [Question-series ``#1'' undefined, probably re-run latex, see messages on console/in .log-file]}%
\par
}{%
\expandafter\UD@PassFirstToSecond\expandafter{%
\romannumeral
\expandafter\expandafter\expandafter\UD@Exchange
\expandafter\expandafter\expandafter{%
\zref@extractdefault{#1}{range}{1}%
}{\UD@stopromannumeral 1,...,}%
}{\foreach \i in }{%
\par\ifnum\i=1 \else\medskip\fi\noindent\hbox{\rlap{Answer \i: }\phantom{Question \i: }}%
\zref@refused{#1.\i}%
\opadd[carryadd=true, voperator=bottom]%
{\zref@extractdefault{#1.\i}{AddOnea}{0}}%
{\zref@extractdefault{#1.\i}{AddTwoa}{0}}%
}%
}%
\par
}%
\newcommand*{\DifficultyOne}{999}%
\newcommand*{\DifficultyTwo}{99}%
%%=============================================================================
%% A dirty hack for resetting page-numbers with each sheet
\newcommand\resetpagezreflabelnamenumber{0}%
\newcommand\resetpage{%
\newpage
\xdef\resetpagezreflabelnamenumber{\number\numexpr\resetpagezreflabelnamenumber+1\relax}%
\zref@labelbyprops{pagereset-\resetpagezreflabelnamenumber}{page}%
}%
\newcommand\obtainlastresetpage{%
\zref@extractdefault{pagereset-\resetpagezreflabelnamenumber}{page}{0}%
}%
\newcommand\ps@resetableplain{%
\let\@mkboth\@gobbletwo
\let\@oddhead\@empty
\def\@oddfoot{\reset@font\hfil\@arabic{\number\numexpr\value{page}-\obtainlastresetpage+1\relax}\hfil}%
\let\@evenhead\@empty
\let\@evenfoot\@oddfoot
}%
\makeatother
\pagestyle{resetableplain}
\newcommand\ExamineeNameList{%
{Coby}%
{Johan}%
{Rudy}%
{Rodrigo}%
{Alejandra}%
{Oswaldo}%
{Yusuf}%
{Luz}%
{Denzel}%
{Abigayle}%
{Bobby}%
{Margaret}%
{Eli}%
{Billy}%
{Jazmine}%
{Miguel}%
{Jon}%
{Valentin}%
{Lance}%
{Skyler}%
}%
\newcommand\ThisExamimeesName{}% <- This raises an error if the macro is already in use by some package/by some other code.
\begin{document}
%%%%%%%
%% Create a sheet of 15 ramdom questions for each examinee:
\DefineVariableWithEachAndDo{\ExamineeNameList}{\ThisExamimeesName}{%
\resetpage
\section*{Question sheet without answers for \ThisExamimeesName}%
\AddQuestions{15}{This question-series-sheet-\ThisExamimeesName-label}%
}%
%%%%%%%
%% Re-create the sheets from above, this time with answers:
\DefineVariableWithEachAndDo{\ExamineeNameList}{\ThisExamimeesName}{%
\resetpage
\section*{Question sheet with answers for \ThisExamimeesName}%
\AddAnswers{This question-series-sheet-\ThisExamimeesName-label}%
}%
\end{document}