Version 46 (modified by 16 years ago) (diff) | ,
---|
Bolt reference manual
A Bolt course consists of:
- Lessons: any web-based teaching material
- Exercises, used for reinforcement and/or assessment.
- A course document describing the order in which lessons and exercises are shown, and grouping them into units.
Installing Bolt
If you already have a BOINC or Bossa project, you already have Bolt. Otherwise:
- create a BOINC project; use make_project --web_only so that you don't have to compile any (irrelevant) programs. Similarly, you can upgrade Bolt software using upgrade --web_only.
Then:
- In the boinc/db directory, run
mysql project_name < bolt_schema.sql mysql project_name < bolt_constraints.sql
to create the Bolt database tables. - Put your lessons, exercises and course document in the project's html/user directory
- Edit and run the html/ops/bolt_setup_sample.php script to create one or more courses.
Lessons
A lesson contains instructional material. It may be an HTML file or a PHP script that generates HTML. In either case, the HTML may contain embedded audio, video, Flash, or any other content. Some restrictions:
- It shouldn't contain enclosing <html> or <body> tags (Bolt will supply these).
- It shouldn't contain any hyperlinks (Bolt will supply navigational links).
If a lesson is implemented as a PHP script, it can access information about the student viewing the lesson, as well as its own attributes (specified in the course document; see below).
Exercises
An exercise involves student interaction (it may also contain instructional material). It may have a notion of "score", in which each interaction produces a number in [0..1] indicating the correctness of the response.
Exercises are PHP scripts that call Bolt API functions to create questions. The exercise API includes the following functions:
exclusive_choice( 'option1', 'option2', ... [, weight(X) ] );
This specifies a multiple-choice question where at most one answer can be chosen. The correct choice is the first one (when the question is shown, the choices are presented in a random order).
An exercise script can contain multiple questions. If weight() is given, it specifies this question's grading weight; the default is 1.
inclusive_choice( array('option1', true|false), array('option2', true|false), ... [, weight(X) ] );
This specifies a multiple-choice question where any number of answers can be chosen.
fitb( [ field(N) | box(nrows, ncols) ] [ answer(x) | answer_regexp(x) | answer_func(function-name) ] [ weight(X) ] );
This specifies a "fill in the blank" question.
- field(N) specifies an input field of size N.
- box(n, m) specifies an input field with n rows and m columns.
- answer(x) specifies that the correct answer is x.
- answer_regext(x) specifies that any response matching the given regular expression is correct.
- answer_func(f) specifies that grading should be done by the given function. This function is passed the student response and returns a number in [0..1].
image_rect( image_filename, array(xmin, xmax, ymin, ymax) ); ?>
This specifies a question where the student clicks on an image; a correct answer is a click in the indicated subrectangle ((0,0) is the upper left corner of the image).
In addition to calling these functions, an exercise script can intersperse text among the questions. Example:
<?php echo 'Conifers are so named because:'; exclusive_choice( 'They carry their seeds in cones.' 'They are cone-shaped.', 'They originated during the Coniceous era.' ); ?>
The same script is used to generate both the exercise page and the answer page (where the student gets feedback on their response). You may want to show different text on these two pages. This can be done as follows:
switch ($bolt_ex->mode) { case BOLT_MODE_SHOW: echo "This is the exercise page."; break; case BOLT_MODE_ANSWER: echo "This is the answer page."; break;
Like lessons, exercises can access student attributes as well as their own attributes.
Attributes
Bolt allows arbitrary attributes to be associated with students and course units. A few student attributes are pre-defined: country, sex and age. All other attributes are specified by the course itself, and are stored in a PHP data structure.
The attributes of a course unit are specified in the course document.
They might include, for example:
- The reading level of the content.
- The intelligence type emphasized by the content.
- The unit's level of detail.
- Keywords representing the student interests targeted by the content.
A lesson or exercise can access its own attributes using:
$attrs = item_attrs();
The attributes of a student are accessed using:
student_sex(); // 0=unknown, 1=male, 2=female (as in ISO 5218) student_age(); student_country(); student_name(); $attrs = student_attrs(); // get course-defined attributes
For example, suppose you want to show the student's name in a lesson:
echo "Welcome, " . student_name();
Course-defined student attributes are modified in callback functions associated with exercises and exercise sets, as follows:
set_student_attrs($attrs);
For example, you could have a (non-graded) exercise that asks the student about their interests or education level, and whose callback function records this information in the student's attributes.
Course documents
The structure of a Bolt course is defined by a PHP script called a course document. The script calls Bolt API functions to create a hierarchy of units. The course document API is as follows.
Lesson
To specify a lesson:
lesson( filename('lesson_1.php?arg=4'), [ attrs((object) array("name"=>"value")) ] );
The parameters are:
- filename
- the file containing lesson content, optionally followed by a query string. The query string specified in filename() is passed in a global variable $bolt_query_string, rather than in $_GET. To parse it, use
parse_str($bolt_query_string);
- attrs
- the lesson's attributes.
NOTE: the parameters of lesson() and all other course document API functions can be given in any order.
Exercise
To specify an exercise:
exercise( filename('bolt_sample_exercise1.php') [, attrs((object) array("name"=>"value")) ] [, callback("function_name") ] );
The filename and attrs parameters are the same as for lesson().
If a callback function is specified, it will be called on completion of the exercise. Typically, this function will modify the user attributes based on the score and/or the specific responses to the exercise. It is called as
callback($score, $qs)
where $score is the exercise score and $qs is the query string. Use
parse_str($qs);
to parse this into form variables. The variable names are of the following forms (N is the index of each question: 0, 1, ...).
q_N (exclusive choice) q_N_i (inclusive choice, item i) pic_N_x, pic_N_y (image)
Sequence
A 'sequence' unit specifies a set of units that are shown in sequence:
sequence( name('course'), unit1, unit2, ... [, attrs() ] );
Select
The select structure takes a set of units and a 'value function'. This function is called with a $unit argument, and can access the unit's attributes using
$unit->get_attrs();
It can access the student's attributes using the functions listed above. The unit for which the function value is greatest is shown. The value function may be partly or entirely random.
This structure can be used to implement
- "experiments" where different lessons are compared;
- "adaptive courses" where different lessons are shown to different types of students.
or a mixture of the two.
select( name('name'), valuator('func_name'), unit1, unit2, ... [, attrs() ] );
For example, suppose your course has a student verbal level attribute, and you want to select among two lessons based on verbal level:
function similar_reading_level($unit) { $student_attrs = get_student_attrs(); $unit_attrs = $unit->get_attrs(); return abs($student_attrs->verbal_level - $unit_attrs->verbal_level); } select( name('course'), valuator('similar_reading_level'), lesson( filename('bolt_sample_lesson1.php'), attrs((object)array("verbal_level", 9)) ), lesson( filename('bolt_sample_lesson2.php') attrs((object)array("verbal_level", 12)) ), );
Random
The random control structure selects randomly (without replacement) from a set of units.
random( name('name'), unit1, unit2, ... [, number(N) ] [, attrs() ] );
- number
- how many units are to be shown (default: all of them).
Example:
random( name('foobar'), number(2), lesson( filename('bolt_sample_lesson1.php') ), lesson( filename('bolt_sample_lesson2.php') ), lesson( filename('bolt_sample_lesson3.php') ), ); ?>
The 'without replacement' applies across multiple visits to the same structure (e.g. because of review or refresh).
Exercise set
The 'exercise_set' structure specifies a set of exercises. A number of exercises is chosen randomly (without replacement) and administered.
The navigation links on the answer page of the last exercise may allow the student to review for and/or repeat the exercise set (see below).
exercise_set( name('name'), exercise1, exercise2, ... [, number(N) ] [, attrs() ] [, callback('my_func') ] [, repeat-spec1 ] [, repeat-spec2 ] [ ... ] [, refresh-spec ] );
- number
- the number of exercises to administer.
- callback
- a function to call on the completion of the exercise set. It will be called as
callback($score);
where $score [0..1] is the score.
- repeat-spec
- A repeat specification (see below).
- refresh-spec
- A refresh specification (see below).
Example:
exercise_set( name('exer_set'), exercise( name('exercise 1'), filename('file_1.php') ), exercise( name('exercise 1'), filename('file_1.php') ), repeat(.3, basic_review(), REVIEW), repeat(.7, int_review(), REVIEW|REPEAT), repeat(1, null, REPEAT|NEXT), refresh(array(7, 14, 28)) );
Repeat specification
The "repeat" items in an exercise set determine the student's options to review for and repeat the exercise set. ( Each repeat item is a function call of the form
repeat(grade_threshold, review_unit, nav_flags);
The arguments are:
- grade_threshold: the highest grade to which this item applies
- review_unit: a unit that reviews the material assessed by for the exercise set.
- nav_flags: a bitmask determining which navigation options will be presented:
- REVIEW: show the review units, then repeat the exercise set
- REPEAT: repeat exercise set immediately
- NEXT: continue without repeating the exercise set
A student's score on an exercise set is the average score of the selected exercises. Call this Y; the "selected repeat item" is the one with the least X such that Y < X.
If there is no such repeat item, the student is not given an option to repeat the exercise set; i.e., they see only a Next button.
Otherwise let R be the selected repeat item. If R.repeat_optional is true, a Next button is shown. If R.review_optional is true, a "Repeat" button is shown. If R.review_unit is present, a "Review" button is shown.
Thus, in the example above, the student's options are:
grade | options |
[0, .3) | review and repeat exercise |
[.3, .7) | review and repeat exercise, or repeat exercise |
[.7, 1) | repeat exercise, or continue |
1 | continue |
Refresh specification
If a refresh() argument is given to exercise_set(), then when the set is completed by a student it is added to a "refresh schedule". Each element in a refresh schedule specifies The intervals (in days) are given as arguments to refresh().
At a given point, one or more exercise sets may be due for refresh. The student may choose any of them to view. Bolt keeps track of the state independently for each set; the student may begin refresh for set A while partway through refresh for set B.
Nesting and functions
Control structures may be nested. For example:
sequence( name("x"); lesson(...), sequence( name("y"), lesson(...), exercise(...) ) );
You can also use PHP functions as a way of organizing course structure:
function my_unit() { return sequence( name("y"), lesson(...), exercise(...) ) } sequence( name("x"), lesson(...), my_unit() );
Course document notation explained
If you're familiar with PHP you may wonder how Bolt's notation works. The answer is that it uses get_func_args() and PHP's ability to identify variable types at runtime. There's a PHP class hierarchy underlying it; units are represented by classes like BoltExercise, BoltSequence, etc., all of which are derived from BoltUnit. So
sequence( name("foo"), lesson(filename("blah.php")) );
is equivalent to
new BoltSequence( "foo", array(new BoltLesson("blah.php")) );
Changing course documents
Course documents can change over time. In fact, that's the whole point of Bolt: to constantly study the effectiveness of course materials, and change the course based on the results of that study.
If a course changes while students are in the middle of it, Bolt recovers as gracefully as possible. For each student, Bolt maintains a "course state" - a set of data, for each control structure that the student has visited in the course, describing the student's "position" in that control structure. When a student clicks the Next button, or resumes the course after an interval, Bolt uses the course state to decide what item to display next.
For example, suppose your course has a sequence with 3 elements, with logical names (red, yellow, blue). and a student is on the third. The course state for the sequence consists of two items: (blue, 2). 'blue' is the logical name of the third element, and the index number 2 (indicates that the student has completed 2 units in the sequence).
If the student resumes the course, Bolt will find their place in the sequence first by looking up the logical name; if it is not found, then it will use the index number. For example:
- If you change the sequence to (red, blue, green, yellow) then the student will be shown the units blue, green, and yellow.
- If you change the sequence to (red, yellow, green) then the student will be shown the unit 'green'.
- If you change the sequence to (red, yellow) then the student will have finished the sequence.
Logical names and state
In general, units must have unique logical names. However, two units may have the same logical name if they are identical. For example:
function my_unit() { return random( name("y"), lesson(...), lesson(...) ) } return sequence( name("x"), my_unit(), exercise_set( name("z"), exercise(...), review(.5, my_unit()) ) );
This specifies a course in which my_unit() is displayed, then an exercise is given. If the student scores below .5 on the exercise, he is shown my_unit() again and the exercise is repeated.
So there are two units with logical name 'y' in this course, but they are identical, so this is allowed.
When there are multiple units with the same logical name, they share a single state.