summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/probsoln
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2006-01-11 23:56:23 +0000
committerKarl Berry <karl@freefriends.org>2006-01-11 23:56:23 +0000
commitc52946ab7533d1e5ef2203bf47b76b406b687d83 (patch)
tree0806a9710c113bcad64032dee85cf424cd068aae /Master/texmf-dist/source/latex/probsoln
parent1a811a112321f9dac1bf770b5cd41202a26e70af (diff)
trunk/Master/texmf-dist/source/latex/probsoln
git-svn-id: svn://tug.org/texlive/trunk@462 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/probsoln')
-rw-r--r--Master/texmf-dist/source/latex/probsoln/probsoln.dtx473
-rw-r--r--Master/texmf-dist/source/latex/probsoln/probsoln.ins11
2 files changed, 484 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/probsoln/probsoln.dtx b/Master/texmf-dist/source/latex/probsoln/probsoln.dtx
new file mode 100644
index 00000000000..07ecd28ba6b
--- /dev/null
+++ b/Master/texmf-dist/source/latex/probsoln/probsoln.dtx
@@ -0,0 +1,473 @@
+%\def\filedate{21 Mar 2004}
+%\def\fileversion{2.0}
+%\def\filename{probsoln.dtx}
+%\def\docdate{19th Dec 2000}
+%\iffalse
+% Doc-Source file to use with LaTeX2e
+% Copyright (C) 2000 Nicola Talbot, all rights reserved.
+%\fi
+%
+% \newsavebox{\syntaxbox}
+% \newenvironment{syntax}{\begin{lrbox}{\syntaxbox}\ttfamily}%
+%{\end{lrbox}\par\noindent\fbox{\usebox{\syntaxbox}}\\}
+% \title{probsoln.sty v\fileversion: \LaTeX\ Package to help create problem sheets}
+% \author{N.L.C. Talbot}
+% \date{\docdate}
+% \maketitle
+% \tableofcontents
+%
+% \section{Introduction}
+% The package |probsoln.sty| is designed for teachers or lecturers who
+% want to create problem sheets for their students. This package was
+% designed with specifically mathematics problems in mind, but can
+% be used for other subjects as well. The idea is to create a file
+% containing a large number of problems with their solutions which
+% can be read in by \LaTeX, and then select a number of problems to
+% typeset. This means that once the database has been set up, each
+% year you can easily create a new problem sheet that is sufficiently
+% different from the previous year, thus preventing the temptation
+% of current students seeking out the previous year's students,
+% and checking out their answers. There is also an option that can be
+% passed to the package to determine whether or not the solutions
+% should be printed. In this way, one file can either produce
+% the student's version or the teacher's version.
+%
+% \section{Package Options}
+% The following options may be passed to this package:
+%
+% \centerline{%
+% \begin{tabular}{@{\ttfamily}ll}
+% answers & Show the answers\\
+% noanswers & Don't show the answers (default)
+% \end{tabular}
+% }
+%
+% \section{Commands Provided}
+% \subsection{Creating a New Problem}
+% \begin{syntax}|\newproblem[|\meta{nargs}|]{|\meta{label}|}{|\meta{problem}|}{|\meta{solution}|}|\end{syntax}
+% \DescribeMacro{\newproblem}
+% A new problem is defined using the command |\newproblem|. This does not print anything,
+% but merely stores the problem. The argument \meta{label} is a unique string that is
+% assigned to this problem so that it can be used later. The argument \meta{problem}
+% is normal \LaTeX\ code that should be used to typeset the problem. The argument
+% \meta{solution} is normal \LaTeX\ code that should be used to typeset the solution,
+% if required. For example:
+%\begin{verbatim}
+%\newproblem{quaddiff}{%
+%%This is the problem
+%\begin{displaymath}
+%f(x) = x^2 + 3x + 4
+%\end{displaymath}
+%}{%
+%%This is the solution
+%\begin{displaymath}
+%f'(x) = 2x + 3
+%\end{displaymath}
+%}
+%\end{verbatim}
+%
+% The optional argument \meta{nargs} specifies the number of parameters this
+% problem will take. By default this value is 0, but any value from 1 to 9
+% may be used. Each parameter is refered to by |#1|, |#2|, \ldots, |#9|.
+% For example, the following problem takes one parameter:
+%\begin{verbatim}
+%\newproblem[1]{sindiff}{%
+%\(f(x) = \sin(#1x)\)
+%}{%
+%\(f'(x) = #1\cos(#1x)\)
+%}
+%\end{verbatim}
+%
+% The |quaddiff| problem shown above can be made more generic by using parameters:
+%\begin{verbatim}
+%\newcount\ctr
+%\newproblem[3]{diff:quad}{%
+%\(f(x) =
+%\ifnum#1=0
+%\else
+%\ifnum#1=1\else#1\fi x^2
+%\fi
+%\ifnum#2=0
+%\else
+%\ifnum#2>0 \ifnum#1=0 \else + \fi \fi
+%\ifnum#2=1\else#2\fi x
+%\fi
+%\ifnum#3=0
+%\else
+%\ifnum#3>0 \ifnum#2=0 \ifnum#1=0 \else + \fi \else + \fi\fi
+%#3
+%\fi\)
+%}{%
+%\(f'(x) =
+%\ifnum#1=0
+%\else
+%\ctr=2
+%\multiply\ctr by #1
+%\the\ctr x
+%\fi
+%\ifnum#2=0
+%\else
+%\ifnum#2>0 \ifnum#1=0 \else + \fi \fi
+%#2
+%\fi
+% % print 0 if both #1 and #2 are 0
+%\ifnum#1=0 \ifnum#2=0 0 \fi\fi
+%\)
+%}
+%\end{verbatim}
+% The three parameters correspond to the coefficients. Note that they
+% must all be integers since \TeX\ only performs integer arithmetic.
+%
+% To generate a database, simply create a |.tex| file where all the problems
+% are defined using |\newproblem|, and either |\input| it at the
+% start of your document if you want to use specific problems
+% (see Section~\ref{sec:useprob}), or
+% pass it to |\selectrandomly| (see Section~\ref{sec:selran}).
+%
+% \subsection{Displaying a Problem}
+% \label{sec:useprob}
+% \begin{syntax}|\useproblem{|\meta{label}|}|\end{syntax}
+% \DescribeMacro{\useproblem}
+% Once a problem has be defined using |\newproblem|, it can be typeset
+% using the command |\useproblem|. If the problem was defined to take
+% arguments, the arguments to the problem should come after the
+% label. In the case of the |sindiff| example above, the command
+% |\useproblem{sindiff}{2}| would produce the following:\\[10pt]
+% \(f(x) = \sin(2x)\)
+% \paragraph{Solution:} \(f'(x) = 2\cos(2x)\)\\[10pt]
+% whereas the command |\useproblem{diff:quad}{3}{0}{-2}| would produce:\\[10pt]
+% \(f(x) = 3x^2 - 2\)
+% \paragraph{Solution:} \(f'(x) = 6x\)
+%
+% \vspace{10pt}
+% Suppose all the above problems are defined in the
+% file |probs.tex|, then the following code will create a problem sheet
+% with four questions in it:
+%\begin{verbatim}
+%\documentclass{article}
+%
+%\usepackage{probsoln}
+%\input{probs}
+%
+%\begin{document}
+%Differentiate the following functions with respect to $x$:
+%\begin{enumerate}
+%\item \useproblem{quaddiff}
+%\item \useproblem{sindiff}{4}
+%\item \useproblem{diff:quad}{2}{3}{1}
+%\item \useproblem{diff:quad}{0}{1}{2}
+%\end{enumerate}
+%\end{document}
+%\end{verbatim}
+%The answer sheet can then be generated by passing the option |answers|
+%to the |probsoln| package.
+%
+% \subsection{Selecting Problems at Random}
+% \label{sec:selran}
+% \begin{syntax}|\selectrandomly{|\meta{filename}|}{|\meta{n}|}|\end{syntax}
+% \DescribeMacro{\selectrandomly}
+% The command |\selectrandomly| will select \meta{n} problems that are defined
+% in the file \meta{filename}. Each problem is preceeded by a |\item|, so the
+% command |\selectrandomly| should occur within one of the list-like environments,
+% such as |enumerate|. For example:
+%\begin{verbatim}
+%\begin{enumerate}
+%\selectrandomly{easy.tex}{4}
+%\end{enumerate}
+%\end{verbatim}
+% will result in four numbered problems, selected at random from the
+% file |easy.tex|. (The \texttt{.tex} extension may be omitted.)
+%
+% Multiple |\selectrandomly| commands may be used. For example:
+%\begin{verbatim}
+%\begin{enumerate}
+%\item Differentiate the following functions with respect to $x$:
+%
+%\begin{enumerate}
+%\selectrandomly{samples/easy.tex}{3}
+%\selectrandomly{samples/args.tex}{1}
+%\end{enumerate}
+%
+%\selectrandomly{samples/implicit.tex}{1}
+%\selectrandomly{samples/1stprncpl.tex}{1}
+%
+%\end{enumerate}
+%\end{verbatim}
+% This will result in a total of 6 problems, numbered 1(a), 1(b), 1(c), 1(d), 2 and 3.
+%
+% If a randomly selected problem requires arguments, a message similar to the following
+% will be displayed:
+%\begin{verbatim}
+%Problem diff:quad requires 3 argument(s), please specify (e.g. {5}{3}):
+%\end{verbatim}
+% Enter the required arguments, where each argument is enclosed in braces (\{ \}).
+%
+% \subsection{Other Commands}
+% \DescribeMacro{\PSNrandseed}
+% The command |\PSNrandseed{|\meta{n}|}| specifies the seed for the random
+% number generator. For example, |\PSNrandseed{\year}| will produce a
+% different set of random problems each year, whereas |\PSNrandseed{\time}|
+% will produce a different set of problems each time you \LaTeX\ the
+% problem (as long as you leave at least a minute between runs.)
+%
+% \DescribeMacro{\showanswers}
+% The command |\showanswers| will show the solutions from that point
+% on. May be localised by placing within a group.
+%
+% \DescribeMacro{\hideanswers}
+% The command |\hideanswers| will hide the solutions from that point
+% on. May be localised by placing within a group.
+%
+% \DescribeMacro{\solutionname}
+% By default, the solution is preceeded by the text: \textbf{Solution:}. This can
+% be changed by redefining the macro |\solutionname|.
+%
+% \DescribeMacro{showanswers}
+% The boolean variable |showanswers| is defined to be true if the answers
+% are shown and false otherwise. You can therefore do something like:
+%\begin{verbatim}
+%\ifthenelse{\boolean{showanswers}}{\textbf{Solution Sheet}}{}
+%\end{verbatim}
+% and \textbf{Solution Sheet} will be printed only if the answers are displayed.
+%(For more information on |\ifthenelse| and |\boolean| see the
+%documentation for the |ifthen| package by David Carlisle.)
+%
+% \section{Error Messages}
+%\begin{ttfamily}
+%! Package probsoln Error: Label \ldots\ already used.
+%\end{ttfamily}\\[10pt]
+% Each label identifier used in |\newproblem| must be unique.
+% Check to make sure you haven't used the same label more than once.
+% Also check to make sure you haven't |\input|ed or randomly selected
+% from the same file more than once. (Or |\input|ed and randomly
+% selected from the same file.)
+%\\[10pt]
+%\begin{ttfamily}
+%! Package probsoln Error: Label \ldots\ undefined.
+%\end{ttfamily}\\[10pt]
+% You need to define a problem before you can use it. Check to
+% make sure you haven't mis-spelt it.
+%\\[10pt]
+%\begin{ttfamily}
+%! Package probsoln Error: Requested number too large.
+%\end{ttfamily}
+%\\[10pt]
+% You have asked for more problems than are defined within
+% the specified file. All problems in that file will be selected.
+%
+%\section{Contact Details}
+%Dr Nicola Talbot\\
+%School of Computing Sciences\\
+%University of East Anglia\\
+%Norwich. NR4 7TJ\\
+%\url{http://theoval.cmp.uea.ac.uk/~nlct/}
+%
+% \StopEventually{}
+% \section{The Code}
+% \iffalse
+% First we have the driver to get the documentation
+% \begin{macrocode}
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage[colorlinks,bookmarks]{hyperref}
+\begin{document}
+\OnlyDescription
+\DocInput{probsoln.dtx}
+\end{document}
+%</driver>
+% \end{macrocode}
+% \fi
+% At the start of the package, specify that the \LaTeX2e format is
+% required. And specify the package provided.
+% \begin{macrocode}
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{probsoln}[2004/03/21 Problems and their Solutions Package]
+\RequirePackage{ifthen}
+% \end{macrocode}
+% Define newif to determine whether or not to show the answers.
+% (Changed to |\provideboolean| 21 Mar 2004.)
+% \begin{macrocode}
+\provideboolean{showanswers}
+\newcommand{\showanswers}{\showanswerstrue}
+\newcommand{\hideanswers}{\showanswersfalse}
+% \end{macrocode}
+% Now define the package options
+% \begin{macrocode}
+\DeclareOption{answers}{\showanswerstrue}
+\DeclareOption{noanswers}{\showanswersfalse}
+\ExecuteOptions{noanswers}
+\ProcessOptions
+% \end{macrocode}
+% Create a newif to determine whether a command has already been defined
+% \begin{macrocode}
+\newif\ifdefined
+\def\checkdefined#1{\ifx#1\relax \definedfalse \else \definedtrue \fi}
+% \end{macrocode}
+% Create newifs for selecting randomly and parsing through file
+% \begin{macrocode}
+\newif\ifselectrandom \selectrandomfalse
+\newif\iffirstpass
+\newif\ifselected
+% \end{macrocode}
+% Define the command that creates a new problem
+% \begin{macrocode}
+\newcommand{\solutionname}{Solution:}
+\newcommand{\newproblem}[4][0]{%
+\ifselectrandom
+\iffirstpass
+% on the first pass, just store the label, and increment \@probN
+\global\advance\@probN by 1
+\expandafter\gdef\csname @problabel\romannumeral\@probN\endcsname{#2}
+\else
+% check to see if this problem has been selected
+\checkselected{#2}
+\ifselected
+\expandafter\checkdefined\csname @prob@#2\endcsname
+\ifdefined
+\PackageError{probsoln}{Label #2 already used}%
+{Each problem must have a unique label identifier}
+\else
+\ifnum#1=0
+% this problem has no arguments
+\expandafter\newcommand\csname @prob@#2\endcsname[#1]{%
+#3 \ifshowanswers\paragraph{\solutionname} #4\fi}
+\else
+\message{Problem #2 requires #1 argument(s), please specify (e.g. {5}{3}):}
+\read-1to\@tmp
+\expandafter\let\csname @prob@#2@arg\endcsname=\@tmp
+\expandafter\newcommand\csname @prob@#2\endcsname[#1]{%
+#3 \ifshowanswers\paragraph{\solutionname} #4\fi}
+\fi
+\fi
+\fi
+\fi
+\else
+\expandafter\checkdefined\csname @prob@#2\endcsname
+\ifdefined
+\PackageError{probsoln}{Label #2 already used}%
+{Each problem must have a unique label identifier}
+\else
+\expandafter\newcommand\csname @prob@#2\endcsname[#1]{%
+#3 \ifshowanswers\paragraph{\solutionname} #4\fi}
+\fi
+\fi
+}
+% \end{macrocode}
+% Define the command that uses a problem
+% \begin{macrocode}
+\newcommand{\useproblem}[1]{%
+\expandafter\checkdefined\csname @prob@#1\endcsname
+\ifdefined
+\def\doprob{\csname @prob@#1\endcsname}
+\else
+\PackageError{probsoln}{Label #1 undefined}%
+{Can't find problem defined with label identifier '#1'}
+\def\doprob{\relax}
+\fi
+\doprob
+}
+% \end{macrocode}
+% Now deal with the stuff for random selection.
+% Syntax: |\selectrandomly{|\meta{filename}|}{|\meta{n}|}|.
+% \begin{macrocode}
+\newcount\@probN \newcount\@probselN \newcount\@rndselctr
+
+% \PSNrandom{<count>}{<n>} stores a random number from 1 to <n>
+% in the TeX count register <count>
+\newcount\r@ndcur
+\r@ndcur=1\relax
+\newcommand{\PSNrandseed}[1]{%
+\ifnum#1=0
+\typeout{Can't have 0 as random seed, changing to 1}
+\r@ndcur=1\relax
+\else
+\r@ndcur=#1\relax
+\fi
+\typeout{Random Seed = \the\r@ndcur}
+}
+
+\newcount\@ps@randtmp
+\newcommand{\PSNrand}{
+\@ps@randtmp=\r@ndcur
+\multiply\@ps@randtmp by 16807\relax
+\r@ndcur=\@ps@randtmp
+\divide\r@ndcur by 120001
+\multiply\r@ndcur by 120001
+\advance\@ps@randtmp by -\r@ndcur
+\r@ndcur = \@ps@randtmp
+\ifnum\r@ndcur=0\relax\r@ndcur=1\fi
+}
+
+\newcommand{\PSNrandom}[2]{%
+% generate new random number.
+\PSNrand
+#1=\r@ndcur
+\@ps@randtmp=\r@ndcur
+% now (#1 mod #2) + 1
+\divide\@ps@randtmp by #2\relax
+\multiply\@ps@randtmp by #2\relax
+\advance#1 by -\@ps@randtmp
+\advance#1 by 1\relax
+}
+
+\newcommand{\selectrandomly}[2]{%
+\global\@probselN=#2
+\global\@probN=0
+\selectrandomtrue
+\firstpasstrue
+\input{#1}
+\ifnum\@probselN>\@probN
+\PackageError{probsoln}{Requested number too large}%
+{You have asked for \the\@probselN \space problems, but there are only
+\the\@probN \space problems defined in the file #1. I will only select \the\@probN \space
+problems.}
+\global\@probselN=\@probN
+\fi
+\shuffle{@problabel}{\@probN}
+\firstpassfalse
+\input{#1}
+\selectrandomfalse
+\@rndselctr=1\relax
+\whiledo{\@rndselctr < \@probselN \TE@or \@rndselctr = \@probselN}{%
+\edef\@tmp{\csname @problabel\romannumeral\@rndselctr\endcsname}
+\edef\@probargs{{\@tmp}\csname @prob@\@tmp @arg\endcsname}
+\item \expandafter\useproblem\@probargs
+\advance\@rndselctr by 1\relax
+}
+}
+% \end{macrocode}
+% Check to see if label has been selected
+% \begin{macrocode}
+\newcount\@ckselctr
+\newcommand{\checkselected}[1]{%
+\selectedfalse
+\@ckselctr=1\relax
+\whiledo{\@ckselctr < \@probselN \TE@or \@ckselctr = \@probselN}{%
+\ifthenelse{\equal{#1}{\csname @problabel\romannumeral\@ckselctr\endcsname}}%
+{\global\selectedtrue \global\@ckselctr=\@probselN}{}
+\advance\@ckselctr by 1\relax
+}
+}
+% \end{macrocode}
+% Shuffle contents of pseudo-array
+% \begin{macrocode}
+\newcount\@shfctr \newcount\@shfA \newcount\@shfB
+\newcommand{\shuffle}[2]{%
+\@shfctr=1\relax
+\whiledo{\@shfctr < 101}{%
+\PSNrandom{\@shfA}{#2}\PSNrandom{\@shfB}{#2}
+\ifnum\@shfA=\@shfB
+\else
+\edef\@@tmpA{\csname#1\romannumeral\@shfA\endcsname}
+\let\@tmpA=\@@tmpA
+\edef\@@tmpB{\csname#1\romannumeral\@shfB\endcsname}
+\let\@tmpB=\@@tmpB
+\expandafter\xdef\csname#1\romannumeral\@shfA\endcsname{\@tmpB}
+\expandafter\xdef\csname#1\romannumeral\@shfB\endcsname{\@tmpA}
+\fi
+\advance\@shfctr by 1\relax
+}
+}
+% \end{macrocode}
+%\Finale
+\endinput
diff --git a/Master/texmf-dist/source/latex/probsoln/probsoln.ins b/Master/texmf-dist/source/latex/probsoln/probsoln.ins
new file mode 100644
index 00000000000..49947b3dc75
--- /dev/null
+++ b/Master/texmf-dist/source/latex/probsoln/probsoln.ins
@@ -0,0 +1,11 @@
+\def\batchfile{probsoln.ins}
+\input docstrip.tex
+\preamble
+Copyright (C) 2000 Nicola Talbot, all rights reserved.
+If you modify this file, you must change its name first.
+You are NOT ALLOWED to distribute this file alone. You are NOT
+ALLOWED to take money for the distribution or use of either this
+file or a changed version, except for a nominal charge for copying
+etc.
+\endpreamble
+\generateFile{probsoln.sty}{f}{\from{probsoln.dtx}{}}