语境

语境

语境

我正在尝试制作一个自动考试,我可以使用pgfmathrandomintegerAMC 包中的 生成随机数(使用 )来使用代码(listings)创建不同的问题,并将这些随机数输入到代码中。例如,更改变量将获得的值,或更改循环的迭代次数等。

问题

然而,该listing包在 AMC 环境中并不容易使用(参见如何扩展宏以在 AMC 的问题中使用它?)。而且,添加应该出现在代码中的随机数,以及从问题中生成该数字也成为一个挑战。

例如,在下面的代码中,我可以生成数字(\pgfmathrandominteger{\mynum}{1}{8}),但是当使用更多问题时它不起作用(使用多个副本时也会发生同样的情况)。

理想情况下,我应该在问题中生成随机数,这样每次 AMC 解析问题时都会生成一个新数字,然后框应该会解析它。但是,框在声明时已经排版(据我所知)。因此,当我在代码上使用它时lstlisting(如果我可以访问\mynum宏),我仍然需要能够一次又一次地重新调整该环境。

如何实现该行为?

\documentclass{article}

\usepackage[box]{automultiplechoice}
\usepackage{listings}
\usepackage{tikz}
\lstset{  escapeinside={@*}{*@}}

% a simple wrapper to create boxes automatically
\makeatletter
\newcounter{myboxcounter}
\newenvironment{mybox}{%
  \stepcounter{myboxcounter}%
  \expandafter\newsavebox\csname foobox\roman{myboxcounter}\endcsname
  \global\expandafter\setbox\csname foobox\roman{myboxcounter}\endcsname\hbox\bgroup\color@setgroup\ignorespaces
}{%
  \color@endgroup\egroup
}
\newcommand{\insertbox}{\stepcounter{myboxcounter}%
  \edef\name{foobox\roman{myboxcounter}}\edef\x{%
  \expandafter\usebox\csname\name\endcsname}\x}
\makeatother


\begin{document}

%%% preparation of the groups
\pgfmathrandominteger{\mynum}{1}{8}
\begin{mybox}
\begin{lstlisting}[language=C++]
  int a = @*\mynum*@;
  a = a + 10;
\end{lstlisting}
\end{mybox}
\element{code}{
  \begin{question}{code 1}
    Which is the result of \texttt{a} \mynum?

    \insertbox
    \begin{choices}
      \correctchoice{\pgfmathparse{\mynum+10}\pgfmathresult}
      \wrongchoice{20}
      \wrongchoice{0}
      \wrongchoice{30}
    \end{choices}
  \end{question}
}

%%% copies
\setcounter{myboxcounter}{0}
\onecopy{1}{% when changed the number of copies to more than one it won't work
\insertgroup{code}
}

\end{document}

答案1

您不应该在参数中使用列表,但如果您在自找麻烦,另一个实验性解决方法(在文档中解释)是^^J在每行末尾添加换行符( ),转义\{}%字符和空格。不幸的是,您无法在这样的列表中转义到 LaTeX(根据包文档),因此您几乎没有机会在此处包含随机值。

但是,无需列表(或仅将其用于不可变代码),使用该包可以轻松在 AMC 中使用随机值进行数学运算fp。一个简单的例子:

1型 微波辐射计

\documentclass{article}
\usepackage[box]{automultiplechoice}
\usepackage{fp}
\usepackage{amsmath}
\usepackage{listings}

\element{code}{
\begin{question}{sum}
\FPeval\Ra{trunc(1+random*8,0)}
\FPeval\Rb{trunc(4+random*5,0)}
\FPeval\RnoA{clip((Ra+1)/Rb)}
\FPeval\RnoB{clip(Ra*Rb+100)}
\FPeval\RnoC{clip(Ra-Rb+1)}
\FPeval\Ryes{clip(Ra+Rb)}
\begin{lstlisting}^^J
a ? b = c ^^J 
\end{lstlisting}
Check the equation with correct result ($c$) when $a = \Ra{}$ and $b = \Rb{}$?

\begin{choices}
\wrongchoice{   $\dfrac{\Ra{}}{\Rb{}} = \RnoA$}
\wrongchoice{   $\Ra{}^{\Rb{}} = \RnoB$}
\wrongchoice{   $\Ra{} - \Rb{} = \RnoC$}
\correctchoice{ $\Ra{} + \Rb{} = \Ryes$}
\end{choices}
\end{question}}

\lstset{basicstyle=\color{red!50!black}\bfseries\sffamily,frame=none} 

\begin{document}
\onecopy{2}{\insertgroup{code}}
\end{document}

编辑:好的,好的,你希望一切都是最好的,无论它有多复杂。

解决此问题的一个肮脏技巧是使用\input{}包含宏的代码。我不确定这种方法有多安全,因此请自行承担风险。逐步修改上述示例:

1)包含转义字符

\lstset{escapechar=!, ....}

2)剪切lstlisting环境,将其另存为 chunk.tex,删除换行符(^^J)并插入转义的随机值:

\begin{lstlisting}
!\Ra\ ? \Rb\ = c  
\end{lstlisting}

3)然后插入\input{chunk}考试。

4)编译并检查结果:

3型 4型

编辑2:

另一个选择是尝试其他代码列表方法。检查CTAN 中的主题列表。您的里程可能会因您对格式和与 AMC 兼容性的目标而异。例如,该包minted算法适合代码列表,但似乎也与上​​述 MWE 不兼容,而该包algpseudocode允许使用 algorithmic似乎在问题内部运行良好的环境,包括变量\Ra\Rb

\begin{algorithmic}[1]
\State $sum\gets \Ra$
\State $i\gets \Rb $
\While{$i\le n$}
\State $sum\gets sum+i$
\State $i\gets i+1$
\EndWhile
\end{algorithmic}

MWE5

相关内容