8

I am trying to set up an environment for making exercises with corresponding answers for students.

Idea

I would like to be able to write the text for an exercise in an environment, and directly after write the answer (preferably in another environment). The exercise should show up where it is written, but the answers should remain hidden until a command, e.g. \listofanswers, is issued. This command would then output the answer to every question at the very place the command is issued (just like inserting e.g. \listoffigures or a bibliography). The answers should appear with the same numbering as the exercises they provide answers to. In this way, I could collect every answer and only show them at the end of the document instead of right after their corresponding exercise.

Current status

This is what I have been able to hack together so far:

\documentclass{scrartcl}

% Exercise environment:
\newcounter{exercise}
\newenvironment{ex}[1]{\refstepcounter{exercise}\par\medskip\noindent%
   \textbf{Exercise~\theexercise\ #1\quad} \rmfamily}{\medskip}

% Basic answer environment that should take care of formatting:
\newenvironment{ansenv}{\par\medskip\noindent%
   \textbf{Answer to exercise~\theexercise\quad} \rmfamily}{\medskip}

% Create a new answer environment that will store the answer for outputting later:
\usepackage{etoolbox}
\usepackage{environ}
\newcommand{\listofanswers}{}
\NewEnviron{answer}{
    \xappto{\listofanswers}{
        \begin{ansenv} \BODY \end{ansenv}
    }
}

\begin{document}

\section{Exercises}
\begin{ex}{Exercise title 1}
    This is the first exercise.
\end{ex}
\begin{answer}
    This is the answer to the first exercise, and should only show up when and where \verb!\listofanswers! is used.
\end{answer}

\begin{ex}{Exercise title 2}
    This is the second exercise.
\end{ex}
\begin{answer}
    This is the answer to the second exercise, and should only show up when and where \verb!\listofanswers! is used.
\end{answer}

This is something that is neither an exercise nor an answer.

\section{Answers}
% Output all answers right here at the very end of the document:
\listofanswers

\end{document}

Expected result

I would like to see something like the below: Expected output when using my custom exercise and answer environment.

Actual result

Compiling gives me the following error:

! Argument of \@firstoftwo has an extra }.
<inserted text> 
                \par 
l.32 \end{answer}

Can someone help me track down the bug or know of a better way to accomplish my exercise and answer environments?

5
  • 4
    Have a a look at packages like »exsheets« or »probsoln«. Feb 18, 2014 at 8:37
  • 2
    You could adapt the answer to tex.stackexchange.com/questions/33229/…
    – egreg
    Feb 18, 2014 at 9:23
  • BTW: Welcome to TeX.SX! You can have a look at our starter guide to familiarize yourself further with our format. Feb 18, 2014 at 9:24
  • @ThorstenDonig: Well, that was embarrassing. I don't know how I have missed those packages. Anyway, exsheets seem to do exactly what I want -- thank you very much! :) Feb 18, 2014 at 13:25
  • @egreg Yes, that seem like the right way to go. Thorsten's suggestions will do exactly what I am after, but I will try to get this running for the fun of it and post the solution. Thank you! :) Feb 18, 2014 at 13:28

2 Answers 2

1

Here's a solution using the collect package to define a collection for the answers; \listofanswers is simply defined as \includecollection{answers}:

\documentclass{scrartcl}
\usepackage{collect}

\definecollection{answers}

\newcommand\mycollect[1]{%
  \collect{answers}
    {\par\medskip\noindent\textbf{Answer to Exercise~#1}}
    {\par}
    {}{}%
}

\newenvironment{answer}
  {\begingroup\edef\x{\endgroup\noexpand\mycollect{\theexercise}}\x}
  {\endcollect}

% Exercise environment:
\newcounter{exercise}
\newenvironment{ex}[1]  
  {\refstepcounter{exercise}%
    \gdef\@tempa{\theexercise}\par\medskip\noindent%
   \textbf{Exercise~\theexercise\ #1\quad}%
  }
  {\medskip}

\newcommand\listofanswers{\includecollection{answers}}

\begin{document}

\section{Exercises}

\begin{ex}{Exercise title 1}
This is the first exercise.
\end{ex}
\begin{answer}
This is the answer to the first exercise.
\end{answer}

\begin{ex}{Exercise title 2}
This is the second exercise.
\end{ex}
\begin{answer}
This is the answer to the second exercise.
\end{answer}

\begin{ex}{Exercise title 3}
This is the third exercise.
\end{ex}
\begin{answer}
This is the answer to the third exercise.
\end{answer}

\section{Answers}
\listofanswers

\end{document}

enter image description here

Thanks to egreg who helped me to solve a problem with the counters in his answer to A problem with counters.

0

tcolorbox can be used as an alternative to collect. It offers several commands to store answers for later use.

  • \savelowerto=file defines which fil will be used to store lower part of a particular box.
  • \tcbstartrecording starts to record all lower parts
  • \tcbstoprecording finishes recording lower parts
  • \tcbinputrecords loads recordings and print them
  • record option allows to define what to write

An example with the complete code:

\documentclass{article}

\usepackage[most]{tcolorbox}

\tcbset{
    enhanced,
    blanker,
    fonttitle=\bfseries,
    coltitle=black,
}

\NewTColorBox[auto counter, number within=section]{exercise}{+O{}}{ %
title={Exercise~\thetcbcounter:},
label={exercise@\thetcbcounter},
attach title to upper=\ ,
lowerbox=ignored,
savelowerto=exercices/exercise-\thetcbcounter.tex,
record={\string\answer{\thetcbcounter}{exercices/exercise-\thetcbcounter.tex}},
#1
}

\NewTotalTColorBox{\answer}{mm}{ %
title={Answer to Exercise~\ref{exercise@#1} on page~\pageref{exercise@#1}:},
phantomlabel={answer@#1},
attach title to upper=\ ,
}{\input{#2}}

\begin{document}
\section{Some exercices}

\tcbstartrecording

\begin{exercise}
First exercise
\tcblower
Answer to first exercise.
\end{exercise}

\begin{exercise}
This is the second exercise.
\tcblower
Answer to second exercise.
\end{exercise}

\begin{exercise}
Third exercise. 
\tcblower
Answer to third exercise.
\end{exercise}

\tcbstoprecording

\section{Answers to previous exercices}

\tcbinputrecords

\end{document}

And the result:

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .