\documentclass{article}
\usepackage{amsmath,amscd}
\usepackage
    [tight,
     dvipsone,
     designi,
     nodirectory,
%     navibar
    ]{web}  % dvipsone, dvips, pdftex, dvipdfm
\usepackage{exerquiz}
\usepackage[vectors,ImplMulti]{dljslib}

\title{Extending the Exerquiz Package Special Processing}
\author{D. P. Story}
\subject{Sample file}
\keywords{LaTeX, PDF, derivative, calculus, JavaScript}

\university{THE UNIVERSITY OF AKRON\\
Theoretical and Applied Mathematics}
\email{dpstory@uakron.edu}
\version{3.0} \copyrightyears{1999-2001}

\makeatletter
\let\web@copyright=\@gobble
\makeatother

\newcommand\redpoint{\par\ifdim\lastskip>0pt\relax\vskip-\lastskip\fi
\vskip\medskipamount\noindent
  \makebox[\parindent][l]{\large\color{red}$\blacktriangleright$}}

\font\hv=cmtt10
\def\hvperk{\char`^}
%\font\hv=hv at 9pt
%\def\hvperk{\char142 }
{\catcode`\^=\active
\gdef\js{\bgroup\hv\catcode`\^=\active \let^=\hvperk \jsi}
}\def\jsi#1{#1\egroup}
\newcommand{\cs}[1]{\texttt{\char`\\#1}}

\newenvironment{sverbatim}
{\endgraf\footnotesize\verbatim}{\endverbatim\endgraf\noindent}

\def\optionalpagematter{\vfill\begin{center}\Huge\bfseries\color{webgray} Needs revision\end{center}}

\def\<{\langle}\def\>{\rangle}
\begin{document}

\maketitle
\tableofcontents

\section{Introduction}

The command \cs{RespBoxMath} is used to define a math fill-in
question. Normally, such a question takes a numerical answer, or
takes a function of a single variable, $x$, that reduces to a
number when $x$ is given a value.

When the user enters an answer into the response box, a
document-level JavaScript function, \texttt{ProcResp} is called to
process the answer. This function then calls another JavaScript
function called \texttt{random\-Point\-Compare}, which randomly
chooses points from a specified interval. For each of the points
chosen, \texttt{randomPointCompare} then calls the (default)
compare function to compare the author's answer with the user's
answer. The diagram below illustrates the normal program flow for
processing math fill-in questions.
{\small
\[
\begin{CD}
\text{\ttfamily User Input} @>>> \text{\ttfamily ProcResp} \\
&&     @VVV\\
\text{\ttfamily compare function} @<<< \text{\ttfamily randomPointCompare}
\end{CD}
\]}
Recently, \cs{RespBoxMath} and \texttt{ProcResp} have been
rewritten to allow the author to modify this normal program flow.
By specifying some optional arguments in the \cs{RespBoxMath}
command, the author can call a custom response function and use a
custom compare function as well. The sections that follow discuss
the methods of redirecting program flow and of writing new compare
and response functions. An extensive example is developed.


\section{\texorpdfstring{\protect\cs{RespBoxMath}}{\textbackslash RespBoxMath}}

The \cs{RespBoxMath} now has a ten parameters that can be used to
modify the default behavior of processing the user's input. Here is
the syntax:
\begin{verbatim}
\RespBoxMath[#1]#2(#3)[#4]#5#6#7#8[#9]*#10
\end{verbatim}
\noindent\textbf{Parameters:}
\begin{description}
 \item[\ttfamily\#1:] Optional parameter used to modify the appearance of the
     text field.
 \item[\ttfamily\#2:] The correct answer to the question.
     This must be a numerical value, or a function of one variable.
     JavaScript Note:
     In JavaScript, functions such as \texttt{sin(x)} and \texttt{cos(x)} are
     methods of the \texttt{Math} object.  It is not necessary, however, to
     type \texttt{Math.sin(x)} or \texttt{Math.cos(x)}; this is done by inserting
     the expression into a \texttt{with(Math)} group.
 \item[\ttfamily\#3:] An optional parameter, \textit{delimited by parentheses},
 that defines the independent variable; \texttt{x}, is the default value. Note
 that this parameter is set off by parentheses.  For a multivariate question, just
 list the variables in juxtaposition, \texttt{(xyz)}.
 \item[\ttfamily\#4:] Optional, a named destination to the solution to the
 question. If this parameter appears, then a solution must follow the
 question, enclosed in a \texttt{solution} environment.  There is
 an alternate forth parameter, a `\texttt*'. In this case, an
 automatic naming scheme is used.
 \item[\ttfamily\#5:] The number of samples points to be used, usually $3$ or $4$ is
 sufficient.
 \item[\ttfamily\#6:] Precision required, the $\epsilon$ value, if you will.
 \item[\ttfamily\#7:] Parameters \texttt{\#7} and \texttt{\#8} are  used to define the interval from
 which to draw the sample points. There are two forms: (1) \texttt{\#7} is the left-hand endpoint
 of the interval and \texttt{\#8} is the right-hand endpoint (the use of \texttt{\#7} and \texttt{\#8} in this form
 is deprecated); (2) the interval is defined by standard interval notation, \texttt{[a,b]}.
 For a multivariate question---one where parameter \texttt{\#2} lists more than one variable,
 separate the intervals for each variable by a `x', \texttt{[0,2]x[1,2]x[3,4]}. Here, `x' stands
 for Cartesian Product.
 \item[\ttfamily\#8:] (1) Parameter \texttt{\#8} is the right-hand endpoint of the interval (the use of this
 parameter is deprecated); (2) in the second case, \texttt{\#8} is not used.
 \item[\ttfamily\#9:] This optional parameter is the name of a customized
 comparison function.
 \item[\ttfamily\#10:] (Only detected if following an asterisk, `\texttt*')
 The name of a JavaScript function that is to be used to process the user input.
\end{description}

Parameters \texttt{\#9} and \texttt{\#10} can be used to specify
custom \textit{compare} and \textit{response} functions, respectively. The
compare function is discussed in \hyperref[s:compare]{Section~\ref*{s:compare}}
followed by a discussion of the response function in \hyperref[s:response]{Section~\ref*{s:response}}.


You can write  your own compare and response functions. An example
of a custom \emph{compare} function is given in the file
\texttt{jquiztst.tex} as well as in the preamble of this document;
this file also demonstrates a custom \emph{response} function. These
JavaScript functions are defined using the \textsf{insdljs} package.


\section{The Compare Function}\label{s:compare}

The way \textsf{exerquiz} determines whether a user's response to
a math fill-in question is by randomly choosing a number of points
(parameter \texttt{\#5}) from an interval of numbers (parameters
\texttt{\#7} and  \texttt{\#8}) and comparing the user's answer
with the author's provided answer (parameter  \texttt{\#2}). If at
any of the comparisons, the two answers differ by more than some
acceptable value (parameter \texttt{\#6}), the user's answer is
judged \emph{incorrect}.

The listing of the default compare functions follows:
\begin{sverbatim}
function diffCompare(_a,_c,_v,_F,_G) {
    var aXY = _c.split(",");
    var n = aXY.length
    with(Math) {
    for (var i=0; i< n; i++)
            eval ( "var "+_v[i] + " = " + aXY[i] + ";");
    _F = eval(_F);
    if ( app.viewerVersion >= 5)
    {
        var rtnCode = 0;
        eval("try { if(isNaN(_G = eval(_G))) rtnCode=-1; }"
            + " catch (e) { rtnCode=1; }");
        switch(rtnCode)
        {
            case  0: break;
            case  1: return null;
            case -1: return -1;
        }
    }
    else
        if(isNaN(_G = eval(_G))) return -1;
    return abs ( _F - _G );
    }
}
\end{sverbatim}
Where `\texttt{\_a}' is an string of comma delimited numbers
representing the endpoints of the intervals from which to sample
points; the parameter `\texttt{\_c}' is a comma delimited string
of randomly chosen point(s); the parameter `\texttt{\_v}' is a
string listing the independent variables of the questions;
`\texttt{\_F}' is the author's answer, and `\texttt{\_G}' is the
user's answer. (Note: We give these parameters special names,
beginning with an underscore, to protect the function from the
user. Without these underscores, it is possible for the user to
enter an answer such as `\texttt{cos(x) + c} the value of
`\texttt{c}' has been passed to function from the calling
function.  When we perform the \texttt{eval(G)}, the value for
`\texttt{c}' will be substituted in; this might lead to unexpected
results. It is unlikely, however, that the user will enter an
expression like `\texttt{cos(x) + \_c}.  With the underscores,
`\texttt{c}' is undefined, and an exception will be thrown.)

JavaScript~1.5, the core JavaScript used by Acrobat~5.0, now
throws an exception if an error occurs. (Prior versions of
JavaScript do not.) Typically, you can try to catch any critical
error, for better error handling. Notice the line
\begin{sverbatim}
eval("try { if(isNaN(_G = eval(_G))) rtnCode=-1; }"
    + " catch (e) { rtnCode=1; }");
\end{sverbatim}
We make the evaluation of \texttt{\_G} within a \texttt{try/catch}
Recall that expression the user enters is passed to this function
as the parameter \texttt{\_G}. If the user has entered any grossly
incorrect expression, an exception will be thrown when we try to
evaluate it at \texttt{\_c}.

In Acrobat 4.0--4.05, \texttt{try/catch} are reserved words and
cannot be used. Therefore, I have made the relevant code into a
string which gets evaluated, in the case the user is viewing the
document in Acrobat Reader~5.0 or above. If a Reader prior to 5.0
is being used, the reserved words are in a string, and are not
parsed by the JavaScript interpreter.

To understand the code, consider a simplified form of the \texttt{try/\-catch}:
\begin{sverbatim}
try { if(isNaN(_G = eval(_G))) return -1; }
catch (e) { return null; }
\end{sverbatim}
\noindent consider the following three examples.

\redpoint Example~1: User enter a good expression:
\begin{sverbatim}
var x = 4;
var _G = "Math.sqrt( x )";
try {
    if(isNaN(_G = eval(_G))) app.alert("-1");
        else app.alert("_G = " + _G);
} catch (e) { app.alert("null"); }
\end{sverbatim}
\noindent If this script is executed, \texttt{\_G = 2} appears in the alert box.

\redpoint Example~2: User enters a functions whose domain falls outside the domain of the
correct answer.  Suppose the user enters the expression, \texttt{sqrt( -x )}.
\begin{sverbatim}
var x = 4;
var _G = "Math.sqrt( -x )";
try {
    if(isNaN(_G = eval(_G))) app.alert("-1");
        else app.alert("_G = " + _G);
} catch (e) { app.alert("null"); }
\end{sverbatim}
When this script is executed, $-1$ is appears in the alert box; i.e., \texttt{iNaN} returned
a \texttt{true}. No exception was thrown here. This is considered an error. The user entered a function
the domain of which did not contain the range of numbers that are to be tested.

\redpoint Example~3: User enters an express that throws an exception:

\begin{sverbatim}
var x = 4;
var _G = "Math.sqrt( t )";
try {
    if(isNaN(_G = eval(_G))) app.alert("-1");
        else app.alert("_G = " + _G);
} catch (e) { app.alert("null"); }
\end{sverbatim}
The declaration of \texttt{\_G} has been changed to
\texttt{"Math.sqrt( t )"}. Now, when we try to evaluate
\texttt{G}, an exception is thrown, and \texttt{null} appears in the alert dialog.
The error message generated by this exception is
\texttt{ReferenceError:~t is not defined}. This kind of error is
considered a typo, and the user is not penalized.

\subsection{The \texttt{randomPointCompare} Function}

The compare function is called by \texttt{randomPointCompare}. It is this function
that randomly chooses a number of points from the specified interval, then calls
the compare function to evaluate and compare the correct answer with the user's answer.
It is \texttt{randomPointCompare} that processes the return value of the compare function.
Below is a snippet of \texttt{randomPointCompare} so you can see how it processes the return value
of the compare function.

\begin{sverbatim}
error = comp(a,cXY,indepVar,CorrAns,userAns);
if (error == null)
    return null;                        // this is considered a typo
if ( (error == -1) || (error > epsilon) )
{
    j=-1;                               // j=-1 signals an error
    break;
}
\end{sverbatim}


\section{A Custom Compare Function}
The custom compare function in the preamble of this document does
a compare appropriate to comparing two indefinite integrals. We list the version
of this compare function that uses \texttt{try/catch}, Acrobat Reader~5.0 or later
is needed.
\begin{sverbatim}
function indefCompare(_a,_c,_v,_F,_G) {
    var eqC;
    var aAB = _a.split(",");
    var aXY = _c.split(",");
    var n = aXY.length
    with(Math) {
        for (var i=0; i< n; i++)
            eval ( "var "+_v[i] + " = " + aAB[2*i] + ";" );
% var C = 0 is used to designate an arbitrary constant
        var C = 0;
        if ( app.viewerVersion >= 5)
        {
            var rtnCode = 0;
            eval("try {"
                + " if(isNaN(eqC = eval(_F)-eval(_G))) rtnCode=-1;}"
                + " catch (e) { rtnCode=1; }");
            switch(rtnCode)
            {
                case  0: break;
                case  1: return null;
                case -1: return -1;
            }
        }
        else
            if (isNaN(eqC = eval(_F)-eval(_G))) return -1;
        for (var i=0; i< n; i++)
            eval ( "var "+_v[i] + " = " + aXY[i] + ";" );
        _F = eval(_F);
        if ( app.viewerVersion >= 5)
        {
            var rtnCode = 0;
            eval("try { if(isNaN(_G = eval(_G))) rtnCode=-1; }"
                + " catch (e) { rtnCode=1; }");
            switch(rtnCode)
            {
                case  0: break;
                case  1: return null;
                case -1: return -1;
            }
        }
        else
            if(isNaN(_G = eval(_G))) return -1;
        return abs( _F - _G - eqC );
    }
}
\end{sverbatim}
First, we evaluate each at the left-hand endpoint
(\texttt{\_a}) and store this value as \texttt{eqC}. Then we compare the
two function \texttt{\_F} and \texttt{\_G} and the randomly supplied
point \texttt{\_c}. We then return the \texttt{abs(\_F - \_G - eqC)}. If
the two supplied are both correct, they would differ by a
constant.

Here is an example of usage of this custom compare function:
%
\begin{oQuestion}{indefInt}
\redpoint$\displaystyle\int \sin(x)\,dx =
\RespBoxMath{-cos(x)}[intSin]{4}{.0001}01[indefCompare]\kern1bp
\CorrAnsButton{-cos(x)}\kern1bp\sqTallyBox\kern1bp\sqClearButton$
\begin{solution}
\begin{equation*}
        \int \sin(x) \,dx = -\cos(x) + C
\end{equation*}
\end{solution}
\end{oQuestion}


\section{The Response Function}\label{s:response}

The \textit{response} function is a JS function that is called when
the math fill-in data is committed by the user. Basically, it strips out
all white space; calls \texttt{ParseInput()} (which scans the user input
for syntax errors, converts exponents to the \texttt{pow()} functions, etc.);
calls \texttt{randomPointCompare()} which returns \texttt{true} or \texttt{false}
depending on whether the user's answer was close enough to the author's answer;
and finally, notifies the field of the result (calls \texttt{notifyField()}).

The default response function is the JavaScript
\texttt{ProcResp()}, but this function can be replaced by a
``custom response function'', such as the one in the preamble of
this document. The listing of \texttt{ProcResp()} follows:

\begin{sverbatim}
function ProcResp(flag,CorrAns,n,epsilon,a,indepVar,comp)
{
    if (!ProcessIt) return null;
    ok2Continue = true;
    var success;
    var fieldname = event.target.name;
    var UserAns = event.value;
    CorrAns = ParseInput(CorrAns);
    if (!ok2Continue) {
        app.alert("Syntax error in author's answer!"
            + " Check console.", 3);
        console.println("Syntax Error: " + CorrAns);
        return null;
    }
    UserAns = ParseInput(UserAns);
    if (!ok2Continue) return null;
    success=randomPointCompare
        (n,a,indepVar,epsilon,CorrAns,UserAns,comp)
    if ( success == null )
        { app.alert(\eqSyntaxErrorUndefVar,3); return null; }
    return notifyField(success, flag, fieldname);
}
\end{sverbatim}
\noindent \texttt{ProcResp} takes eight arguments, {\ttfamily
flag, CorrAns, n, epsilon, a, b, indepVar, comp}. The
\texttt{flag} indicates whether we are in `silent mode' (no
immediate reporting back of results); obviously, \texttt{CorrAns}
is the author's correct answer; \texttt n is the number of points
to sample; \texttt{epsilon} is the acceptance level; arguments
\texttt a and \texttt b are the left and right hand endpoints,
respectively; \texttt{indepVar} is a string indicating the
independent variable, the default is \texttt{"x"}; and finally,
\texttt{comp} is the name of the compare function that is to be
called.

The JS function \texttt{changeToX} uses regular expressions to replace
the declared \texttt{indepVar} with an internal variable. After changing
variables, we call \texttt{randomPointCompare}, then \texttt{notifyField}
of the results.

\redpoint\textcolor{red}{Important: }Any custom response function must use
the above eight arguments, and finish off by returning a
\texttt{true} or \texttt{false} value. In the above example, the
return value of \texttt{notifyField} is used.

\section{Demo: Quizzes}

We illustrate the \texttt{ProcVec} and \texttt{indefCompare}
function through a \texttt{shortquiz} and \texttt{quiz} by
extending \textsf{exerquiz} to be able to process vector answers.
Other extensions are possible, such as processing functions of
several variables, for example.

%Note that \hyperref[item:indef] {Problem~\ref*{item:indef}}
%demonstrates the full range of parameters of the \cs{RespBoxMath}
%command.

\redpoint Click on the ``Ans'' button to see the answer. If the
``Ans'' button has a green boundary, that problem has a solution.
Shift-click on ``Ans'' to jump to the solution.


\newpage
\subsection{A shortquiz}

\textcolor{red}{Instructions:} Enter vectors with angle brackets,
e.g., \js{<1,2,3>}. You can also enter scalar multiples of vectors,
e.g.,  \js{4*<1,2,3>}.

\begin{shortquiz}[vectorSQ]
\noindent Let $\vec a =  \< 1, 2, 3 \>$, $\vec b =  \<3, 2, 1\> $ and
$\vec f(t) = \< e^t, t^2, \sin(t)\>$. Calculate each of the following.

\begin{questions}

\item $\vec a + \vec b = \RespBoxMath{<4, 4, 4>}{1}{.0001}24*{ProcVec}$
\hfill\CorrAnsButton{<4, 4, 4>}\kern1bp\sqTallyBox

% \item $2\vec a - 3\vec b = \RespBoxMath{<-7, -2, 5>}{1}{.0001}24*{ProcVec}$
% \hfill\CorrAnsButton{<-7, -2, 5>}\kern1bp\sqTallyBox

\item $\vec a\cdot\vec b =\RespBoxMath{10}{1}{.0001}24$
\hfill\CorrAnsButton{10}\kern1bp\sqTallyBox

\item $\vec a \times\vec b =\RespBoxMath{<-4, 8, -4>}[axb]{1}{.0001}24*{ProcVec}$
\hfill\CorrAnsButton{<-4, 8, -4>}\kern1bp\sqTallyBox
\begin{solution}
We load the vectors $$\vec a =  < 1, 2, 3 >\text{ and }\vec b =  <3, 2, 1> $$ into
a $3\times 3$ determinant, like so:
\begin{align*}
    \vec a\times\vec b &
        = \begin{vmatrix}
                \vec i & \vec j & \vec k\\
                   1   &    2   &    3 \\
                   3   &    2   &    1
        \end{vmatrix} \\&
        = \begin{vmatrix}2&3\\2&1\end{vmatrix}\vec i -
          \begin{vmatrix}1&3\\3&1\end{vmatrix}\vec j +
          \begin{vmatrix}1&2\\3&2\end{vmatrix}\vec k \\&
        = (2-6)\vec i - (1-9)\vec j + (2-6)\vec k \\&
        = -4\vec i + 8\vec j - 4\vec k \\&
        = <-4, 8, -4> \\&
        = 4 <-1, 2, -1>
\end{align*}
\end{solution}

\item $\vec f'(t) =
\RespBoxMath{<e^t, 2*t, cos(t)>}(t){3}{.0001}{0}{1}*{ProcVec}$
\hfill\CorrAnsButton{<e^t, 2*t, cos(t)>}\kern1bp\sqTallyBox

\item\label{item:indef} $\displaystyle\int \vec f(t)\,dt =
\RespBoxMath{<e^t, t^3/3, -cos(t)>}(t)[diffvec]{3}{.0001}{0}{1}[indefCompare]*{ProcVec}$
\hfill\CorrAnsButton{<e^t, t^3/3, -cos(t)>}\kern1bp\sqTallyBox
\begin{solution}
We simply integrate componentwise:
\begin{align*}
\int \vec f(t)\,dt &
    = \int \<\, e^t, t^2, \sin(t)\,\>\,dt \\&
    = \< \int e^t\,dt, \int t^2\,dt, \int \sin(t)\,dt\> \\&
    = \<e^t, \tfrac 13 t^3, -\cos(t)\> + \vec C
\end{align*}
In the syntax of this document, the answer is
\js{<e^t,t^3/3,-cos(t)>}.
\end{solution}
\end{questions}
\end{shortquiz}
\begin{flushright}
\sqClearButton\kern1bp\sqTallyTotal
\end{flushright}

\NewPage

\subsection{A quiz}

\textcolor{red}{Instructions: } Same instructions as in the \texttt{shortquiz}.

\begin{quiz}*{vectorQ}
\noindent Let $\vec a =  \< 1, 2, 3 \>$, $\vec b =  \<3, 2, 1\> $ and
$\vec f(t) = \< e^t, t^2, \sin(t)\>$.
Calculate each of the following.
\begin{questions}

\item $\vec a + \vec b = \RespBoxMath{<4, 4, 4>}{1}{.0001}24*{ProcVec}
\CorrAnsButton{<4, 4, 4>}$

% \item $2\vec a - 3\vec b = \RespBoxMath{<-7, -2, 5>}{1}{.0001}24*{ProcVec}
% \CorrAnsButton{<-7, -2, 5>}$

\item $\vec a\cdot\vec b =\RespBoxMath{10}{1}{.0001}24
\CorrAnsButton{10}$

\item $\vec a \times\vec b =\RespBoxMath{<-4, 8, -4>}[axbq]{1}{.0001}24*{ProcVec}
\CorrAnsButton{<-4, 8, -4>}$
\begin{solution}
We load the vectors $$\vec a =  < 1, 2, 3 >\text{ and }\vec b =  <3, 2, 1> $$ into
a $3\times 3$ determinant, like so:
\begin{align*}
    \vec a\times\vec b &
        = \begin{vmatrix}
                \vec i & \vec j & \vec k\\
                   1   &    2   &    3 \\
                   3   &    2   &    1
        \end{vmatrix} \\&
        = \begin{vmatrix}2&3\\2&1\end{vmatrix}\vec i -
          \begin{vmatrix}1&3\\3&1\end{vmatrix}\vec j +
          \begin{vmatrix}1&2\\3&2\end{vmatrix}\vec k \\&
        = (2-6)\vec i - (1-9)\vec j + (2-6)\vec k \\&
        = -4\vec i + 8\vec j - 4\vec k \\&
        = <-4, 8, -4> \\&
        = 4 <-1, 2, -1>
\end{align*}
\end{solution}

\item $\vec f'(t) =
\RespBoxMath{<e^t, 2*t, cos(t)>}(t){3}{.0001}{0}{1}*{ProcVec}
\CorrAnsButton{<e^t, 2*t, cos(t)>}$

\item $\displaystyle\int \vec f(t)\,dt =
\RespBoxMath{<e^t, t^3/3, -cos(t)>}(t)[diffvecq]
{3}{.0001}{0}{1}[indefCompare]*{ProcVec}
\CorrAnsButton{<e^t, t^3/3, -cos(t)>}$

\begin{solution}
We simply integrate componentwise:
\begin{align*}
\int \vec f(t)\,dt &
    = \int \<\, e^t, t^2, \sin(t)\,\>\,dt \\&
    = \< \int e^t\,dt, \int t^2\,dt, \int \sin(t)\,dt\> \\&
    = \<e^t, \tfrac 13 t^3, -\cos(t)\> + \vec C
\end{align*}
In the syntax of this document, the answer is
\js{<e^t,t^3/3,-cos(t)>}.
\end{solution}
\end{questions}
\end{quiz}\quad\ScoreField\currQuiz\eqButton\currQuiz

\noindent
Answers: \AnswerField\currQuiz


\end{document}
