About
Shop
LaTeX
Software
Books
Gallery
News
Contact
Blog
Settings

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 1
Alternatively 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.

© 2015 Dickimaw Books. "Dickimaw", "Dickimaw Books" and the Dickimaw parrot logo are trademarks. The Dickimaw parrot was painted by Magdalene Pritchett.

Terms of Use Privacy Policy Cookies Site Map FAQs