-
Notifications
You must be signed in to change notification settings - Fork 1
Writing Exercises: Answer Types
There are a few answer types available. You can specify what type of answer is expected by using the data-type
attribute on the .solution
element.
-
text
It compares the answer strings literally; no numerical interpretation is done at all (e.g.,
1.0
would be marked incorrect if the answer was1
, even though they're numerically equal). The only text transformation is to strip leading and trailing whitespace before comparison.<p class="solution" data-type="text"><var>ANSWER</var></p>
-
radio (default if
ul.choices
present)If you want the user to pick an answer from a list, you can provide the possible choices that you want the user to select from, using an un-ordered list. You'll need to add an UL with a class of
choices
inside of your main problem container.<p class="solution"><code><var>A</var>x <var>BP + B</var></code></p> <ul class="choices"> <li><code><var>-1 * A</var>x <var>BP + B</var></code></li> <li><code><var>A</var>x <var>BN + (-1 * B)</var></code></li> <li><code><var>B</var>x <var>AP + A</var></code></li> <li><code><var>-1 * B</var>x <var>AN + (-1 * A)</var></code></li> </ul>
The above markup will generate a problem that has 5 possible choices to choose from, one of which is the valid solution. Note that when you use multiple choice formatting you can let the user pick from more-complicated answers (such as formulas). Do not put the correct answer among the choices, unless you are using category.
Example: Limits 2
The framework also gives you the ability to provide more possible choices than what may actually be displayed. For example you could provide a total of 5 choices (1 solution + 4 other choices) but only show 3 of them (1 of which will always be the valid answer).
<ul class="choices" data-show="3"> ... </ul>
Example: Plugging in Values
Additionally the framework provides a mechanism for supplying a "None of the above" choice as a viable option. All you would need to do is supply a
data-none="true"
attribute on your choices UL to enable it, like so:<ul class="choices" data-show="5" data-none="true"> ... </ul>
In this example, 5 possible choices will be displayed - one of which will be the "None of the above" choice. It's possible that the valid solution will be hidden and that "None of the above" will be the correct answer.
Example: Multiplying Polynomials
-
list If your exercise involves asking the user something like an inequality, where you want the answer or part of the answer to be one of a list of options, you can have the answer come from a drop down menu.
Here is an example of how this works:
<p class="solution" data-type="multiple"> <code>x</code> <span class="sol" data-type="list" data-choices="['', '<', '>', '≤', '≥']"> </span> <span class="sol" data-type="rational"><var>( D - B ) / ( A - C )</var></span></p>
This produces drop down menu in the answer area with <, >, <= and >= options and then a free answer box with type rational. Thus, the list answer type takes in an array and outputs a drop down menu.
Example: Range of a Function
-
category (a type of radio)
If your exercise involves asking the user to choose from the same set of choices displayed in the same order every time, supply a
data-category="true"
attribute. Note that you should supply the solution in the unordered list as well (Normal radio answers only have wrong answers in the unordered list.).<div class="solution">Acute</div> <ul class="choices" data-category="true"> <li>Acute</li> <li>Right</li> <li>Obtuse</li> </ul>
Example: Scaling Vectors
-
decimal(decimal)
Just like text except it compares numerical equality. With
decimal
,1.0
is the same as1
, but no other evaluation is done so fractions and the like don't work.<p class="solution" data-type="decimal">1.0</p>
Example: Units
If an error margin needs to be allowed in the answer, as is the case in many statistics problems, you can specify the amount of error that is to be allowed.
<p class="solution" data-inexact data-max-error="0.1" data-type="decimal">1.0</p>
Example: Standard Deviation
-
rational
Compares two fractions for equality. Under the hood, it converts both to decimals so the contents of
p.solution
should actually be a decimal version of the correct answer. You can accomplish this usingvar
:<p class="solution" data-type="rational"><var>2/3</var></p>
Example: Subtracting Fractions
By default, answers must be reduced to be considered correct. (
4/6
would not be a correct answer.) If you want to specifically allow unsimplified answers, adddata-simplify="optional"
to the element containing the solution. -
radical
Use this type if your answer involves a radical, like in the Simplifying Radicals exercise. Specify the coefficient and the part under the radical in separate
span
tags.<div class="solution" data-type="radical"> <span><var>COEFFICIENT</var></span><span><var>RADICAL</var></span> </div>
Example: Pythagorean Theorem 1
-
line
Use this if the answer is a function, like 2(3x + 7)/5. Currently being developed.
-
regex
Just what it sounds like. Omit the delimiting slashes but include
^
and$
if appropriate. To match the four smilies:)
,;)
,:P
,;P
:<p class="solution" data-type="regex">^[:;][\)P]$</p>
-
multiple
This special type allows you to have a composite of other answer forms as an answer. The "Slope Intercept Form" exercise uses this to ask the user for the slope
m
and y-interceptb
of a line:Example: Slope Intercept Form
<div class="solution" data-type="multiple"> <p><code>m</code> = <span class="sol" data-type="rational"><var>M</var></span></p> <p><code>b</code> = <span class="sol" data-type="rational"><var>B</var></span></p> </div>
The code inside the solution will be copied into the solution area and each
.sol
element will be interpreted as if it was its own answer. In this case, you'll get a form that asks form
andb
and gives two separate text entry boxes. Sincedata-type="rational"
was specified on each.sol
element, each text box acts like a single rational answer.Answers are marked correct only if all of the parts are correct. Having a radio input as a part of an answer has not been tested. (You probably don't need more than one radio input, anyway.)
Since multiple-type answers can vary wildly in what they expect from the user, the framework won't show the predefined "acceptable answers," unlike with most of the default answer types. Instead, you should define your own examples inside the solution block to help the user answer properly:
<div class="solution" data-type="multiple"> <p><code>m</code> = <span class="sol" data-type="rational"><var>M</var></span></p> <p><code>b</code> = <span class="sol" data-type="rational"><var>B</var></span></p> <p class="example"><code>m</code> = a <em>simplified proper</em> fraction, like <code>3/5</code></p> <p class="example"><code>b</code> = a <em>simplified proper</em> fraction, like <code>2/5</code></p> </div>
-
set
This special type permits one or more correct answers to be entered in any order. You provide a list of correct answers and indicate how many of them you want. If you provide more answers than inputs, the student can enter any subset. If you provide more inputs than answers, the student must leave some boxes blank.
This example allows the user to provide two answers that can be entered in either order. In this case, the solutions to a quadratic equation:
<div class="solution" data-type="set"> <div class="set-sol"><var>A</var></div> <div class="set-sol"><var>B</var></div> <div class="input-format"> <p><code>x = </code><span class="entry"></span> or</p> <p><code>x = </code><span class="entry"></span></p> </div> <p class="example">two integers like <code>6</code> or <code>9</code></p> </div>
The code consists of three sections: the
set-sol
elements, theinput-format
element, and theexample
elements. Theset-sol
elements list the correct answers to the question. In the example above, it's the values of the variables A and B. Theinput-format
section defines what the solution area looks like to the student. Within theinput-format
element, you also provide one or moreentry
elements to create blanks where the student will enter his or her answer. In the example above, there are twoentry
elements, so the student would be expected to provide two answers (A and B, but in either order). Theexample
elements function in the same way as described in multiple above.The next example provides two right answers, and the user may enter either one of them:
<div class="solution" data-type="set"> <div class="set-sol"><var>X1</var></div> <div class="set-sol"><var>X2</var></div> <div class="input-format"> <p><code>x = \quad</code><span class="entry"></span><code></p> </div> <p class="example">an integer, like <code>6</code> </div>
Because there is only one
entry
element in theinput-format
, there will only be a single text box to enter an answer. Because there are fewerentry
elements (one) than correct answers (twoset-sol
elements), the user is allowed to enter either answer. You can extend this by providing any number of inputs and/or correct answers.The next example is like the previous in that there are two correct answers and the user may enter either one of them, but in this case the answers are themselves
multiple
answers. In other words this requires the student to provide (X1 and Y1 and SLOPE) or (X and Y and SLOPE):<div class="solution" data-type="set"> <div class="set-sol" data-type="multiple"> <span class="sol"><var>X1</var></span> <span class="sol"><var>Y1</var></span> <span class="sol"><var>SLOPE</var></span> </div> <div class="set-sol" data-type="multiple"> <span class="sol"><var>X</var></span> <span class="sol"><var>Y</var></span> <span class="sol"><var>SLOPE</var></span> </div> <div class="input-format"> <p class="entry" data-type="multiple"> <code>\text{x1 = }</code><span class="sol"></span><br /> <code>\text{y1 = }</code><span class="sol"></span><br /> <code>\text{m = }</code><span class="sol"></span> </p> </div> </div>
In this example, the user is asked to provide two numbers that multiply to 15. The solution type is going to be "multiple", since the answer could be "3 and 5" or "1 and 15", but not "5 and 15" as the second factor depends on the first. Let's say you have defined a variable that is an array of the factors of 15:
<div class="vars"> <var id="FACTORS">[1, 3, 5, 15]</var> </div>
The solution can be implemented by utilizing the "set" and "multiple" solution types as in the example above, iterating through the array of factors and defining the second acceptable answer as 15 divided by the current element. Notice the use of
data-each
when setting the solutions.<div class="solution" data-type="set"> <div class="set-sol" data-type="multiple" data-each="FACTORS as factor"> <span class="sol"><var>factor</var></span> <span class="sol"><var>15 / factor</var></span> </div> <div class="input-format"> <div class="entry" data-type="multiple"> <p><code>x = \enspace</code><span class="sol"></span></p> <p><code>y = \enspace</code><span class="sol"></span></p> </div> </div> </div>
-
expression
The expression answer type parses a given expression or equation and semantically compares it to the solution. In addition, instant feedback is provided by rendering the last answer that fully parsed.
<p class="solution" data-type="expression"><var>A</var>x + <var>B</var></p>
By default, single-letter symbols are interpreted as variables. This can be overwritten by specifying, via the
data-functions
attribute, a space or comma separated list of variables that should be interpreted as functions. Variables are case sensitive;e
andi
are reserved. If no functions are specified,f(x+y) == fx + fy
. However iff
is a function,f(x+y)
cannot be expanded.<p class="solution" data-type="expression" data-functions="f g">f(<var>x</var>) + g(<var>y</var>)</p>
Sometimes you don't want to accept just any answer. For example, if the problem is "Factor
x^2 + x - 2
" you don't want the student to get credit for just repeating the question back. You can impose a stricter equality requirement by specifying thedata-same-form
attribute. If present, the answer must match the solution's structure in addition to evaluating the same. Commutativity and excess negation are ignored, but all other changes will trigger a rejection.<p class="solution" data-type="expression" data-same-form>(x-1)(x+2)</p>
The above snippet will accept
(x-1)(x+2)
,(x+2)(x-1)
,---(-x-2)(-1+x)
, and similar answers. It will rejectx^2+x-2
,x*x+x-2
,x(x+1)-2
,(x-1)(x+2)^1
, etc. with the message "Your answer is not in the correct form."Example: Factoring Polynomials 1
Other times you don't care about a particular form, but you do want the student's answer to be simplified. For example, if the question is "Simplify
((n*x^5)^5) / (n^(-2)*x^2)^-3
". That's easy - just use thedata-simplify
attribute. If present, the answer must be fully expanded and simplified. Use this carefully - simplification is hard and there may be bugs, or you might not agree on the definition of "simplified" used. You will get an error when using this if the provided solution is not itself fully expanded and simplified.<p class="solution" data-type="expression" data-simplify>x^31 / n</p>
The above snippet will accept
x^31 / n
,x^31 / n^1
,n^(-1) * x^31
. It will reject(x^25 * n^5) / (x^(-6) * n^6)
, etc. with the message "Your answer is not fully expanded and simplified."Finally, you can tweak the way that the student's answer get rendered. By default, explicit multiplication (such as between numbers) will be rendered with a center dot (TeX:
\cdot
). There may be cases where you want to use the cross/x symbol instead (TeX:\times
). To do so, just specify thedata-times
attribute like below.<p class="solution" data-type="expression" data-times>2 * 3^x</p>
-
custom
This type allows you to create a unique type of answer for your exercise. This is particularly useful for interactive exercises, but could also be used in any exercise where you need to do more complex validation of the answer. But before using it, be sure you can't do what you're trying to do using the existing answer types. For example, a combination of
set
andmultiple
can often be used to validate an answer that at first seems to require using a custom answer type.This example from the interactive exercise Graphing linear equations, checks to see that the student has correctly positioned two points to graph a line:
<div class="solution" data-type="custom"> <div class="instruction"> Drag the two points to move the line into the correct position. </div> <div class="guess"> [ graph.pointA.coord, graph.pointB.coord ] </div> <div class="validator-function"> var slope = ( guess[1][1] - guess[0][1] ) / ( guess[1][0] - guess[0][0] ); var yint = slope * ( 0 - guess[0][0] ) + guess[0][1]; return abs( SLOPE - slope ) < 0.001 && abs( YINT - yint ) < 0.001; </div> <div class="show-guess"> graph.pointA.setCoord( guess[0] ); graph.pointB.setCoord( guess[1] ); graph.line1.transform( true ); </div> <div class="example">acceptable answer format goes here</div> </div>
As shown in the example above, the
custom
answer type uses the following five elements:-
instruction
The content within this
div
is copied to the solution area just above the "Check Answer" button. In this case, it tells the student to graph a line, but you can include anything you like: buttons, input boxes, or other form elements. If you're just using input boxes, you might be better served using the other answer types rather than creating a custom answer. -
guess
This is evaluated to determine what the student's answer is. Since it gets sent to the server and stored in the user's history, you should try to limit the amount of information that makes up an answer. In the example above, the guess consists of the coordinates of the two points the student can drag around to make the graph.
-
validator-function
This is where you determine whether the student's answer is correct or not. Within this block, the framework will provide the variable
guess
which will be of the format you created in the previousguess
element. It's important that you only use information contained in theguess
variable to determine if the answer is correct or not! Thevalidator-function
is called in different contexts (such as when a coach is reviewing a student's answers) and the only context you can count on having is whatever you put into theguess
variable.In the example above, you can see the
validator-function
uses the two points stored in theguess
variable to calculate the slope and y-intercept of the line the student graphed. It compares the graphed slope and y-intercept to the correct answer and returnstrue
orfalse
if the answer is correct or incorrect. Note the use of<
and&
rather than<
or&
. Since this is an HTML document, you should escape certain characters to ensure all browsers parse it correctly.In addition to
true
andfalse
, yourvalidator-function
can return a string. If you return a string, the answer will be marked wrong, but the string will be displayed to the user to give a clue about why it was marked wrong. This is similar to the feedback provided by the built-in answer types that require an answer to be simplified. If you enter a correct answer that hasn't been simplified, a message is displayed saying the answer is almost correct, but must be simplified.As a special case, if you return an empty string
""
from thevalidator-function
, the answer won't be graded at all. You should try to do this any time the user hasn't provided an answer yet. This will prevent frustration if the user accidentally clicks the "Check answer" button too quickly. -
show-guess
A great feature of the Khan Academy framework is the ability for a student or coach to look back at previous problems done and see exactly what answers were given and what hints were taken, showing the student or coach a replay of what the student did. To make this work, the existing answer types know how to "display themselves" to recreate a view of the problem the student did. When creating a custom answer type, you'll have to do this yourself.
Like the
validator
element, theshow-guess
element is provided with aguess
variable containing the student's guess. But inshow-guess
you must use theguess
variable to recreate the answer the student gave. For example: copying the values from the guess into text boxes, moving points around an interactive exercise, etc. In the example code above, the two points are moved into the positions provided by theguess
and the line between the points is redrawn. This allows a coach to see exactly where the student placed the points after the fact.As you're developing, you can append
?debug
to the URL and you'll see an "Answer timeline" link on the right. If you provide a few answers to a problem, then click this link, you'll see the same timeline view that a coach reviewing a student's work would see. Use this timeline view to make sure yourshow-guess
function properly displays the student's work. -
example
This optional element works the same way as it does for
multiple
orset
answers. Use it to include additional information in the "Acceptable answer formats" section.
-
Back to Writing Exercises: Home
-
percent
See utils/answer-types.js.