Title: Authoring tips
Course: Demonstrating STACK (v4.4.7)

Graphs that do not need to remember their state between page reloads are simple to build, just act like you would with the official JSXGraph filter. Note however that you do not need that filter as STACK provides its own implementation which has some handy features:

- STACK version does not allow you to name the div-element storing the graph, instead it gives you the name it has chosen in a variable named divid, the reason for this is that we ensure that each graph has an unique identifier and that there cannot exist name collisions, not even if you were to place the same question twice on the same page.
- We provide a way to reference the input fields of the question and provide the identifiers of those input field elements if requested. The key benefit here is that we can provide those references in the same way regardless on the VLE you are running the question in, so you do not need to adapt the graph code if you decide to ditch Moodle and move ILIAS or some other system. (see more of this in the other examples of this category)
- We also provide convenience functions to bind primitives (points and sliders) in the graph to STACK input fields so that you do not need to repeat that binding code yourself. Basically, single call to binding function will replace about twenty lines of code, more importantly we can change the implementation of the binding functions if the world changes so that you do not need to fix all your graphs with all their bindings.

Note that as these graphs are coded in JavaScript you should not use WYSIWYG editors to edit these questions, as they tend to "helpfully" add random styling to random places and might break things. In Moodle do switch your text editor to 'plain text area', before editing these.

Now as a minimal example lets copy some example from JSXGraphs showcase library http://jsxgraph.uni-bayreuth.de/wiki/index.php/Showcases. Note, that we do not provide memory for this example, so it will revert to its initial state when the page reloads or you return to this page.

[[escape value="[[jsxgraph width='500px' height='500px']]"/]]
// http://jsxgraph.uni-bayreuth.de/wiki/index.php/Five_Circle_Theorem
// Only difference here to the example is the 'jxgbox' => divid replacement
// so that the element name becomes dynamic.
var brd = JXG.JSXGraph.initBoard(divid, {boundingbox:[-5,5,5,-5]});
var p = [], l = [], i = [], c = [], j = [], k;

p[0] = brd.create('point',[-2.5,-3],{name:'',strokeColor:'#7355ff',fillColor:'#7355ff'});
p[1] = brd.create('point',[-0,4],{name:'',strokeColor:'#7355ff',fillColor:'#7355ff'});
p[2] = brd.create('point',[2.5,-3],{name:'',strokeColor:'#7355ff',fillColor:'#7355ff'});
p[3] = brd.create('point',[-4,0],{name:'',strokeColor:'#7355ff',fillColor:'#7355ff'});
p[4] = brd.create('point',[4,0],{name:'',strokeColor:'#7355ff',fillColor:'#7355ff'});

for (k=0;k<5;k++) {
   l[k] = brd.create('segment',[p[k],p[(k+1)%5]],{strokeColor:'black',strokeWidth:1});
}

for (k=0;k<5;k++) {
   i[k] = brd.create('intersection',[l[k],l[(k+2)%5],0],{name:'',strokeColor:'#EAEA00',fillColor:'#EAEA00'});
}

for (k=0;k<5;k++) {
   c[k] = brd.create('circumcircle',[p[k],i[k],i[(k+2)%5]],{strokeColor:'gray', strokeWidth:1, point: {visible: false}});
}
for (k=0;k<5;k++) {
   j[k] = brd.create('intersection',[c[k],c[(k+2)%5],0],{name:'',strokeColor:'#EA0000',fillColor:'#EA0000'});
}

cc = brd.create('circumcircle',[j[0],j[2],j[3]],{strokeColor:'red',strokeWidth:2,point:{strokeColor:'#000000',fillColor:'#000000',size:1}});
brd.update();
[[escape value="[[/jsxgraph]]"/]]

Renders as:

"Binding", in the context of STACK + JSXGraph integration, means connecting the value of a STACK input field to some element in the graph. If the element gets moved the input field's value is also changed. In the simplest example if you drag a slider from value 1 to value 2 the bound input will be set to 2. This is obviously important when you wish to use that part of the graph as an input. Also, as the VLE in the background stores the values of the input fields we can start remembering state. E.g. f you dragged the slider to value 2 and left the page then the binding logic should be able to ensure that the slider gets placed back to that same value if you return to the page.

As an simplified example of this we now build a graph with a line segment which has two draggable end points one of which is bound and one which is not. Drag the two points around and then press 'Check'. When the checking process reloads the page you should see the bound one staying where you dragged it to and the other to return into its initial position. You should also see that the STACK logic side received the position of the bound point.

