18

I have been using the exercise.sty package for a while now, mostly to build exercise lists for my students. After a few months from when I started, the code became very complicated. Today, it is a living nightmare.

But first, let me explain what I am using it for:

I am building Math, Precalculus and Calculus exercise lists and tests for my students. They range from Second Degree Equations, Integration Techniques, Volumes by Disks, you name it. That said, each type of class I teach demands a separate material "filtered" so that it best fits the class: level of dificulty, topic, number of questions on the exercise list and so on.

The problem is: I have close to 500 exercises and I'm not sure where to start. I would like to start the right way, so that I don't fall into a hole (like I am today).

My questions:

  • How can I type these exercises, the most efficient way possible, so that I can easily build these pdfs filled with the exercises that correspond to the given topic? Should I write these 500 exercises in a single .tex file?
  • Is there a package that allows two different types of solution for the same question? Let me explain this one: sometimes I just want to show the final solution, and sometimes the complete (worked-out) solution.
  • Some of my students are native from US so is there a way to, for the same exercise, create two (or more) different descriptions and answers (one in Portuguese and one in English)?
  • Lest's say at one point I reach 10,000 exercises. Can I use a single .tex file with all of them to build, for example, an exercise list with 40 "quadratic equations" exercises? In other words: use the "filters" or "labels" from these packages to make this filtering process?

I understand that these packages' capabilities are HUGE so I would love if someone could shine a light in a very efficient approach.

Thank you.

PS.: If I wasn't very clear on my explanations please let me know.

12
  • 3
    With 500+ exercises I think you need a serious workflow that goes beyond TeX. Probably each exercise in a separate file, with tags and a search mechanism to find the ones you want, and glue them together. Maybe even a database solution (might be possible with TeX). I think you should ask the two kinds of answers question separately from this one, with an MWE. Sep 27, 2016 at 17:31
  • 4
    Don't know how well it would work with that many entries, but you could try using datatooltk to store the questions, although with 10,000 exercises as @EthanBolker mentioned, you'd be better off using a database solution (which can be integrated with TeX using datatooltk in batch mode). Sep 29, 2016 at 8:14
  • 1
    1) is opinion based question you can write all exercises in a single .tex you can make file by exercise or file by topic. for 2) and 3) the answer is yes 4) whatever choice you make (single file or multiple) yes you can do what you're asking.
    – touhami
    Sep 29, 2016 at 17:29
  • 1
    @bru1987 Yes, that's right. You could just define a boolean, e.g. \newif\ifcomplete and then just have \ifcomplete extra stuff\fi within the answer. Alternatively, with the database approach have an extra field for the complete answer (depends how different the complete answer is from the abridged answer). Sep 30, 2016 at 10:38
  • 1
    You might look at webwork. That system allows you to use their exercises (1000s of them) and add your own. It gives latex output, or html output, and uses a sophisticated language (Perl) so that you can give online tests using your problems. You can also easily share your problems with other instructors who use webwork. Oct 3, 2016 at 8:53

3 Answers 3

18
+250

Since your question is about storing, maintaining and referencing a large set of exercises (potentially in the order of 10,000), I'm going to concentrate on that, so the style here is very basic.

It's possible to define conditionals using \newif (or through commands provided by packages such as etoolbox). For example:

\newif\ifsolutions
\newif\ifcomplete

These default to false, but can be switched on:

\solutionstrue
\completetrue

It's also useful to provide syntactic commands to mark the solution. For example:

\newcommand{\solutionname}{Solution}
\newcommand{\solution}{\par\textbf{\solutionname}:\par}

As has been mentioned in one of the other answers, it's also possible to use environments and the comment package. For multilingual support, the caption hooks can be used to redefine \solutionname as appropriate. For example:

\usepackage[USenglish]{babel}

\addto\captionsUSenglish{%
  \renewcommand\solutionname{Solution}%
}

Now an exercise can be written using these commands. For example:

