# Questions on designing a dynamic database of exercises

Almost all packages to handle exercises allow us to attach/retrieve meta-data to/from each exercise.

Some things one might want when handling exercises are:

• Filter exercises according to their meta-data.
• Select random exercises from an external file.
• Have dynamic data associated to each exercise.

The first and second things are already addressed by the packages exsheets and prob­soln.

What I'm referring to by "dynamic data" is data that can change with time. For example a key tused to store the number of times an exercise have been used in past documents.

As far as I know, this have not been covered yet.

Now, let me be more specific:

# The problems to solve

Say I want to use the exsheets package to handle the questions for my exams. So I do something like \DeclareQuestionProperty{difficulty,topic,lsused,lyused,tused}, where lsused/lyused are last semester/year the question have been used and tused is as explained above.

I can choose random questions by topic (by putting them in separate external files). So I have one file for each topic, and in each file questions like

\begin{question}[ID=L1]
\SetQuestionProperties{difficulty=hard,topic=logic,lsused=1,lyused=2011,tused=3}
Proof that this is not our first very hard question.
\end{question}


I need to see the IDs of the questions in order to decide which to keep and which to discard. Let's call this the "selection stage". Say my exam must have 9 questions, so I do something like:

\documentclass{article}
\usepackage{exsheets}

\DeclareQuestionProperty{difficulty,topic,lsused,lyused,tused}
\DebugExSheets{true}

\begin{document}
\includequestions[random=3,difficulty=easy]{logic}
\includequestions[random=3,difficulty=medium]{arithmetic}
\includequestions[random=3,difficulty=hard]{geometry}
\end{document}


Notice that if I compile this file many times I'll probably get a different set of questions each time.

Here is where the first problem arises: I'm not sure if we can filter questions according user-defined properties. It will be useful to avoid questions by ID, for example some:

\includequestions[random=3,difficulty=easy,noIDs={L5,L6}]{logic}


And, even if we can do so, it would be better to have some way to enter in a "preliminary stage" which allow us to keep the exercises obtained in the last compilation (say by storing their IDs and the topic/file they belong to in an external file) on the "selection stage" and just change the questions we do not want.

Suppose that the package which solves all this problems is called upackage. And that it provides ways to say which stage we are in. Suppose all the unknown commands that appear hereafter are provided by this package. So in the first stage I do something like:

\documentclass{article}

\usepackage{exsheets}
\usepackage{upackage}

\DeclareQuestionProperty{difficulty,topic,lsused,lyused,tused}
\DebugExSheets{true}

\begin{document}
\setstage{selection}
\includequestions[random=3,difficulty=easy]{logic}
\includequestions[random=3,difficulty=medium]{arithmetic}
\includequestions[random=3,difficulty=hard]{geometry}
\end{document}


Suppose that after compile this, I like all the questions except the second geometry question. So I do:

\documentclass{article}

\usepackage{exsheets}
\usepackage{upackage}

\DeclareQuestionProperty{difficulty,topic,lsused,lyused,tused}
\DebugExSheets{true}

\begin{document}
\setstage{preliminary}
\changequestion{number=2,topic=geometry}
\end{document}


What I expect from this is, the same set of questions I got before but with a different second geometry question. And if still do not like it, I just compile again. This is a bit complex since it must keep track of the unwanted questions list. Here I assuming that file names and topics are the same.

Once I decide that the 9 questions are fine, then I just do:

\documentclass{article}

\usepackage{exsheets}
\usepackage{upackage}

\DeclareQuestionProperty{difficulty,topic,lsused,lyused,tused}

\begin{document}
\setstage{final}
\end{document}


And I get the questions this time without displaying their IDs. And here is where the other problem comes. Suppose that the package allow us to set \currentsemester and \currentyear (which by default must be \year). I would like that when the document is marked as final, the properties lsused, lyused get updated in the corresponding questions, as well as the tused which must be incremented in one. This will be useful to set, say, a \tolerance. For example if I set \tolerance{2} and I'm in the first semester of 2013, this will avoid including questions used in the past year.

So the process to build an exam should be, in short:

Selection:

\documentclass{article}
\usepackage{exsheets}
\usepackage{upackage}

\DeclareQuestionProperty{difficulty,topic,lsused,lyused,tused}
\DebugExSheets{true}

\currentsemester{1}
\currentyear{2013}
\tolerance{2}

\begin{document}
\setstage{selection}
\includequestions[random=3,difficulty=easy]{logic}
\includequestions[random=3,difficulty=medium]{arithmetic}
\includequestions[random=3,difficulty=hard]{geometry}
\end{document}


Preliminary:

\documentclass{article}

\usepackage{exsheets}
\usepackage{upackage}

