summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/probsoln
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2013-03-13 22:35:46 +0000
committerKarl Berry <karl@freefriends.org>2013-03-13 22:35:46 +0000
commit95080bc66f5d1022cbcfbe7535a87055d02aa568 (patch)
tree78110a9731c73d008803b1243437378b52afc905 /Master/texmf-dist/source/latex/probsoln
parent8b6e07d34f4b46b6c6a049934683348b12ff3fd6 (diff)
probsoln (13mar13)
git-svn-id: svn://tug.org/texlive/trunk@29371 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/probsoln')
-rw-r--r--Master/texmf-dist/source/latex/probsoln/probsoln.dtx750
-rw-r--r--Master/texmf-dist/source/latex/probsoln/probsoln.ins8
2 files changed, 720 insertions, 38 deletions
diff --git a/Master/texmf-dist/source/latex/probsoln/probsoln.dtx b/Master/texmf-dist/source/latex/probsoln/probsoln.dtx
index 9515bfe3a4a..0468d92c632 100644
--- a/Master/texmf-dist/source/latex/probsoln/probsoln.dtx
+++ b/Master/texmf-dist/source/latex/probsoln/probsoln.dtx
@@ -9,7 +9,7 @@
% -doc "probsoln-manual.tex"
% -author "Nicola Talbot"
% probsoln
-% Created on 2011/12/10 17:17
+% Created on 2013/3/13 15:28
%\fi
%\iffalse
%<*package>
@@ -32,7 +32,7 @@
%\fi
% \iffalse
% Doc-Source file to use with LaTeX2e
-% Copyright (C) 2011 Nicola Talbot, all rights reserved.
+% Copyright (C) 2013 Nicola Talbot, all rights reserved.
% \fi
% \iffalse
%<*driver>
@@ -54,7 +54,7 @@
\RecordChanges
\PageIndex
-\CheckSum{1484}
+\CheckSum{1822}
\newcommand*{\dq}[1]{``#1''}
@@ -66,7 +66,7 @@
%\MakeShortVerb{"}
%\DeleteShortVerb{\|}
%
-% \title{probsoln v3.02:
+% \title{probsoln v3.04:
%creating problem sheets optionally with solutions}
% \author{Nicola L.C. Talbot\\[10pt]
%School of Computing Sciences\\
@@ -75,7 +75,7 @@
%NR4 7TJ. United Kingdom.\\
%\url{http://theoval.cmp.uea.ac.uk/~nlct/}}
%
-% \date{2011-12-10}
+% \date{2012-08-23}
% \maketitle
%\tableofcontents
%
@@ -535,6 +535,8 @@
%\end{definition}
%This is similar to \cs{loadrandomproblems} except that it won't load
%those problems whose labels are listed in \meta{exception list}.
+%\textbf{If you want to automatically exclude problems included in
+%previous documents, see \sectionref{sec:exprev}.}
%
%Note that the random number generator has been modified in version
%3.01 in order to fix a bug. If you want to ensure that your random
@@ -555,6 +557,117 @@
%a problem definition will be parsed twice.
%\end{important}
%
+%\subsection{Randomly Selecting Problems Not Selected in Previous
+%Documents}
+%\label{sec:exprev}
+%
+%Suppose you have a large set of questions that you want to randomly
+%select for assignments and exams. The chances are, you don't want to
+%include questions that have been previously set for, say, the last
+%three years. That is, you don't want to select questions the
+%students may already have seen. As from version 3.03, you can now do
+%this.
+%
+%The \sty{probsoln} package defaults to the UK academic year, which
+%starts in September. If this isn't appropriate, you can change it
+%using:
+%\begin{definition}[\DescribeMacro{\SetStartMonth}]
+%\cs{SetStartMonth}\marg{n}
+%\end{definition}
+%where \meta{n} is the number of the month. (1 = January, 2 =
+%February, etc.)
+%
+%The \emph{start year} is the calender year in effect when the
+%academic year started. For example, if this is the academic year
+%2011/12, then the start year is 2011. This is automatically set to
+%the start of the current academic year. It is also updated when
+%\cs{SetStartMonth} is used.\footnote{So don't use \cs{SetStartMonth}
+%after \cs{SetStartYear}.} If you want to set it to a specific year,
+%you can use:
+%\begin{definition}[\DescribeMacro{\SetStartYear}]
+%\cs{SetStartYear}\marg{year}
+%\end{definition}
+%For example: \verb|\SetStartYear{2008}| indicates the academic year
+%2008/9.
+%
+%There are two files concerned with previously used labels. They are:
+%\begin{description}
+%
+% \item[The previously used labels file] This keeps track of all
+% problems used in previous years, as well as problems used by
+% other documents that have this as their previously used labels
+% file, and it contains the problem labels from the last run of
+% the current document.
+%
+% \item[The current used labels file] This defaults to
+%\cs{jobname}\texttt{.prb}, but the name can be changed using:
+% \begin{definition}[\DescribeMacro{\SetUsedFileName}]
+% \cs{SetUsedFileName}\marg{name}
+% \end{definition}
+% This file keeps track of all the labels used in the current
+% document from the previous \LaTeX\ run. Note that if you want to
+% delete this file, first clear it using
+% \begin{definition}[\DescribeMacro{\ClearUsedFile}]
+% \cs{ClearUsedFile}\marg{file}
+% \end{definition}
+% in place of \cs{ExcludePreviousFile}\marg{file}, described below.
+% The argument \meta{file} is the previously used labels file
+% described above. \cs{ClearUsedFile} will remove all labels in
+% the current used labels file from the previously used labels file
+% and clear the current used labels file. Once this file is empty,
+% it may then be deleted.
+%
+%\end{description}
+%
+%Before loading randomly selected problems, first specify the
+%previously used labels file with the command:
+%\begin{definition}[\DescribeMacro{\ExcludePreviousFile}]
+%\cs{ExcludePreviousFile}\oarg{number of years}\marg{file name}
+%\end{definition}
+%where \meta{file name} is the name of the previously used file. The
+%optional argument \meta{number of years} specifies the year cut-off.
+%This defaults to 3, which means that only those labels used this
+%year or the previous 2 years will be kept. Any problems used before
+%then may be reused.
+%
+%Suppose I'm lecturing a first year undergraduate mathematics course
+%(designated, say, mth101). I want to set assignments on each topic
+%and an exam at the end of the year (as well as a resit or second
+%sitting paper). I've got databases with problems for each topic, but
+%the first and second sitting exams mustn't include any of the
+%problems used in the assignments or any problems used in assignments
+%or exams for the previous two academic years. I'm going to arrange
+%my directory structure as follows:
+%\begin{itemize}
+%\item \texttt{mth101/}
+% \begin{itemize}
+% \item \texttt{assignment1/} (differentiation)
+% \begin{itemize}
+% \item \texttt{assignment1.tex}
+% \end{itemize}
+% \item \texttt{assignment2/} (probability spaces)
+% \begin{itemize}
+% \item \texttt{assignment2.tex}
+% \end{itemize}
+% \item \texttt{assignment3/} (linear algebra)
+% \begin{itemize}
+% \item \texttt{assignment3.tex}
+% \end{itemize}
+% \item \texttt{exams/}
+% \begin{itemize}
+% \item \texttt{exam.tex} (first sitting)
+% \item \texttt{resit.tex} (second sitting)
+% \end{itemize}
+% \item \texttt{databases/}
+% \begin{itemize}
+% \item \texttt{differentiation.tex}
+% \item \texttt{probabilityspaces.tex}
+% \item \texttt{linearalgebra.tex}
+% \end{itemize}
+% \item \texttt{previouslabels.tex} (created by \sty{probsoln})
+% \end{itemize}
+%\end{itemize}
+%
%\section{Iterating Through Datasets}\label{sec:foreach}
%
%Once you have defined all your problems for a given data set, you
@@ -854,7 +967,7 @@
% \end{macrocode}
% Identify this package and version:
% \begin{macrocode}
-\ProvidesPackage{probsoln}[2011/12/10 v3.02 (NLCT)]
+\ProvidesPackage{probsoln}[2012/08/23 v3.04 (NLCT)]
% \end{macrocode}
% Required packages:
%\changes{3.01}{2011/08/22}{substr package no longer required}
@@ -862,6 +975,11 @@
\RequirePackage{ifthen}
\RequirePackage{amsmath}
% \end{macrocode}
+%\changes{3.03}{2011/01/16}{added etoolbox to list of required
+%packages}
+% \begin{macrocode}
+\RequirePackage{etoolbox}
+% \end{macrocode}
% \subsection{Package Options}
%\begin{macro}{\ifshowanswers}
% Define boolean to determine whether or not to show the
@@ -979,6 +1097,393 @@
% \end{macrocode}
%\end{macro}
%
+%\begin{macro}{\probsoln@startyear}
+%\changes{3.03}{2011/01/16}{new}
+% The year as at the start of the new academic year. (For example,
+% if the academic year starts in September and today is any date
+% between 2011-09-01 and 2012-08-30, then the start year is 2011.)
+% \begin{macrocode}
+\newcount\probsoln@startyear
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\SetStartYear}
+%\changes{3.03}{2011/01/16}{new}
+% Provide command to set the starting year manually.
+% \begin{macrocode}
+\newcommand*{\SetStartYear}[1]{%
+ \probsoln@startyear=#1\relax
+ \renewcommand\SetStartMonth[1]{%
+ \PackageError{probsoln}{\string\SetStartMonth\space
+ can't be used after \string\SetStartYear}{}}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\GetStartYear}
+% Gets the value of the start year count register:
+% \begin{macrocode}
+\newcommand*{\GetStartYear}{\probsoln@startyear}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\probsoln@startmonth}
+%\changes{3.03}{2011/01/16}{new}
+% The month starting the academic year. (1=January, 2=February,
+% etc).
+% \begin{macrocode}
+\newcount\probsoln@startmonth
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\SetStartMonth}
+%\changes{3.03}{2011/01/16}{new}
+% Define command to set the month starting the academic year. This
+% also sets the starting year.
+% \begin{macrocode}
+\newcommand*{\SetStartMonth}[1]{%
+ \probsoln@startmonth=#1\relax
+ \probsoln@startyear=\year\relax
+ \ifnum\month<\probsoln@startmonth
+ \advance\probsoln@startyear by -1\relax
+ \fi
+}
+% \end{macrocode}
+%\end{macro}
+%
+% Set the default starting month to 9 (September):
+% \begin{macrocode}
+\SetStartMonth{9}
+% \end{macrocode}
+%
+%\begin{macro}{\probsoln@prev}
+%\changes{3.03}{2011/01/16}{new}
+% File handle for file containing previous labels.
+% \begin{macrocode}
+\newwrite\probsoln@prev
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\probsoln@used}
+%\changes{3.03}{2011/01/16}{new}
+% File handle for file containing previous used.
+% \begin{macrocode}
+\newwrite\probsoln@used
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\probsoln@prev@cutoff}
+%\changes{3.03}{2011/01/16}{new}
+% Cut-off year. Problems excluded if the year they were set is
+% greater than the cut-off year.
+% \begin{macrocode}
+\newcount\probsoln@prev@cutoff
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@probsoln@usedfilename}
+% Stores the file name for the used problems file. (Defaults to
+% \cs{jobname}\texttt{.prb})
+% \begin{macrocode}
+\newcommand*{\@probsoln@usedfilename}{\jobname.prb}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\SetUsedFileName}
+% Set the name of the used problems file.
+% \begin{macrocode}
+\newcommand*{\SetUsedFileName}[1]{%
+ \renewcommand*{\@probsoln@usedfilename}{#1}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\ClearUsedFile}
+%\changes{3.03}{2011/01/16}{new}
+% Clear the contents of the used file (\cs{@probsoln@usedfilename})
+% and remove corresponding entries from the previous file (as
+% specified in \cs{ExcludePreviousFile}).
+% Not to be used after \cs{ExcludePreviousFile}.
+% \begin{macrocode}
+\newcommand*{\ClearUsedFile}[1]{%
+ \probsoln@prev@cutoff=0\relax
+ \@probsoln@readprev{#1}%
+% \end{macrocode}
+% Only write labels that aren't in the used file.
+% \begin{macrocode}
+ \@for\@this@db:=\prob@databases\do{%
+ {%
+ \edef\@prev@list{\csname probsoln@prev@list@\@this@db\endcsname}%
+ \ifdefempty{\@prev@list}%
+ {}%
+ {%
+ \@for\@this@label:=\@prev@list\do{%
+ \ifcsundef{@used@problem@\@this@db @\@this@label}%
+ {%
+ \immediate\write\probsoln@prev{%
+ \string\previousproblem{\@this@label}{\@this@db}%
+ {\csname @prev@problem@\@this@db @\@this@label\endcsname}}%
+ }%
+ {}%
+ }%
+ }%
+ }%
+ }%
+ \immediate\closeout\probsoln@prev
+ \immediate\closeout\probsoln@used
+ \@disable@exclude@prev
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\ExcludePreviousFile}
+%\changes{3.03}{2011/01/16}{new}
+% Exclude problems used in the last \meta{n} years.
+% \begin{macrocode}
+\newcommand*{\ExcludePreviousFile}[2][3]{%
+ \probsoln@prev@cutoff=\probsoln@startyear\relax
+ \advance\probsoln@prev@cutoff by -#1\relax
+ \@probsoln@readprev{#2}%
+ \@write@prev
+ \def\ExcludePreviousFile[2][3]{\PackageError{probsoln}{Only one
+ instance of \string\ExcludePreviousFile\space allowed}{You've
+ already used this command. You are only allowed to use it once}}%
+ \def\ClearUsedFile[1]{%
+ \PackageError{probsoln}%
+ {\string\ClearUsedFile\space may not be used after
+ \string\ExcludePreviousFile}{}}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@probsoln@readprev}
+% Read contents of previous and used files and open for writing.
+% \begin{macrocode}
+\newcommand*{\@probsoln@readprev}[1]{%
+ \@enable@exclude@prev
+ \InputIfFileExists{#1}%
+ {\PackageInfo{probsoln}%
+ {Excluded problem file `#1' found}}%
+ {\PackageInfo{probsoln}%
+ {Excluded problem file `#1' not found. A new one will be
+ created}}%
+ \InputIfFileExists{\@probsoln@usedfilename}%
+ {\PackageInfo{probsoln}%
+ {Current problems file `\@probsoln@usedfilename' found}}%
+ {\PackageInfo{probsoln}%
+ {No current problem file `\@probsoln@usedfilename' found. A new one will be created}}%
+ \immediate\openout\probsoln@prev=#1
+ \immediate\openout\probsoln@used=\@probsoln@usedfilename
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\probsoln@prev@list}
+%\changes{3.03}{2011/01/16}{new}
+% Maintain a list of all previous problem labels:
+% \begin{macrocode}
+\newcommand*{\probsoln@prev@list@default}{}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@write@prev}
+%\changes{3.03}{2011/01/16}{new}
+% Write all previous labels to file.
+% \begin{macrocode}
+\newcommand*{\@write@prev}{%
+ \@for\@this@db:=\prob@databases\do{%
+ {%
+ \edef\@prev@list{\csname probsoln@prev@list@\@this@db\endcsname}%
+ \ifdefempty{\@prev@list}%
+ {}%
+ {%
+ \@for\@this@label:=\@prev@list\do{%
+ \immediate\write\probsoln@prev{%
+ \string\previousproblem{\@this@label}{\@this@db}%
+ {\csname @prev@problem@\@this@db @\@this@label\endcsname}}%
+ }%
+ }%
+ }%
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@enable@exclude@prev}
+%\changes{3.03}{2011/01/16}{new}
+% Enable commands for excluding previously selected problems.
+% \begin{macrocode}
+\newcommand*{\@enable@exclude@prev}{%
+% \end{macrocode}
+% Redefine macro that adds used problem to used problem file and
+% previous problem file.
+% \begin{macrocode}
+ \renewcommand*{\@add@used@problem}[2]{%
+ \immediate\write\probsoln@used{\string\usedproblem{##1}{##2}{\number\probsoln@startyear}}%
+ \ifcsundef{@prev@problem@##2@##1}%
+ {%
+ \immediate\write\probsoln@prev{%
+ \string\previousproblem{##1}{##2}{\number\probsoln@startyear}}%
+ \expandafter\xdef\csname @prev@problem@##2@##1\endcsname{%
+ \number\probsoln@startyear}%
+ }%
+ {%
+ \expandafter\ifnum\csname @prev@problem@##2@##1\endcsname
+ <\probsoln@startyear
+ \immediate\write\probsoln@prev{%
+ \string\previousproblem{##1}{##2}{\number\probsoln@startyear}}%
+ \expandafter\xdef\csname @prev@problem@##2@##1\endcsname{%
+ \number\probsoln@startyear}%
+ \fi
+ }%
+ }%
+% \end{macrocode}
+% Redefine macro that fetches the exclusion list. (First argument is
+% the macro in which to store the list, the second argument is the
+% database.)
+% \begin{macrocode}
+ \renewcommand*{\@fetch@excluded@list}[2]{%
+ \def##1{}%
+ \ifcsdef{probsoln@prev@list@##2}%
+ {%
+ \edef\@prev@list{\csname probsoln@prev@list@##2\endcsname}%
+ \@for\@this@label:=\@prev@list\do{%
+% \end{macrocode}
+% If it isn't one of the used problems, it can be added to the
+% exclusion list:
+% \begin{macrocode}
+ \ifcsundef{@used@problem@##2@\@this@label}%
+ {%
+% \end{macrocode}
+% It isn't, so label can be added to the exclusion list:
+% \begin{macrocode}
+ \ifcsempty{##1}%
+ {\edef##1{\@this@label}}%
+ {\edef##1{##1,\@this@label}}%
+ }%
+ {}%
+ }%
+ }%
+ {}%
+ }%
+% \end{macrocode}
+% Add new previous list for given database:
+% \begin{macrocode}
+ \renewcommand*{\@add@newprevlist}[1]{%
+ \expandafter\gdef\csname probsoln@prev@list@##1\endcsname{}%
+ }%
+% \end{macrocode}
+% Redefine macro that closes the exclusion-related files.
+% \begin{macrocode}
+ \renewcommand*{\close@probsoln@prev}{%
+ \closeout\probsoln@prev
+ \closeout\probsoln@used
+ }%
+}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\@disable@exclude@prev}
+%\changes{3.03}{2011/01/16}{new}
+% Disable commands for excluding previously selected problems.
+% \begin{macrocode}
+\newcommand*{\@disable@exclude@prev}{%
+ \renewcommand*{\@add@used@problem}[2]{}%
+ \renewcommand*{\@fetch@excluded@list}[2]{\def##1{}}%
+ \renewcommand*{\@add@newprevlist}[1]{}%
+ \renewcommand*{\close@probsoln@prev}{}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+% By default, the commands for excluding previously selected
+% problems are disabled.
+%\begin{macro}{\@add@used@problem}
+%\changes{3.03}{2011/01/16}{new}
+% Adds problem to used problems list. (First argument is the label,
+% the second argument is the database name.)
+% \begin{macrocode}
+\newcommand*{\@add@used@problem}[2]{}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@fetch@excluded@list}
+%\changes{3.03}{2011/01/16}{new}
+% Fetches the excluded list. (First argument macro in which to store
+% the list. The second argument is the database name.)
+% \begin{macrocode}
+\newcommand*{\@fetch@excluded@list}[2]{%
+ \def#1{}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@add@newprevlist}
+%\changes{3.03}{2011/01/16}{new}
+% Adds a new previous list for the given database:
+% \begin{macrocode}
+\newcommand*{\@add@newprevlist}[1]{}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\close@probsoln@prev}
+%\changes{3.03}{2011/01/16}{new}
+% Close file used for previous labels
+% \begin{macrocode}
+\newcommand*{\close@probsoln@prev}{}
+% \end{macrocode}
+%\end{macro}
+%
+% At the end of the document, close file if required:
+% \begin{macrocode}
+\AtEndDocument{\close@probsoln@prev}
+% \end{macrocode}
+%
+%\begin{macro}{\previousproblem}
+%\changes{3.03}{2011/01/16}{new}
+% Identifies problem that has been selected and the year it was
+% selected. (First argument label, second argument database name,
+% third argument year.)
+% \begin{macrocode}
+\newcommand*{\previousproblem}[3]{%
+ \ifnum#3>\probsoln@prev@cutoff
+% \end{macrocode}
+% If data set hasn't been defined, define it:
+% \begin{macrocode}
+ \ifcsundef{prob@db@#2}{\prob@newdb{#2}}{}%
+% \end{macrocode}
+% Define command that stores the year the problem was used:
+% \begin{macrocode}
+ \expandafter\gdef\csname @prev@problem@#2@#1\endcsname{#3}%
+% \end{macrocode}
+% Add label to the previous list for this data set:
+% \begin{macrocode}
+ \edef\@prev@list{\csname probsoln@prev@list@#2\endcsname}%
+ \ifdefempty{\@prev@list}%
+ {%
+ \expandafter\xdef\csname probsoln@prev@list@#2\endcsname{#1}%
+ }%
+ {%
+ \expandafter\xdef\csname probsoln@prev@list@#2\endcsname{%
+ \@prev@list,#1}%
+ }%
+ \fi
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\usedproblem}
+%\changes{3.03}{2011/01/16}{new}
+% Don't want to exclude problems that were selected in the previous
+% run of this document for the current year, so they need to be
+% identified in the aux file.
+% \begin{macrocode}
+\newcommand*{\usedproblem}[3]{%
+ \ifnum#3=\probsoln@startyear
+ \expandafter\def\csname @used@problem@#2@#1\endcsname{#3}%
+ \fi
+}
+% \end{macrocode}
+%\end{macro}
+%
%\subsection{Databases}
% All the problems are stored in data bases. Each data base
% \meta{name} is represented as a macro \cs{prob@db@}\meta{name}
@@ -1014,12 +1519,18 @@
% Creates a new (empty) data base.
% \begin{macrocode}
\newcommand*{\prob@newdb}[1]{%
-\@ifundefined{prob@db@#1}{%
- \expandafter\gdef\csname prob@db@#1\endcsname{}%
- \xdef\prob@databases{\prob@databases,#1}%
- \expandafter\gdef\csname prob@db@#1@solutions\endcsname{}%
- }{%
- \PackageError{probsoln}{Data set `#1' is already defined}{}}}
+ \ifcsundef{prob@db@#1}%
+ {%
+ \expandafter\gdef\csname prob@db@#1\endcsname{}%
+ \xdef\prob@databases{\prob@databases,#1}%
+ \expandafter\gdef\csname prob@db@#1@solutions\endcsname{}%
+ \@add@newprevlist{#1}%
+ }%
+ {%
+ \PackageError{probsoln}{Data set `#1' is already defined}%
+ {Data set names must be unique}%
+ }%
+}
% \end{macrocode}
%\end{macro}
%
@@ -1067,12 +1578,14 @@
% \end{macrocode}
% Add label to target data base
% \begin{macrocode}
- \expandafter\ifx\csname prob@db@#3\endcsname\@empty
+ \ifcsempty{prob@db@#3}%
+ {%
\expandafter\xdef\csname prob@db@#3\endcsname{#1}%
- \else
+ }%
+ {%
\expandafter\xdef\csname prob@db@#3\endcsname{%
\csname prob@db@#3\endcsname,#1}%
- \fi
+ }%
% \end{macrocode}
% Redefine \cs{prob@data@}\meta{source}"@"\meta{label} as
% \cs{prob@data@}\meta{target}"@"\meta{label}.
@@ -1665,6 +2178,7 @@ Please specify (e.g. \csname @prob@getargs@eg@\romannumeral#1\endcsname):}%
\def\@prob@currentlabel{#2}%
\def\prob@currentdb{#1}%
\prob@showdraftlabel{#1}{#2}%
+ \@add@used@problem{#2}{#1}%
\let\@useprob@next=\relax
\@ifundefined{prob@data@#1@#2}%
{%
@@ -1793,9 +2307,11 @@ Please specify (e.g. \csname @prob@getargs@eg@\romannumeral#1\endcsname):}%
%\cs{loadrandomproblems}\oarg{db name}\marg{n}\marg{filename}
%\end{definition}
% Loads \meta{n} randomly selected problems from \meta{filename}.
+%\changes{3.03}{2011/01/16}{fetch exclusion list}
% \begin{macrocode}
\newcommand{\loadrandomproblems}[3][default]{%
- \@loadrandomproblems{#1}{#2}{#3}{}%
+ \@fetch@excluded@list{\@excl@list}{#1}%
+ \@loadrandomproblems{#1}{#2}{#3}{\@excl@list}%
}
% \end{macrocode}
%\end{macro}
@@ -1835,8 +2351,13 @@ Please specify (e.g. \csname @prob@getargs@eg@\romannumeral#1\endcsname):}%
% \begin{macrocode}
\@probselN=0\relax
\@for\@thislabel:=\prob@selectedlabels\do{%
- \expandafter\DTLifinlist\expandafter
- {\@thislabel}{#4}{}%
+% \end{macrocode}
+%\changes{3.03}{2011/01/16}{ensure arguments expanded in
+%\cs{DTLifinlist}}
+% \begin{macrocode}
+ \edef\@if@in@list{\noexpand\DTLifinlist{\@thislabel}{#4}}%
+ \@if@in@list
+ {}%
{%
\advance\@probselN by 1\relax
\expandafter
@@ -1844,16 +2365,41 @@ Please specify (e.g. \csname @prob@getargs@eg@\romannumeral#1\endcsname):}%
\@thislabel}%
}%
}%
- \shuffle{@prob@tmp@}{\@probselN}%
- \ifnum\@probselN<#2\relax
% \end{macrocode}
-%\changes{3.01}{2011/08/22}{changed error to warning}
+%\changes{3.03}{2012/01/16}{added exclusion list to warning messages}
% \begin{macrocode}
- \PackageWarning{probsoln}{You have requested
- \number#2\space\space problem(s) but `#3' only contains
- \number\@probselN\space problems. All problems will be selected}%
+ \edef\@do@excludedlist{#4}%
+ \ifdefempty{\@do@excludedlist}%
+ {}%
+ {\def\@do@excludedlist{(Excluded list: #4.) }}%
+% \end{macrocode}
+%\changes{3.03}{2012/01/16}{added check for 0 available problems}
+% \begin{macrocode}
+ \ifnum\@probselN=0\relax
+ \PackageWarning{probsoln}{You have requested
+ \number#2\space\space problem(s) but there are no available
+ problems in `#3'. \@do@excludedlist No problems will be selected}%
\else
- \@probselN=#2\relax
+ \shuffle{@prob@tmp@}{\@probselN}%
+ \ifnum\@probselN<#2\relax
+% \end{macrocode}
+%\changes{3.01}{2011/08/22}{changed error to warning}
+% \begin{macrocode}
+ \ifnum\@probselN=1\relax
+ \PackageWarning{probsoln}{You have requested
+ \number#2\space\space problem(s) but there is only
+ 1 problem available in `#3'. \@do@excludedlist
+ Only 1 problem will be selected}%
+ \else
+ \PackageWarning{probsoln}{You have requested
+ \number#2\space\space problem(s) but there are only
+ \number\@probselN\space problems available in `#3'.
+ \@do@excludedlist
+ Only \number\@probselN\space problems will be selected}%
+ \fi
+ \else
+ \@probselN=#2\relax
+ \fi
\fi
% \end{macrocode}
% Store only the first \meta{n} of the shuffled labels.
@@ -2139,33 +2685,38 @@ Please specify (e.g. \csname @prob@getargs@eg@\romannumeral#1\endcsname):}%
%\loadrandomproblems{1}{\tmp}}
%\end{verbatim}
%
+%\changes{3.03}{}{added count register to keep track of level to
+%allow for nested loops}
% \begin{macrocode}
\newcount\@ps@forrand
+\newcount\@ps@forrand@level
\newcommand{\doforrandN}[4]{%
+ \global\advance\@ps@forrand@level by 1\relax
{%
\@ps@forrand=0\relax
\@for#2:=#3\do{%
\advance\@ps@forrand by 1\relax
\expandafter
- \edef\csname @doforrandN@\romannumeral\@ps@forrand\endcsname{#2}%
+ \edef\csname @doforrandN@\number\@ps@forrand@level @\romannumeral\@ps@forrand\endcsname{#2}%
}%
\ifnum\@ps@forrand<#1\relax
- \PackageError{probsoln}{Can't randomly select \number#1 item(s)}{You
- have requested \number#1 item(s), but there
- are only \number\@ps@forrand item(s) in the list}%
+ \PackageError{probsoln}{Can't randomly select \number#1\space item(s)}{You
+ have requested \number#1\space item(s), but there
+ are only \number\@ps@forrand\space item(s) in the list: #3}%
\else
- \shuffle{@doforrandN@}{\@ps@forrand}%
+ \shuffle{@doforrandN@\number\@ps@forrand@level @}{\@ps@forrand}%
\ifnum#1>0\relax
\@ps@forrand=0\relax
\loop
\advance\@ps@forrand by 1\relax
- \edef#2{\csname @doforrandN@\romannumeral\@ps@forrand\endcsname}%
+ \edef#2{\csname @doforrandN@\number\@ps@forrand@level @\romannumeral\@ps@forrand\endcsname}%
#4%
\ifnum\@ps@forrand<#1\relax
\repeat
\fi
\fi
}%
+ \global\advance\@ps@forrand@level by -1\relax
}
% \end{macrocode}
%\end{macro}
@@ -2264,12 +2815,13 @@ Please specify (e.g. \csname @prob@getargs@eg@\romannumeral#1\endcsname):}%
% environment's counters.
%\begin{environment}{textenum}
%\changes{2007 Oct 6}{2.05}{new}
+%\changes{2012/08/23}{3.04}{fixed bug that interfered with depth counter}
% \begin{macrocode}
\newenvironment{textenum}{%
\ifnum\@enumdepth>\thr@@
\@toodeep
\else
- \advance\@enumdepth\@ne\relax
+ \advance\@enumdepth by 1\relax
\edef\@enumctr{enum\romannumeral\the\@enumdepth}%
\let\@item\@textitem
\def\@itemlabel{%
@@ -2281,7 +2833,6 @@ Please specify (e.g. \csname @prob@getargs@eg@\romannumeral#1\endcsname):}%
\ignorespaces
}%
{%
- \global\advance\@enumdepth\m@ne\relax
}
% \end{macrocode}
%\end{environment}
@@ -2359,7 +2910,7 @@ Please specify (e.g. \csname @prob@getargs@eg@\romannumeral#1\endcsname):}%
%\fi
%\iffalse
% \begin{macrocode}
-%<*sample.tex>
+%<*sample-exclude.tex>
% \end{macrocode}
%\fi
%\iffalse
@@ -2369,7 +2920,100 @@ Please specify (e.g. \csname @prob@getargs@eg@\romannumeral#1\endcsname):}%
\usepackage{probsoln}
%uncomment the following line to display the answers
-\showanswers
+ %\showanswers
+
+ % Set the academic year to be 2011/12 (if omitted assume current
+ % academic year):
+ \SetStartYear{2011}
+
+ % Set the seed for the random number generator:
+ \PSNrandseed{\GetStartYear}
+
+ % Exclude problems that have been used this year or the previous
+ % two academic years. (Creates a file called 'excluded.tex' to
+ % store labels of used problems. Also creates a file called
+ % \jobname.prb that stores labels of problems used in this
+ % document, so they don't get excluded on subsequent runs.)
+ \ExcludePreviousFile[3]{excluded}
+
+ % To clear the used problems file (\jobname.prb) of the labels
+ % generated in the previous run, comment the above and uncomment
+ % below:
+ % \ClearUsedFile{excluded}
+
+ % Load 1 problem randomly selected from the given file
+ % and store in database 'firstprinciples':
+\loadrandomproblems[firstprinciples]{1}{prob-1stprncp}
+
+ % Load 5 problems randomly selected from the given file
+ % and store in database 'easy':
+\loadrandomproblems[easy]{5}{prob-easy}
+
+ % Load 2 problems randomly selected from the given file
+ % and store in database 'implicit':
+\loadrandomproblems[implicit]{2}{prob-implicit}
+
+ % Load 2 problems randomly selected from the given file
+ % and store in database 'probspaces':
+\loadrandomproblems[probspaces]{2}{prob-probspaces}
+
+ % Load 1 problem randomly selected from the given file
+ % and store in database 'mchoice':
+\loadrandomproblems[mchoice]{1}{prob-mchoice}
+
+ % Load 1 problem randomly selected from the given file
+ % and store in database 'nosoln':
+\loadrandomproblems[nosoln]{1}{prob-nosoln}
+
+
+\begin{document}
+\title{Sample Problem Sheet}
+\author{Nicola Talbot}
+\maketitle
+
+\begin{enumerate}
+ % Differentiation from first principles
+ \foreachproblem[firstprinciples]{\item \thisproblem}
+
+\item Differentiate the following functions:
+\begin{enumerate}
+ \foreachproblem[easy]{\item \thisproblem}
+\end{enumerate}
+
+ % Implicit differentiation
+\foreachproblem[implicit]{\item \thisproblem}
+
+ % Finite probability spaces
+\foreachproblem[probspaces]{\item \thisproblem}
+
+ % Multiple choice question
+\foreachproblem[mchoice]{\item \thisproblem}
+
+ % select one essay style question that doesn't come with a solution
+
+\foreachproblem[nosoln]{\item \thisproblem}
+\end{enumerate}
+\end{document}
+% \end{macrocode}
+%\fi
+%\iffalse
+% \begin{macrocode}
+%</sample-exclude.tex>
+% \end{macrocode}
+%\fi
+%\iffalse
+% \begin{macrocode}
+%<*sample.tex>
+% \end{macrocode}
+%\fi
+%\iffalse
+% \begin{macrocode}
+ % This file is public domain
+\documentclass[a4paper]{article}
+
+\usepackage{probsoln}
+ % uncomment the following line to display the answers
+ % \showanswers
% The following will generate a different set of
% problems each year
@@ -2941,6 +3585,33 @@ f'(x) & = & g'(x)\ln(g(x)) + \frac{g(x)}{g(x)}g'(x)\\
$y = \frac{\sin x}{x}$.}{%
\[\frac{dy}{dx} = \frac{\cos x}{x} - \frac{\sin x}{x^2}\]}
+\newproblem{diffeasy:exp4x}{%
+ $y = \exp(4x)$
+}%
+{%
+ \[\frac{dy}{dx} = 4\exp(4x)\]
+}
+
+\newproblem{diffeasy:exp3x+2}{%
+ $y = \exp(3x+2)$
+}%
+{%
+ \[\frac{dy}{dx} = 3\exp(3x+2)\]
+}
+
+\newproblem{diffeasy:cubic}{%
+ $y=x^3 + 4x^2 - x + 3$
+}%
+{%
+ \[\frac{dy}{dx} = 3x^2 + 8x - 1\]
+}
+
+\newproblem{diffeasy:quad}{%
+ $y=2x^3 + 6x -1$
+}%
+{%
+ \[\frac{dy}{dx} = 6x + 6 = 6(x+1)\]
+}
% \end{macrocode}
%\fi
%\iffalse
@@ -3119,6 +3790,15 @@ Differentiating with respect to $x$ gives:
& = & \frac{-x}{\sqrt{1-x^2}}.
\end{eqnarray*}}
+\newproblem{imd:ellipse}{%
+Find the gradient of the ellipse given by $4x^2 + 3y^2 = 25$.}{%
+Differentiating with respect to $x$ gives:
+\begin{eqnarray*}
+8x + 6y\frac{dy}{dx} & = & 0\\
+\frac{dy}{dx} & = & \frac{-8x}{6y}\\
+ & = & \frac{-4x}{\sqrt{25-4x^2}}.
+\end{eqnarray*}}
+
\newproblem{imd:ysq:xcuov2mx}{%
Find $\frac{dy}{dx}$, given
\begin{displaymath}
diff --git a/Master/texmf-dist/source/latex/probsoln/probsoln.ins b/Master/texmf-dist/source/latex/probsoln/probsoln.ins
index 20afb0ffb88..261f5de04d8 100644
--- a/Master/texmf-dist/source/latex/probsoln/probsoln.ins
+++ b/Master/texmf-dist/source/latex/probsoln/probsoln.ins
@@ -1,10 +1,10 @@
-% probsoln.ins generated using makedtx version 0.94b 2011/12/10 17:17
+% probsoln.ins generated using makedtx version 0.94b 2013/3/13 15:28
\input docstrip
\preamble
probsoln.dtx
- Copyright 2011 Nicola Talbot
+ Copyright 2013 Nicola Talbot
This work may be distributed and/or modified under the
conditions of the LaTeX Project Public License, either version 1.3
@@ -18,7 +18,7 @@
The Current Maintainer of this work is Nicola Talbot.
- This work consists of the files probsoln.dtx and probsoln.ins and the derived files probsoln.sty, sample.tex, sample2.tex, sample3.tex, sample4.tex, sample5.tex, sample6.tex, sample7.tex, sample8.tex, prob-1stprncp.tex, prob-args.tex, prob-easy.tex, prob-easy2.tex, prob-implicit.tex, prob-mchoice.tex, prob-mixed.tex, prob-newdata.tex, prob-nosoln.tex, prob-probspaces.tex, prob-probspaces2.tex, prob-tabmchoice.tex, prob-verb.tex.
+ This work consists of the files probsoln.dtx and probsoln.ins and the derived files probsoln.sty, sample-exclude.tex, sample.tex, sample2.tex, sample3.tex, sample4.tex, sample5.tex, sample6.tex, sample7.tex, sample8.tex, prob-1stprncp.tex, prob-args.tex, prob-easy.tex, prob-easy2.tex, prob-implicit.tex, prob-mchoice.tex, prob-mixed.tex, prob-newdata.tex, prob-nosoln.tex, prob-probspaces.tex, prob-probspaces2.tex, prob-tabmchoice.tex, prob-verb.tex.
\endpreamble
@@ -26,6 +26,8 @@
\generate{\file{probsoln.sty}{\usepreamble\defaultpreamble
\usepostamble\defaultpostamble\from{probsoln.dtx}{probsoln.sty,package}}
+\file{sample-exclude.tex}{\usepreamble\defaultpreamble
+\usepostamble\defaultpostamble\from{probsoln.dtx}{sample-exclude.tex,package}}
\file{sample.tex}{\usepreamble\defaultpreamble
\usepostamble\defaultpostamble\from{probsoln.dtx}{sample.tex,package}}
\file{sample2.tex}{\usepreamble\defaultpreamble