$y = \sin(2x)$
\ifsolutions
 \solution
 \ifcomplete
  Intermediate steps, further details etc.
 \fi
 $y' = 2\cos(2x)$
\fi

Environments provide a more LaTeXy feel, but let's concentrate on storing and accessing the questions.

The simple method, which has already been suggested, is to put each question in a separate file and load it with \input. For example, if this exercise is in the file exercises/calculus/easy/dsin.tex then the following MWE works:

\documentclass{article}

\newif\ifsolutions
\newif\ifcomplete

\solutionstrue
\completetrue

\newcommand{\solutionname}{Solution}
\newcommand{\solution}{\par\textbf{\solutionname}:\par}

\begin{document}
\begin{enumerate}
\item \input{exercises/calculus/easy/dsin}

\end{enumerate}
\end{document}

This is a relatively generic method, which can easily be translated to other TeX formats. For example, the Plain TeX equivalent is:

\newif\ifsolutions
\newif\ifcomplete

\solutionstrue
\completetrue

\def\solutionname{Solution}
\long\def\solution{\par{\bf\solutionname}:\par}

\newcount\questionnum

\long\def\question{%
 \par
 \advance\questionnum by 1\relax
 \number\questionnum.
}

\question \input exercises/calculus/easy/dsin

\bye

