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.
The API docs provide complete documentation for the various library APIs.
First, like any HTML file we need a header to define the document type, title, and the CSS files to be used.
In this case, we included the standard JSAV.css file, as well as the CSS file used by OpenDSA textbook components (AeBookAV.css).
Next come the style elements.
Here we first define the style for
which holds the visualization.
We define the dimensions and give it a pale green background color.
jsavoutput is where messages can be written by the
In this example it will hold the directions for what to do.
We will define the output field to be of type
which is one of the style options provided by the API.
We define its height to be 40 pixels.
Next, we will define the various DOM elements on the HTML page.
jsavcontainer 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
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 display the current score.
Finally, we position the message output, which is merely a special
type of paragraph.
Next we load in the various libraries.
We use the standard jquery libraries, and we also load the JSAV
Next we make variable definitions specific to the exercise.
```arraySize``` defines the array to be of size 8.
```initialArray``` 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.
```jsavArray``` will hold a reference to the JSAV array the student is working on.
```av``` is the JSAV visualization object itself.
We pass in ```jsavcontainer``` to bind the container of the
visualization to the DOM element with this ```id```.
Next we deal with giving instructions to the user.
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
When making an exercise, we want to animate user operations as soon as
they are performed.
Thus, we call ```av.recorded()``` to end the "recording" mode.
Note that animation state changes are still stored in JSAV's internal
animation state sequence array.
### Write an Initialization Function
We are now ready to specify the pieces to the exercise itself.
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"
The ```initialize()``` 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.
Our example here is a simplified version of the one used by
the Shellsort Proficiency Exercise. The code start by checking if we have an old instance
of jsavArray, and clears the HTML elements if we do (calls to ```clear()```).
Next, the code generates random numbers with a call to ```JSAV.utils.rand.numKeys```.
The call to ```av.ds.array``` initializes a new JSAV array from
the given array and the given options. The call to ```av.variable``` 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 ```av.umsg()``` provides the text of the message
that give directions to the user. Finally, the function
returns the JSAV array.
### Write the Model Answer Function
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.
The function takes a single parameter (```modeljsav``` 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
The function above first creates a JSAV array using the data stored
in variable ```initialArray``` in the initialization
function. Next, it marks the current state as the initially displayed state. Without this line,
the first step in the model answer would be empty and the first step would show the array.
It then goes through all indices in turn and highlights the current
The ```gradeableStep()``` function 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 ```gradeableStep``` is
called, are graded. Such explanatory steps can be added through call to
### Creating the exercise
The exercise is initialized with a call to ```av.exercise()```.
The function can also take several options, some of which are
required. Given our ```initialize``` and ```modelSolution```
functions, we initialize an exercise as follows.
The parameters that we pass: