/
exercise.html
363 lines (322 loc) · 12.6 KB
/
exercise.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
<!DOCTYPE html>
<html>
<head>
<title>Creating a Profiency Exercise with JavaScript Algorithm Visualization API (JSAV) Version 0.3</title>
<link rel="stylesheet" href="apidoc.css" >
</head>
<body>
<h1>Creating a Profiency Exercise with JavaScript Algorithm Visualization API (JSAV) Version 0.3</h1>
<p>This tutorial will walk you through the code needed to create a
simple proficiency exercise.
The user of the exercise is supposed to click array positions in order
from left to right to highlight each cell.
A point is scored for each correctly selected cell.
The options panel lets the user choose from various standard settings
for controlling the exercise, including whether feedback for incorrect
steps should be given, and whether such incorrect steps should be
corrected or not.
For the final code version,
see the file [JSAV]/examples/simple-exercise.html.</p>
<p>
The <a href="api.html">API docs</a> provide complete documentation for
the various library APIs.
<h2>Setting Up</h2>
<p>
First, like any HTML file we need a header to define the document
type, title, and the CSS files to be used.
</p>
<pre>
<!DOCTYPE html>
<html>
<head>
<title>ShellSort Proficiency Exercise</title>
<link href="AeBookAV.css" rel="stylesheet" type="text/css" />
<link rel="stylesheet" href="../css/JSAV.css" type="text/css" />
</head>
</pre>
<p>
In this case, we included the standard JSAV.css file, as well as the
CSS file used by OpenDSA textbook components (AeBookAV.css).
</p>
<p>
Next come the style elements.
</p>
<pre>
<style>
#jsavcontainer {
width: 500px;
height: 150px;
background-color: #efe;
}
p.jsavoutput.jsavline {
height: 40px;
}
</style>
</pre>
<p>
Here we first define the style for <code>jsavcontainer</code>,
which holds the visualization.
We define the dimensions and give it a pale green background color.
<code>jsavoutput</code> is where messages can be written by the
visualization.
In this example it will hold the directions for what to do.
We will define the output field to be of type <code>jsavline</code>,
which is one of the style options provided by the API.
We define its height to be 40 pixels.
</p>
<p>
Next, we will define the various DOM elements on the HTML page.
</p>
<pre>
<div id="jsavcontainer">
<a class="jsavsettings" href="#">Settings</a>
<p align="center" class="jsavexercisecontrols"></p>
<ol id="exerArray"></ol>
<p class="jsavoutput jsavline"></p>
</div>
</pre>
<p>
<code>jsavcontainer</code> holds the AV itself.
We have given it two standard elements that typically appear in a
JSAV exercise: the options (or "settings") panel, and the exercise
standard controls.
The settings panel is accessed by clicking on the settings button,
which in this example is in the upper right corner and looks like a
pair of gears.
The standard exercise controls include the ability to regenerate a new
instance of the exercise ("reset"), a slideshow showing the "model
answer", and information about the grade received on the exercise.
We create a placeholder for what will be the displayed array.
Note that the DOM type is just a numbered list.
Finally, we position the message output, which is merely a special
type of paragraph.
</p>
<p>
Next we load in the various libraries.
</p>
<pre>
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js">
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script>
<script src="../lib/jquery.transit.js"></script>
<script src="../build/JSAV.js"></script>
</pre>
<p>
We use the standard jquery libraries, and we also load the JSAV
library.
</p>
<p>
Next we make variable definitions specific to the exercise.
</p>
<pre>
var arraySize = 8,
initialArray = [],
jsavArray,
$array = $("#exerArray"),
av = new JSAV($("#jsavcontainer"));
</pre>
<p>
<code>arraySize</code> defines the array to be of size 8.
<code>initialArray</code> will hold the array values.
This placeholder is needed since JSAV will have to maintain two
versions of the array object: The one that the user works on, and the
copy displayed when the model answer is presented.
<code>jsavArray</code> will hold a reference to the JSAV array the student is working on.</b>
<code>$array</code> will store a reference to the <code>ol</code> DOM element used later to
generate the HTML for the array.
<code>av</code> is the visualization object itself.
We pass in <code>jsavcontainer</code> to bind the position of the
visualization to this DOM element.
</p>
<p>
Next we deal with giving instructions to the user.
</p>
<pre>
av.recorded(); // we are not recording an AV with an algorithm
</pre>
<p>
By default, when a JSAV visualization is initialized it is expecting a
series of effects to be recorded by running an algorithm.
In this mode, the effects are only recorded and not
visualized/animated.
When making an exercise, we want to animate user operations as soon as
they are performed.
Thus, we call <code>av.recorded()</code> to end the "recording" mode.
Note that animation state changes are still stored in JSAV's internal
animation state sequence array.
</p>
<h2>Write an Initialization Function</h2>
<p>
We are now ready to specify the pieces to the exercise itself.
</p>
<p>
The first step in creating an exercise is to write a function that
initializes the exercise.
This method will be called both on startup, and by the "reset"
button.
The <code>initialize()</code> function should clear the previous
visualization (if there was one) and initialize a new one.
It should also return the structures that will be used in grading to
compare with the model answer.
The name of the function does not have to be "initialize", as
its name will be bound when we create the exercise object,
as shown later in the tutorial.
</p>
<pre>
function initialize() {
var htmldata = "";
for (var i = arraySize; i > 0; i--) {
var randomVal = Math.floor(Math.random()*100);
htmldata += "<li>" + randomVal + "</li>";
initialArray[arraySize-i] = randomVal;
}
$array.html(htmldata);
jsavArray = av.ds.array($array, {indexed: true});
swapIndex = av.variable(-1);
av.umsg("Directions: Click on all array elements from left to right to highlight them. Then click on the first and last elements to swap them.");
av.forward();
return jsavArray;
}
</pre>
<p>
Our example here is a simplified version of the one used by
the Shellsort Proficiency Exercise.
This code generates random numbers and changes the content
of an existing HTML element.
In the HTML, there is an element <code><ol id="exerArray"></ol></code>
and the <code>$theArray</code> variable is a jQuery object that refers
to that element (<code>var $theArray = $("#exerArray")</code>).
The <code>$array.html(htmldata);</code> function call replaces the existing
array contents with new data.
The call to <code>av.ds.array</code> initializes a new JSAV array from
the given jQuery object and the given options. The call to <code>av.variable</code> initializes a new
variable that can be used to store value changes in the animation sequence. See
section "Adding Student Interaction" below for explanation why we need this.
The call to <code>av.umsg()</code> provides the text of the message
that give directions to the user,
and <code>av.forward()</code> causes the message to be
displayed on the screen. Finally, the function
returns the JSAV array.
</p>
<h2>Write the Model Answer Function</h2>
<p>To be able to grade the student's solution, the exercise will need
to have a model solution.
This will be used both to show the correct solution (as an AV shown to
the student through the "Model Answer" button) and to compare to the
student's answer to judge correctness.
Below is a simple model answer function where the correct solution is
to highlight the array indices from left (index 0) to right
(index arraySize-1) and then swap first and last element.
<pre>
function modelSolution(jsav) {
var modelArray = jsav.ds.array(initialArray);
for (var i = 0; i < arraySize; i++) {
modelArray.highlight(i);
jsav.stepOption("grade", true);
jsav.step();
}
// swap the first and last element
modelArray.swap(0, arraySize - 1);
jsav.stepOption("grade", true);
return modelArray;
}
</pre>
<p>
The function takes a single parameter (<code>jsav</code> above) that
is a reference to the JSAV animation of the model answer.
Like the initialization function, the model solution function should
return the structures used in comparing the model solution with
student's solution
</p>
<p>The function above first creates a JSAV array using the data stored
in variable <code>initialArray</code> in the initialization
function.
It then goes through all indices in turn and highlights the current
index.
It also sets a step option for the current collection of effects and
calls <code>jsav.step()</code>.
The step option <code>grade</code> is used to mark states in the model
solution that should be used in grading.
Thus, the model solution can contain an AV with explanations and other
structures, but only the returned structures at steps where grade is
set to true, are graded.
The call to <code>jsav.step()</code> notifies the AV that
a new step should be started.
</p>
<h2>Creating the exercise</h2>
<p>
The exercise is initialized with a call to <code>av.exercise()</code>.
The function can also take several options, some of which are
required. Given our <code>initialize</code> and <code>modelSolution</code>
functions, we initialize an exercise as follows.
</p>
<pre>
var exercise = av.exercise(modelSolution, initialize, {css: "background-color"});
exercise.reset();
</pre>
<p>The options that we pass:</p>
<ul>
<li><code>{model: <function>}</code> The function to generate the
model solution. <strong>Required.</strong></li>
<li><code>{reset: <function>}</code> The initialization function
that resets the exercise. <strong>Required.</strong></li>
<li><code>{compare: <Object or Array>}</code> Specifies which
properties to compare for the structures. In the example below, we
set the comparison to be the CSS property <code>background-color</code>,
since that is changed when highlighting indices. <strong>Required.</strong></li>
</ul>
<p>
The full set of options can be found in the
<a href="api.html">API documentation</a>.
</p>
<p>
At this point, the exercise can be graded and model solution shown.
It now remains to write the code that allows the student to construct
her solution.
</p>
<h2>Adding Student Interaction</h2>
<p>
It is simple to attach listeners for user actions (like mouse clicks)
to JSAV data structures. We will
register a click event handler to the array.
Inside the handler, we need to first decide if we are in "swap mode" or not. This
is done based on whether the last index is highlighted or not.
</p>
<pre>
// bind a function to handle all click events on the array
jsavArray.click(function(index) {
// if last index is highlighted, we are in "swap mode"
if (this.isHighlight(arraySize - 1)) {
// when in swap mode, first click on index will store that index
// and change the font size on the value
if (swapIndex.value() == -1) {
swapIndex.value(index);
// apply the CSS property change to index
this.css(index, {"font-size": "130%"});
av.step(); // add a step to the animation
} else {
// the second click (swapIndex has some value) will cause
// the swap of indices index and stored swapIndex
this.swap(index, swapIndex.value());
// change the font-size back to normal
this.css([swapIndex.value(), index], {"font-size": "100%"});
swapIndex.value(-1);
exercise.gradeableStep(); // this step will be graded
}
} else { // we are in highlight mode
// highlight the index
this.highlight(index);
if (index == (arraySize - 1)) {
av.umsg("Good, now swap the first and last index");
}
// mark this as a gradeable step; also handles continuous feedback
exercise.gradeableStep();
}
});
</pre>
<p>If we are in swap mode, we need to check if this is the first or second index for the swap. On the first click, we need to store that index to be used when second click occurs. Normally we could store the value in plain JavaScript variable. However, a student can undo a step, which should also reset the swapIndex value. For this, we have defined swapIndex as a JSAV variable. It has functions <code>value()</code> that will return the current value and <code>value(newVal)</code> that will set the value.</p>
<p>
Now, the exercise should be interactive and ready for use!</p>
</body>
</html>