<m>...</m>
tags. For some reason, the text goes between <startouttext/> and <endouttext/>
tags. The responses go in response tags. There are many types: the usual ones like numerical, string, and options, but the math response is what distinguishes Lon-Capa from alternative such software. (There are other types of responses, too.) The math responses lets the student input something that either R or Maxima can understand and evaluate.
<numericalresponse answer="2"> <responseparam type="tolerance" default="0.005" name="tol" description="Numerical Tolerance" /> <textline size="10"></textline> </numericalresponse> <stringresponse answer="NaN" type="ci"> <textline size="10"></textline> </stringresponse> <formularesponse answer="a*b/(a+b)"> <textline size="10"></textline> </formularesponse>The tolerance is optional. The default can also be a percentage, e.g., "2%". For the string response, type is "cs" or "ci", depending on whether the answer should be case sensitive or not. (There is also "mc", multiple choice.) The formula response is nice because the student can put in any formula that evaluates to the answer.
<radiobuttonresponse max="10" randomize="yes" direction="vertical"> <foilgroup> <foil location="random" value="true" name="foil1"> <startouttext />This is foil One.<endouttext /> </foil> <foil location="random" value="true" name="foil2"> <startouttext />This is foil Two.<endouttext /> </foil> <foil location="random" value="false" name="foil3"> <startouttext />This is foil Three.<endouttext /> </foil> <foil location="random" value="false" name="foil4"> <startouttext />This is foil Four.<endouttext /> </foil> <foil location="random" value="false" name="foil5"> <startouttext />This is foil Five.<endouttext /> </foil> </foilgroup> </radiobuttonresponse>Other attributes:
<radiobuttonresponse max="10" randomize="no" direction="horizontal"> <foilgroup> <foil value="true" name="foil1"> <startouttext />Yes<endouttext /> </foil> <foil value="false" name="foil2"> <startouttext />No<endouttext /> </foil> </foilgroup> </radiobuttonresponse>What if you want a drop-down box? See next type of question.
<optionresponse max="10" randomize="yes"> <foilgroup options="('Green','Red','Blue')"> <foil location="random" value="Green" name="Foil1"> <startouttext />This is foil One. It is currently set to "Green."<endouttext /> </foil> <foil location="random" value="Red" name="Foil2"> <startouttext />This is foil Two. It is currently set to "Red."<endouttext /> </foil> <foil location="random" value="Blue" name="Foil3"> <startouttext />This is foil Three. It is currently set to "Blue."<endouttext /> </foil> <foil location="random" value="Red" name="Foil4"> <startouttext />This is foil Four. It is currently set to "Red."<endouttext /> </foil> </foilgroup> </optionresponse>The choices are the options within the foilgroup tag. Rather than radio buttons, the options are shown within drop-down boxes, one for each foil.
Thus, if you want a regular multiple choice but with a drop-down box, you use just one foil (still within a foilgroup):
<optionresponse max="10"> <foilgroup options="('Green','Red','Blue')"> <foil value="Green" name="the_foil"> <startouttext />The only foil.<endouttext /> </foil> </foilgroup> </optionresponse>[Compare this with the multiple choice using radio responses. There, the choices are the foils, and the values are true/false, though the student doesn't see these values explicitly. But here, the choices are the values, and the foil is the question.] To situate the dropdown box within the foil text, use <drawoptionlist /> at the desired location.
The following sets up a question where the correct answer is to check foils 1, 3, and 5. They are the ones whose value is true.
<optionresponse max="10" randomize="no"> <foilgroup options="('True','False')" checkboxvalue="True" checkboxoptions="nochoice"> <foil name="Foil1" value="True"> <startouttext />This is foil One. It is currently set to "True."<endouttext /> </foil> <foil name="Foil2" value="False"> <startouttext />This is foil Two. It is currently set to "False."<endouttext /> </foil> <foil name="Foil3" value="True"> <startouttext />This is foil Three. It is currently set to "True."<endouttext /> </foil> <foil name="Foil4" value="False"> <startouttext />This is foil Four. It is currently set to "False."<endouttext /> </foil> <foil name="Foil5" value="True"> <startouttext />This is foil Five. It is currently set to "True."<endouttext /> </foil> <foil name="Foil6" value="False"> <startouttext />This is foil Six. It is currently set to "False."<endouttext /> </foil> </foilgroup> </optionresponse>
All one needs to do is wrap the desired responses in a <part> </part>
environment. One warning: If there is at least one part, then every response has to be within some part's environment.
But the real power comes in randomizing the actual questions students see, e.g., one can randomly generate numbers or formulas within questions. Almost anything can be done through scripting. The basic scripting language for Lon-Capa is perl, but with many added functions, including those that can interface with R and Maxima. Scripting can be used within the script environment in the problem, as well as within the answer environment within problems.
$a
and $b
. We first have to set the script environment, where type="loncapa/perl" specifies perl with the added functions. The most useful function is &random($l,$u,$d)
, which returns a random number between $l
and $u
, in steps of $d
. (There are also a number of functions for simulating from specific distributions.) So if we want our beta parameters to be integers between 2 and 10, we'd use
<script type="loncapa/perl"> $a = &random(2,10,1); $b = &random(2,10,1); $mu = $a/($a+$b); </script>Note we've also put the mean of the beta in the variable
$mu
. Now within the text, we can use $a
and $b
directly. So the question could be
<startouttext /> Find the mean of a Beta($a,$b) random variable. <endouttext />Or, if we want it to look more math-y, we can use TeX, but add the eval="on" attribute in the math tag:
<startouttext /> Find the mean of a <m eval="on">$Beta($a,$b)$</m> random variable. <endouttext />Also, and quite importantly, we can put the
$mu
in the answer. This problem uses a numerical response:
<numericalresponse answer="$mu"> <responseparam type="tolerance" default="0.01" name="tol" description="Numerical Tolerance" /> <textline size="10"></textline> </numericalresponse>
<mathresponse answerdisplay="1/3" cas="R"> <answer> abs(RESPONSE[1]-1/3)< 0.001 </answer> <textline readonly="no" size=" 8 " /> </mathresponse>Within the answer block you can put any sequence of R statements, as long as the final one returns true or false. The student's input is placed in the
RESPONSE
array, the components consisting of the comma-separated input. (I mean "a,12,log(18)" resolves to RESPONSE[1]="a", RESPONSE[2] = "12", RESPONSE[3] = "log(18)"
.) To get scripting variables (like $x
) into the answer block, add in the args
attribute to the math response tag. This attribute can then be set to another comma-separated list. Elements are specified using LONCAPALIST[i]
. E.g., using the beta example from above, one could code the response block as
<mathresponse answerdisplay="$mu" cas="R" args="$mu"> <answer> abs(RESPONSE[1]-LONCAPALIST[1])< 0.001 </answer> <textline readonly="no" size=" 8 " /> </mathresponse>Maxima can be used in the answer block by specifiying cas="maxima".
The custom response type uses perl to evaluate the input. Since it is perl, the scripting variables can be used as is. The student's input is in the variable $submission
. (If there are several input fields in the question, then the inputs will be in $$submission[1], $$submission[2]
, etc.) The perl code has to return a special Lon-Capa word indicating the result of the evaluation. There are about ten of them, but the two simplest are EXACT_ANS
, meaning the student is correct, and INCORRECT
. The beta response block would then be written
<customresponse answerdisplay="$mu"> <answer type="loncapa/perl"> if(abs($submission-$mu)< 0.001) {return('EXACT_ANS');} return("INCORRECT"); </answer> <textline readonly="no" size=" 8 " /> </customresponse>
&cas($w,$s,$l)
and &cas_hashref($w,$s,$l)
. The first argument is a string indicating which language to use, "R" or "maxima". The second argument is a string containing the commands to use. The third lets you specify libraries to load, but I'm not sure how it works in R. The commands will return either a singleton, a vector, a matrix, or a list. (I think that's about it.) If the result is one of the first three types, then the first function &cas
can be used. The output will be a string of the values, e.g., "1 2 3 4". The matrix structure is lost. This is a good choice if the answer is a singleton. For example, if you want the correlation between two independent random uniform vectors of size three, the following statement (within a script block) would place the correlation in $cor
.
$cor = &cas("R","x<-runif(3);y<-runif(3);cor(x,y)");The function
&cas_hashref
can always be used, and for lists it is the only one that works. Its output is a vector of two strings. The first is the address (I guess) of the result of the R calculations, or the value if the result is a singleton. The second is a dump of the result. For example, consider doing a regression with the above vectors: ($data,$dump) = &cas_hashref("R","x<-runif(3);y<-runif(3);lm(y~x);");Then
$data
is HASH(0x55555ec16330)
, and $dump
is $VAR1 = { 'coefficients' => \{ '(Intercept)' => '-0.5160445', 'x' => '1.868763' }, 'residuals' => \{ '1' => '-0.7194856', '2' => '0.3506257', '3' => '0.3688598' }, 'effects' => \{ '(Intercept)' => '-0.7298277', 'x' => '-1.269063', 'result2' => '0.8812806' }, 'rank' => '2', 'fitted.values' => \{ '1' => '0.4062064', '2' => '1.326213', '3' => '-0.4683212' }, 'assign' => \{ '1' => '0', '2' => '1' }, 'qr' => \{ 'qr' => \{ '1' => \{ '1' => '-1.732051', '2' => '-0.8688332' }, '2' => \{ '1' => '0.5773503', '2' => '-0.6790929' }, '3' => \{ '1' => '0.5773503', '2' => '-0.6966859' } }, 'qraux' => \{ '1' => '1.577350', '2' => '1.717376' }, 'pivot' => \{ '1' => '1', '2' => '2' }, 'tol' => '1e-07', 'rank' => '2' }, 'df.residual' => '1', 'xlevels' => \{}, 'call' => \{ '1' => 'lm', '2' => 'y ~ x' }, 'terms' => \{ '1' => '~', '2' => 'y', '3' => 'x' }, 'model' => \{ 'y' => \{ '1' => '-0.3132791', '2' => '1.676839', '3' => '-0.09946135' }, 'x' => \{ '1' => '0.4935089', '2' => '0.985817', '3' => '0.02553737' } } };
$data
element. (You can ignore the $dump
info.) To obtain a single value, use the entry form of the function. E.g., the slope of the regression is in the "x" element of the "coefficients" list. Thus $slope = &cas_hashref_entry($data,"coefficients","x");yields the slope. An element of an array is obtained similarly. For example, to find an element of the outer product of the two vectors:
($data2,$dump2) = &cas_hashref("R","x<-runif(3);y<-runif(3);outer(x,y);"); $z = &cas_hashref_entry($data2,"2","3");gets the (2,3) element of the matrix. To extract a vector, into a perl array, use the array form. For example, to obtain the residuals from the above regression, use
@resid = &cas_hashref_array($data,"residuals");For more information, including for Maxima, see http://www.lon-capa.org/cas.html
<m>$E[X] = \frac{\Gamma(\alpha+\beta)}{\Gamma(\alpha)\Gamma(\beta)}.$</m>Use $$ for display. If you want scripting variables, like $a, to be evaluated within the TeX, then add the eval="on" attribute to the tag:
<m on="eval">$E[X] = \frac{\Gamma($a+$b)}{\Gamma($a)\Gamma($b)}.$</m>