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.