\DeclareQuestionProperty{difficulty,topic,lsused,lyused,tused}
\DebugExSheets{true}

\currentsemester{1}
\currentyear{2013}
\tolerance{2}

\begin{document}
\setstage{preliminary}
\changequestion{number=2,topic=geometry}
\end{document}


until the second geometry question is acceptable.

Final:

\documentclass{article}

\usepackage{exsheets}
\usepackage{upackage}

\DeclareQuestionProperty{difficulty,topic,lsused,lyused,tused}
\DebugExSheets{true}

\currentsemester{1}
\currentyear{2013}
\tolerance{2}

\begin{document}
\setstage{final}
\end{document}


# Questions

My questions, is it plausible to achieve things like this with TeX/LaTeX? Is there some other approach? How to solve these problems?

-
It's not possible to filter questions by properties with exsheets. But it shouldn't be too complicated to add... If I find the time I'll try to add something –  cgnieder Mar 2 '13 at 13:43
this should also be doable –  cgnieder Mar 2 '13 at 14:45
I just uploaded v0.8 to CTAN. It adresses at least the exsheets related issues of your question. –  cgnieder Mar 10 '13 at 11:13
@leo I'm developing an application called datatooltk to accompany datatool that will help with this type of thing. There are some examples in the manual. I'll upload it to CTAN once it's had a bit more testing. –  Nicola Talbot Jun 29 '13 at 18:55
@leo Inspired by this Q, I've started work on a box-metadata system, and I should be done within a week or so if I'm able to devote a reasonable amount of time to it. Using this general solution, I'd be able to create an exam class solution, but not an exsheets one. –  Sean Allred Aug 12 '13 at 18:27

It is very plausible to achieve such things in LaTeX, but if you are comfortable with Unix systems, I would rather recommand to rely on shell scripts and makefiles to generate exercise sheets.

# Walking the TeX way

I (almost) started my education in computer science with assembly language and, while it might sound surprising, I find this experience incredibly useful when programming TeX—and if you remember Knuth's inclination for assembler languages, this might well not sound surprising at all.

You can devise arbitrary complicated macro sets in TeX, by working with data structures. Data structures are most easily processed with the help of macros reading and writing to registers, using controlled expansion: edef, xdef, expandafter, futurelet and token registers are the tools of the trade.

If you are not familiar with these techniques, I suggest you look at the TeXbook of course, but also David Salomon's Advanced TeXbook that emphasizes the use of more advanced techniques. I wrote a macro package for plain TeX, the getoptk package allowing to define macros taking fancy (i.e. à la hbox) arguments. The example is small enough so that you can quickly grasp it, and shows how to do some simple lexical analyse on TeX input.

Besides the use of the aforementioned controlled expansion toolkit, I recommand to avoid defining false predicates, that is, test macros whose text expansion contains an iftrue or iffalse. This makes the construction of complex conditionals complicated. Instead, you should separate the test logic and the branching logic—look for ifgetoptbracket in the getoptk package.

Also, I find useful to split the macro logic in small chunks, see for instance the definition of the getoptk macro, it has many codeblocks labelled geoptk@A and so on, some suffixes having more or less standardised meaning (to me) like @L for loop and @E for exit or end.

Once you are comfortable with these techniques, you can define and work with abstract data types as you would do in any other computer language and describe complicated algorithms.

You might also be interested by the graphicx package, that does some kind of file processing. (It looks for bboxes in EPS files.)

The getoptk package on CTAN: http://www.ctan.org/tex-archive/macros/plain/contrib/getoptk

The issue of TuGboat where the package is described: http://tug.org/TUGboat/tb32-2

# Walking the UNIX way

A native TeX solution has the advantage of portability at the cost of maintainance ease. Since the problem you are trying to solve is probably underspecified (wouldn't be nice to have some random parameters in the exercises? and so on) you would probably want to extend its functionalities.

If you are working on a UNIX system and are comfortable with makefiles, shell programming and a couple of other utilies (mostly sed and awk) or programming languages, you may want to devise your own worfklow writing your TeX files, or part of them that you include in your main document.

By the way, this technique simplifies a lot the generation of complex tables.

I wrote a couple of make macros called BSD Make Pallàs Scripts that makes it very easy.

Documentation of my make macros: http://home.gna.org/bsdmakepscripts/tex.html

# Other solutions

If you agree to use perltex or luatex or anything similar, you could also try them, I have no experience with the tools, though.

-
Not strictly an answer, but a very nice exposition :-). With something like this, though, the 'TeX way' would be better served with the 'LaTeX3 way', as one of LaTeX3's main goals is a programmer's interface to the system. With LuaTeX, obviously, this question becomes a fair bit simpler (assuming a knowledge of Lua). –  Sean Allred Aug 12 '13 at 18:34