5

I cannot figure out the reason for this weird occurrence. If I declare my exam to print answers, I get an error that

! LaTeX Error: \begin{choices} on input line 21 ended by \end{questions}
! LaTeX Error: \begin{questions} on input line 20 ended by \end{document}.

This is fixed, if I simply add a second line of

\end{choices}

To my newcommand. If I am not printing answers, the second \end{choices} is not required.

What am I writing improperly for the loop that is making it ignore the first \end{choices}?

I have included all the lines needed in my MWE, but I have commented out the print answers part and the 2nd \end{choices} so you can see it compile and work properly as well.

% to see the error in action, comment this first documentclass command, and uncomment the one with [answers]
% to resolve the error generated when enabling the answers, uncomment the second \end{choices} command down in \newcommand{\newmpchoice}
\documentclass{exam}
%\documentclass[answers]{exam}
\usepackage{pgffor}

\newcommand{\printchoice}[3]{\ifnum\numexpr#1\relax=\numexpr#2\relax \CorrectChoice #3 \else \choice #3\fi}

\newcommand{\newmpchoice}[4]{
\question #1
\begin{choices}
\foreach \x[count=\xi] in {#3}
{   \printchoice{#2}{\xi}{\x}};
\end{choices}
%\end{choices}
\begin{solution}
#4
\end{solution}
}

\begin{document}
\begin{questions}
\newmpchoice{Test question}{1}{{Answer 1},{Answer 2},{Answer 3},{Answer 4},{Answer 5}}{Solution}
\end{questions}
\end{document}
7
  • running your code with a single \end{choice} works fine here. I get the error you describe if I add two of them. Unless I am misinterpreting something here.
    – Runar
    Commented Sep 11, 2016 at 18:34
  • At the top, if you switch out the documentclass commands, and use the one with "answers" in it, it should give you an error without the second \end{choice} in it. I've added a comment to the top of the code to make that more clear
    – J M
    Commented Sep 11, 2016 at 18:38
  • @RunarTrollet I do appreciate you looking into it!
    – J M
    Commented Sep 11, 2016 at 18:45
  • Have a look at the coumentation (commandline texdoc exam, or ctan.org/pkg/exam ), section **3.2 The option answers ** which specifies some changes. The problem has something to to with \CorrectChoice, but I cannot look into it further right now.
    – Runar
    Commented Sep 11, 2016 at 18:50
  • 1
    I removed my comment, as the code could possibly break stuff. See egregs solution.
    – Runar
    Commented Sep 12, 2016 at 11:01

1 Answer 1

4

The usual issue with \foreach, that executes each cycle in a group and this breaks the \CorrectChoice settings, that are forgotten as soon as the cycle ends and the group is closed.

You can do it more easily with expl3:

\documentclass[
  answers % comment this line for not showing answers
]{exam}

\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\newmpchoice}{mmmm}
 {
  \question #1
  \begin{choices}
  \clist_map_inline:nn { #3 }
   {
    \int_compare:nTF { #2 = \value{choice}+1 } { \CorrectChoice } { \choice }
    ##1
   }
  \end{choices}
  \begin{solution}
  #4
  \end{solution}
 }

\ExplSyntaxOff

\begin{document}
\begin{questions}
\newmpchoice{Test question}{1}{{Answer 1},{Answer 2},{Answer 3},{Answer 4},{Answer 5}}{Solution}
\end{questions}
\end{document}

I use the fact that the choice counter is incremented at each \choice or \CorrectChoice command (and reset to zero at \begin{choices}), so before one of these commands its value is one less than needed for the comparison.

enter image description here

You can also do it with \foreach, but in this case you have to collect the bits in some macro that you can then deliver.

\documentclass[
  answers % comment this line for not showing solutions
]{exam}
\usepackage{pgffor,etoolbox}

\newcommand{\newmpchoice}[4]{%
  \question #1
  \begin{choices}
  \def\thesechoices{}%
  \foreach \x[count=\xi] in {#3} {%
    \ifnum\numexpr#2\relax=\numexpr\xi\relax
       \xappto\thesechoices{\noexpand\CorrectChoice\expandonce{\x}}%
    \else
       \xappto\thesechoices{\noexpand\choice\expandonce{\x}}%
    \fi
  }%
  \thesechoices
  \end{choices}
  \begin{solution}
  #4
  \end{solution}
}

\begin{document}

\begin{questions}
\newmpchoice{Test question}{1}{{Answer 1},{Answer 2},{Answer 3},{Answer 4},{Answer 5}}{Solution}
\end{questions}

\end{document}

You can also accommodate more than one correct answer, with a modification of the first solution:

\documentclass[
  answers % comment this line for not showing answers
]{exam}

\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\newmpchoice}{mmmm}
 {
  \question #1
  \begin{choices}
  \clist_map_inline:nn { #3 }
   {
    \clist_if_in:nxTF { #2 } { \int_to_arabic:n { \value{choice} + 1 } }
     { \CorrectChoice } { \choice }
    ##1
   }
  \end{choices}
  \begin{solution}
  #4
  \end{solution}
 }
\cs_generate_variant:Nn \clist_if_in:nnTF { nx }

\ExplSyntaxOff

\begin{document}
\begin{questions}
\newmpchoice{Test question}{1}{{Answer 1},{Answer 2},{Answer 3},{Answer 4},{Answer 5}}{Solution}
\newmpchoice{Test question}{1, 3}{{Answer 1},{Answer 2},{Answer 3},{Answer 4},{Answer 5}}{Solution}
\end{questions}
\end{document}

enter image description here

2
  • Hi @egreg would it be possible for this to be modified to accept multiple amount of correct answers? Correct choices would be comma separated (or whatever else was easier)\newmpchoice{question}{1,3}{{Answer 1 - is correct},{Answer 2},{Answer 3 - is correct},{Answer 4},{Answer 5}}{Solution}
    – J M
    Commented Nov 27, 2016 at 3:38
  • 1
    @JM Easy enough. ;-)
    – egreg
    Commented Nov 27, 2016 at 10:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .