Skip to content

Instantly share code, notes, and snippets.

@xziyue
Created August 23, 2022 15:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xziyue/2e99f47e9f13c162b719990d59a96759 to your computer and use it in GitHub Desktop.
Save xziyue/2e99f47e9f13c162b719990d59a96759 to your computer and use it in GitHub Desktop.
Randomized H/V LaTeX Exam
\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
\tl_new:N \l_tmpd_tl
\tl_new:N \l_tmpe_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}
}
}
\cs_set:Npn \new_env_group:nn #1#2 {
\NewDocumentEnvironment{#1}{}
{% select a random item from the clist and save it
\tl_gset:cx {g__env_group_cur_item_#1_tl} {\clist_rand_item:n {#2}}
\exp_args:Nc \begin {g__env_group_cur_item_#1_tl}
}
{\exp_args:Nc \end {g__env_group_cur_item_#1_tl}}
}
\randomize_env:nn {choices} {choice,CorrectChoice}
\randomize_env:nn {oneparchoices} {choice,correctchoice}
\randomize_env:nn {oneparcheckboxes} {choice,correctchoice}
\randomize_env:nn {checkboxes} {choice,correctchoice}
\new_env_group:nn {hvchoices} {choices,oneparchoices}
\new_env_group:nn {hvcheckboxes} {checkboxes,oneparcheckboxes}
\ExplSyntaxOff
\begin{document}
\begin{questions}
\question Which of these famous physicists invented time?
\begin{hvchoices}
\choice John
\choice Pau
\CorrectChoice Ringo
\choice Socrates
\end{hvchoices}
\question Which of these famous physicists invented time?
\begin{hvchoices}
\choice Stephen Hawking
\choice Albert Einstein
\correctchoice Emmy Noether
\end{hvchoices}
\question Which of these famous physicists invented time?
\begin{hvchoices}
\choice John
\choice Pau
\CorrectChoice Ringo
\choice Socrates
\end{hvchoices}
\question Which of these famous physicists invented time?
\begin{hvchoices}
\choice Stephen Hawking
\choice Albert Einstein
\correctchoice Emmy Noether
\end{hvchoices}
\question Which of these famous physicists published a paper on Brownian Motion?
\begin{hvcheckboxes}
\choice Stephen Hawking
\choice Albert Einstein
\choice Emmy Noether
\choice This makes no sense
\end{hvcheckboxes}
\question Which of these famous physicists published a paper on Brownian Motion?
\begin{hvcheckboxes}
\correctchoice Emmy Noether
\choice Albert Einstein
\choice Emmy Noether H
\end{hvcheckboxes}
\question Which of these famous physicists published a paper on Brownian Motion?
\begin{hvcheckboxes}
\choice Stephen Hawking
\choice Albert Einstein
\choice Emmy Noether
\choice This makes no sense
\end{hvcheckboxes}
\question Which of these famous physicists published a paper on Brownian Motion?
\begin{hvcheckboxes}
\correctchoice Emmy Noether
\choice Albert Einstein
\choice Emmy Noether H
\end{hvcheckboxes}
\end{questions}
\end{document}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment