2

I am building a template for writing exams, and I'd like to randomly shuffle my enumerated lists at compile time. The answers to this question worked for that purpose, however I am using other functions to be able to switch between a 'Student View' and a view of the 'Key', and the solutions provided doesn't work with the functionality of the enumerate package which I used when constructing my other functionality.

Here is an MWE, without the randomize functionality

\documentclass{article}
\usepackage[dvipsnames]{xcolor}
\usepackage{amsmath, enumerate, ifthen, multicol, tikz}

\newif\ifgrading

\newcommand*\circleAns[1]{\tikz[baseline=(char.base)]{ \node[shape=circle,draw,inner sep=2pt,color=ForestGreen] (char) {#1};}}

\makeatletter
\newcommand{\itemAns}{ \ifgrading \stepcounter{enum\romannumeral@enumdepth} \item[\circleAns{\textcolor{ForestGreen}{@nameuse{label@enumctr}}}] \else \item \fi } \makeatother

\begin{document}

\begin{multicols}{2} \gradingtrue \begin{enumerate}[a)] \itemAns \item \item \end{enumerate}

\gradingfalse \begin{enumerate}[a)] \itemAns \item \item \end{enumerate} \end{multicols}

\end{document}

Producing the output:

Ideally, the randomization functionality would allow me to continue using both \begin{enumerate}[<options>] and \itemAns, and would also allow me to set a seed for the random generation process for repeatability. Thank you in advance for your assistance.

Shaun
  • 75
  • 1
    I answered a similar question before. Does it help? https://tex.stackexchange.com/questions/566202/could-i-do-a-different-automatic-exam-copies-one-for-each-student/566247#566247 – Alan Xiang Nov 15 '20 at 22:42
  • Alan, thank you for your comment, it was helpful to see, though I will be implementing egreg's solution. – Shaun Nov 16 '20 at 21:25

1 Answers1

1

Here's how you can shuffle the answers in a repeatable way, by fixing the seed. Devise a formula based on the student number to be fed as the seed.

\documentclass{article}
%\usepackage{xparse} % not needed with LaTeX 2020-10-01 or later
\usepackage{enumitem} % much more powerful than enumerate
\usepackage[dvipsnames]{xcolor}
\usepackage{tikz}

\newcommand*\circleanswer[1]{% \smash{\tikz[baseline=(char.base)]{% \node[shape=circle,draw,inner sep=2pt,color=ForestGreen] (char) {#1}; }}% }

\ExplSyntaxOn \sys_gset_rand_seed:n { 43221+32 } % a fixed number + the student number

\NewDocumentEnvironment{answers}{+b} { \begin{enumerate}[label=__shaun_answers_maybecorrect:n {\alph*})] \shaun_answers:n { #1 } \end{enumerate} }{}

\NewDocumentCommand{\grading}{} { \bool_gset_true:N \g_shaun_answers_grading_bool } \NewDocumentCommand{\notgrading}{} { \bool_gset_false:N \g_shaun_answers_grading_bool }

\seq_new:N \l__shaun_answers_seq \bool_new:N \l__shaun_answers_correct_bool \bool_new:N \g_shaun_answers_grading_bool

\cs_new_protected:Nn \shaun_answers:n { \seq_set_split:Nnn \l__shaun_answers_seq { \item } { #1 } \seq_pop_left:NN \l__shaun_answers_seq \l_tmpa_tl \seq_shuffle:N \l__shaun_answers_seq \exp_last_unbraced:Ne __shaun_answers_item: { \seq_use:Nn \l__shaun_answers_seq { __shaun_answers_item: } } }

\cs_new_protected:Nn __shaun_answers_item: { \peek_charcode_remove:NTF + { \bool_set_true:N \l__shaun_answers_correct_bool \item } { \bool_set_false:N \l__shaun_answers_correct_bool \item } }

\cs_new_protected:Nn __shaun_answers_maybecorrect:n { \bool_if:NTF \l__shaun_answers_correct_bool { \bool_if:NTF \g_shaun_answers_grading_bool { \circleanswer{#1} } { #1 } } { #1 } }

\ExplSyntaxOff

\begin{document}

%\grading \notgrading

\subsection*{First question} \begin{answers} \item+ Correct \item Incorrect (1) \item Incorrect (2) \item Incorrect (3) \end{answers}

\subsection*{Second question} \begin{answers} \item+ Correct \item Incorrect (1) \item Incorrect (2) \item Incorrect (3) \end{answers}

\end{document}

Grading

enter image description here

Not grading

enter image description here

egreg
  • 1,121,712
  • Thank you for your very elegant solution (as well as for including my name in your solution, it was a very nice touch) – Shaun Nov 16 '20 at 20:57
  • 1
    @Shaun expl3 functions and variables should always start with a “unique” prefix in order to avoid clashes with other people's code. I often use as prefix the nickname of the person who asked for the code, if possible. – egreg Nov 16 '20 at 21:14
  • I am having one problem where I am trying to reference to the answer item using \label{} and \ref{} and I am receiving errors. Would you have any suggestions for implementing this functionality? – Shaun Nov 17 '20 at 00:24