# Create math-exams with lists of student names

I am a math teacher form Germany. I want to create tests for my students. As is customary I will design two test groups:

• Test A
• Test B

I will also have a list of names:

• Joe
• Peter
• Julie
• ...

I want that Joe gets test A, Peter test B, Julie test A and so forth. So in pseudo-code:

for(i=0; i<names.size(); i++)
if(i even)
else


where the addpagewith-function works something like this

\include{head}
Name: name(i)
\include{testA.tex}


This should result in a .pdffile with as many pages as students. What is preventing me to try it on my own is:

1. I do not know if and how containers (list of names) work in LaTeX
2. I do not know if and how for-loops or alternatives work in Latex

Can someone point me in the right direction of where to find this or even better provide a minimal working example?

• Hallo Herr Kollege (als Mathemathlehrer): We need more information... Are you open to brute force (i.e. new LaTeX3 syntax)? – user31729 Oct 14 '15 at 14:31
• Even though this is certainly possible in LaTeX, you could consider generating the target document in another programming language and compiling only the end result in LaTeX. – Marijn Oct 14 '15 at 15:17
• Hallo Herr Hupfer :), Just read your profile. We have a similar cv. I have a Diplom in math and am now teaching at a Berufliche Gymnasium. But this specific project is for a Beruchfachschule. – BjörnK Oct 14 '15 at 19:34
• @BjörnK: But not in BaWü, I assume? ;-) Actually I am trying to write a package specific for school teachers, but there is one great obstacle: Everydays work as Teacher ;-) – user31729 Oct 14 '15 at 20:16
• I am in BaWü (Heidenheim). The world is small :) Yeah... school without students would be nice. – BjörnK Oct 20 '15 at 19:19

You can use foreach from package pgffor:

\documentclass{article}
\usepackage{pgf,pgffor}

\begin{document}
\foreach \x [count=\xi] in {Joe,Peter,Julie} {
Name: $\mathrm{\x}$
\ifodd\xi
\input{testA}
\else
\input{testB}
\fi
}
\end{document}


Note the input instead of include to prevent clearing the page. Test files:

head.tex

\section*{Today's test}


testA.tex

\section*{Test A}
Solve: 1+1
\clearpage


testB.tex

\section*{Test B}
Solve: 2+1
\clearpage


The use of section* is to prevent section numbering.

• Works great. Easy to understand (even for a noob like myself) and easy to maintain. Thanks a lot. – BjörnK Oct 14 '15 at 20:32

Improved version -- with a nice header

This defines a comma-separated list and stores the students' names on this list; afterwards its contents are mapped to a \DoTheHeader macro, which displays the page header and includes the test questions from testXY.tex -- XY is the test number as uppercase character (thus it does allow only 26 different tests ;-))

\documentclass{article}

\usepackage{tabularx}
\usepackage{booktabs}
\usepackage[ngerman]{babel}
\usepackage[tmargin=1cm,lmargin=1cm,rmargin=1cm,bmargin=1cm]{geometry}

\usepackage{xparse}

\newcounter{testgroup}

\ifnum\value{testgroup} < #1%
\stepcounter{testgroup}%
\else%
\setcounter{testgroup}{1}%
\fi%
\clearpage%
{%
\centering
\bfseries
\begin{tabularx}{\linewidth}{XXX}
\toprule
Name der Pappnase:  & Datum:  & Fach: Mathematik \tabularnewline
#2 & \today & Testgruppe \Alph{testgroup} \tabularnewline
\bottomrule
\end{tabularx}
}

\bigskip%
\InputIfFileExists{test\Alph{testgroup}.tex}{}{} % Load the content from disk
\blindtext[2]
}

\ExplSyntaxOn
\clist_new:N \l_bjoern_studentnames_clist
\NewDocumentCommand{\FillStudentNames}{m}{%
\clist_set:Nn \l_bjoern_studentnames_clist {#1}
}

\NewDocumentCommand{\AssignTestToStudents}{O{2}}{%
\setcounter{testgroup}{0}
% loop through the clist
\clist_map_inline:Nn {\l_bjoern_studentnames_clist} {\DoTheHeader[#1]{##1}}  %##1 comes from from the list -> student name
}

\ExplSyntaxOff

\usepackage{blindtext}

\FillStudentNames{Janis Joplin, Grace Slick, John Lennon,
Paul McCartney, George Harrison, Ringo Starr, Groucho Marx,
Harpo Marx, Zeppo Marx,Chico Marx, Gummo Marx, Stan Laurel, Oliver Hardy,
Graham Chapman, John Cleese, Terry Jones, Terry Gilliam,
Eric Idle, Cameron Diaz, Paulo Cereda, Other blokes on TeX.SX}

\begin{document}
\AssignTestToStudents % Uses 2 as maximal test group value A,B

\AssignTestToStudents[5] % Uses 5 as maximal test group value A,B,C,D,E

\end{document}


• Looks really nice and looks like it has benefits over Marajin's solution. (Your solution respects blank spaces in the FillStudentNames-part, while you have to add an \, in Marijn's solution) However I would have a lot harder time to maintain the code as there are several parts that I don't understand. Marijn's solution is pretty much a version of my pseudo-code so I gave him the "accept answer honor". Greetings from Heidenheim. – BjörnK Oct 14 '15 at 20:26
• @BjörnK: Your decision ;-) – user31729 Oct 14 '15 at 20:27

My colleague and I have created a procedure to obtain what you want using our package esami and the package datatool.

Tests are generated by compiling a tex file which produces a pdf with students' data automatically inserted. Data are read from a csv file.

Each student can have a different test or you can assign one of two versions to each of them.

You can see at this link https://www.dropbox.com/s/oxgok5rx76xlhyr/prova-test.pdf?dl=0 a simple example of how the test looks (the example is in Italian, but our package esami is localized also in German and the doc files are in English too).

If you are interested, we can send you the master file and the instructions to generate this kind of tests. The package esami is on CTAN (and in Texlive and Miktex).

• Looks nice. Are some of the questions randomized? This is an idea I have been playing around with. I would prefer to stay in latex as in Marijn's solution though. – BjörnK Oct 14 '15 at 19:39
• Yes, all of the questions are randomized, in order, order of the answers and value of the parameters. The exercise that you see in the example contains basically only one exercise. Questions are randomly chosen from a set of questions (in external files). – grames Oct 15 '15 at 7:51

Here is a solution using (la)TeX \loop

\documentclass{article}
\newcounter{student}
\renewcommand{\thestudent}{%
\ifcase\value{student}\or
Smith\or
John\or
Chriss\or
David\or
Black\or
notstudent\fi
}
\def\notstudent{notstudent}
\begin{document}
\setcounter{student}{0}
\loop
\stepcounter{student}%
\edef\student{\thestudent}%
\unless\ifx\student\notstudent

Some unchanged stuff

Name: \student

\ifodd\value{student}
Test A
\else
Test B
\fi
\repeat
\end{document}

• Again, very nice! – user31729 Oct 14 '15 at 18:16
• Looks very good. I slightly prefer the version below as I am sure I understand everything there. – BjörnK Oct 14 '15 at 20:33
• @BjörnK you're right. – touhami Oct 14 '15 at 21:28