[[escape value="[[jsxgraph input-ref-ans1='ans1Ref']]"/]]
var board = JXG.JSXGraph.initBoard(divid, {boundingbox: [-5, 5, 5, -5],showNavigation:false});
var p1 = board.create('point', [-3,3], {name:'Bound',size:4});
var p2 = board.create('point', [3,-3], {name:'Free',size:4});
var line = board.create('line', [p1,p2], {straightFirst:false, straightLast:false});

// There exists a simple convenience method for binding inputs to points
// It just needs an input reference, defined as a parameter of the jsxgraph-block
// and a primitive object of the type of the binding, in this case a point.
stack_jxg.bind_point(ans1Ref, p1);

// Always call board.update() at the end if you have bindings.
board.update();

// In this example we hide the input as we are not yet ready to talk about two-way binding.
document.getElementById(ans1Ref).style.display = 'none';
[[escape value="[[/jsxgraph]]"/]]

As a special test case here, try moving the bound one out of the box. For that to work the binding needs to track not only direct actions affecting the point but also changes caused by other actions. Those needing to build their own binding logic for more complex things should note this. Simply tracking the point may not be enough.

In the previous example the binding transfers the position of both something in the graph to the input and retrieves the stored value of the input on page reload. Basically, one way binging is when the action in a graph changes setting the input value. For two way binding we also track the input value after the page has loaded so that if it changes due to any action we change the graph.

Now why would we want to do that when the graph itself set the value!?

- We might want to provide the input field as a visible editable field so that if the student cannot drag e.g. the slider in the graph they can write the value into the input and the graph reacts as if the thing was moved there, this may be necessary in some cases, but it is not that useful generally.
- More likely is the case where we have multiple graphs connected to the same input and we want them to move in sync when something is done in any one of them.
- We could also have scripting outside the graph that could act on the value on the input(s) in some way and connecting to that might be difficult, but it is much simpler to connect to the input directly and our binding does just that.

This time you will need to open the questions source to see the code for these graphs, the key here being that each of them reference that same input and bind their slider to it.

Area slider:
Test point:

Note that in this example if you write a valid value that the slider does not allow the slider will map that value to a value it allows and the binding to the other way will fix the input value. Basically, this slider has specific fixed ticks and those are enforced even in the input.

The previous examples have shown the use of simplified binding of single primitives to single inputs, that should cover most use cases but once you start to do more complex things you will need to start building your own binding logic. Some examples of such situations are:

- Creation and deletion of arbitrary numbers of points/objects in graph cannot be tracked with one input per object logic as you cannot create inputs. In these cases you need to store more structure into inputs.
- Not dealing with the positions of things might also be an obvious case, if you want to for example track the order the student clicks some edges in some graph use of the simple binding tools will not help.

Basically, you cannot use one-to-one input-object-binding if you have dynamic number of objects. To deal with this you need to have some form of data-structures (simple lists of coordinates are often enough but once you have multiple types of things with connections between them you will probably want more) that you can store that represent the state of your graph. As you are authoring JSXGraph graphs in JavaScript the obvious structures are JavaScript objects/dictionaries and lists, luckily those can easily be turned to JSON strings that can be stored into String input fields. And what is important STACK now provides a way for parsing those JSON strings on Maxima side so that you can process the values there.

[[escape value="[[jsxgraph height='700px' width='700px' input-ref-ans1='ans1Ref']]"/]]
// In this example ans1 is a String type input, which is important as the value we store
// there is most definitely not a valid Maxima expression.
var board = JXG.JSXGraph.initBoard(divid, {boundingbox: [-5, 5, 5, -5],showNavigation:false});

// We will store our points here.
var points = new Array();
var i = 0;

