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...
1 parent 7a82d19 commit 2443a13e754998cdf81d50930e7f4dc0acd3e50b kaipe committed Jul 30, 2004
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.