5

If I wrote an exam of ten Multiple choice questions, and I have 20 student. so Could I do a different automatic -by jumble the questions- exam copies -one for each student-?

\documentclass{exam}
\begin{document}
    
\begin{questions} 
        
\question Which of these famous physicists invented time?   
\begin{choices}
    \choice John
    \choice Pau
    \CorrectChoice Ringo
    \choice Socrates
\end{choices}

\question Which of these famous physicists invented time?   
\begin{oneparchoices} 
    \choice Stephen Hawking 
    \choice Albert Einstein
    \correctchoice  Emmy Noether
\end{oneparchoices} 

\question Which of these famous physicists published a paper on Brownian Motion?
\begin{oneparcheckboxes} 
    \choice Stephen Hawking 
    \choice Albert Einstein
    \choice Emmy Noether
    \choice This makes no sense
\end{oneparcheckboxes}  

\question Which of these famous physicists published a paper on Brownian Motion?
\begin{checkboxes}
    \correctchoice  Emmy Noether
    \choice Albert Einstein
    \choice Emmy Noether  H
\end{checkboxes}        
        
\end{questions}
    
\end{document}
1
  • 2
    The esami package, according to its documentation, seems to offer ways to randomly order the answers of a multiple choice question, as well as randomly ordering the questions themselves.
    – leandriis
    Commented Oct 10, 2020 at 10:50

1 Answer 1

6

This is an approach based on LaTeX that generates questions with order of choice across each compilation. The key is to use \randomize_env:nn command as follows:

\randomize_env:nn {choices} {choice,CorrectChoice}

The first argument specifies we want to randomize choices environment; the second argument says that the item-like commands are \choice and \CorrectChoice for this environment. The implementation is actually straightforward: the body of the randomized command is captured and is split into multiple segments based on item-like commands. The segments are stored in a sequence and will be subsequently shuffled with \seq_shuffle:N. As a result, randomness is introduced in the output.

enter image description here

\documentclass[answers]{exam}
\usepackage[T1]{fontenc}
\usepackage{expl3}
\usepackage{amsmath}
\usepackage{xparse}

\ExplSyntaxOn

\seq_new:N \l_curenv_seq
\seq_new:N \l_item_cmd_seq
\tl_new:N \l_curitem_tl
\tl_new:N \l_tmpc_tl

\cs_set:Nn \push_curitem: {
  \tl_if_empty:NF \l_curitem_tl {
    \seq_push:NV \l_curenv_seq \l_curitem_tl
  }
}

% randomize an environment
% #1: environment name
% #2: item command names
\cs_set:Npn \randomize_env:nn #1#2 {
  % definitions of the old environment
  \cs_gset_eq:cc {old_#1_e} {#1}
  \cs_gset_eq:cc {old_end#1_e} {end#1}
  
  % redefine the environment
  \RenewDocumentEnvironment{#1}{+b}{
    \tl_set:Nn \l_tmpa_tl {##1}
    % replace all space characters with explicit space command
    \regex_replace_all:nnN {\s} {\c{space}} \l_tmpa_tl
    
    %\tl_show:N \l_tmpa_tl
    % process item commands
    \clist_set:Nn \l_tmpa_clist {#2}
    \seq_clear:N \l_item_cmd_seq
    \clist_map_variable:NNn \l_tmpa_clist \l_tmpb_tl {
      \exp_args:NNo \tl_set:No \l_tmpc_tl {\use:c {\l_tmpb_tl}}
      \seq_push:NV \l_item_cmd_seq \l_tmpc_tl
    }
    %\seq_show:N \l_item_cmd_seq
    
    % analyze content and form sequence
    \seq_clear:N \l_curenv_seq
    \tl_clear:N \l_curitem_tl
    
    \bool_do_while:nn {!\tl_if_empty_p:N \l_tmpa_tl} {
      % add space if space is found
      % pop first item
      \tl_set:Nx \l_tmpb_tl {\tl_head:N \l_tmpa_tl}
      \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl}
      
      \seq_if_in:NVTF \l_item_cmd_seq \l_tmpb_tl {
        % if an item command is found
        % update variables
        \push_curitem:
        \tl_clear:N \l_curitem_tl
        \tl_put_right:NV \l_curitem_tl \l_tmpb_tl
      } {
        \tl_put_right:NV \l_curitem_tl \l_tmpb_tl
      }
      
    }
    % if the last item is not empty, push it into the sequence
    \push_curitem:
  }{
    % shuffle the sequence
    \seq_shuffle:N \l_curenv_seq
    \use:c {old_#1_e}
    \seq_use:Nn \l_curenv_seq {}
    \use:c {old_end#1_e}
  }
}

\randomize_env:nn {choices} {choice,CorrectChoice}
\randomize_env:nn {oneparchoices} {choice,correctchoice}
\randomize_env:nn {oneparcheckboxes} {choice,correctchoice}
\randomize_env:nn {checkboxes} {choice,correctchoice}
\ExplSyntaxOff

\begin{document}

\begin{questions} 
        
\question Which of these famous physicists invented time?   
\begin{choices}
    \choice John
    \choice Pau
    \CorrectChoice Ringo
    \choice Socrates
\end{choices}

\question Which of these famous physicists invented time?   
\begin{oneparchoices} 
    \choice Stephen Hawking 
    \choice Albert Einstein
    \correctchoice  Emmy Noether
\end{oneparchoices} 

\question Which of these famous physicists published a paper on Brownian Motion?
\begin{oneparcheckboxes} 
    \choice Stephen Hawking 
    \choice Albert Einstein
    \choice Emmy Noether
    \choice This makes no sense
\end{oneparcheckboxes}  

\question Which of these famous physicists published a paper on Brownian Motion?
\begin{checkboxes}
    \correctchoice  Emmy Noether
    \choice Albert Einstein
    \choice Emmy Noether  H
\end{checkboxes}        
        
\end{questions}
    
\end{document}


2
  • Nice answer, thankk you very much. I would add code to set the random seed, and I have a question: Why you replace all space characters with explicit space command? Commented Mar 29, 2022 at 8:32
  • I can't remember everything clearly. I think it is because of expl3, which ignores spaces.
    – Alan Xiang
    Commented Apr 1, 2022 at 15:46

You must log in to answer this question.

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