// If we have stored state of points we will resurrect them now.
var theInput = document.getElementById(ans1Ref);
if (theInput.value && theInput.value != '') {
 var pointList = JSON.parse(theInput.value);
 for (i=0; i





Drag some points around and pres check, as expected the points stay in place. The feedback should also show you the raw stored state and some very simple numbers collected from it. You may wish to check the feedback logic but it has very little to show.

A random name: [value]

A random degree 2 polynomial with non-trivial constants: [value]

(Any answer is correct here.)

Evaluate [value].

Simplify

\[[value].\]
Feedback: The numerator [value] simplifies to [value]. The denominator [value] simplifies to [value]. Hence [value] simplifies to [value]\(=\)[value].

Strict Syntax

Usually, STACK requires students to type in exact Maxima syntax. For example, 2x has to be written as 2*x.

You can turn this off to let the system guess implied multiplication. In this question, it has been set to guess multiplication by assuming all variables are single-characters.

Try typing in xy and see how STACK interprets it. Also try typing in sinx.

Simplify the expression: [value]

Use trigonometric identities to turn the following expression into an equivalent one involving no use of the \(\sin\) function.

\[[value]\]
Feedback: Recall \[[value].\] Also recall \[[value].\] It follows that \[[value]=[value]=[value]\]

Find \[ \int [value] d[value]\]

\( \int [value] d[value] = \)
Feedback: We can either do this question by inspection (i.e. spot the answer) or in a more formal manner by using the substitution \[ u = ([value]-[value]).\] Then, since \(\frac{d}{d[value]}u=1\) we have \[ \int [value] d[value] = \int u^[value] du = \frac{u^[value]}[value]+c = [value].\]

Q: Differentiate \[[value]\]

with respect to x.
Feedback: By the quotient rule, \[\left( [value] \right)'=\frac{([value])'\cdot[value]-[value]'}{[value]}.\] By the chain rule, this equals \[[value]=[value]\]
  Hint: You may find the quotient rule helpful.
  Hint: You may also find the chain rule helpful.

This question only lets the student have one try, by using a 100% penalty.

True or False: If the order of a group \(G\) is prime, then it has no subgroups.
Feedback: The two trivial subgroups, {e} and G are always subgroups of G.

Try getting this question wrong, i.e. by typing [value].

Consider the line \[[value].\]

[value]

Fine a line parallel to the line sown above. Your line should be in the form \(y=mx+c\) where \(m,c\) are constants.

\(y = \)
Feedback: Two lines are parallel if they have the same gradient but different y-intercepts. That is, any line of the form [value] where \(k \neq 0\) will be parallel to [value].

You can change the way multiplication is displayed throughout a question, either as "none" [value], "cross" [value] or "dot" [value]. However, you can also change it during a question to emphasise a point. For example, try getting the following question wrong by typing \([value]\)

Evaluate \[[value].\]

Interactive With Multiple Tries

This quiz is set to interactive with multiple tries.

This question lets the student have three tries, and gives a hint after each one. Each wrong attempt applies a penalty of \(\frac{1}{3}\) mark.

Immediate Feedback

This quiz is set to immediate feedback.

Only one attempt per question is allowed. You can choose to either give feedback immediately after answering the question, or only at the end of the quiz. This quiz is set to only give feedback once the entire quiz is completed and submitted.

Penalties are not used in this format.

Integrate \[[value]\] with respect to [value].
Feedback: To solve this problem we will have to use the linearity rules for integration [[facts:calc_int_linearity_rule]] as follows: \[\begin{array}{rcl}\displaystyle \int \left([value]\right) d[value] &\displaystyle =&\displaystyle [value]\int [value] d[value] \\ &\displaystyle =&\displaystyle [value][[value]] \\ &\displaystyle =&\displaystyle [value] + c \end{array}\]

Find the following second derivative: \[ \frac{d^2}{d[value]^2}([value]). \]
Feedback: The second derivative of a function \(f(x)\) with respect to \(x\) is \[\frac{d^2f}{dx^2}=\frac{d}{dx}\left(\frac{df}{dx}\right)\] So, if \(f([value])=[value]\) then its second derivative is \[\begin{array}{rcl}\displaystyle \frac{d^2}{d[value]^2}([value]) &\displaystyle =&\displaystyle \frac{d}{d[value]}\left[\frac{d}{d[value]}([value])\right] \\ &\displaystyle =&\displaystyle \frac{d}{d[value]}([value]) \\ &\displaystyle =&\displaystyle [value] \end{array}\]

Adaptive Mode

This quiz is set to adaptive mode.

It lets the student have as many tries as they want, but subtracts a penalty for each incorrect choice. This option is useful when testing questions, as you do not have to keep resetting the question every time you want to try a different input.

You can choose how much feedback (whether correct, specific feedback, correct answer) you want the student to see after each attempt. This quiz is customised for question testing, so it will show all feedback after each attempt.

This question applies a penalty of 0.1 for each incorrect answer.

Simplify the following expression by collecting together like terms:
\[[value]x+[value]y-[value]x-[value]y+5.\]
Feedback: In order to collect like terms simply pull out the common factors (the x's and y's in this example) like so: \[ = [value]x+[value]y-[value]x-[value]y+5,\] \[ = \left([value]-[value]\right)x+\left([value]-[value]\right)y+5,\] \[ = [value].\]

Randomization

STACK can generate random values for questions, so that students are shown unique versions.

Introduction

This quiz will showcase some of the more advanced authoring features of STACK, including:

- Standard Answer tests
- Plotting
- Numerical tests
- Scientific units
- Follow-through marking

Simplification

STACK automatically simplifies equations. You can turn this off to let students evaluate an expression.

Standard Feedback

STACK can give specific feedback depending on which mistake the student made. Some answer tests, like int, automate this process.

Try making a mistake, such as forgetting the integration constant, or accidentally differentiating instead.

Forbidden and Allowed Words

STACK automatically forbids students to type in variable names longer than 2 characters. You can turn this off if you want students to use a long variable name.

Similarly, you can forbid words that are usually allowed by STACK, such as elementary functions.

Plotting

STACK can use graphs both in question text and feedback. It can also graph the student's answer against the teacher's answer for better feedback.

Fact Sheets

STACK has built-in fact sheets that can be displayed to students. The following trigonometric identity fact sheet has been generated by STACK.

Use trigonometric identities to simplify the following expression:

\[[value]\]

[[facts:trig_standard_identities]]
Feedback: Recall that \[\tan(x)=\frac{\sin(x)}{\cos(x)}.\] Hence \[[value]=\cos(x)+\frac{\sin(x)^2}{cos(x)}\] Now recall \[\sin(x)^2=1-\cos(x)^2.\] Hence \[\cos(x)+\frac{\sin(x)^2}{cos(x)}=\cos(x)+\frac{1}{\cos(x)}-\cos(x)=[value].\]

Numerical Precision

STACK can do numerical precision tests, for example asking students to give their answer to a certain number of significant figures. Try to input your answer to different significant figures.

Evaluate [value] to exactly 5 s.f.

Evaluate [value] to at least 3 s.f.

Evaluate [value] to exactly 2 d.p.
Feedback: Recall that 5 s.f. means five "significant figures" should be given, including digits on either side of the decimal separator. Hence \[[value]=7.07106781=[value]\text{(5 s.f.)}\] \[[value]=23.1406926=[value]\text{(3 s.f.)}\] Recall that 2.d.p. means only two "decimal points" should be given, which includes only digits on the right side of the decimal seperator. Hence \[[value]=0.14112=[value]\text{(2 d.p.)}\]

Scientific Units

STACK also supports the use of scientific units, as demonstrated in this question. This is particularly useful for Physics questions.

A body has a mass of [value]\(kg\). It moves at a speed of [value] \(ms^{-1}\). Calculate its kinetic energy, giving your answer to 3.s.f. with SI units.
Feedback: Kinetic energy \(E=\frac{1}{2}mv^2\) where \(m\) is the mass and \(v\) the speed. Hence \(E=\frac{1}{2}([value]kg) ([value] ms^{-1})^2 = [value]\) = [value] (3.s.f.).

Follow-through Marking

STACK can have multiple part questions with follow-through marking. Try getting part (a) wrong, for example by entering 50 m/s, and then use your wrong answer to finish the question. STACK will mark part (a) as wrong, but part (b) as correct. This way you can design questions that don't disproportionately punish students for an early error.

A car moves at a constant velocity. The car moves \(1000 m\) in \(14.0 s\). Calculate the car's speed, \(v\), to 3 s.f., in SI units.

\(v=\)

After a time \(t=0\), the car applies a constant acceleration of \(3.00 m s^-2\). Calculate the distance \(s\) the car travels between \(t=0\) and \(t=100\). Give your answer to 3.s.f with SI units.

\(s=\)
Feedback: (a) Speed \(v=\frac{s}{t}\) where \(s\) is distance traveled and \(t\) time passed. Hence \(v=\frac{1000m}{14s}=[value]=[value]\) (3.s.f.) (b) Distance traveled \(s=v_0 t+\frac{1}{2} a t^2\) where \(a\) is acceleration. Hence \(s=([value]ms^{-1}) (100s)+(\frac{1}{2}) (3.00 ms^{-1}) (100s)^2 = [value]m= [value]\) (3 s.f.)

STACK supports multi-lingual content, as shown in this example.

Give an example of an even function. \(f_2(x)=\) .
Feedback: A function \(f\) is odd if \[ f(x)=-f(-x) \forall x.\] An example is \(f(x)=4x^3\). Indeed, polynomials with only odd powers are fine. A function \(f\) is even if \[ f(x)=f(-x) \forall x.\] An example is \(f(x)=5x^4\). Indeed, polynomials with only even powers are fine. It is possible to have both \[ f(x)=f(-x)=-f(-x) \] in which case \(f(x)=0\) for all \(x\). This example is unique.