diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/probsoln/probsoln.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/probsoln/probsoln.dtx | 2932 |
1 files changed, 2316 insertions, 616 deletions
diff --git a/Master/texmf-dist/source/latex/probsoln/probsoln.dtx b/Master/texmf-dist/source/latex/probsoln/probsoln.dtx index b15dc024005..a92e37f6598 100644 --- a/Master/texmf-dist/source/latex/probsoln/probsoln.dtx +++ b/Master/texmf-dist/source/latex/probsoln/probsoln.dtx @@ -1,12 +1,16 @@ %\iffalse % probsoln.dtx generated using makedtx version 0.94b (c) Nicola Talbot % Command line args: -% -src "(.+)\.(sty)=>\1.\2" -% -doc "manual.tex" +% -macrocode ".*\.tex" +% -setambles ".*\.tex=>\nopreamble\nopostamble" +% -comment ".*\.tex" +% -src "(.+\.sty)\Z=>\1" +% -src "(.+\.tex)\Z=>\1" +% -doc "probsoln-manual.tex" % -author "Nicola Talbot" % -dir "source" % probsoln -% Created on 2007/8/21 16:58 +% Created on 2008/8/27 14:19 %\fi %\iffalse %<*package> @@ -29,49 +33,96 @@ %\fi % \iffalse % Doc-Source file to use with LaTeX2e -% Copyright (C) 2007 Nicola Talbot, all rights reserved. +% Copyright (C) 2008 Nicola Talbot, all rights reserved. % \fi % \iffalse %<*driver> -\documentclass{ltxdoc} +\documentclass[a4paper]{ltxdoc} \usepackage[colorlinks, bookmarks, hyperindex=false, - pdfauthor=Nicola Talbot, - pdftitle={probsoln.sty : a LaTeX2e package to help create problem sheets}]{hyperref} + pdfauthor={Nicola L.C. Talbot}, + pdftitle={probsoln: creating problem sheets optionally with solutions}]{hyperref} +\usepackage{color} +\usepackage{probsoln} +\RecordChanges +\PageIndex +\CheckSum{886} -\newcommand{\sty}[1]{\textsf{#1}}\newcommand{\env}[1]{\textsf{#1}} -\newcommand{\cmddef}[1]{\hypertarget{#1}{\cmdname{#1}}} -\newcommand{\cmdlink}[1]{\hyperlink{#1}{\cmdname{#1}}} -\newcommand{\problabel}[2]{\hypertarget{#1}{\texttt{#2}}} -\newcommand{\probref}[1]{\hyperlink{#1}{\texttt{#1}}} -\newcommand{\cmdname}[1]{\cs{#1}} - %hyperindex conflicts with doc - %(end up with |usage|hyperpage in indexentry) \renewcommand{\usage}[1]{\textit{\hyperpage{#1}}} \renewcommand{\main}[1]{\hyperpage{#1}} \newcommand{\see}[2]{\emph{see} #1} \makeatletter \def\index@prologue{\section*{Index}} \makeatother -\CheckSum{499} -\OnlyDescription +\CodelineNumbered +\newcommand{\dq}[1]{``#1''} +\definecolor{defbackground}{rgb}{0.8,1,1} + +\newsavebox\defsbox +\newlength\defwidth +\newenvironment{definition}{% +\setlength{\fboxsep}{4pt}\setlength{\fboxrule}{1.25pt}% +\begin{lrbox}{\defsbox}% +\setlength\defwidth\linewidth +\addtolength\defwidth{-2\fboxrule}% +\addtolength\defwidth{-2\fboxsep}% +\begin{minipage}{\defwidth}\flushleft +}{% +\end{minipage} +\end{lrbox}% +\vskip10pt +\noindent +\fcolorbox{black}{defbackground}{\usebox\defsbox}% +\vskip10pt +} + +\newlength\boxlength +\newsavebox\importantbox +\newenvironment{important}{% +\setlength{\fboxrule}{4pt}% +\setlength\boxlength{\linewidth}% +\addtolength\boxlength{-2\fboxsep}% +\addtolength\boxlength{-2\fboxrule}% +\begin{lrbox}{\importantbox}% +\begin{minipage}{\boxlength}% +}{\end{minipage}\end{lrbox}% +\par\vskip10pt\noindent +\fcolorbox{red}{white}{\usebox{\importantbox}}\par\vskip10pt} -\PageIndex -\begin{document} -\DocInput{probsoln.dtx} +\newcommand*{\ics}[1]{\cs{#1}\SpecialMainIndex{#1}} + +\newcommand{\pkgopt}[1]{\textsf{#1}\index{package options>#1=\textsf{#1}|hyperpage}} +\newcommand*{\sty}[1]{\textsf{#1}} +\newcommand*{\isty}[1]{\sty{#1}\index{#1 package=\sty{#1} package|hyperpage}} +\newcommand*{\env}[1]{\textsf{#1}} +\newcommand{\ienv}[1]{\env{#1}\index{#1 environment=\env{#1} environment|hyperpage}} +\newcommand*{\bool}[1]{\textsf{#1}\index{#1 boolean variable=\textsf{#1} boolean variable|hyperpage}} +\newcommand{\csdef}[1]{\cs{#1}} + + +\begin{document}\DocInput{probsoln.dtx} \end{document} %</driver> %\fi -% \title{probsoln.sty v2.04: \LaTeXe\ Package to help create problem sheets} -% \author{Nicola L.C. Talbot} -% \date{21st August 2007} +%\MakeShortVerb{"} +%\DeleteShortVerb{\|} +% +% \title{probsoln v3.0: creating problem sheets optionally with solutions} +% \author{Nicola L.C. Talbot\\[10pt] +%School of Computing Sciences\\ +%University of East Anglia\\ +%Norwich. Norfolk\\ +%NR4 7TJ. United Kingdom.\\ +%\url{http://theoval.cmp.uea.ac.uk/~nlct/}} +% +% \date{26th August 2008} % \maketitle -% \tableofcontents +%\tableofcontents % % \section{Introduction} %The \sty{probsoln} package is designed for teachers or @@ -91,466 +142,635 @@ %printed. In this way, one file can either produce the %student's version or the teacher's version. % -%\section{Package Options} +%\section{Package Options}\label{sec:pkgopt} %The following options may be passed to this package: -%\begin{center} -%\begin{tabular}{@{\ttfamily}ll} -%answers & Show the answers\\ -%noanswers & Don't show the answers (default) -%\end{tabular} -%\end{center} -% -%\section{Creating a New Problem} -%\DescribeMacro{\newproblem} -%\cmddef{newproblem}\verb|[|\meta{nargs}\verb/]{/\meta{label}\verb!}{!\meta{problem}\verb+}{+\meta{solution}\verb=}=\\[10pt] -%A new problem is defined using the command -%\cmdname{newproblem}. This does not print anything, -%but merely stores the problem. As from version 2.03, there is also -%a starred version of this command for problems without a solution -%(for example, essay style questions):\\[10pt] -%\DescribeMacro{\newproblem*} -%\cmddef{newproblem*}\verb|[|\meta{nargs}\verb/]{/\meta{label}\verb!}{!\meta{problem}\verb+}+\\[10pt] -%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, the following defines a problem with the label -%\problabel{quaddiff}{quaddiff}: +%\begin{description} +%\item[\pkgopt{answers}] Show the answers +%\item[\pkgopt{noanswers}] Don't show the answers (default) +%\item[\pkgopt{draft}] Display the label and dataset name when a problem is used +%\item[\pkgopt{final}] Don't display label and dataset name when a problem is used +%\end{description} +% +%\section{Showing and Hiding Solutions}\label{sec:showanswers} +% +%In addition to the \pkgopt{answers} and \pkgopt{noanswers} package +%options, it is also possible to show or suppress the solutions +%using \DescribeMacro{\showanswers}\cs{showanswers} and +%\DescribeMacro{\hideanswers}\cs{hideanswers}, respectively. +%The boolean variable \bool{showanswers} determines whether the +%answers should be displayed. You can use this value with the +%\isty{ifthen} package to specify different text depending on +%whether the solutions should be displayed. For example: +%\begin{verbatim} +%Assignment 1\ifthenelse{\boolean{showanswers}}{ (Solution Sheet)}{} +%\end{verbatim} +%Alternatively you can use \ics{ifshowanswers}\ldots\cs{else}\ldots +%\cs{fi}: +%\begin{verbatim} +%Assignment 1\ifshowanswers\space (Solution Sheet)\fi +%\end{verbatim} +% +%For longer passages, you can use the environments \DescribeEnv{onlyproblem}\env{onlyproblem} +%and \DescribeEnv{onlysolution}\env{onlysolution}. For example: +%\begin{verbatim} +%\begin{onlyproblem}% +%What is the derivative of $f(x) = x^2$? +%\end{onlyproblem}% +%\begin{onlysolution}% +%$f'(x) = 2x$ +%\end{onlysolution} +%\end{verbatim} +%The above will only display the question if \bool{showanswers} +%is false and will only display the solution if \bool{showanswers} +%is true. If you want the question to appear in the answer +%sheet as well as the solution, then don't put the question in +%the \env{onlyproblem} environment: %\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} -% } +%What is the derivative of $f(x) = x^2$? +%\begin{onlysolution}% +%Solution: $f'(x) = 2x$ +%\end{onlysolution} %\end{verbatim} -%The following is an essay question, so doesn't come with a solution: +%\begin{important} +%You can't use verbatim text in the body of the +%\ienv{onlyproblem} or \ienv{onlysolution} environments. +%If you need verbatim-like text, then try packages such as +%\isty{alltt}. Remember that you also can't use verbatim +%text in command arguments. +%\end{important} +% +%\section{General Formatting Commands}\label{sec:formatting} +% +%The commands and environments described in this section are +%provided to assist formatting problems and their solutions. +%\DescribeEnv{solution} +%\begin{definition} +%\verb|\begin{solution}|\meta{text}\verb|\end{solution}| +%\end{definition} +%This is equivalent to +%\verb|\par\noindent\textbf{\solutionname}:|\meta{text} +%where \DescribeMacro{\solutionname}\cs{solutionname} defaults +%to \dq{Solution}. Note that you must place the \env{solution} +%environment inside the \ienv{onlysolution} environment or +%between \ics{ifshowanswers}\ldots\cs{fi} to ensure that it +%is suppressed when the solutions are not wanted. (See +%\autoref{sec:showanswers}.) +% +% +%Note that the \sty{probsoln} package will only define the +%\env{solution} environment if it is not already defined. +% +%\DescribeEnv{textenum} +%\begin{definition} +%\verb|\begin{textenum}|\ldots\verb|\end{textenum}| +%\end{definition} +%The \env{textenum} environment is like the \ienv{enumerate} +%environment but is in-line. It uses the same counter that the +%\env{enumerate} environment would use at that level so the +%question can be compact but the answer can use \env{enumerate} +%instead. For example: %\begin{verbatim} -%\newproblem*{inheritance}{Describe what is meant by the term -%\emph{inheritance} in object-oriented programming. Use examples.} +%\begin{onlyproblem}% +%Differentiate the following: +%\begin{textenum} +%\item $f(x)=2^x$; +%\item $f(x)=\cot(x)$ +%\end{textenum} +%\end{onlyproblem} +%\begin{onlysolution} +%\begin{enumerate} +%\item +%\begin{align*} +%f(x) &= 2^x = \exp(\ln(x^2)) =\exp(2\ln(x))\\ +%f'(x) &= \exp(2\ln(x))\times \frac{2}{x}\\ +% &= f(x)\frac{2}{x} +%\end{align*} +%\item +%\begin{align*} +%f(x) &= \cot(x) = (\tan(x))^{-2}\\ +%f'(x) &= -(\tan(x))^{-2}\times\sec^2(x)\\ +%&=-\csc^2x +%\end{align*} +%\end{enumerate} +%\end{onlysolution} %\end{verbatim} +%In this example, the items in the question are brief, so an +%\ienv{enumerate} environment would result in a lot of +%unnecessary white space, +%but the answers require more space, so an \env{enumerate} +%environment is more appropriate. Since the \ienv{textenum} +%environment uses the same counters as the \env{enumerate} +%environment, the question and answer sheets use consistent +%labelling. Note that there are other packages available on +%CTAN that you can use to create in-line lists. Check the +%\href{http://www.tex.ac.uk/tex-archive/help/Catalogue/bytopic.html\#enumeration}{TeX Catalogue} for +%further details. % -%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 -%referred to by \verb|#1|, \verb/#2/, \ldots, \verb!#9!. -%For example, the following problem, labelled \problabel{sindiff}{sindiff}, -%takes one parameter: +%\DescribeMacro{\correctitem}\DescribeMacro{\incorrectitem} +%\begin{definition} +%\csdef{correctitem}\\ +%\csdef{incorrectitem} +%\end{definition} +%You can use the commands \cs{correctitem} and \cs{incorrectitem} +%in place of \ics{item}. If the solutions are suppressed, these +%commands behave in the same way as \cs{item}, otherwise they +%format the item label using one of the commands: +%\DescribeMacro{\correctitemformat}\DescribeMacro{\incorrectitemformat} +%\begin{definition} +%\csdef{correctitemformat}\marg{label}\\ +%\csdef{incorrectitemformat}\marg{label} +%\end{definition} +%For example: %\begin{verbatim} -%\newproblem[1]{sindiff}{% +%Under which of the following functions does $S=\{a_1,a_2\}$ +%become a probability space? +%\begin{enumerate} +%\incorrectitem $P(a_1)=\frac{1}{3}$, $P(a_2)=\frac{1}{2}$ +%\correctitem $P(a_1)=\frac{3}{4}$, $P(a_2)=\frac{1}{4}$ +%\correctitem $P(a_1)=1$, $P(a_2)=0$ +%\incorrectitem $P(a_1)=\frac{5}{4}$, $P(a_2)=-\frac{1}{4}$ +%\end{enumerate} +%\end{verbatim} +% +%\section{Defining a Problem}\label{sec:defproblem} +% +%It is possible to construct a problem sheet with solutions using +%the commands described in the previous sections, however it is +%also possible to define a set of problems for later use. In this +%way you can create an external file containing many problems some +%or all of which can be loaded and used in a document. The +%\sty{probsoln} package has a default data set labelled +%\dq{default} in which you can store problems or you can create +%multiple data sets. You can then iterate through each problem +%in a problem set. You can use a previously defined problem more +%than once, which means that by judicious use of \ienv{onlyproblem}, +%\ienv{onlysolution} or the \bool{showanswers} boolean variable +%in conjunction with \ics{showanswers} and \ics{hideanswers}, +%you can print the solutions in a different location to the +%questions (for example in an appendix). +% +%\DescribeEnv{defproblem} +%\begin{definition} +%\verb|\begin{defproblem}|\oarg{n}\marg{label}\meta{definition}\verb|\end{defproblem}| +%\end{definition} +%This defines the problem whose label is given by \meta{label}. +%The label must be unique for a given data set and should not +%contain active characters. (Active characters include the special +%characters such as \$ and \&, but some packages may make other +%symbols active. For example, the \isty{ngerman} and \isty{babel} +%packages make certain punctuation active. Check the relevant +%package documentation for details.) +% +%If \env{defproblem} occurs in the document or is included via +%\cs{input} or \cs{include}, then the problem will be added to +%the default data set. If \env{defproblem} occurs in an external +%file that is loaded using one of the commands defined in +%\autoref{sec:load} then the problem will be added to +%the specified data set. +% +%The contents of the \env{defproblem} environment should be the +%text that defines the problem. This may include any of the +%commands defined in +%\autoref{sec:showanswers} and \autoref{sec:formatting}. +% +%The problem may optionally take \meta{n} arguments (where +%\meta{n} is from 0 to 9). The arguments can be referenced +%in the definition via \texttt{\#1},\ldots,\texttt{\#9}. +%If \meta{n} is omitted then the problem doesn't take any +%arguments. +%The following example defines a problem with one argument: +%\begin{verbatim} +%\begin{defproblem}[1]{diffsin} +%Differentiate $f(x)=\sin(#1x)$. +%\begin{onlysolution}% +%\begin{solution} +%$f'(x) = #1\cos(#1x)$ +%\end{solution} +%\end{onlysolution} +%\end{defproblem} +%\end{verbatim} +% +%\DescribeMacro{\newproblem} +%\begin{definition} +%\csdef{newproblem}\oarg{n}\marg{label}\marg{problem}\marg{solution} +%\end{definition} +%This is a shortcut command for: +%\begin{ttfamily}\obeylines +%\cs{begin}\{defproblem\}\oarg{n}\marg{label}\% +%\meta{problem}\% +%\cs{begin}\{onlysolution\}\% +%\cs{begin}\{solution\}\% +%\meta{solution}\% +%\cs{end}\{solution\}\% +%\cs{end}\{onlysolution\}\% +%\cs{end}\{defproblem\} +%\end{ttfamily} +%For example: +%\begin{verbatim} +%\newproblem[1]{diffsin}{% %\(f(x) = \sin(#1x)\) %}{% %\(f'(x) = #1\cos(#1x)\) %} %\end{verbatim} +%is equivalent to +%\begin{verbatim} +%\begin{defproblem}[1]{diffcos}% +%\(f(x) = \cos(#1x)\) +%\begin{onlysolution}% +%\begin{solution}% +%\(f'(x) = -#1\sin(#1x)\) +%\end{solution}% +%\end{onlysolution}% +%\end{defproblem} +%\end{verbatim} +%(In this example, the argument will need to be a positive number +%to avoid a double minus in the answer. If you want to perform +%floating point arithmetic on the arguments, then try the +%\isty{fp} package.) +% +%\DescribeMacro{\newproblem*} +%\begin{definition} +%\csdef{newproblem*}\oarg{n}\marg{label}\marg{definition} +%\end{definition} +%This is a shortcut for: +%\begin{ttfamily}\obeylines +%\cs{begin}\{defproblem\}\oarg{n}\marg{label}\% +%\meta{definition}\% +%\cs{end}\{defproblem\} +%\end{ttfamily} +% +%\begin{important} +%Verbatim text must not be used in the contents of \ienv{defproblem} +%or in any of the arguments to \cs{newproblem} or +%\cs{newproblem*}. If you need verbatim-like text consider using +%\cs{texttt} or the \isty{alltt} package. +%\end{important} +% +%\section{Using a Problem}\label{sec:useproblem} % -%The \probref{quaddiff} problem shown above can be made more -%generic by using parameters\problabel{diff:quad}{}: +%Once you have defined a problem using \ienv{defproblem} or +%\cs{newproblem} (see +%\autoref{sec:defproblem}), you can later display the problem +%using: +%\DescribeMacro{\useproblem} +%\begin{definition} +%\csdef{useproblem}\oarg{data set}\marg{label}\marg{arg$_1$}\ldots\marg{arg$_N$}\end{definition} +%where \meta{data set} is the name of the data set that contains +%the problem (the default data set is used if omitted), +%\meta{label} is the label identifying the required problem and +%\meta{arg$_1$}, \ldots, \meta{arg$N$} are the arguments to pass to the problem, if the problem was +%defined to have arguments (where $N$ is the number of arguments specified when the problem was defined). +% +%For example, in the previous section the problem \texttt{diffcos} +%was defined to have one argument, so it can be used as follows: %\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 -%\) -%} +%\useproblem{diffcos}{3} %\end{verbatim} -%The three parameters correspond to the coefficients. Note -%that they must all be integers since \TeX\ only performs -%integer arithmetic. -% -%\section{Creating a Database} -% -%To generate a database, simply create a \texttt{.tex} file -%where all the problems are defined using \cmdlink{newproblem} or -%\cmdlink{newproblem*}, -%and either \cmdname{input} it at the start of your document if -%you want to use specific problems (see Section~\ref{sec:useprob}), or pass it to -%\cmdname{selectrandomly} (see Section~\ref{sec:selran}). This package -%comes with some sample databases, along with some sample documents -%that use these databases. -% -%\section{Displaying a Problem} -%\label{sec:useprob} -% \DescribeMacro{\useproblem} -%\cmddef{useproblem}\verb|{|\meta{label}\verb/}/\\[10pt] -%Once a problem has been defined using \cmdlink{newproblem}, it -%can be typeset using the command \cmdname{useproblem}. If the -%problem was defined to take arguments, the arguments to the -%problem should come after the label. In the case of the -%\probref{sindiff} example above, the command -%\verb|\useproblem{sindiff}{2}| would produce the following:\\[10pt] -% $f(x) = \sin(2x)$ \paragraph{Solution:} $f'(x) = 2\cos(2x)$\\[10pt]whereas the command \verb|\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 -%\texttt{probs.tex}, then the following code will create a -%problem sheet with four questions in it: +%This will be equivalent to: %\begin{verbatim} -%\documentclass{article} +%\(f(x) = \cos(3x)\) +%\begin{onlysolution}% +%\begin{solution}% +%\(f'(x) = -3\sin(3x)\) +%\end{solution}% +%\end{onlysolution}% +%\end{verbatim} % -%\usepackage{probsoln} -%\input{probs} +%\section{Loading Problems From External Files}\label{sec:load} % -%\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 -%\texttt{answers} to the \texttt{probsoln} package. +%You can store all your problem definitions (see +%\autoref{sec:defproblem}) in an external file. +%These problems can all be appended to the default data set by +%including the file via \ics{input} or they can be appended +%to other data sets using one of the commands described below. +%Once you have loaded all the required problems, you can +%iterate through the data sets using the commands described +%in \autoref{sec:foreach}. Note that the commands below +%will create a new data set, if the named data set doesn't +%exist. % -%\section{Selecting All Problems} +%\DescribeMacro{\loadallproblems} +%\begin{definition} +%\csdef{loadallproblems}\oarg{data set}\marg{filename} +%\end{definition} +%This will load all problems defined in \meta{filename} and +%append them to the specified data set, in the order in which +%they are defined in the file. If \meta{data set} is +%omitted, the default data set will be used. If \meta{data set} +%doesn't exist, it will be created. % -%To select all problems defined in a database, in the order in -%which they were defined, use the command: -%\DescribeMacro{\selectallproblems} -%\cmddef{selectallproblems}\verb|{|\meta{filename}\verb/}/ -%For example, suppose the problems are defined in the file -%\texttt{easy.tex}, then the following will create a problem sheet -%which uses all these problems: +%\DescribeMacro{\loadselectedproblems} +%\begin{definition} +%\csdef{loadselectedproblems}\oarg{data set}\marg{labels}\marg{filename} +%\end{definition} +%This is like \cs{loadproblems}, but only those problems whose +%label is listed in the comma-separated list \meta{labels} are +%loaded. For example, if I have some problems defined in the +%file \texttt{derivatives.tex}, then %\begin{verbatim} -%\documentclass[a4paper]{article} +%\loadselectedproblems{diffsin,diffcos}{derivatives} +%\end{verbatim} +%will only load the problems whose labels are \texttt{diffsin} +%and \texttt{diffcos}, respectively. All the other problems in +%the file will remain undefined. % -%\usepackage{probsoln} +%\DescribeMacro{\loadrandomproblems} +%\begin{definition} +%\csdef{loadrandomproblems}\oarg{data set}\marg{n}\marg{filename} +%\end{definition} +%This randomly loads \meta{n} problems from \meta{filename} and +%adds them to the given data set. If \meta{data set} is omitted, +%the default data set is assumed. Note that the problems will be +%added to the data set in a random order, not in the order in +%which they were defined. There must be at least \meta{n} problems +%defined in \meta{filename}. % -%\begin{document} -%Differentiate the following functions: +%\begin{important} +%It is generally not a good idea to place anything in +%\meta{filename} that is not inside the body of \ienv{defproblem} +%or in the arguments to \ics{newproblem} or \ics{newproblem*}. +%All the commands in this section input the external file within +%a local scope, so commands definitions would need to be made +%global to have any effect. In addition, \cs{loadrandomproblems} +%has to load each file twice, which means that anything outside +%a problem definition will be parsed twice. +%\end{important} +% +% +%\section{Iterating Through Datasets}\label{sec:foreach} +% +%Once you have defined all your problems for a given data set, +%you can use an individual problem with \ics{useproblem} +%(see \autoref{sec:useproblem}) but it is more likely that you will +%want to iterate through all the problems so that you don't need +%to remember the labels of all the problems you have defined. +% +%\DescribeMacro{\foreachproblem} +%\begin{definition} +%\csdef{foreachproblem}\oarg{data set}\marg{body} +%\end{definition} +%This does \meta{body} for each problem in the given data set. +%If \meta{data set} is omitted, the default data set is used. +%Within \meta{body} you can use +%\DescribeMacro{\thisproblem}\cs{thisproblem} to use the +%current problem and \DescribeMacro{\thisproblemlabel}\cs{thisproblemlabel} +%to access the current label. If the problem requires arguments, +%you will be prompted for them, so if you want to use this +%approach you will need to use \LaTeX\ in interactive mode. If +%you do provide arguments, they will be stored in the event that +%you need to iterate through the data set again. The +%arguments will be included in \cs{thisproblem}, so you only +%need to use \cs{thisproblem} without having to specify +%\ics{useproblem}. For example, to iterate through all problems +%in the default data set: +%\begin{verbatim} %\begin{enumerate} -%\selectallproblems{easy} +%\foreachproblem{\item\thisproblem} %\end{enumerate} -%\end{document} %\end{verbatim} % -%\section{Selecting Problems at Random} -%\label{sec:selran} -% \DescribeMacro{\selectrandomly} -%\cmddef{selectrandomly}\verb|{|\meta{filename}\verb/}{/\meta{n}\verb!}!\\[10pt] -%The command \cmdname{selectrandomly} will select \meta{n} -%problems that are defined in the file \meta{filename}. Each -%problem is proceeded by -%\DescribeMacro{\PSNitem}\cmddef{PSitem} which is -%defined to be \cmdname{item}, so the command -%\cmdname{selectrandomly} should occur within one of the -%list-like environments, such as \texttt{enumerate}. -%For example: +%\DescribeMacro{\foreachdataset} +%\begin{definition} +%\csdef{foreachdataset}\marg{cmd}\marg{body} +%\end{definition} +%This does \meta{body} for each of the defined data sets. Within +%\meta{body}, \meta{cmd} will be set to the name of the current +%data set. For example, to display all problems in all data sets: %\begin{verbatim} %\begin{enumerate} -%\selectrandomly{easy.tex}{4} +%\foreachdataset{\thisdataset}{% +%\foreachproblem[\thisdataset]{\item\thisproblem}} %\end{enumerate} %\end{verbatim} -%will result in four numbered problems, selected at random -%from the file \texttt{easy.tex}. (The \texttt{.tex} extension -%may be omitted.) Each problem is followed by the command -%\cmddef{endPSNitem} which by default does nothing. -% -%Multiple \cmdname{selectrandomly} commands may be used, however a -%different file must be used each time. For -%example: +% +%Suppose I have two external files called +%\texttt{derivatives.tex} and \texttt{probspaces.tex} which +%define problems using both \ienv{onlyproblem} and +%\ienv{onlysolution} for example: +%\begin{verbatim} +%\begin{defproblem}{cosxsqsinx}% +%\begin{onlyproblem}% +%$y = \cos(x^2)\sin x$.% +%\end{onlyproblem}% +%\begin{onlysolution}% +%\[\frac{dy}{dx} = -\sin(x^2)2x\sin x + \cos(x^2)\cos x\] +%\end{onlysolution}% +%\end{defproblem} +%\end{verbatim} +%I can write a document that creates two data sets, one for +%the derivative problems and one for the problems about +%probability spaces. I can then use \ics{hideanswers} and +%iterate through the require data set to produce the problems. +%Later, I can use \ics{showanswers} and iterate over all problems defined in both data +%sets to produce the chapter containing all the answers. When +%displaying the questions, I have taken advantage of the fact that +%I can cross-reference items within an \ienv{enumerate} environment, +%and redefined \ics{theenumi} to label the questions according to +%the chapter. The cross-reference label is constructed from +%the problem label and is referenced in the answer section to +%ensure that the answers have the same label as the questions. %\begin{verbatim} -%\begin{enumerate} -%\item Differentiate the following functions with respect to $x$: +%\documentclass{report} +%\usepackage{probsoln} +%\begin{document} +%\hideanswers +%\chapter{Differentiation} +%% randomly select 25 problems from derivatives.tex and add to +%% the data set called 'deriv' +%\loadrandomproblems[deriv]{25}{derivatives} % +%% Display the problems +%\renewcommand{\theenumi}{\thechapter.\arabic{enumi}} %\begin{enumerate} -%\selectrandomly{samples/easy.tex}{3} -%\selectrandomly{samples/args.tex}{1} +%\foreachproblem[deriv]{\item\label{prob:\thisproblemlabel}\thisproblem} %\end{enumerate} +%% You may need to change \theenumi back here % -%\selectrandomly{samples/implicit.tex}{1} -%\selectrandomly{samples/1stprncpl.tex}{1} +%\chapter{Probability Spaces} +%% randomly select 25 problems from probspaces.tex and add to +%% the data set called 'spaces' +%\loadrandomproblems[spaces]{25}{probspaces} % +%% Display the problems +%\renewcommand{\theenumi}{\thechapter.\arabic{enumi}} +%\begin{enumerate} +%\foreachproblem[spaces]{\item\label{prob:\thisproblemlabel}\thisproblem} %\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. +%% You may need to change \theenumi back here % -%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 (\{ \}). +%\appendix % -%\section{Other Commands} -%\DescribeMacro{\PSNrandseed} -%The command \cmddef{PSNrandseed}\verb|{|\meta{n}\verb/}/ specifies -%the seed for the random number generator. For example, -%if you are using \cmdlink{selectrandomly}, -%\verb|\PSNrandseed{\year}| will produce a different set of -%problems each year, whereas \verb|\PSNrandseed{\time}| -%will produce a different set of problems each time you -%\LaTeX\ the problem sheet (as long as you leave at least a -%minute between runs.) +%\chapter{Solutions} +%\showanswers +%\begin{itemize} +%\foreachdataset{\thisdataset}{% +%\foreachproblem[\thisdataset]{\item[\ref{prob:\thisproblemlabel}]\thisproblem} +%} +%\end{itemize} % -%\DescribeMacro{\random} -%The command \cmddef{random}\verb|{|\meta{counter}\verb/}{/\meta{a}\verb!}{!\meta{b}\verb-}- -%generates a random number from \meta{a} to \meta{b} and -%stores it in the \LaTeX\ counter \meta{counter}. For example, -%to select 2, 3 or 4 problems from the file -%\texttt{implicit.tex}: -%\begin{verbatim} -%\newcounter{numproblems} -%\begin{enumerate} -%\random{numproblems}{2}{4} -%\selectrandomly{implicit.tex}{\value{numproblems}} -%\end{enumerate} +%\end{document} %\end{verbatim} -%(Note the use of \cmdname{value}.) % -%This command can also be used to generate random values for -%problems that take arguments. Consider the problem \probref{diff:quad} -%defined earlier. Three counters can be defined to represent the -%three coefficients: +% +%\section{Random Number Generator}\label{sec:random} +% +%This package provides a pseudo-random number generator that is used +%by \ics{loadrandomproblems}. +% +%\DescribeMacro{\PSNrandseed} +%\begin{definition} +%\csdef{PSNrandseed}\marg{n} +%\end{definition} +%This sets the seed to \meta{n} which must be a non-zero integer. +%For example, to generate a different set of random numbers +%every time you \LaTeX\ your document,\footnote{assuming you +%leave at least a minute between runs.} put the following in your +%preamble: %\begin{verbatim} -%\newcounter{A} -%\newcounter{B} -%\newcounter{C} +%\PSNrandseed{\time} %\end{verbatim} -%Random values can now be assigned to these counters: +%or to generate a different set of random numbers every year you +%\LaTeX\ your document: %\begin{verbatim} -%\random{A}{-5}{5} -%\random{B}{-5}{5} -%\random{C}{-5}{5} +%\PSNrandseed{\year} %\end{verbatim} -%Finally, the problem can be used (note the use of \cmdname{arabic}): -%\begin{verbatim} -%\useproblem{diff:quad}{\arabic{A}}{\arabic{B}}{\arabic{C}} -%\end{verbatim} -% -%\DescribeMacro{\doforrandN}% -%The command -%\cmddef{doforrandN}\verb|{|\meta{n}\verb/}{/\meta{cmd}\verb!}{!\meta{list}\verb+}{+\meta{text}\verb-}- will apply -%\meta{text} for a random selection of \meta{n} items in the -%comma separated \meta{list}. In each iteration the list -%item is denoted by \meta{cmd}. For example, suppose you -%have three files called \texttt{file1.tex}, -%\texttt{file2.tex} and \texttt{file3.tex}, and you want to -%select 1 problem from two of the three files, then you can -%do: +% +%\DescribeMacro{\PSNgetrandseed} +%\begin{definition} +%\csdef{PSNgetrandseed}\marg{register} +%\end{definition} +%This stores the current seed in the count register specified by +%\meta{register}. +%For example: %\begin{verbatim} -%\doforrandN{2}{\file}{file1,file2,file3}{\selectrandomly{\file}{1}} +%\newcount\myseed +%\PSNgetrandseed{\myseed} %\end{verbatim} -%Note that it is also possible to do +% +%\DescribeMacro{\PSNrandom} +%\begin{definition} +%\csdef{PSNrandom}\marg{register}\marg{n} +%\end{definition} +%Generates a random integer from 1 to \meta{n} and stores in +%the count register specified by \meta{register}. For example, +%the following generates an integer from 1 to 10 and stores it +%in the register \cs{myreg}: %\begin{verbatim} -%\newcounter{numproblems} -%\random{numproblems}{1}{3} -%\selectrandomly{file\arabic{numproblems}}{1} -%\random{numproblems}{1}{3} -%\selectrandomly{file\arabic{numproblems}}{1} +%\newcount\myreg +%\PSNrandom{\myreg}{10} %\end{verbatim} -%however there is a possibility that the same file may be -%selected twice which will cause an error. -% -%\DescribeMacro{\showanswers} -%The command \cmddef{showanswers} will show the solutions from -%that point on. May be localised by placing within a group. -% -%\DescribeMacro{\hideanswers} -%The command \cmddef{hideanswers} will hide the solutions from -%that point on. May be localised by placing within a group. -% -%The solution is placed inside the \DescribeEnv{solution}\env{solution} -%environment. By default this environment simply does -%\verb|\par\noindent\textbf{\solutionname:} | at the start, where -%\DescribeMacro{\solutionname}\cmddef{solutionname} -%has the value: Solution. See the file \texttt{sample3.tex}, which -%comes with this package, for an illustration of how to -%customise the way in which the randomly selected problems are -%displayed. This sample file randomly selects multiple choice -%problems stored in the file \texttt{tabmchoice.tex}, and displays them -%in a longtable \env{environment}. As from version 2.03, the package -%will not define this environment if another package or class file has -%already defined it. -% -%\DescribeMacro{showanswers} -%The boolean variable \texttt{showanswers} is defined to be -%true if the answers are shown and false otherwise. You can -%therefore do something like: +% +%\DescribeMacro{\random} +%\begin{definition} +%\csdef{random}\marg{counter}\marg{min}\marg{max} +%\end{definition} +%Generates a random integer from \meta{min} to \meta{max} and +%stores in the given counter. For example, the following generates +%a random number between 3 and 8 (inclusive) and stores it in +%the counter \texttt{myrand}. %\begin{verbatim} -%\ifthenelse{\boolean{showanswers}}{\textbf{Solution Sheet}}{} +%\newcounter{myrand} +%\random{myrand}{3}{8} %\end{verbatim} -%and \textbf{Solution Sheet} will be printed only if the -%answers are displayed. (For more information on -%\cmdname{ifthenelse} and \cmdname{boolean} see the -%documentation for the \texttt{ifthen} package by -%David Carlisle.) -% -%The \texttt{showanswers} switch can also be used within the definition -%of a problem, if you want the question to appear differently if the -%solution is displayed. For example: +% +%\DescribeMacro{\doforrandN} +%\begin{definition} +%\csdef{doforrandN}\marg{n}\marg{cmd}\marg{list}\marg{text} +%\end{definition} +%Randomly selects \meta{n} values from the comma-separated list +%given by \meta{list} and iterates through this subset. On +%each iteration it sets \meta{cmd} to the current value and +%does \meta{text}. For example, the following will load a +%randomly selected problem from two of the listed files (where +%\texttt{file1.tex}, \texttt{file2.tex} and \texttt{file3.tex} +%are files containing at least one problem): %\begin{verbatim} -%\newproblem{mc:prod}{% -%Which of the following is the derivative of $x\sin(x)$? -%(Circle the correct answer.) -%\ifthenelse{\boolean{showanswers}}{}% -%{\begin{description} -%\item[A] $\sin(x)$ -%\item[B] $x\cos(x)$ -%\item[C] $\sin(x) + x\cos(x)$ -%\end{description} -%}}{% -%\begin{description} -%\item[A] $\sin(x)$ -%\item[B] $x\cos(x)$ -%\item[\textcircled{C}] $\sin(x) + x\cos(x)$ (product rule). -%\end{description} -%} +%\doforrandN{2}{\thisfile}{file1,file2,file3}{% +%\loadrandomproblems{1}{\thisfile}} %\end{verbatim} -%If the solutions are not displayed, the question will appear -%as -%\begin{description} -%\item Which of the following is the derivative of -%$x\sin(x)$? (Circle the correct answer.) -%\begin{description} -%\item[A] $\sin(x)$\item[B] $x\cos(x)$\item[C] $\sin(x) + x\cos(x)$\end{description} -%\end{description} -%otherwise it will appear as: -%\begin{description} -%\item Which of the following is the derivative of -%$x\sin(x)$? (Circle the correct answer.) -%\begin{description} -%\item[A] $\sin(x)$\item[B] $x\cos(x)$\item[\textcircled{C}] $\sin(x) + x\cos(x)$ (product rule)\end{description} -%\end{description} % -%\section{Troubleshooting} -%\subsection{Unexpected Output} -%\begin{itemize} -%\item I have lots of blank space before the first problem when -%using \cmdlink{selectrandomly}. -% -%This is probably because you have lots of extraneous white space -%in your database. \cmdlink{selectrandomly} will input the entire -%file, so any extra space will be included. Try commenting out the -%extra space using \%. -%\end{itemize} -% -%\subsection{Error Messages} -%\begin{itemize} -%\item -%\begin{ttfamily} -%! Package probsoln Error: Label \ldots\ already used. -%\end{ttfamily} % -%Each label identifier used in \cmdlink{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 -%\cmdname{input}ed or randomly selected from the same file more -%than once. (Or \cmdname{input}ed and randomly selected from -%the same file.) +%\section{Compatibility With Versions Prior to 3.0} % -%\item -%\begin{ttfamily} -%! Package probsoln Error: Label \ldots\ undefined. -%\end{ttfamily} +%Version 3.0 of the \sty{probsoln} package completely changed the +%structure of the package, but the commands described in this +%section have been provided to maintain compatibility with +%earlier versions. The only problems that are likely to occur are +%those where commands are contained within groups. This will +%effect any commands that are contained in external files that are +%outside of the arguments to \ics{newproblem} and \ics{newproblem*}. +%However, since the external files had to be parsed twice in +%order to load the problems, this shouldn't be an issue as adding +%anything other than problem definitions in those files would +%be problematic anyway. % -%You need to define a problem before you can use it. Check to -%make sure you haven't mis-spelt it, and check to make sure you -%have \cmdname{input}ed the file in which it is defined. +%The other likely difference is where the random generator is +%used in a group. This includes commands such as +%\ics{selectrandomly}. For example, if your document contained +%something like: +%\begin{verbatim} +%\begin{enumerate} +%\selectrandomly{file1}{8} % -%\item -%\begin{ttfamily} -%! Package probsoln Error: Requested number too large. -%\end{ttfamily} +%\item Solve the following: +%\begin{enumerate} +%\selectrandomly{file2}{4} +%\end{enumerate} % -%You have asked for more problems than are defined within the -%specified file. All problems in that file will be selected. +%\selectrandomly{file3}{2} +%\end{enumerate} +%\end{verbatim} +%Then using versions prior to v3.0 will produce a different +%set of random numbers since the second \cs{selectrandomly} +%is in a different level of grouping. If you want to ensure +%that the document produces exactly the same random set with +%the new version as with the old version, you will need to +%get and set the random number seed. For example, the above +%would need to be modified so that it becomes: +%\begin{verbatim} +%\begin{enumerate} +%\selectrandomly{file1}{8} % -%\item -%\begin{ttfamily} -%! Package probsoln Error: Can't randomly select \meta{n} -%item(s) -%\end{ttfamily} +%\item Solve the following: +%\newcount\oldseed +%\PSNgetrandseed{\oldseed} +%\begin{enumerate} +%\selectrandomly{file2}{4} +%\end{enumerate} +%\PSNrandseed{\oldseed} % -%You have asked to randomly select \meta{n} items from a list -%that has less than \meta{n} elements. For example, the -%following will generate this error: -%\begin{verbatim} -%\doforrandN{10}{\file}{file1,file2,file3}{% -%\selectrandomly{\file}{1}} +%\selectrandomly{file3}{2} +%\end{enumerate} %\end{verbatim} -%In this case the list, \texttt{file1,file2,file3} has only 3 -%elements, but the user has asked for 10 elements. If you type -%`h' at the \LaTeX\ prompt it will tell you how many items it thinks -%there are in the list. Remember that each item must be separated by a -%comma. % -%\item -%\begin{ttfamily} -%! LaTeX Error: Lonely \cmdname{item}--perhaps missing list -%environment. +%\DescribeMacro{\selectrandomly} +%\begin{definition} +%\csdef{selectrandomly}\marg{filename}\marg{n} +%\end{definition} +%This is now equivalent to: +%\begin{ttfamily}\obeylines +%\{\cs{loadrandomproblems}\oarg{filename}\marg{n}\marg{filename}\}\% +%\cs{foreachproblem}\oarg{filename}\marg{\cs{PSNitem}\cs{thisproblem}\cs{endPSNitem}} %\end{ttfamily} % -%Each problem selected using \cmdlink{selectrandomly} is -%proceeded by \cmdlink{PSNitem} which by default is defined -%as \cmdname{item}, and should therefore be -%placed in one of the list environments, such as -%\texttt{enumerate}. Alternatively, redefine \cmdlink{PSNitem}. +%\DescribeMacro{\selectallproblems} +%\begin{definition} +%\csdef{selectallproblems}\marg{filename} +%\end{definition} +%This is now equivalent to: +%\begin{ttfamily}\obeylines +%\{\cs{loadallproblems}\oarg{filename}\marg{filename}\}\% +%\cs{foreachproblem}\oarg{filename}\marg{\cs{PSNitem}\cs{thisproblem}\cs{endPSNitem}} +%\end{ttfamily} % -%\item I get an error when I put a command definition in my database -%when using \cmdname{selectrandomly}. +%Note that in both the above cases, a new data set is created +%with the same name as the file name. % -%\cmdlink{selectrandomly} inputs the database twice, so any -%command definition will be read twice, causing an error. You -%can use the switch \cmdname{iffirstpass} to prevent the error. For -%example: -%\begin{verbatim} -%\iffirstpass -%\newcommand{\mycmd}{} -%\fi -%\end{verbatim} -%It is generally not a good idea to put anything other than -%\cmdlink{newproblem} commands within the database. % -%\end{itemize} +% \StopEventually{\clearpage\phantomsection\addcontentsline{toc}{section}{Index}\PrintIndex} % -%\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{\PrintIndex} % %\section{The Code} %\iffalse @@ -558,147 +778,641 @@ %<*probsoln.sty> % \end{macrocode} %\fi -% At the start of the package, specify that the \LaTeXe\ format is -% required. And specify the package provided. +%\subsection{Package Definition} +% This package requires \LaTeXe. % \begin{macrocode} \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{probsoln}[2007/08/21 v2.04 Problems and their Solutions Package (NLCT)] +% \end{macrocode} +% Identify this package and version: +% \begin{macrocode} +\ProvidesPackage{probsoln}[2008/08/25 v3.0 (NLCT)] +% \end{macrocode} +% Required packages: +% \begin{macrocode} \RequirePackage{ifthen} +\RequirePackage{substr} +\RequirePackage{amsmath} % \end{macrocode} -% Define newif to determine whether or not to show the answers. -% (Changed to |\provideboolean| 21 Mar 2004.) +% \subsection{Package Options} +%\begin{macro}{\ifshowanswers} +% Define boolean to determine whether or not to show the +% solutions. This governs whether the contents of \env{onlysolution} +% and \env{onlyproblem} are displayed. % \begin{macrocode} -\provideboolean{showanswers} +\newif\ifshowanswers +\showanswersfalse % \end{macrocode} +%\end{macro} %\begin{macro}{\showanswers} +% Define synonym for \cs{showanswerstrue} % \begin{macrocode} -\let\showanswers=\showanswerstrue +\let\showanswers\showanswerstrue % \end{macrocode} %\end{macro} %\begin{macro}{\hideanswers} +% Define synonym for \cs{showanswersfalse} % \begin{macrocode} -\let\hideanswers=\showanswersfalse +\let\hideanswers\showanswersfalse % \end{macrocode} %\end{macro} -% Now define the package options +% The package option \pkgopt{answers} displays the solutions. % \begin{macrocode} \DeclareOption{answers}{\showanswerstrue} +% \end{macrocode} +% The package option \pkgopt{noanswers} hides the solutions. +% \begin{macrocode} \DeclareOption{noanswers}{\showanswersfalse} -\ExecuteOptions{noanswers} +% \end{macrocode} +%\begin{macro}{\prob@showdraftlabel} +%\begin{definition} +%\cs{prob@showdraftlabel}\marg{db name}\marg{label} +%\end{definition} +% Used by \cs{useproblem} to display data base name and problem +% label when in draft mode. +% \begin{macrocode} +\newcommand*{\prob@showdraftlabel}[2]{} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\draftproblemlabel} +%\begin{definition} +%\cs{draftproblemlabel}\marg{db name}\marg{label} +%\end{definition} +% Displays the data base name and label. +% \begin{macrocode} +\newcommand*{\draftproblemlabel}[2]{[#1,#2]} +% \end{macrocode} +%\end{macro} +% Draft mode displays the problem label using \cs{draftproblemlabel} +% \begin{macrocode} +\DeclareOption{draft}{% +\renewcommand*{\prob@showdraftlabel}[2]{\draftproblemlabel{#1}{#2}}} +% \end{macrocode} +% Final mode: +% \begin{macrocode} +\DeclareOption{final}{% +\renewcommand*{\prob@showdraftlabel}[2]{}} +% \end{macrocode} +% Process package options: +% \begin{macrocode} \ProcessOptions +% \end{macrocode} +%\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} +% which stores a comma-separated list of labels for each problem +% associated with that data base. Each problem \meta{label} is +% stored in the macro +% \cs{prob@data@}\meta{name}"@"\meta{name}"@"\meta{label}. Problems +% loaded from an external file using \cs{loadproblems} are added +% to the specified data base. Any problems that are defined in the +% document or are \cs{input}ed from another file (without the +% use of \cs{loadproblems}) are added to the default data base. +% +% Define the default data base: +% \begin{macrocode} +\newcommand*{\prob@db@default}{} % \end{macrocode} -% Create newifs for selecting randomly and parsing through file +% +%\begin{macro}{\prob@databases} +% Store a list of all the defined data bases. % \begin{macrocode} -\newif\ifselectrandom \selectrandomfalse -\newif\iffirstpass -\newif\ifselected +\newcommand*{\prob@databases}{default} % \end{macrocode} -%\begin{macro}{\newproblem} -% Define the command that creates a new problem. As from version -% 2.03 this command now has a starred version for problems without -% solutions. +%\end{macro} +% +%\begin{macro}{\prob@newdb} +%\begin{definition} +%\cs{prob@newdb}\marg{name} +%\end{definition} +% Creates a new (empty) data base. % \begin{macrocode} -\newcommand{\newproblem}{\@ifstar\@snewproblem\@newproblem} +\newcommand*{\prob@newdb}[1]{% +\@ifundefined{prob@db@#1}{% + \expandafter\gdef\csname prob@db@#1\endcsname{}% + \xdef\prob@databases{\prob@databases,#1}% + }{% + \PackageError{probsoln}{Data set `#1' is already defined}{}}} % \end{macrocode} %\end{macro} -%\begin{macro}{\@newproblem} -% The unstarred version. +% +%\begin{macro}{\prob@currentdb} +% Keep a track of the current data base % \begin{macrocode} -\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 -\@ifundefined{@prob@#2}{% -\ifnum#1=0 -% this problem has no arguments -\expandafter\gdef\csname @prob@#2\endcsname{% -#3 \ifshowanswers\begin{solution}#4\end{solution}\fi}% -\expandafter\gdef\csname @prob@#2@arg\endcsname{\relax}% -\else -\message{Problem #2 requires #1 argument(s), please specify (e.g. {5}{3}):}% -\read-1to\@tmp -\expandafter\xdef\csname @prob@#2@arg\endcsname{\@tmp}% -\expandafter\global\expandafter\newcommand\csname @prob@#2\endcsname[#1]{% -#3 \ifshowanswers\begin{solution}#4\end{solution}\fi}% -\fi -}{% -\PackageError{probsoln}{Label #2 already used}% -{Each problem must have a unique label identifier}% +\newcommand*{\prob@currentdb}{default} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\moveproblem} +%\begin{definition} +%\cs{moveproblem}\marg{label}\marg{source}\marg{target} +%\end{definition} +% \begin{macrocode} +\newcommand{\moveproblem}[3]{% +\@moveproblem{#1}{#2}{#3}% +\expandafter\let\expandafter\@tmpdblist + \csname prob@db@#2\endcsname +\expandafter\gdef\csname prob@db@#2\endcsname{}% +\@for\@tmplab:=\@tmpdblist\do{% + \ifthenelse{\equal{\@tmplab}{#1}}{}{% + \expandafter\ifx\csname prob@db@#2\endcsname\@empty + \expandafter\xdef\csname prob@db@#2\endcsname{\@tmplab}% + \else + \expandafter\xdef\csname prob@db@#2\endcsname{% + \csname prob@db@#2\endcsname,% + \@tmplab}% + \fi + }% }% -\fi -\fi -\else -\@ifundefined{@prob@#2}{% -\expandafter\global\expandafter\newcommand\csname @prob@#2\endcsname[#1]{% -#3 \ifshowanswers\begin{solution}#4\end{solution}\fi}% -}{% -\PackageError{probsoln}{Label #2 already used}% -{Each problem must have a unique label identifier}% } -\fi +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@moveproblem} +%\begin{definition} +%\cs{@moveproblem}\marg{label}\marg{source}\marg{target} +%\end{definition} +% Moves problem identified by \meta{label} from the data base +% \meta{source} to the data base \meta{target}. (Doesn't remove +% label from \meta{source} --- that needs to be done separately.) +% \begin{macrocode} +\newcommand*{\@moveproblem}[3]{% +% \end{macrocode} +% Add label to target data base +% \begin{macrocode} + \expandafter\ifx\csname prob@db@#3\endcsname\@empty + \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}. +% \begin{macrocode} + \edef\do@movedata{% + \noexpand\global\noexpand\let\expandafter\noexpand + \csname prob@data@#3@#1\endcsname=% + \expandafter\noexpand\csname prob@data@#2@#1\endcsname + \noexpand\global\noexpand\let + \expandafter\noexpand + \csname prob@data@#2@#1\endcsname=\noexpand\undefined + }% + \do@movedata +% \end{macrocode} +% Redefine \cs{prob@argN@}\meta{source}"@"\meta{label} as +% \cs{prob@argN@}\meta{target}"@"\meta{label}. +% \begin{macrocode} + \edef\do@moveargN{% + \noexpand\global\noexpand\let\expandafter\noexpand + \csname prob@argN@#3@#1\endcsname=% + \expandafter\noexpand\csname prob@argN@#2@#1\endcsname + \noexpand\global\noexpand\let + \expandafter\noexpand + \csname prob@argN@#2@#1\endcsname=\noexpand\undefined + }% + \do@moveargN +% \end{macrocode} +% Redefine \cs{prob@args@}\meta{source}"@"\meta{label} as +% \cs{prob@args@}\meta{target}"@"\meta{label}, if defined. +% \begin{macrocode} + \@ifundefined{prob@args@#2@#1}{}{% + \edef\do@moveargs{% + \noexpand\global\noexpand\let\expandafter\noexpand + \csname prob@args@#3@#1\endcsname=% + \expandafter\noexpand\csname prob@args@#2@#1\endcsname + \noexpand\global\noexpand\let + \expandafter\noexpand + \csname prob@args@#2@#1\endcsname=\noexpand\undefined + }% + \do@moveargs + }% } % \end{macrocode} %\end{macro} -%\begin{macro}{\@snewproblem} -% The starred version (new to version 2.03). Note that there is one -% less argument, because the problem doesn't have a solution. +% +%\subsection{Defining New Problems} +%\begin{macro}{\prob@newproblem} +%\begin{definition} +%\cs{prob@newproblem}\marg{n}\marg{db name}\marg{label}\marg{definition} +%\end{definition} +% Define a new problem identified by \meta{label} for data base +% \meta{db name} with the given definition. The problem has \meta{n} +% arguments (each represented by "#1" etc). The arguments may +% either be appended to \cs{useproblem}\marg{label} or may +% be stored in \cs{prob@args@}\meta{db name}"@"\meta{label} if +% the problem is to be accessed via \cs{foreachproblem}. The +% number of arguments is stored in +% \cs{prob@argN@}\meta{db name}"@"\meta{label} % \begin{macrocode} -\newcommand{\@snewproblem}[3][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 -\@ifundefined{@prob@#2}{% -\ifnum#1=0 -% this problem has no arguments -\expandafter\gdef\csname @prob@#2\endcsname{#3}% -\expandafter\gdef\csname @prob@#2@arg\endcsname{\relax}% +\newcommand{\prob@newproblem}[4]{% +% \end{macrocode} +% If the given data base is not defined, create it: +% \begin{macrocode} +\@ifundefined{prob@db@#2}{\prob@newdb{#2}}{}% +% \end{macrocode} +% Check whether this entry has already been defined: +% \begin{macrocode} +\@ifundefined{prob@data@#2@#3}{% +% \end{macrocode} +% Define the new problem and make it global: +% \begin{macrocode} +\let\@tmp=\undefined +\newcommand\@tmp[#1]{#4}% +\expandafter\global\expandafter\let + \csname prob@data@#2@#3\endcsname=\@tmp +\expandafter\xdef\csname prob@argN@#2@#3\endcsname{\number#1}% +\let\@tmp=\undefined +% \end{macrocode} +% Add the label to the data base: +% \begin{macrocode} +\expandafter\ifx\csname prob@db@#2\endcsname\@empty + \expandafter\xdef\csname prob@db@#2\endcsname{#3}% \else -\message{Problem #2 requires #1 argument(s), please specify (e.g. {5}{3}):}% -\read-1to\@tmp -\expandafter\xdef\csname @prob@#2@arg\endcsname{\@tmp}% -\expandafter\global\expandafter\newcommand\csname @prob@#2\endcsname[#1]{#3}% -\fi -}{% -\PackageError{probsoln}{Label #2 already used}% -{Each problem must have a unique label identifier}% -}% + \expandafter\xdef\csname prob@db@#2\endcsname{% + \csname prob@db@#2\endcsname,#3}% \fi +% \end{macrocode} +% If the problem requires arguments, prompt the user if necessary: +% \begin{macrocode} +\ifnum#1>0\relax + \@prob@do@getargs{#1}{#2}{#3}% \fi + }{% + \PackageError{probsoln}{Problem `#3' is already defined for + data base `#2'}{Problem labels must be unique for each data base}}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\@prob@gobblethree} +% Ignore all three arguments +% \begin{macrocode} +\newcommand{\@prob@gobblethree}[3]{} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\@prob@getargs} +%\begin{definition} +%\cs{@prob@getargs}\meta{n}\meta{db name}\meta{label} +%\end{definition} +% Prompt user for \meta{n} arguments for problem \meta{label} +% in data base \meta{db name}. +% \begin{macrocode} +\newcommand{\@prob@getargs}[3]{% +\message{Problem `#3' (in data base `#2') requires #1 argument(s).^^J +Please specify (e.g. {5}{3}):}% +\read-1to\@tmp +\expandafter\global\expandafter\let + \csname prob@args@#2@#3\endcsname=\@tmp +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\@prob@do@getargs} +% \begin{macrocode} +\let\@prob@do@getargs\@prob@gobblethree +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\long@collect@body} +% Need long versions of \cs{collect@body}. These macros are +% adapted from the macros defined by \sty{amsmath}. +% \begin{macrocode} +\long\def\long@collect@body#1{% + \@envbody{\@xp#1\@xp{\the\@envbody}}% + \edef\process@envbody{\the\@envbody\@nx\end{\@currenvir}}% + \@envbody\@emptytoks \def\begin@stack{b}% + \begingroup + \@xp\let\csname\@currenvir\endcsname\long@collect@@body + \edef\process@envbody{\@xp\@nx\csname\@currenvir\endcsname}% + \process@envbody +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\long@addto@envbody} +% \begin{macrocode} +\long\def\long@addto@envbody#1{\global\@envbody\@xp{\the\@envbody#1}} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\long@collect@@body} +% \begin{macrocode} +\long\def\long@collect@@body#1\end#2{% + \edef\begin@stack{\long@push@begins#1\begin\end \@xp\@gobble\begin@stack}% + \ifx\@empty\begin@stack + \endgroup + \@checkend{#2}% + \long@addto@envbody{#1}% + \else + \long@addto@envbody{#1\end{#2}}% + \fi + \process@envbody +} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\long@push@begins} +% \begin{macrocode} +\long\def\long@push@begins#1\begin#2{% + \ifx\end#2\else b\@xp\long@push@begins\fi +} +% \end{macrocode} +%\end{macro} +% +%\begin{environment}{defproblem} +%\begin{definition} +%"\begin{defproblem}"\oarg{n}\marg{label} +%\end{definition} +% Define a new problem identified by \meta{label} with +% \meta{n} arguments to add to the current data base. Note that +% since the contents of the environment are passed to a command, +% the contents can't contain any verbatim text. +% \begin{macrocode} +\newenvironment{defproblem}[2][0]{% + \def\@prob@currentargN{#1}% + \def\@prob@currentlabel{#2}% + \long@collect@body\prob@do@defproblem +}{} +% \end{macrocode} +%\end{environment} +%\begin{macro}{\prob@do@newproblem} +%\begin{definition} +%\cs{prob@do@newproblem}\marg{definition} +%\end{definition} +% Defines a new problem given by \meta{definition}, where +% the number of arguments is given by \cs{@prob@currentargN}, +% the label is given by \cs{@prob@currentlabel} and the data base +% is given by \cs{prob@currentdb}. +% \begin{macrocode} +\newcommand{\prob@do@newproblem}[1]{% +\prob@newproblem\@prob@currentargN\prob@currentdb + \@prob@currentlabel{#1}} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\prob@do@defproblem} +% The default action of the \env{defproblem} environment is to +% define a new problem. +% \begin{macrocode} +\let\prob@do@defproblem=\prob@do@newproblem +% \end{macrocode} +%\end{macro} +% +%\begin{environment}{onlysolution} +% Define an environment that only displays its contents if the +% solutions should be displayed. +% \begin{macrocode} +\newenvironment{onlysolution}{% + \long@collect@body\do@onlysolution +}{} +% \end{macrocode} +%\end{environment} +%\begin{macro}{\do@onlysolution} +% \begin{macrocode} +\newcommand{\do@onlysolution}[1]{% +\ifshowanswers + #1% +\fi} +% \end{macrocode} +%\end{macro} +% +%\begin{environment}{onlyproblem} +% Define an environment that only displays its contents if the +% solutions should not be displayed. +% \begin{macrocode} +\newenvironment{onlyproblem}{% + \long@collect@body\do@onlyproblem +}{} +% \end{macrocode} +%\end{environment} +%\begin{macro}{\do@onlyproblem} +% \begin{macrocode} +\newcommand{\do@onlyproblem}[1]{% +\ifshowanswers \else -\@ifundefined{@prob@#2}{% -\expandafter\global\expandafter\newcommand\csname @prob@#2\endcsname[#1]{#3}% + #1% +\fi} +% \end{macrocode} +%\end{macro} +% +%\subsection{Using Problems} +%\begin{macro}{\useproblem} +%\begin{definition} +%\cs{useproblem}\oarg{db name}\marg{label}\marg{arg1}\ldots +%\marg{argN} +%\end{definition} +% Use problem identified by \meta{label} in data base +% \meta{db name} where \meta{arg1}\ldots\meta{argN} are the +% arguments to pass to the problem, if the problem was defined +% to take arguments. +% \begin{macrocode} +\newcommand{\useproblem}[2][default]{% +\prob@showdraftlabel{#1}{#2}% +\let\@next=\relax +\@ifundefined{prob@data@#1@#2}{% + \PackageError{probsoln}{Problem `#2' is not defined in data set + `#1'}{}% }{% -\PackageError{probsoln}{Label #2 already used}% -{Each problem must have a unique label identifier}% + \def\@next{\csname prob@data@#1@#2\endcsname}% +}% +\@next} +% \end{macrocode} +%\end{macro} +%\subsection{Loading Problems From Another File} +%\begin{macro}{\loadallproblems} +%\begin{definition} +%\cs{loadallproblems}\oarg{db name}\marg{filename} +%\end{definition} +% Loads all the problems defined in \meta{filename} and adds +% them to data base \meta{db name}. (\cs{par} is temporarily +% disabled to allow for blank lines between problems.) +% \begin{macrocode} +\newcommand*{\loadallproblems}[2][default]{% +\bgroup + \let\par\relax + \edef\prob@currentdb{#1}% + \input{#2}% +\egroup } +% \end{macrocode} +%\end{macro} +%\begin{macro}{\prob@do@selectedproblem} +% Only define problem if the label is listed in +% \cs{prob@selectedlabels}. (The current label is +% given by \cs{@prob@currentlabel}.) +% \begin{macrocode} +\newcommand{\prob@do@selectedproblem}[1]{% +\IfSubStringInString{,\@prob@currentlabel,}{,\prob@selectedlabels,}{% +\prob@do@newproblem{#1}}{}% +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\loadselectedproblems} +%\begin{definition} +%\cs{loadselectedproblems}\oarg{db name}\marg{list}\marg{filename} +%\end{definition} +% Loads only those problems whose labels are listed in +% \meta{list}. +% \begin{macrocode} +\newcommand{\loadselectedproblems}[3][default]{% +\bgroup + \let\par\relax + \edef\prob@currentdb{#1}% + \edef\prob@selectedlabels{#2}% + \let\prob@do@defproblem=\prob@do@selectedproblem + \input{#3}% +\egroup +} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\prob@add@currentlabel} +% Adds the current label to \cs{prob@selectedlabels} (ignores +% argument.) +% \begin{macrocode} +\newcommand{\prob@add@currentlabel}[1]{% +\ifx\prob@selectedlabels\@empty + \xdef\prob@selectedlabels{\@prob@currentlabel}% +\else + \xdef\prob@selectedlabels{\prob@selectedlabels,\@prob@currentlabel}% \fi } % \end{macrocode} %\end{macro} -%\begin{macro}{\useproblem} -% Define the command that uses a problem +%\begin{macro}{\iffirstpass} +% Determines if this is the first pass of the filename when loading +% a data base. +% \begin{macrocode} +\newif\iffirstpass +\firstpasstrue +% \end{macrocode} +%\end{macro} +%\begin{macro}{\loadrandomproblems} +%\begin{definition} +%\cs{loadrandomproblems}\oarg{db name}\marg{n}\marg{filename} +%\end{definition} +% Loads \meta{n} randomly selected problems from \meta{filename}. +% Needs to input \meta{filename} twice: the first time just gathers +% all the labels, the second time only loads the selected problems. +% \begin{macrocode} +\newcommand{\loadrandomproblems}[3][default]{% +\bgroup + \let\par\relax + \def\prob@db@reserved{}% + \def\prob@currentdb{reserved}% + \edef\prob@selectedlabels{}% +% \end{macrocode} +% Collect labels: +% \begin{macrocode} + \let\prob@do@defproblem=\prob@add@currentlabel + \firstpasstrue + \input{#3}% +% \end{macrocode} +% Shuffle labels. +% \begin{macrocode} + \@probselN=0\relax + \@for\@thislabel:=\prob@selectedlabels\do{% + \advance\@probselN by 1\relax + \expandafter + \edef\csname @prob@tmp@\romannumeral\@probselN\endcsname{% + \@thislabel}% + }% + \shuffle{@prob@tmp@}{\@probselN}% + \ifnum\@probselN<#2\relax + \PackageError{probsoln}{% + Can't select \number#2\space\space problem(s):^^J + '#3' only contains \number\@probselN\space problem(s)}{% + Only \number\@probselN\space problem(s) will be selected}% + \else + \@probselN=#2\relax + \fi +% \end{macrocode} +% Store only the first \meta{n} of the shuffled labels. +% \begin{macrocode} + \@probN=0\relax + \def\prob@selectedlabels{}% + \whiledo{\@probN<\@probselN}{% + \advance\@probN by 1\relax + \ifx\prob@selectedlabels\@empty + \edef\prob@selectedlabels{% + \csname @prob@tmp@\romannumeral\@probN\endcsname}% + \else + \edef\prob@selectedlabels{% + \prob@selectedlabels,% + \csname @prob@tmp@\romannumeral\@probN\endcsname}% + \fi + }% +% \end{macrocode} +% Only load selected labels. % \begin{macrocode} -\newcommand*{\useproblem}[1]{% -\@ifundefined{@prob@#1}{% -\PackageError{probsoln}{Label #1 undefined}% -{Can't find problem defined with label identifier `#1'}% -}{\csname @prob@#1\endcsname}% + \let\prob@do@defproblem=\prob@do@selectedproblem + \firstpassfalse + \input{#3}% +% \end{macrocode} +% Move them from the reserved data base into the required data base +% in the order specified by \cs{prob@selectedlabels} +% \begin{macrocode} +\@ifundefined{prob@db@#1}{\prob@newdb{#1}}{}% +\@for\@thislabel:=\prob@selectedlabels\do{% + \@moveproblem{\@thislabel}{reserved}{#1}% +}% +% \end{macrocode} +% \cs{prob@selectedlabels} had to be globally defined. It's no +% longer required to undefine it. +% \begin{macrocode} + \let\prob@selectedlabels=\undefined +\egroup +} +% \end{macrocode} +%\end{macro} +% +%\subsection{Iterating Through a Data Base} +%\begin{macro}{\foreachproblem} +%\begin{definition} +%\cs{foreachproblem}\oarg{db name}\marg{body} +%\end{definition} +% Does \meta{body} for each problem defined in the data base +% \meta{db name}. Within \meta{body}, the command \cs{thisproblem} +% can be used to do the current problem and the command +% \cs{thisproblemlabel} can be used to access the current label. +% \begin{macrocode} +\newcommand{\foreachproblem}[2][default]{% +\@ifundefined{prob@db@#1}{% + \PackageError{probsoln}{Data base `#1' is not defined}{}% +}{% + \expandafter\let\expandafter\@tmp\csname prob@db@#1\endcsname + \@for\thisproblemlabel:=\@tmp\do{% + \expandafter\ifnum + \csname prob@argN@#1@\thisproblemlabel\endcsname>0\relax + \@ifundefined{prob@args@#1@\thisproblemlabel}{% + \expandafter\@prob@getargs + \csname prob@argN@#1@\thisproblemlabel\endcsname + {#1}{\thisproblemlabel}}{}% + \expandafter\let\expandafter\thisproblemargs + \csname prob@args@#1@\thisproblemlabel\endcsname + \else + \let\thisproblemargs\@empty + \fi + \expandafter\toks@\expandafter{\thisproblemargs}% + \edef\thisproblem{\noexpand\useproblem[#1]{\thisproblemlabel}% + \the\toks@}% + #2% + }% +}% } % \end{macrocode} %\end{macro} -% Now deal with the stuff for random selection. +% +%\begin{macro}{\foreachdataset} +%\begin{definition} +%\cs{foreachdataset}\marg{cmd}\marg{body} +%\end{definition} +% Iterates through all defined data sets. Assigns \meta{cmd} to the +% name of the data base. +% \begin{macrocode} +\newcommand{\foreachdataset}[2]{% +\@for#1:=\prob@databases\do{#2}} +% \end{macrocode} +%\end{macro} +% +%\subsection{Random Numbers} % First define some registers for later use. % \begin{macrocode} \newcount\@probN \newcount\@probselN \newcount\@rndselctr @@ -712,14 +1426,19 @@ \newcommand*{\PSNrandseed}[1]{% \ifnum#1=0\relax \PackageWarning{probsoln}{Can't have 0 as random seed, changing to 1}% - \r@ndcur=1\relax + \global\r@ndcur=1\relax \else - \r@ndcur=#1\relax + \global\r@ndcur=#1\relax \fi \PackageInfo{probsoln}{Random Seed = \number\r@ndcur}% } % \end{macrocode} %\end{macro} +%\begin{macro}{\PSNgetrandseed} +% \begin{macrocode} +\newcommand*{\PSNgetrandseed}[1]{#1=\r@ndcur\relax} +% \end{macrocode} +%\end{macro} %\begin{macro}{\PSNrand} % Generate a random integer. % \begin{macrocode} @@ -727,17 +1446,21 @@ \@ps@randtmp=\r@ndcur \multiply\@ps@randtmp by 16807\relax \r@ndcur=\@ps@randtmp -\divide\r@ndcur by 120001\relax -\multiply\r@ndcur by 120001\relax +\global\divide\r@ndcur by 120001\relax +\global\multiply\r@ndcur by 120001\relax \advance\@ps@randtmp by -\r@ndcur -\r@ndcur = \@ps@randtmp -\ifnum\r@ndcur=0\relax\r@ndcur=1\fi +\global\r@ndcur = \@ps@randtmp +\ifnum\r@ndcur=0\relax + \global\r@ndcur=1\relax +\fi } % \end{macrocode} %\end{macro} %\begin{macro}{\PSNrandom} -% \cs{PSNrandom}\marg{count}\marg{n} stores a random number -% from 1 to \meta{n} +%\begin{definition} +%\cs{PSNrandom}\marg{count}\marg{n} +%\end{definition} +% stores a random number from 1 to \meta{n} % in the TeX count register \meta{count} % \begin{macrocode} \newcommand{\PSNrandom}[2]{% @@ -758,7 +1481,9 @@ % \end{macrocode} %\end{macro} %\begin{macro}{\random} -% \cs{random}\marg{counter}\marg{a}\marg{b}: +%\begin{definition} +% \cs{random}\marg{counter}\marg{a}\marg{b} +%\end{definition} % Generate a random number in the range $[a,b]$, and store this % number in the \LaTeX\ counter \meta{counter}. % \begin{macrocode} @@ -776,101 +1501,12 @@ } % \end{macrocode} %\end{macro} -%\begin{macro}{\selectallproblems} -% Define command to use all problems from a given file. -% Syntax: \cs{selectallproblems}\marg{filename}. -% \begin{macrocode} -\newcommand*{\selectallproblems}[1]{% -\global\@probN=0\relax -\selectrandomtrue -\firstpasstrue -\input{#1}% -\firstpassfalse -\selectrandomfalse -\input{#1}% -\global\@rndselctr=1\relax -\whiledo{\@rndselctr < \@probN \TE@or \@rndselctr = \@probN}{% -\edef\@tmp{\csname @problabel\romannumeral\@rndselctr\endcsname}% -\edef\@probargs{{\@tmp}\csname @prob@\@tmp @arg\endcsname}% -\PSNitem \expandafter\useproblem\@probargs \endPSNitem -\global\advance\@rndselctr by 1\relax -}} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\selectrandomly} -% Now define command to randomly select \meta{n} problems from -% a given file. -% Syntax: \cs{selectrandomly}\marg{filename}\meta{n}. -% \begin{macrocode} -\newcommand*{\selectrandomly}[2]{% -\global\@probselN=#2\relax -\global\@probN=0\relax -\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 -\global\@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}% -\PSNitem \expandafter\useproblem\@probargs \endPSNitem -\global\advance\@rndselctr by 1\relax -}% -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\PSNitem} -% What to do at start and end of each randomly selected item: -% (I may turn this into a normal environment at a later date. At the -% moment, I have kept \verb|\PSNitem| for compatibility with earlier -% versions.) -% \begin{macrocode} -\newcommand*{\PSNitem}{\item} -\@ifundefined{endPSNitem}{\def\endPSNitem{}}{% -\PackageError{probsoln}{\string\endPSitem\ already defined}{}} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\solutionname} -% How to display each solution -% \begin{macrocode} -\providecommand*{\solutionname}{Solution} -\@ifundefined{solution}{% -\newenvironment{solution}{\par\noindent\textbf{\solutionname:} }{}}{% -} -% \end{macrocode} -%\end{macro} -%\begin{macro}{\checkselected} -% 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} -%\end{macro} %\begin{macro}{\shuffle} % Shuffle contents of pseudo-array. For example, suppose you have -% the following definitions: |\def\fooi{A}|, |\def\fooii{B}| and -% |\def\fooiii{C}|, then |\shuffle{foo}{3}| will shuffle the -% definitions, so you may end up with, e.g.\ |\def\fooi{C}|, -% |\def\fooii{A}|, |\def\fooiii{B}|, or some other variation. +% the following definitions: "\def\fooi{A}", "\def\fooii{B}" and +% "\def\fooiii{C}", then "\shuffle{foo}{3}" will shuffle the +% definitions, so you may end up with, e.g.\ "\def\fooi{C}", +% "\def\fooii{A}", "\def\fooiii{B}", or some other variation. % \begin{macrocode} \newcount\@shfctr \newcount\@shfA \newcount\@shfB \newcommand{\shuffle}[2]{% @@ -892,15 +1528,18 @@ % \end{macrocode} %\end{macro} %\begin{macro}{\doforrandN} -% Syntax: \cs{doforrandN}\marg{n}\marg{cmd}\marg{list}\marg{text}. -% A bit like |\@for| but only for a random subset of the given list. -% For example, +%\begin{definition} +% \cs{doforrandN}\marg{n}\marg{cmd}\marg{list}\marg{text}. +%\end{definition} +% A bit like \cs{@for} but only for a random subset of the given +% list. +% For example, the following will load one problem each from two +% out of the three listed files. %\begin{verbatim} %\doforrandN{2}{\tmp}{file1,file2,file3}{% -%\selectrandomly{\tmp}{1}} +%\loadrandomproblems{1}{\tmp}} %\end{verbatim} -%This will select one problem each from two out of the three listed -%files. +% % \begin{macrocode} \newcount\@ps@forrand \newcommand{\doforrandN}[4]{% @@ -927,10 +1566,1071 @@ are only \number\@ps@forrand item(s) in the list}% }} % \end{macrocode} %\end{macro} +%\subsection{Compatibility With Older Versions} +% These commands ensure that this version is compatible with +% versions prior to v3.0 +%\begin{macro}{\newproblem} +% Defines a new problem. +% \begin{macrocode} +\newcommand*{\newproblem}{\@ifstar\@snewproblem\@newproblem} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\@snewproblem} +% \begin{macrocode} +\newcommand{\@snewproblem}[3][0]{% +\begin{defproblem}[#1]{#2}% +#3% +\end{defproblem}} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\@newproblem} +% \begin{macrocode} +\newcommand{\@newproblem}[4][0]{% +\begin{defproblem}[#1]{#2}% +#3% +\begin{onlysolution}% +\begin{solution}% +#4% +\end{solution}% +\end{onlysolution}% +\end{defproblem}} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\selectallproblems} +% \begin{macrocode} +\newcommand*{\selectallproblems}[1]{{\loadallproblems[#1]{#1}}% +\foreachproblem[#1]{\PSNitem\thisproblem\endPSNitem}} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\selectrandomly} +% \begin{macrocode} +\newcommand*{\selectrandomly}[2]{% +{\loadrandomproblems[#1]{#2}{#1}}% +\foreachproblem[#1]{\PSNitem\thisproblem\endPSNitem}% +} +% \end{macrocode} +%\end{macro} +%\begin{environment}{PSNitem} +% \begin{macrocode} +\newenvironment{PSNitem}{\item}{} +% \end{macrocode} +%\end{environment} +% +%\subsection{Formatting Commands} +% These commands are provided to format parts of the +% problems/solutions. +%\begin{environment}{solution} +% \begin{macrocode} +\@ifundefined{solution}{% +\newenvironment{solution}{\par\noindent\textbf{\solutionname:}}{}% +}{} +% \end{macrocode} +%\end{environment} +%\begin{macro}{\solutioname} +% \begin{macrocode} +\newcommand*{\solutionname}{Solution} +% \end{macrocode} +%\end{macro} +% Define an in-line enumeration which uses the enumeration +% environment's counters. +%\begin{environment}{textenum} +%\changes{2007 Oct 6}{2.05}{new} +% \begin{macrocode} +\newenvironment{textenum}{% +\ifnum\@enumdepth>\thr@@ + \@toodeep +\else + \advance\@enumdepth\@ne + \edef\@enumctr{enum\romannumeral\the\@enumdepth}% + \let\@item\@textitem + \def\@itemlabel{\refstepcounter{\@enumctr}% + \csname label\@enumctr\endcsname}% + \setcounter{\@enumctr}{0}% +\fi\ignorespaces}{% +\global\advance\@enumdepth\m@ne} +% \end{macrocode} +%\end{environment} +%\begin{macro}{\@textitem} +% In-line enumeration item +% \begin{macrocode} +\def\@textitem[#1]{#1\space\ignorespaces} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\correctitemformat} +% \changes{2007 Oct 6}{2.05}{new} +% Indicates how to format the item label for \cs{correctitem} when +% the solutions are shown. The argument is the label. This +% defaults to placing the argument in a box. +% \begin{macrocode} +\newcommand*{\correctitemformat}[1]{\fbox{#1}} +% \end{macrocode} +%\end{macro} +%\begin{macro}{\incorrectitemformat} +% \changes{2007 Oct 6}{2.05}{new} +% Indicates how to format the item label for \cs{incorrectitem} when +% the solutions are shown. The argument is the label. This +% defaults to just the argument shifted +% by \cs{fboxsep} + \cs{fboxrule} to ensure it aligns +% with the default \cs{correctitemformat}. +% \begin{macrocode} +\newcommand*{\incorrectitemformat}[1]{% +\hspace{\fboxsep}\hspace{\fboxrule}#1} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\correctitem} +% \changes{2007 Oct 6}{2.05}{new} +%This can be used instead of \cs{item}. If the solutions are +% not shown, it behaves like \cs{item}, otherwise, it's like +% \cs{item}, but the label is formatted according to +% \cs{correctitemformat}. +% \begin{macrocode} +\newcommand*{\correctitem}{\@inmatherr\correctitem +\@ifnextchar[\@correctitem{\@noitemargtrue\@correctitem[\@itemlabel]}} +% \end{macrocode} +% \begin{macrocode} +\def\@correctitem[#1]{% +\ifshowanswers + \@item[\correctitemformat{#1}]% +\else + \@item[#1]% +\fi} +% \end{macrocode} +%\end{macro} +% +%\begin{macro}{\incorrectitem} +% \changes{2007 Oct 6}{2.05}{new} +%This can be used instead of \cs{item}. If the solutions are +% not shown, it behaves like \cs{item}, otherwise, it's like +% \cs{item}, but the label is formatted according to +% \cs{incorrectitemformat}. +% \begin{macrocode} +\newcommand*{\incorrectitem}{\@inmatherr\incorrectitem +\@ifnextchar[\@incorrectitem{\@noitemargtrue\@incorrectitem[\@itemlabel]}} +% \end{macrocode} +% \begin{macrocode} +\def\@incorrectitem[#1]{% +\ifshowanswers + \@item[\incorrectitemformat{#1}]% +\else + \@item[#1]% +\fi} +% \end{macrocode} +%\end{macro} %\iffalse % \begin{macrocode} %</probsoln.sty> % \end{macrocode} %\fi +%\iffalse +% \begin{macrocode} +%<*1stprncp.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} + % These all involve differentiating from 1st principles + +\newproblem{dfp:xcube}{% +Differentiate $f(x) = x^3$ with respect to $x$ by first principles.}{% +\begin{eqnarray*} +\frac{dy}{dx} & = & \lim_{\Delta x\rightarrow 0}\frac{f(x+\Delta x) - f(x)}{\Delta x}\\ + & = & \lim_{\Delta x\rightarrow 0}\frac{(x+\Delta x)^3-x^3}{\Delta x}\\ + & = & \lim_{\Delta x\rightarrow 0}\frac{(x+\Delta x)(x^2+2x\Delta x+(\Delta x)^2)-x^3}{\Delta x}\\ + & = & \lim_{\Delta x\rightarrow 0}\frac{x^3+3x^2\Delta x+3x(\Delta x)^2+(\Delta x)^3-x^3}{\Delta x}\\ + & = & \lim_{\Delta x\rightarrow 0}\frac{3x^2\Delta x+3x(\Delta x)^2+(\Delta x)^3}{\Delta x}\\ + & = & \lim_{\Delta x\rightarrow 0}3x^2+3x\Delta x + (\Delta x)^2\\ + & = & 3x^2 +\end{eqnarray*}} + +\newproblem{dfp:Ioverxsq}{% +Differentiate $\displaystyle f(x) = \frac{1}{x^2}$ with respect to $x$ by first principles.}{% +\begin{eqnarray*} +\frac{df}{dx} & = & \lim_{\Delta x\rightarrow 0}\frac{\frac{1}{(x+\Delta x)^2}-\frac{1}{x^2}}{\Delta x}\\ + & = & \lim_{\Delta x\rightarrow 0}\frac{\frac{x^2-(x+\Delta x)^2}{x^2(x+\Delta x)^2}}{\Delta x}\\ + & = & \lim_{\Delta x\rightarrow 0}\frac{x^2-(x^2+2x\Delta x+(\Delta x)^2)}{x^2\Delta x(x+\Delta x)^2}\\ + & = & \lim_{\Delta x\rightarrow 0}\frac{-2x\Delta x-(\Delta x)^2}{x^2\Delta x(x+\Delta x)^2}\\ + & = & \lim_{\Delta x\rightarrow 0}\frac{-2x-\Delta x}{x^2(x+\Delta x)^2}\\ + & = & \frac{-2x}{x^2x^2}\\ + & = & -\frac{2}{x^3} +\end{eqnarray*}} + +\newproblem{dfp:sqrtx}{% +Differentiate from first principles $f(x) = \surd x$}{% +\begin{eqnarray*} +\frac{df}{dx} & = & \lim_{\Delta x\rightarrow 0}\frac{\sqrt{x+\Delta x}-\surd x}{\Delta x}\\ + & = & \lim_{\Delta x\rightarrow 0}\frac{(\sqrt{x+\Delta x}-\surd x)(\sqrt{x+\delta x}+\surd x)}{\Delta x(\sqrt{x+\Delta x}+\surd x)}\\ + & = & \lim_{\Delta x\rightarrow 0}\frac{x+\Delta x - x}{\Delta x(\sqrt{x+\Delta x}+\surd x)}\\ + & = & \lim_{\Delta x\rightarrow 0}\frac{\Delta x}{\Delta x(\sqrt{x+\Delta x}+\Delta x)}\\ + & = & \lim_{\Delta x\rightarrow 0}\frac{1}{\sqrt{x+\Delta x}+\surd x}\\ + & = & \frac{1}{2\surd x} +\end{eqnarray*}} + +\newproblem{dfp:cons}{% +Differentiate from first principles $f(x) = c$ where $c$ is a constant.}{% +\begin{eqnarray*} +\frac{df}{dx} & = & \lim_{\Delta x\rightarrow 0}\frac{c-c}{\Delta x}\\ + & = & \lim_{\Delta x\rightarrow 0}0\\ + & = & 0 +\end{eqnarray*}} + +\newproblem{dfp:cosx}{% +Given +\begin{eqnarray*} +\lim_{x \rightarrow 0} \frac{\cos x - 1}{x} & = & 0\\ +\lim_{x \rightarrow 0} \frac{\sin x}{x} & = & 1 +\end{eqnarray*} +differentiate from first principles $f(x) = \cos x$.}{% +\begin{eqnarray*} +\frac{df}{dx} & = & \lim_{\Delta x \rightarrow 0}\frac{f(x + \Delta x) - f(x)}{\Delta x}\\ + & = & \lim_{\Delta x \rightarrow 0} \frac{\cos(x + \Delta x) - \cos(x)}{\Delta x}\\ + & = & \lim_{\Delta x \rightarrow 0} \frac{\cos x\cos\Delta x - \sin x\sin\Delta x - \cos x}{\Delta x}\\ + & = & \lim_{\Delta x \rightarrow 0} \frac{\cos x(\cos\Delta x - 1) - \sin x\sin\Delta x}{\Delta x}\\ + & = & \cos x\lim_{\Delta x \rightarrow 0}\frac{\cos\Delta x - 1}{\Delta x} + - \sin x\lim_{\Delta x \rightarrow 0}\frac{\sin\Delta x}{\Delta x}\\ + & = & -1 \qquad\mbox{(using given results)} +\end{eqnarray*}} +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%</1stprncp.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%<*args.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} + % These problems require arguments + + % Arguments: #1->a_2, #2->a_1 and #3->a_0 + % (Arguments must be integers) +\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 +\) +} + +\newproblem[1]{diff:sin}{% +\(f(x) = \sin(#1x)\) +}{% +\(f'(x) = #1\cos(#1x)\) +} + +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%</args.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%<*easy.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} + % These are all easy differentiation problems + +\newproblem{diffeasy:gpowh}{% +\(f(x) = g(x)^{h(x)}.\)}{% +\begin{eqnarray*} +f(x) & = & e^{\ln g(x)^{h(x)}}\\ + & = & e^{h(x)\ln g(x)}\\ +f'(x) & = & e^{h(x)\ln g(x)}(h'(x)\ln g(x) + h(x)\frac{g'(x)}{g(x)})\\ + & = & g(x)^{h(x)}(h'(x)\ln g(x) + \frac{h(x)g'(x)}{g(x)}) +\end{eqnarray*}} + +\newproblem{diffeasy:arcsin}{% +\(y = \arcsin(x)\)}{% +\[\sin(y) = x\] +diff. w.r.t. $x$: +\begin{eqnarray*} +\cos y \frac{dy}{dx} & = & 1\\ +\frac{dy}{dx} & = & \frac{1}{\cos y}\\ + & = & \frac{1}{\sqrt{1 - \sin^2y}}\\ + & = & \frac{1}{\sqrt{1-x^2}}. +\end{eqnarray*}} + +\newproblem{diffeasy:arccos}{% +$y = \arccos x$.}{% +\(\cos y = x\) +diff. w.r.t. $x$: +\begin{eqnarray*} +-\sin y \frac{dy}{dx} & = & 1\\ +\frac{dy}{dx} & = & \frac{-1}{\sin y}\\ + & = & \frac{-1}{\sqrt{1-\cos^2y}}\\ + & = & \frac{-1}{\sqrt{1-x^2}} +\end{eqnarray*}} + +\newproblem{diffeasy:tan}{% +\(y = \tan x\)}{% +\begin{eqnarray*} +y & = & \tan x\\ + & = & \frac{\sin x}{\cos x}\\ +\frac{dy}{dx} & = & \frac{\cos x}{\cos x} + \sin x\times\frac{-1}{\cos^2x}\times -\sin x\\ + & = & 1 + \tan^2x\\ + & = & \sec^2x. +\end{eqnarray*}} + +\newproblem{diffeasy:arctan}{% +\(y = \arctan x = \tan^{-1}x\)}{% +\[\tan y = x\] +diff w.r.t. $x$: +\begin{eqnarray*} +\sec^2y\frac{dy}{dx} & = & 1\\ +\frac{dy}{dx} & = & \frac{1}{\sec^2y}\\ + & = & \frac{1}{1+\tan^2y}\\ + & = & \frac{1}{1+x^2} +\end{eqnarray*}} + +\newproblem{diffeasy:cot}{% +\(y = (\tan x)^{-1} = \cot x\)}{% +\begin{eqnarray*} +\frac{dy}{dx} & = & -(\tan x)^{-2}\sec^2x\\ + & = & -\frac{\cos^2x}{\sin^2x}\cdot\frac{1}{\cos^2x}\\ + & = & \frac{-1}{\sin^2x}\\ + & = & -\csc^2x. +\end{eqnarray*}} + +\newproblem{diffeasy:cosxsqsinx}{% +$y = \cos(x^2)\sin x$.}{% +\[\frac{dy}{dx} = -\sin(x^2)2x\sin x + \cos(x^2)\cos x\]} + +\newproblem{diffeasy:xlnx}{% +$y = (x+1)\ln(x+1)$.}{% +\begin{eqnarray*} +\frac{dy}{dx} & = & \ln(x+1) + \frac{x+1}{x+1}\\ + & = & 1 + \ln(x+1). +\end{eqnarray*}} + +\newproblem{diffeasy:glng}{% +$f(x) = g(x)\ln(g(x))$.}{% +\begin{eqnarray*} +f'(x) & = & g'(x)\ln(g(x)) + \frac{g(x)}{g(x)}g'(x)\\ + & = & g'(x)(1+\ln(g(x))). +\end{eqnarray*}} + +\newproblem{diffeasy:sinx/x}{% +$y = \frac{\sin x}{x}$.}{% +\[\frac{dy}{dx} = \frac{\cos x}{x} - \frac{\sin x}{x^2}\]} + +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%</easy.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%<*easy2.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} + % These are all easy differentiation problems + +\begin{defproblem}{diffeasy:gpowh}% +\begin{onlyproblem}% +\(f(x) = g(x)^{h(x)}.\)% +\end{onlyproblem}% +\begin{onlysolution}% +\begin{eqnarray*} +f(x) & = & e^{\ln g(x)^{h(x)}}\\ + & = & e^{h(x)\ln g(x)}\\ +f'(x) & = & e^{h(x)\ln g(x)}(h'(x)\ln g(x) + h(x)\frac{g'(x)}{g(x)})\\ + & = & g(x)^{h(x)}(h'(x)\ln g(x) + \frac{h(x)g'(x)}{g(x)}) +\end{eqnarray*}% +\end{onlysolution}% +\end{defproblem} + +\begin{defproblem}{diffeasy:arcsin}% +\begin{onlyproblem}% +\(y = \arcsin(x)\)% +\end{onlyproblem}% +\begin{onlysolution}% +\[\sin(y) = x\] +diff. w.r.t. $x$: +\begin{eqnarray*} +\cos y \frac{dy}{dx} & = & 1\\ +\frac{dy}{dx} & = & \frac{1}{\cos y}\\ + & = & \frac{1}{\sqrt{1 - \sin^2y}}\\ + & = & \frac{1}{\sqrt{1-x^2}}. +\end{eqnarray*} +\end{onlysolution}% +\end{defproblem} + +\begin{defproblem}{diffeasy:arccos}% +\begin{onlyproblem}% +$y = \arccos x$.% +\end{onlyproblem}% +\begin{onlysolution}% +\(\cos y = x\) +diff. w.r.t. $x$: +\begin{eqnarray*} +-\sin y \frac{dy}{dx} & = & 1\\ +\frac{dy}{dx} & = & \frac{-1}{\sin y}\\ + & = & \frac{-1}{\sqrt{1-\cos^2y}}\\ + & = & \frac{-1}{\sqrt{1-x^2}} +\end{eqnarray*} +\end{onlysolution}% +\end{defproblem} + +\begin{defproblem}{diffeasy:tan}% +\begin{onlyproblem}% +\(y = \tan x\)% +\end{onlyproblem} +\begin{onlysolution}% +\begin{eqnarray*} +y & = & \tan x\\ + & = & \frac{\sin x}{\cos x}\\ +\frac{dy}{dx} & = & \frac{\cos x}{\cos x} + \sin x\times\frac{-1}{\cos^2x}\times -\sin x\\ + & = & 1 + \tan^2x\\ + & = & \sec^2x. +\end{eqnarray*} +\end{onlysolution}% +\end{defproblem} + +\begin{defproblem}{diffeasy:arctan}% +\begin{onlyproblem}% +\(y = \arctan x = \tan^{-1}x\)% +\end{onlyproblem}% +\begin{onlysolution}% +\[\tan y = x\] +diff w.r.t. $x$: +\begin{eqnarray*} +\sec^2y\frac{dy}{dx} & = & 1\\ +\frac{dy}{dx} & = & \frac{1}{\sec^2y}\\ + & = & \frac{1}{1+\tan^2y}\\ + & = & \frac{1}{1+x^2} +\end{eqnarray*} +\end{onlysolution}% +\end{defproblem} + +\begin{defproblem}{diffeasy:cot}% +\begin{onlyproblem}% +\(y = (\tan x)^{-1} = \cot x\)% +\end{onlyproblem} +\begin{onlysolution}% +\begin{eqnarray*} +\frac{dy}{dx} & = & -(\tan x)^{-2}\sec^2x\\ + & = & -\frac{\cos^2x}{\sin^2x}\cdot\frac{1}{\cos^2x}\\ + & = & \frac{-1}{\sin^2x}\\ + & = & -\csc^2x. +\end{eqnarray*} +\end{onlysolution}% +\end{defproblem} + +\begin{defproblem}{diffeasy:cosxsqsinx}% +\begin{onlyproblem}% +$y = \cos(x^2)\sin x$.% +\end{onlyproblem}% +\begin{onlysolution}% +\[\frac{dy}{dx} = -\sin(x^2)2x\sin x + \cos(x^2)\cos x\] +\end{onlysolution}% +\end{defproblem} + +\begin{defproblem}{diffeasy:xlnx}% +\begin{onlyproblem}% +$y = (x+1)\ln(x+1)$. +\end{onlyproblem}% +\begin{onlysolution}% +\begin{eqnarray*} +\frac{dy}{dx} & = & \ln(x+1) + \frac{x+1}{x+1}\\ + & = & 1 + \ln(x+1). +\end{eqnarray*} +\end{onlysolution} +\end{defproblem} + +\begin{defproblem}{diffeasy:glng}% +\begin{onlyproblem}% +$f(x) = g(x)\ln(g(x))$. +\end{onlyproblem} +\begin{onlysolution}% +\begin{eqnarray*} +f'(x) & = & g'(x)\ln(g(x)) + \frac{g(x)}{g(x)}g'(x)\\ + & = & g'(x)(1+\ln(g(x))). +\end{eqnarray*} +\end{onlysolution}% +\end{defproblem} + +\begin{defproblem}{diffeasy:sinx/x} +\begin{onlyproblem}% +$y = \frac{\sin x}{x}$. +\end{onlyproblem} +\begin{onlysolution}% +\[\frac{dy}{dx} = \frac{\cos x}{x} - \frac{\sin x}{x^2}\] +\end{onlysolution}% +\end{defproblem} + +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%</easy2.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%<*implicit.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} + % These are all implicit differentiation problems + +\newproblem{imd:circ}{% +Find the gradient of the unit circle ($x^2 + y^2 = 1$).}{% +Differentiating with respect to $x$ gives: +\begin{eqnarray*} +2x + 2y\frac{dy}{dx} & = & 0\\ +\frac{dy}{dx} & = & \frac{-2x}{2y}\\ + & = & \frac{-x}{\sqrt{1-x^2}}. +\end{eqnarray*}} + +\newproblem{imd:ysq:xcuov2mx}{% +Find $\frac{dy}{dx}$, given +\begin{displaymath} +y^2 = \frac{x^3}{2-x} +\end{displaymath}}{% +Differentiating both sides w.r.t.\ $x$: +\begin{eqnarray*} +2y\frac{dy}{dx} & = & \frac{(2-x)3x^2 - x^3(-1)}{(2-x)^2}\\ + & = & \frac{3x^2(2-x) + x^3}{(2-x)^2}\\ + & = & \frac{6x^2 - 3x^3 + x^3}{(2-x)^2}\\ + & = & \frac{6x^2-2x^3}{(2-x)^2}\\ + & = & 2x^2\frac{3-x}{(2-x)^2} +\end{eqnarray*} +Therefore +\begin{displaymath} +y\frac{dy}{dx} = x^2\frac{3-x}{(2-x)^2} +\end{displaymath}} + +\newproblem{imd:exy:IIxay}{% +Differentiate w.r.t.\ $x$: +\begin{displaymath} +e^{xy} = 2x + y +\end{displaymath}}{% +Differentiating both sides w.r.t.\ $x$: +\begin{eqnarray*} +e^{xy}(1y + x\frac{dy}{dx}) & = & 2 + \frac{dy}{dx}\\ +xe^{xy}\frac{dy}{dx} - \frac{dy}{dx} & = & 2 - ye^{xy} \\ +\frac{dy}{dx}(xe^{xy}-1) & = & 2 - ye^{xy}\\ +\frac{dy}{dx} & = & \frac{2-ye^{xy}}{xe^{xy}-1} +\end{eqnarray*}} +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%</implicit.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%<*mchoice.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +\newproblem{mc:prod}{% +Which of the following is the derivative of $x\sin(x)$? +(Circle the correct answer.) +\ifthenelse{\boolean{showanswers}}{}% +{\begin{description} +\item[A] $\sin(x)$ +\item[B] $x\cos(x)$ +\item[C] $\sin(x) + x\cos(x)$ +\end{description} +}}{% +\begin{description} +\item[A] $\sin(x)$ +\item[B] $x\cos(x)$ +\item[\textcircled{C}] $\sin(x) + x\cos(x)$ (product rule). +\end{description} +} + +\newproblem{mc:quot}{% +Which of the following is the derivative of $\frac{\sin(x)}{x}$? +(Circle the correct answer.) +\ifthenelse{\boolean{showanswers}}{}% +{\begin{description} +\item[A] $\sin(x)$ +\item[B] $\cos(x)$ +\item[C] $\frac{\cos(x)x-\sin(x)}{x^2}$ +\end{description} +}}{% +\begin{description} +\item[A] $\sin(x)$ +\item[B] $\cos(x)$ +\item[\textcircled{C}] $\frac{\cos(x)x-\sin(x)}{x^2}$ +(quotient rule) +\end{description} +} +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%</mchoice.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%<*newdata.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +\begin{defproblem}{sample} +\begin{onlyproblem} +Differentiate $y=\sin x$ +\end{onlyproblem} +\begin{onlysolution} +$y'=\cos x$ +\end{onlysolution} +\end{defproblem} + +\begin{defproblem}[1]{sample2} +\begin{onlyproblem} +Differentiate $y = \sin(#1x)$ +\end{onlyproblem} +\begin{onlysolution} +$y'=#1\cos #1x$ +\end{onlysolution} +\end{defproblem} + +\begin{defproblem}{sample3} +\begin{onlyproblem} +Differentiate $y = x^2$. +\end{onlyproblem} +\begin{onlysolution} +$y' = 2x$ +\end{onlysolution} +\end{defproblem} +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%</newdata.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%<*nosoln.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} + % these problems don't have solutions + +\newproblem*{oop}{Describe what is meant by object-oriented +programming.} + +\newproblem*{inheritance}{Describe what is meant by the term +\emph{inheritance} in object-oriented programming. Use examples.} +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%</nosoln.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%<*probspaces.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} + % Finite probability spaces +\newproblem{weightedcoin}{% +A coin is weighted so that heads is four times as likely +as tails. Find the probability that: +\begin{textenum} +\item tails appears, +\item heads appears +\end{textenum}}{% +Let $p=P(T)$, then $P(H)=4p$. We require $P(H)+P(T)=1$, +so $4p+p=1$, hence $p=\frac{1}{5}$. Therefore: +\begin{textenum} +\item $P(T)=\frac{1}{5}$, +\item $P(H)=\frac{4}{5}$ +\end{textenum}} + +\newproblem*{validprobspaces}{% +Under which of the following functions does +$S=\{a_1,a_2\}$ become a probability space? +\par +\begin{textenum} +\begin{tabular}{ll} +\incorrectitem $P(a_1)=\frac{1}{3}$, $P(a_2)=\frac{1}{2}$ +& +\correctitem $P(a_1)=\frac{3}{4}$, $P(a_2)=\frac{1}{4}$ +\\ +\correctitem $P(a_1)=1$, $P(a_2)=0$ +& +\incorrectitem $P(a_1)=\frac{5}{4}$, $P(a_2)=-\frac{1}{4}$ +\end{tabular} +\end{textenum} +} +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%</probspaces.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%<*probspaces2.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} + % Finite probability spaces +\begin{defproblem}{weightedcoin} +\begin{onlyproblem}% +A coin is weighted so that heads is four times as likely +as tails. Find the probability that: +\begin{textenum} +\item tails appears, +\item heads appears +\end{textenum} +\end{onlyproblem} +\begin{onlysolution}% +Let $p=P(T)$, then $P(H)=4p$. We require $P(H)+P(T)=1$, +so $4p+p=1$, hence $p=\frac{1}{5}$. Therefore: +\begin{textenum} +\item $P(T)=\frac{1}{5}$, +\item $P(H)=\frac{4}{5}$ +\end{textenum} +\end{onlysolution} +\end{defproblem} + +\begin{defproblem}{validprobspaces} +\begin{onlyproblem}% +Under which of the following functions does +$S=\{a_1,a_2\}$ become a probability space? +\par +\begin{textenum} +\begin{tabular}{ll} +\item $P(a_1)=\frac{1}{3}$, $P(a_2)=\frac{1}{2}$ +& +\item\label{validprobspacescorrect1} $P(a_1)=\frac{3}{4}$, $P(a_2)=\frac{1}{4}$ +\\ +\item\label{validprobspacescorrect2} $P(a_1)=1$, $P(a_2)=0$ +& +\item $P(a_1)=\frac{5}{4}$, $P(a_2)=-\frac{1}{4}$ +\end{tabular} +\end{textenum} +\end{onlyproblem}% +\begin{onlysolution}% +\ref{validprobspacescorrect1} and \ref{validprobspacescorrect2}% +\end{onlysolution} +\end{defproblem} +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%</probspaces2.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%<*sample.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +\documentclass[a4paper]{article} + +\usepackage{probsoln} + %uncomment the following line to display the answers +\showanswers + + % The following will generate a different set of + % problems in subsequent years + %\PSNrandseed{\year} +\PSNrandseed{2007} + +\begin{document} +\title{Sample Problem Sheet} +\author{Nicola Talbot} +\maketitle + +\begin{enumerate} + % Differentiation from first principles +\selectrandomly{1stprncp}{1} + +\item Differentiate the following functions: +\newcount\oldseed +\PSNgetrandseed\oldseed +\begin{enumerate} +\selectrandomly{easy}{5} +\end{enumerate} +\PSNrandseed\oldseed + + % Implicit differentiation +\selectrandomly{implicit}{2} + + % Finite probability spaces +\selectrandomly{probspaces}{2} + + % Multiple choice question +\selectrandomly{mchoice}{1} + + % select one essay style question that doesn't come with a solution + +\selectrandomly{nosoln}{1} +\end{enumerate} +\end{document} +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%</sample.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%<*sample2.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +\documentclass[a4paper]{article} + +\usepackage{probsoln} + %uncomment the following line to display the answers +\showanswers + + % The following will generate a different set of + % problems in subsequent years + %\PSNrandseed{\year} + + % The following will generate a different set of + % problems on every run (where each run is at + % least a minute apart from the previous one) +\PSNrandseed{\time} + +\begin{document} +\title{Sample Problem Sheet} +\author{Nicola Talbot} +\maketitle + +\begin{enumerate} + +\newcounter{numproblems} + % store a random number from 1 to 3 in the counter numproblems +\random{numproblems}{1}{3} + + % selects 1,2 or 3 problems from 1 of the given files: +\doforrandN{1}{\file}{1stprncp,implicit}{\selectrandomly{\file}{\value{numproblems}}} + +\item Differentiate the following functions: +\input{args}% load database +\begin{enumerate} +\newcounter{A} +\newcounter{B} +\newcounter{C} +\random{A}{-4}{5} +\random{B}{-3}{3} +\random{C}{-1}{10} +\item \useproblem{diff:quad}{\arabic{A}}{\arabic{B}}{\arabic{C}} + +\random{A}{-5}{5} + % make sure its not 0 +\whiledo{\value{A}=0}{\random{A}{-5}{5}} +\item \useproblem{diff:sin}{\arabic{A}} +\end{enumerate} +\end{enumerate} +\end{document} +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%</sample2.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%<*sample3.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +\documentclass[a4paper]{article} + +\usepackage{longtable} +\usepackage{probsoln} + + %\showanswers + +\newcounter{problem} +\renewcommand{\PSNitem}{\refstepcounter{problem}% +\theproblem. } +\renewcommand{\endPSNitem}{\\} + +\renewenvironment{solution}{}{} + +\newcommand{\selected}{\fbox{$\times$}} +\newcommand{\notselected}{\fbox{\phantom{$\times$}}} + +\begin{document} +\begin{longtable}{lrrrl} +\bfseries Question & \bfseries A & \bfseries B & +\bfseries C & \ifshowanswers \bfseries Reason\fi\\ +\selectrandomly{tabmchoice}{2} +\end{longtable} +\end{document} +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%</sample3.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%<*sample4.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +\documentclass[a4paper]{article} + +\usepackage{probsoln} + + % Sample file illustrating use of \selectallproblems + % All problems defined in specified file will be used + % in order of definition + +\showanswers + +\begin{document} +Differentiate the following functions: +\begin{enumerate} +\selectallproblems{easy} +\end{enumerate} +\end{document} +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%</sample4.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%<*sample5.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +\documentclass[a4paper]{report} + +\usepackage{probsoln} + +\begin{document} + +\hideanswers + +\chapter{Easy Problems} +\loadrandomproblems[easyproblems]{5}{easy2} + +\renewcommand{\theenumi}{\thechapter.\arabic{enumi}} +\begin{enumerate} +\foreachproblem[easyproblems]{\item\label{prob:\thisproblemlabel}\thisproblem} +\end{enumerate} + +\chapter{Probability Spaces} +\loadrandomproblems[probspaces]{2}{probspaces2} + +\renewcommand{\theenumi}{\thechapter.\arabic{enumi}} +\begin{enumerate} +\foreachproblem[probspaces]{\item\label{prob:\thisproblemlabel}\thisproblem} +\end{enumerate} + +\appendix +\chapter{Solutions} +\showanswers +\begin{enumerate} +\foreachdataset{\thisdataset}{% +\foreachproblem[\thisdataset]{\item[\ref{prob:\thisproblemlabel}]\thisproblem} +} +\end{enumerate} + +\end{document} +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%</sample5.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%<*tabmchoice.tex> +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} + % These problems are designed to be placed in a + % tabular environment + % +\newproblem{tab:1}{% +What is $(3+2)\times5$? & +25 \ifshowanswers\selected\else\notselected\fi & +13 \notselected & +10 \notselected & +}{Brackets come first}% + +\newproblem{tab:2}{% +What is $-1+2\times3$? & +3 \notselected & +-7 \notselected & +5 \ifshowanswers\selected\else\notselected\fi & +}{Multiplication comes first}% +% \end{macrocode} +%\fi +%\iffalse +% \begin{macrocode} +%</tabmchoice.tex> +% \end{macrocode} +%\fi %\Finale \endinput |