Permalink
Browse files

New generic tools that allow the creation of dataset-dependent questions

as well as the new question type Calculated that uses this generic support.
  • Loading branch information...
kaipe
kaipe committed Jul 30, 2004
1 parent 7a82d19 commit 2443a13e754998cdf81d50930e7f4dc0acd3e50b
View
@@ -22,11 +22,13 @@
define("DESCRIPTION", "7");
define("NUMERICAL", "8");
define("MULTIANSWER", "9");
define("CALCULATED", "10");
$QUIZ_QUESTION_TYPE = array ( MULTICHOICE => get_string("multichoice", "quiz"),
TRUEFALSE => get_string("truefalse", "quiz"),
SHORTANSWER => get_string("shortanswer", "quiz"),
NUMERICAL => get_string("numerical", "quiz"),
CALCULATED => get_string("calculated", "quiz"),
MATCH => get_string("match", "quiz"),
DESCRIPTION => get_string("description", "quiz"),
RANDOM => get_string("random", "quiz"),
@@ -293,7 +295,6 @@ function quiz_load_questiontypes() {
}
}
/// FUNCTIONS ///////////////////////////////////////////////////////////////////
function quiz_add_instance($quiz) {
@@ -0,0 +1,177 @@
<FORM name="theform" method="post" <?php echo $onsubmit ?> action="question.php">
<CENTER>
<INPUT type="hidden" name="nextwizardpage" value="<?php p($nextwizardpage)?>"/>
<?php foreach ($calculatedmessages as $message) {formerr("$message<br/>");} ?>
<TABLE cellpadding=5>
<TR valign=top>
<TD align=right><P><B><?php print_string("category", "quiz") ?>:</B></P></TD>
<TD>
<?php quiz_category_select_menu($course->id, true, true, $question->category); ?>
</TD>
</TR>
<TR valign=top>
<TD align=right><P><B><?php print_string("questionname", "quiz") ?>:</B></P></TD>
<TD>
<INPUT type="text" name="name" size=50 value="<?php p($question->name) ?>">
<?php if (isset($err["name"])) formerr($err["name"]); ?>
</TD>
</TR>
<tr valign=top>
<td align="right"><p><b><?php print_string("question", "quiz") ?>:</b></p>
<br />
<br />
<br />
<p><font SIZE="1">
<?php
if ($usehtmleditor) {
helpbutton("richtext", get_string("helprichtext"), "moodle", true, true);
} else {
helpbutton("text", get_string("helptext"), "moodle", true, true);
}
?>
</font></p>
</td>
<td>
<?php if (isset($err["questiontext"])) {
formerr($err["questiontext"]);
echo "<br />";
}
print_textarea($usehtmleditor, 15, 60, 630, 300, "questiontext", $question->questiontext);
if ($usehtmleditor) { /// Trying this out for a while
echo '<input type="hidden" name="questiontextformat" value="'.FORMAT_HTML.'">';
} else {
echo "<div align=right>";
print_string("formattexttype");
echo ":&nbsp;";
if (!isset($question->questiontextformat)) {
$question->questiontextformat = FORMAT_MOODLE;
}
choose_from_menu(format_text_menu(), "questiontextformat", $question->questiontextformat, "");
helpbutton("textformat", get_string("helpformatting"));
echo "</div>";
}
?>
</td>
</tr>
<TR valign=top>
<TD align=right><P><B><?php print_string("imagedisplay", "quiz") ?>:</B></P></TD>
<TD>
<?php if (empty($images)) {
print_string("noimagesyet");
} else {
choose_from_menu($images, "image", "$question->image", get_string("none"),"","");
}
?>
</TD>
</TR>
<TR valign=top>
<TD align=right><P><B><?php print_string("correctanswerformula", "quiz") ?>:</B></P></TD>
<TD>
<INPUT align="LEFT" type="text" id="formula0" name="answer[]" size="20" value="<?php p($answers[0]->answer) ?>"/>&nbsp;&nbsp;
<INPUT type="hidden" name="fraction[]" value="1.0"/>
</TD>
</TR>
<TR valign=top>
<TD align=right><P><B><?php print_string("tolerance", "quiz"); ?>:</B></P></TD>
<TD>
<INPUT align="LEFT" type="text" id=tolerance0" name="tolerance[]" size="15" value="<?php p($answers[0]->tolerance) ?>" />&plusmn;
</TD>
</TR>
<TR valign=top>
<TD align=right><P><B><?php print_string("tolerancetype", "quiz"); ?>:</B></P></TD>
<TD>
<?php choose_from_menu($qtypeobj->tolerance_types(),
'tolerancetype[]', $answers[0]->tolerancetype, false); ?>
</TD>
</TR>
<TR valign=top>
<TD align=right><P><B><?php print_string("correctanswerlength", "quiz"); ?>:</B></P></TD>
<TD>
<?php choose_from_menu(array('1' => '1', '2' => '2', '3' => '3',
'4' => '4', '5' => '5', '6' => '6',
'7' => '7', '8' => '8', '9' => '9',
'10' => '10'),
'correctanswerlength[]',
$answers[0]->correctanswerlength, false); ?>
</TD>
</TR>
<TR valign=top>
<TD align=right><P><B><?php print_string("feedback", "quiz") ?>:</B></P></TD>
<TD>
<textarea name="feedback[]" rows=2 cols=50 wrap="virtual"><?php p($answers[0]->feedback) ?></textarea>
</TD>
</TR>
<TR valign=top>
<TD align=right><P><B><?php print_string("unit", "quiz") ?>:</B></P></TD>
<TD>
<P><INPUT type="HIDDEN" name="multiplier[]" value="1.0"/>
<INPUT align="LEFT" type="text" id="defaultunit" name="unit[]"
size="5" value="<?php p($units[0]->unit) ?>"/>
<B>(<?php print_string("optional", "quiz") ?>)</B></P>
</TD>
</TR>
<TR valign=top>
<td></td>
<TD align=left><P><B><?php print_string("alternativeunits", "quiz") ?>:</B></P></TD>
<td></td>
</TR>
<?PHP
for ($i=1; $i<count($units); $i++) {
$unit=$units[$i];
?>
<TR valign=top>
<td></td>
<TD align=left>
<P><B><?php print_string("multiplier", "quiz") ?>:</B>
<INPUT type="text" id="<?php p("multiplier$i") ?>" size="10"
align="RIGHT" name="multiplier[]"
value="<?php p($unit->multiplier) ?>"/>
<B>&nbsp;&nbsp;&nbsp;<?php print_string("unit", "quiz") ?>:</B>
<INPUT align="LEFT" type="text" id="<?php p("unit$i") ?>"
name="unit[]"
size="5" value="<?php p($unit->unit) ?>"/></P>
</TD>
</TR>
<?PHP
} /// END for
?>
</TABLE>
<INPUT type="hidden" name=id value="<?php p($question->id) ?>">
<INPUT type="hidden" name=qtype value="<?php p($question->qtype) ?>">
<INPUT type="submit" onClick="return determineMinAndMax();" value="<?php print_string("savechanges") ?>">
</CENTER>
</FORM>
<SCRIPT language="JAVASCRIPT">
function determineMinAndMax() {
// This client-side script will determine the values for min and max
// based on the input for answer and acceptederror.
with(document.theform) {
if (formula0.value=='') {
alert('<?php print_string("missingformula","quiz") ?>');
return false;
/* It could perhaps be an idea to parse the formula here
* but as it is necessary at the server anyway, we can
* leave like this for the moment. */
} else if (''!=defaultunit.value && !isNaN(defaultunit.value)) {
alert('<?php print_string("unitmustnotbenumeric","quiz") ?>');
return false;
} else if (isNaN(tolerance0.value)) {
alert('<?php print_string("tolerancemustbenumeric","quiz") ?>');
return false;
} else {
return true;
}
}
}
</SCRIPT>
<?php
if ($usehtmleditor) {
print_richedit_javascript("theform", "questiontext", "no");
}
?>
@@ -0,0 +1,198 @@
<?PHP // $Id$
// Get a handle to the question type we are dealing with here
$qtypeobj = $QUIZ_QTYPES[CALCULATED];
if (isset($form->editdatasets) && $form->editdatasets) {
require("$CFG->dirroot/mod/quiz/questiontypes/datasetdependent/datasetitems.php");
exit();
}
$calculatedmessages = array();
if ($form) {
// Verify the quality of the question properties
if (empty($question->name)) {
$calculatedmessages[] = get_string('missingname', 'quiz');
}
if (empty($question->questiontext)) {
$calculatedmessages[] = get_string('missingquestiontext', 'quiz');
}
// Formula stuff (verify some of them)
$answers[0]->answer = trim(array_shift($form->answer))
and false===($formulaerrors =
quiz_qtype_calculated_find_formula_errors($answers[0]->answer))
or $answers[0]->answer
and $calculatedmessages[] = $formulaerrors
or $calculatedmesages[] = get_string('missingformula', 'quiz');
$answers[0]->tolerance = array_shift($form->tolerance)
or $answers[0]->tolerance = 0.0;
is_numeric($answers[0]->tolerance)
or $calculatedmessages[] = get_string('tolerancemustbenumeric', 'quiz');
$answers[0]->feedback = array_shift($form->feedback);
// Let's trust the drop down menus.
$answers[0]->tolerancetype = array_shift($form->tolerancetype);
$answers[0]->correctanswerlength = array_shift($form->correctanswerlength);
$answers[0]->fraction = array_shift($form->fraction);
// Fill with remaining answers, in case calculated.html
// supports multiple formulas.
$i = 1;
foreach ($form->answer as $key => $answer) {
if (trim($answer)) {
$answers[$i]->answer = trim($answer);
$answers[$i]->tolerance = $form->tolerance[$key]
or $answers[$i]->tolerance = 0.0;
$answers[$i]->tolerancetype = $form->tolerancetype[$key];
$answers[$i]->correctanswerlength =
$form->correctanswerlength[$key];
$answers[$i]->fraction = $form->fraction[$key];
$answers[$i]->feedback = $form->feedback[$key];
// Check for errors:
false === ($formulaerrors =
quiz_qtype_calculated_find_formula_errors($answer))
or $calculatedmessages[] = $formulaerrors;
is_numeric($answers[$i]->tolerance)
or $calculatedmessages[] = get_string('tolerancemustbenumeric',
'quiz');
// Increase answer count
++$i;
}
}
// Finally the units:
// Start with the default units...
$units[0]->unit = array_shift($form->unit);
array_shift($form->multiplier); // In case it is not 1.0
$units[0]->multiplier = 1.0; // Must!
// Accept other units if they have legal multipliers
$i = 1;
foreach ($form->multiplier as $key => $multiplier) {
if ($multiplier && is_numeric($multiplier)) {
$units[$i]->multiplier = $multiplier;
$units[$i]->unit = $form->unit[$key];
++$i;
}
}
if (empty($calculatedmessages)) {
// First page calculated.html passed all right!
if (!empty($form->dataset)) {
// Dataset definitions have been set
// Save question!
$subtypeoptions->answers = $answers;
$subtypeoptions->units = $units;
$question = $qtypeobj->save_question
($question, $form, $course, $subtypeoptions);
require("$CFG->dirroot/mod/quiz/questiontypes/datasetdependent/datasetitems.php");
exit();
} else {
$datasetmessage = '';
}
// Now continue by preparing for the second page questiondatasets.html
$possibledatasets = $qtypeobj->find_dataset_names(
$question->questiontext);
$mandatorydatasets = array();
foreach ($answers as $answer) {
$mandatorydatasets += $qtypeobj
->find_dataset_names($answer->answer);
}
$datasets = $qtypeobj->construct_dataset_menus(
$question, $mandatorydatasets, $possibledatasets);
print_heading_with_help(get_string("choosedatasetproperties", "quiz"), "questiondatasets", "quiz");
require("$CFG->dirroot/mod/quiz/questiontypes/datasetdependent/questiondatasets.html");
exit();
}
} else {
// First page in question wizard - calculated.html!
// The layout of the editing page will only support
// one formula alternative for calculated questions.
// However, the code behind supports up to six formulas
// and the database store and attempt/review framework
// does not have any limit.
if (!empty($question->id)) {
$answersraw= $qtypeobj->get_answers($question);
}
$answers= array();
for ($i=0; $i<6; $i++) {
// Make answer slots with default values
$answers[$i]->answer = "";
$answers[$i]->feedback = "";
$answers[$i]->fraction = "1.0";
$answers[$i]->tolerance = "0.01";
$answers[$i]->tolerancetype = "1";
$answers[$i]->correctanswerlength = "2";
}
if (!empty($answersraw)) {
$i=0;
foreach ($answersraw as $answer) {
$answers[$i] = $answer;
$i++;
}
}
// Units are handled the same way
// as for numerical questions
$units = array();
for ($i=0 ; $i<6 ; $i++) {
// Make unit slots, default as blank...
$units[$i]->multiplier = '';
$units[$i]->unit = '';
}
if (!empty($question->id) and $unitsraw = get_records(
'quiz_numerical_units', 'question', $question->id)) {
/// Find default unit and have it put in the zero slot
/// This procedure might be overridden later when
/// the unit is stripped form an answer...
foreach ($unitsraw as $key => $unit) {
if (1.0 == $unit->multiplier) {
/// Default unit found:
$units[0] = $unit;
unset($unitsraw[$key]);
break;
}
}
/// Fill remaining answer slots with whatsever left
if (!empty($unitsraw)) {
$i = 1; // The zero slot got the default unit...
foreach ($unitsraw as $unit) {
$units[$i] = $unit;
$i++;
}
}
} else {
$units[0]->multiplier = 1.0;
}
// Strip trailing zeros from multipliers
foreach ($units as $i => $unit) {
if (ereg('^(.*\\..(.*[^0])?)0+$', $unit->multiplier, $regs1)) {
if (ereg('^(.+)\\.0$', $regs1[1], $regs2)) {
$units[$i]->multiplier = $regs2[1];
} else {
$units[$i]->multiplier = $regs1[1];
}
}
}
}
print_heading_with_help(get_string("editingcalculated", "quiz"), "calculated", "quiz");
require("calculated.html");
?>
Oops, something went wrong.

0 comments on commit 2443a13

Please sign in to comment.