.
// Bolt exercise API
// The following is a global var accessed by exercise functions.
//
$bolt_ex = null;
$bolt_ex->mode = 0; // input: SHOW/SCORE/ANSWER
$bolt_ex->index = 0; // input: sequence of this exercise in file
$bolt_ex->score = 0; // input/output: cumulative score (if mode = SCORE)
$bolt_ex->weight = 0; // input/output: cumulative weight
$bolt_ex->query_string = ""; // user's response (if SCORE or ANSWER)
function weight($w) {
return array('weight', $w);
}
function exclusive_choice() {
global $bolt_ex;
$weight = 1;
$choices = array();
$args = func_get_args();
foreach ($args as $arg) {
if (is_string($arg)) {
$choices[] = $arg;
} else if (is_array($arg)) {
switch ($arg[0]) {
case 'weight': $weight = $arg[1]; break;
default: echo "bad arg to exclusive_choice()";
}
} else {
echo "bad arg to exclusive_choice()";
}
}
parse_str($bolt_ex->query_string);
switch ($bolt_ex->mode) {
case BOLT_MODE_SHOW:
shuffle($choices);
$i = 0;
start_table();
foreach ($choices as $choice) {
row2($choice, "index type=radio value=$i>");
$i++;
}
end_table();
break;
case BOLT_MODE_SCORE:
$right_ans = $choices[0];
shuffle($choices);
$key = "q_$bolt_ex->index";
if (isset($$key)) {
$response = $$key;
if ($choices[$response] == $right_ans) {
$bolt_ex->score += 1;
}
}
$bolt_ex->weight += $weight;
break;
case BOLT_MODE_ANSWER:
$right_ans = $choices[0];
shuffle($choices);
$key = "q_$bolt_ex->index";
if (isset($$key)) {
$response = $$key;
} else {
$response = -1;
}
$i = 0;
start_table();
foreach ($choices as $choice) {
$x = "
| ";
if ($response == $i) {
if ($choice == $right_ans) {
$x = "Right";
} else {
$x = " | You chose this answer";
}
} else {
if ($choice == $right_ans) {
$x = " | Right answer | ";
}
}
echo "$choice $x |
";
$i++;
}
end_table();
break;
}
$bolt_ex->index++;
}
function inclusive_choice() {
global $bolt_ex;
$weight = 1;
$choices = array();
$args = func_get_args();
foreach ($args as $arg) {
if (is_array($arg)) {
$choices[] = $arg;
} else if (is_object($arg)) {
if (get_class($arg) == 'BoltWeight') {
$weight = $arg->weight;
} else {
echo "bad arg to inclusive_choice()";
}
} else {
echo "bad arg to inclusive_choice()";
}
}
parse_str($bolt_ex->query_string);
switch ($bolt_ex->mode) {
case BOLT_MODE_SHOW:
shuffle($choices);
$i = 0;
start_table();
foreach ($choices as $choice) {
$c = $choice[0];
row2("index."_$i type=checkbox>", $c);
$i++;
}
end_table();
break;
case BOLT_MODE_SCORE:
$i = 0;
$n = count($choices);
$score = 0;
shuffle($choices);
foreach ($choices as $choice) {
$key = "q_".$bolt_ex->index."_$i";
$response = isset($$key);
$r = $choice[1];
$correct = ($r && $response) || (!$r && !$response);
if ($correct) $score += 1./$n;
$i++;
}
$bolt_ex->score += $score;
$bolt_ex->weight += $weight;
break;
case BOLT_MODE_ANSWER:
$i = 0;
$n = count($choices);
shuffle($choices);
start_table();
table_header("Choice", "Correct?", "Your answer");
foreach ($choices as $choice) {
$c = $choice[0];
$key = "q_".$bolt_ex->index."_$i";
$response = isset($$key);
$r = $choice[1];
$correct = ($r && $response) || (!$r && !$response);
$color = $correct?"#88ff88":"#ff8888";
table_row($c, $r?"yes":"no",
array($response?"yes":"no", "bgcolor=$color")
);
$i++;
}
end_table();
break;
}
$bolt_ex->index++;
}
function image_rect($img, $rect) {
global $bolt_ex;
parse_str($bolt_ex->query_string);
switch ($bolt_ex->mode) {
case BOLT_MODE_SHOW:
echo "index src=$img>
";
break;
case BOLT_MODE_SCORE:
$x = get_int("pic_".$bolt_ex->index."_x");
$y = get_int("pic_".$bolt_ex->index."_y");
$right = true;
if ($x < $rect[0]) $right = false;
if ($x > $rect[1]) $right = false;
if ($y < $rect[2]) $right = false;
if ($y > $rect[3]) $right = false;
if ($right) {
$bolt_ex->score += 1;
}
$bolt_ex->weight += $weight;
break;
case BOLT_MODE_ANSWER:
$x = get_int("pic_".$bolt_ex->index."_x");
$y = get_int("pic_".$bolt_ex->index."_y");
$right = true;
if ($x < $rect[0]) $right = false;
if ($x > $rect[1]) $right = false;
if ($y < $rect[2]) $right = false;
if ($y > $rect[3]) $right = false;
$cx = $rect[0];
$cy = $rect[2];
$sizex = $rect[1]-$rect[0];
$sizey = $rect[3]-$rect[2];
$ax = $x-4;
$ay = $y-4;
$color = $right?"green":"red";
if ($right) {
echo "The point you selected (shown in green) is correct.";
} else {
echo "The point you selected (shown in red) is not correct.";
}
echo "
";
break;
}
$bolt_ex->index++;
}
class BoltFitbField {
public $textarea, $nrows, $ncols;
function __construct($textarea, $nrows, $ncols) {
$this->textarea = $textarea;
$this->nrows = $nrows;
$this->ncols = $ncols;
}
}
function field($n) {
return new BoltFitbField(false, 1, $n);
}
function box($nr, $nc) {
return new BoltFitbField(true, $nr, $nc);
}
class BoltFitbAnswer {
public $type; // 0=constant, 1=regexp, 2=func
public $ans;
function __construct($type, $ans) {
$this->type = $type;
$this->ans = $ans;
}
}
function answer($ans) {
return new BoltFitbAnswer(0, $ans);
}
function answer_regexp($ans) {
return new BoltFitbAnswer(1, $ans);
}
function answer_func($ans) {
return new BoltFitbAnswer(2, $ans);
}
function fitb() {
global $bolt_ex;
$args = func_get_args();
$field = new BoltFitbField(false, 1, 20);
$answer = null;
foreach ($args as $arg) {
if (is_array($arg)) {
$choices[] = $arg;
} else if (is_object($arg)) {
if (get_class($arg) == 'BoltFitbField') {
$field = $arg;
} else if (get_class($arg) == 'BoltFitbAns') {
$answer = $arg;
} else {
echo "bad arg to fitb()";
}
} else {
echo "bad arg to fitb()";
}
}
switch ($bolt_ex->mode) {
case BOLT_MODE_SHOW:
if ($field->textarea) {
echo "
";
} else {
echo "index." length=$field->ncols>";
}
break;
case BOLT_MODE_SCORE:
if (!$answer) break;
$bolt_ex->score = 0;
$key = "q_".$bolt_ex->index;
if (isset($$key)) {
$response = $$key;
} else {
$response = "";
}
switch ($answer->type) {
case 0:
if ($response == $answer->ans) {
$bolt_ex->score = 1;
}
break;
case 1:
if (ereg($answer->ans, $response)) {
$bolt_ex->score = 1;
}
break;
case 2:
$bolt_ex->score = call_user_func($answer->ans, $response);
break;
}
break;
case BOLT_MODE_ANSWER:
$key = "q_".$bolt_ex->index;
if (isset($$key)) {
$response = $$key;
} else {
$response = "";
}
break;
}
$bolt_ex->index++;
}
?>