Exercise 26: Creating an Assignment Sheet with the datatool Package (Solution)
This is a solution to Exercise 26. This exercise requires the mth102.dbtex database. Before you compile this document, you need to run the following:datatooltk --name easybasic --output easybasic.dbtex --in mth102.dbtex --shuffle --filter-and --filter Level eq 1 --filter Topic eq Basic --truncate 2 datatooltk --name mediumbasic --output mediumbasic.dbtex --in mth102.dbtex --shuffle --filter-and --filter Level eq 2 --filter Topic eq Basic --truncate 1 datatooltk --name hard1stpr --output hard1stpr.dbtex --in mth102.dbtex --shuffle --filter-and --filter Level eq 3 --filter Topic eq Theory --truncate 1Alternatively you can use arara with the directives shown below. This code uses internal commands (\@for, \protected@write and \@auxout) so \makeatletter and \makeatother are required.
% arara: datatooltk: { name: easybasic, output: easybasic.dbtex, input: mth102.dbtex, shuffle: true, options: "--filter-and --filter Level eq 1 --filter Topic eq Basic --truncate 2"} % arara: datatooltk: { name: mediumbasic, output: mediumbasic.dbtex, input: mth102.dbtex, shuffle: true, options: "--filter-and --filter Level eq 2 --filter Topic eq Basic --truncate 1"} % arara: datatooltk: { name: hard1stpr, output: hard1stpr.dbtex, input: mth102.dbtex, shuffle: true, options: "--filter-and --filter Level eq 3 --filter Topic eq Theory --truncate 1"} % arara: pdflatex % arara: pdflatex \documentclass{article} \usepackage{etoolbox} \usepackage{datatool} \newbool{showanswers} \booltrue{showanswers} \newcommand{\solution}[1]{% \ifbool{showanswers}{\par\textbf{Solution: }#1}{}% } % This assumes all points are integers: \newcount\runningtotal \newcommand*{\points}[1]{% \marginpar{% (#1 \ifnum#1=1 point\else points\fi) }% \global\advance\runningtotal by #1\relax } \newcommand*{\PointsForLevel}[1]{% \ifcase#1 \or \points{5}% \or \points{10}% \or \points{20}% \fi } \newcommand{\dblist}{} \makeatletter \newcommand{\loaddata}[1]{% \@for\thisfile:=#1\do{% \input{\thisfile.dbtex}% \listxadd{\dblist}{\dtllastloadeddb}% }% } \newcommand{\thetotalpoints}{% \ifundef\totalpoints {??% \GenericWarning{}{Rerun required to determine the total points}% }% {% \totalpoints }% } \newcommand*{\settotalpoints}[1]{\gdef\totalpoints{#1}} \newcommand*{\writerunningtotal}{% \protected@write\@auxout{}{% \protect\settotalpoints{\number\runningtotal}}% \ifdef\totalpoints {% \ifnum\totalpoints=\runningtotal \relax \else \GenericWarning{}{Total points has changed. Rerun required}% \fi }% {}% } \makeatother \loaddata{easybasic,mediumbasic,hard1stpr} % do all the questions in the given database: \newcommand{\doquestions}[1]{% \DTLforeach*{#1} {\Label=Label,\Question=Question,\Answer=Answer,\Level=Level,\Topic=Topic}% {% \item {[Topic: \Topic. Level: \Level.]} % debugging information \PointsForLevel{\Level}\Question \solution{\Answer}% } } \begin{document} \begin{center}\bfseries\Large Assignment~1\ifbool{showanswers}{ (Solution Sheet)}{} \end{center} This assignment is worth a~total of \thetotalpoints\ points. \begin{enumerate} \forlistloop{\doquestions}{\dblist}% \end{enumerate} \writerunningtotal \end{document}
Download mth102.tex or mth102.pdf.