Skip to main content

Math in questions

If you have a question where a student has to calculate a result form given
data it would be nice if you did not have to give fixed ranges for the correct
answer, but if the question calculated those from the given data. It would
also be nice if the question would give different numbers each time a student
makes the question. That is now possible with ClosedQuestion using the
<matheval /> and <mathresult />
tags.

Lets start with an example:

<?xml version="1.0" encoding="UTF-8"?>
<question type="fillblanks">
  <matheval expression="a=random()" store="1" />
  <matheval expression="b=random()" store="1" />
  <matheval expression="a=round(a*0.8+0.11,2)" />
  <matheval expression="b=round(b*5+2,0)" />
  <matheval expression="ans=a*b" />
  <matheval expression="min=min(round(ans,1),(ans-0.01))" />
  <matheval expression="max=max(round(ans,1),(ans+0.01))" />

  <text>
    <p>You have measured a concentration of <mathresult expression="a" />mg/ml in a <mathresult expression="b" />-times diluted sample.<br/>
       What was the concentration in the non-diluted solution?</p>
    <p><b>The original concentration was: <inlineChoice identifier="c" freeform="1" />g/l</b></p>
  </text>

  <hint mintries="1">That's not correct.</hint>
  <hint mintries="2">The concentration in the non-diluted solution is higher than the measured concentration.</hint>
  <hint mintries="3">The correct answer is: <mathresult expression="a" /> * <mathresult expression="b" /> = <mathresult expression="ans" />.</hint>

  <mapping correct="1">
    <range inlineChoice="c" minval="min" maxval="max" />
    <feedback>Very good.</feedback>
  </mapping>

  <mapping correct="0" stop="1">
    <not><match inlineChoice="c" pattern="^[+-]?[0-9]+(\.[0-9]+)?(e[+-]?[0-9]+)?$" /></not>
    <feedback>Please give a number.</feedback>
  </mapping>
</question>

There are two new tags in this example: <matheval />
and <mathresult />.

The <matheval /> tag evaluates an expression. The
<mathresult /> tag evaluates an expression AND puts the
result in it's place in the text.

The example first generates two random numbers (between 0 and 1) and stores
those in variables a and b.

store="1" in a <matheval /> means all variables
up to that expression are stored and loaded the next time a student visits the
question. Expressions with store="1" are only evaluated on the first visit. So
in our example the values of variable a and b are stored. This makes sure that
when the student "reloads" the page to give his answer, the variables stay the
same.

Next the variables a and b, that have a value between 0 and 1, are changed to
have the required range and precision. Variable a is now between 0.11 and 0.91
with a two decimal precision, while b is a whole number between 2 and 7.

Then the answer is calculated from a and b, and stored in the variable ans.

Lastly the minimum and maximum values that will be considered "correct" are
calculated form ans. By using this trick with min() and round() we make sure
that the student has to give a precision of at least one decimal, but can give
more if he wants to.

In the question text the different variables are displayed.

When a <range> tag finds a non-numeric value in the minval
or maxval attributes it will check of the given value is a math variable
that was previously defined. If so, it will use the value of that variable.

Functions that are built-in:

sin, sinh, asin, asinh, cos, cosh, acos, acosh, tan, tanh, atan, atanh, sqrt,
abs, log, round, floor, ceil, min, max, number_format, lcg_value

Function aliases:

  • ln = log
  • arcsin = asin
  • arccos = acos
  • arctan = atan
  • arcsinh = asinh
  • arccosh = acosh
  • arctanh = atanh
  • random = lcg_value
  • nf = number_format