diff options
author | Karl Berry <karl@freefriends.org> | 2006-01-11 23:56:23 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2006-01-11 23:56:23 +0000 |
commit | c52946ab7533d1e5ef2203bf47b76b406b687d83 (patch) | |
tree | 0806a9710c113bcad64032dee85cf424cd068aae /Master/texmf-dist/source/latex/probsoln | |
parent | 1a811a112321f9dac1bf770b5cd41202a26e70af (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.dtx | 473 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/probsoln/probsoln.ins | 11 |
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}{}} |