The problem is that, although this structure is fine for a small number of questions, it can become unmanageable for 10,000. I mentioned datatooltk in the comments, which can read and write .dbtex files (datatool's internal format), but I don't recommend using this format directly. These files just contain LaTeX code that defines the internal registers and control sequences used by datatool to store the required data. There's no compression and it takes up a huge amount of resources. The datatooltk application works better as an intermediary that can pull filtered, shuffled or sorted data from external sources in a way that can easily be input in the document. (See the datatool performance page that compares build times for large databases.)

There are switches, such as --shuffle or --sort, which instructs datatooltk to shuffle or sort the data after it's been pulled from the data source. This uses Java, which is more efficient than TeX, but if the data is stored in a SQL database, it's even more efficient to include these steps in the actual --sql switch. (Currently, datatooltk is only configured for MySQL, but it may be possible to use something else if the necessary .jar file can be added to the class path.)

SQL databases can be optimized to improve performance. Suppose you want to randomly select 20 questions from 500. How do you perform that selection in LaTeX? First you'd need to use the shell to find out all the available files (or have an index file that can be parsed). Then you need to shuffle the list. That will take a while to do with TeX. It's more efficient to do this with SQL. (See, for example, MySQL select 10 random rows from 600K rows fast.)

If you decide to use SQL, the next thing to consider is the table structure.

  • You'll need a unique id field. With this you'll be able to specifically select certain questions rather than have a random selection. (An auto increment primary key is best.)
  • A field containing the question. (Let's call it Question.)
  • A field containing the brief answer. (Let's call it Answer.)
  • A field containing the extended answer. (Let's call it ExtendedAnswer.)
  • A field identifying the difficulty level. (Let's call it Level.) This could be an integer (1 = easy) or an enumeration (easy, medium, hard).
  • A field identifying the topic. (Let's call it Topic.) An enumeration is probably the simplest type (for example, calculus, settheory).

I'm not quite sure about the language. There are two approaches that I can think of: have fields for the other language (For example, QuestionPortuges, AnswerPortuges and ExtendedAnswerPortuges) or have a separate entry for the question in a different language with an extra field for the language.

So the above exercise example, could have

  • Question => $y = \sin(2x)$
  • Answer => $y' = 2\cos(2x)$
  • ExtendedAnswer => Intermediate steps, further details etc. \[y' = 2\cos(2x)\]
  • Level => 1
  • Topic => calculus
  • Language => english or ExtendedAnswerPortuges => Passos intermédios, etc. \[y' = 2\cos(2x)\]

Note that this doesn't include the syntactic command \solution or the conditionals \ifsolutions and \ifcomplete, which makes it easier to arrange the various parts of the question and answer.

It may be that some exercises require a particular package (such as amsmath or graphicx), so perhaps there could also be a field for the required packages. For example Packages => graphicx,amsmath.

Any images or verbatim text must be stored outside the database somewhere on the file system. They could be on TeX's path or the database table could have a field with a list of external resources or the question/answer could simply use the full path.

The datatooltk call can be done before the LaTeX run or using the shell escape. There's also a datatooltk rule for arara users. Let's suppose, I use datatooltk to pull a random selection of questions and save the results in a file called exercises.dbtex. This can then be loaded in the document using:

\DTLloaddbtex{\exercisedb}{exercises.dbtex}

If the data includes the Packages field, you can make sure all the required packages are loaded by adding the following to the preamble:

\DTLforeach*{\exercisedb}{\Packages=Packages}
{\DTLifnullorempty{\Packages}{}{\usepackage{\Packages}}}

In the main part of the document:

\begin{enumerate}
\DTLforeach*{\exercisedb}% data base
{\Question=Question,\Answer=Answer,\ExtendedAnswer=ExtendedAnswer}% assignment list
{%
  \item \Question
  \ifsolutions
   \solution
   \ifcomplete
    \ExtendedAnswer
   \else
     \Answer
   \fi
  \fi
}
\end{enumerate}

Further reading: Using the datatool Package for Exams or Assignment Sheets

3
  • Thank you for the input Nicola, your solution and your package are exactly what I was looking for. Thank you for the awesome input. Best Regards!
    – bru1987
    Oct 3, 2016 at 20:20
  • I think that the second "\Answer" sould be "Answer" at the begining of the main document code. Excellent work by the way!
    – mac
    Oct 5, 2016 at 11:36
  • @mac Yes, you're right. I've fixed it. Thank you. Oct 5, 2016 at 11:49
7

What I did for my students was this.

  1. I seperated all my exercises in different folders by subject. Each folder is named like this "1_package, 2_package" etc.
  2. Each exercise in any folder is numbered by the name of the folder and the number of the exercise. For example "3_294" is the 294th exercise in the 3rd folder.
  3. In order to remember the content of each folder I made a list that shows what's inside. Let's say 1-> Integration, 2->Limits etc.
  4. I created the following (mwe) Test.tex template:
\documentclass[a4paper]{article}
  \usepackage{amsmath}
  \usepackage{enumitem}
  \newcommand{\exercise}[2]{\input{#1_package/#1_#2.tex}} 
  \begin{document}
  \begin{enumerate}
  \item \exercise{1}{3}
  \item \exercise{2}{28}
  \item \exercise{3}{294}
  \end{enumerate}
  \end{document}

The result for example could be like this: enter image description here

But I was also concerned about how could I select the proper exercise among 500+ exercises. Thus I created a list of them using the following code in a Database.tex file:

\begin{enumerate}[label=Integration.\arabic*.]
\foreach \t in {1,...,"number of the last ex. in folder 1"}{\item\exercise{1}{\t}}
\end{enumerate}
\begin{enumerate}[label=Differential Equations.\arabic*.]
\foreach \x in {1,...,"number of the last ex. in folder 2"}{\item\exercise{2}{\x}}
\end{enumerate}
\begin{enumerate}[label=Limits.\arabic*.]
\foreach \y in {1,...,"number of the last ex. in folder 3"}{\item\exercise{3}{\y}}
\end{enumerate}

............... E.T.C. The output is a list of all my exercises in all of my folders. Maybe printing that list will be more helpful in choosing the exercises.


EDIT 24/11/2021


I would like introduce DataTeX. It is a program for creating and managing LaTeX files databases as well as LaTeX document databases. I will give a brief description for each of these 2 database types:

1. Files database enter image description here

  • A LaTeX file can be a definition, a theorem, an exercise or any other file type that anyone needs to store and add in a document. Each time we dreate a file we can choose tags like filetype, topic, chapter, section and many more, which will then be used to filter our database and easily find the file we need. enter image description here
  • Exercises can be solved and many solutions can be stored for each file. enter image description here
  • The files can be added, removed and edited.

2. Document database enter image description here

  • In DataTeX we can create LaTeX document databases, where each document can be filtered by type such as Exams, Notes etc. enter image description here
  • In these documents we can add the files that we mentioned above by simply selecting them from the database table. enter image description here
  • If a document contains exercises then we can create a solution document almost automatically. enter image description here

Many Files and Document databases can be created. The database engine is Sqlite. It is written in C++.

The program uses a very simple pdf viewer and a minimal LaTeX compiler for the files that can run PdfLaTeX,LaTeX,XeLaTeX,PythonTeX,Asymptote and BibTeX.(PdfLaTeX, XeLaTeX and PythonTeX have been tested and work fine but many improvments are needed)

DISCLAIMER

I'm not a professional programmer so the code might be quite messy and the software still needs a lot of work untill it is fully functionable. I can say that a 70%-80% is ready and the basic functions I mentioned above work fine.

For the moment it is only available for linux with Texlive installed.

I don't know how to make the software ready to build and installed in linux, so qt creator (5.15.2) is the only way I know so far to compile it for the 1st time.

Any help and contribution is most welcome!!

4
  • That is a neat idea. I'm going to use it.
    – hola
    Nov 24, 2021 at 7:39
  • How it works I have not understood. :-((((( I use Windows but it is "only available for linux with Texlive installed".
    – Sebastiano
    Nov 30, 2021 at 21:23
  • I hope that I will be able to upload a brief documentation or a short video presentation as soon as possible. Unfortunatelly the software is only available for Linux at the moment because I haven't yet managed to compile it and make it available for windows also. I need help and contribution in this part in order for a Windows version to be available.
    – mac
    Nov 30, 2021 at 21:36
  • I hope this will help a little: youtube.com/watch?v=KWkXTwT7L2Y
    – mac
    Nov 30, 2021 at 23:00
1

Here;'s a proof of concept solution for the easy parts of your question - the second and third bullet points.

You could easily make it more elaborate, formatting and numbering exercises, adding keywords and tags. I don't think it makes sense to do that until the overall project structure is set.

\documentclass{article}

\usepackage{comment}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%This material should be in a preamble  
%
\newenvironment{exercise}
{}{}

\newenvironment{portuguese}
{}{}

\newenvironment{english}
{}{}

\newenvironment{final}
{}{}
\newenvironment{workedout}
{}{}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% This part can be in a master file for one handout that inputs the
% preamble and then the exercises for that handout.

% \documentclass{whatever}
% \input{preamble}

% decide what appears in the document

\excludecomment{english}
%\includecomment{english}

%\excludecomment{portuguese}
\includecomment{portuguese}

\excludecomment{final}
%\includecomment{final}

%\excludecomment{workedout}
\includecomment{workedout}

\begin{document}

General description for this worksheet.

%\input{ex1}
%\input{ex2}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% for each exercise in its own file
% \documentclass{standalone} 
\begin{exercise}

\begin{english}
This is an exercise.
\end{english}
\begin{portuguese}
Exercise text in Portuguese.
\end{portuguese}

\begin{final}

Solution here, no details. Could switch between English and Portuguese
easily, as above.
\end{final}

\begin{workedout}
Complete worked out solution. Could be multilingual.
\end{workedout}
\end{exercise}

\end{document}
2
  • 1
    Why would you invent new environments for the different languages rather than using Babel or Polyglossia or ...? Are you sure those names won't conflict if the user is using one of those packages?
    – cfr
    Sep 30, 2016 at 1:17
  • @cfr You're right (as usual). My goal was just to show that the easy parts of the OPs problem could be solved, so others could focus on the hard parts. I used what I knew, so not the tools designed for multilanguage support. If you'd like to improve my answer, feel free. Or post your own and I'll cheerfully delete mine. Sep 30, 2016 at 12:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.