Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
New question type: Numerical questions.
Mostly coded by Henrik Kaipe - I changed a few things on the way in.
  • Loading branch information
moodler committed Jul 10, 2003
1 parent 60bb260 commit 361f649
Show file tree
Hide file tree
Showing 11 changed files with 303 additions and 24 deletions.
2 changes: 2 additions & 0 deletions lang/en/help/index.html
Expand Up @@ -65,11 +65,13 @@
<li><a href="help.php?module=quiz&file=categories.html">Categories</a>
<li><a href="help.php?module=quiz&file=correctanswers.html">Correct answers</a>
<li><a href="help.php?module=quiz&file=createmultiple.html">Creating multiple quizzes</a>
<li><a href="help.php?module=quiz&file=description.html">Descriptions</a>
<li><a href="help.php?module=quiz&file=grademethod.html">Grading method</a>
<li><a href="help.php?module=quiz&file=import.html">Importing questions</a>
<li><a href="help.php?module=quiz&file=match.html">Matching questions</a>
<li><a href="help.php?module=quiz&file=maxgrade.html">Maximum grade</a>
<li><a href="help.php?module=quiz&file=multichoice.html">Multiple choice questions</a>
<li><a href="help.php?module=quiz&file=numerical.html">Numerical questions</a>
<li><a href="help.php?module=quiz&file=timeopen.html">Opening and closing the quiz</a>
<li><a href="help.php?module=quiz&file=feedback.html">Question Feedback</a>
<li><a href="help.php?module=quiz&file=questiontypes.html">Question types- creating a new question</a>
Expand Down
10 changes: 10 additions & 0 deletions lang/en/help/quiz/numerical.html
@@ -0,0 +1,10 @@
<P ALIGN=CENTER><B>Numerical questions</B></P>

<p>In response to a question (that may include a image) the respondent
must type a number.</p>

<p>The required answer may have an accepted error. This allows a range of
answers to be set.</p>

<p>For example, if the answer is 30 with an error of 5, then any number
between 25 and 35 will be accepted as correct.</p>
5 changes: 5 additions & 0 deletions lang/en/quiz.php
Expand Up @@ -5,6 +5,7 @@
$string['modulenameplural'] = "Quizzes";
#------------------------------------------------------------

$string['acceptederror'] = "Accepted error";
$string['addquestions'] = "Add questions";
$string['addingquestions'] = "This side of the page is where you manage your database of questions. Questions are stored in categories to help you keep them organised, and can be used by any quiz in your course or even other courses if you choose to 'publish' them. <br /><br />After you select or create a question category you will be able to create or edit questions. You can select any of these questions to add to your quiz over on the other side of this page.";
$string['addquestionstoquiz'] = "Add questions to current quiz";
Expand All @@ -16,6 +17,7 @@
$string['answerhowmany'] = "One or multiple answers?";
$string['answersingleyes'] = "One answer only";
$string['answersingleno'] = "Multiple answers allowed";
$string['answerswithacceptederrormarginmustbenumeric'] = "Answers with accepted error must be numeric";
$string['attempt'] = "Attempt \$a";
$string['attemptfirst'] = "First attempt";
$string['attemptlast'] = "Last attempt";
Expand Down Expand Up @@ -51,6 +53,7 @@
$string['editingdescription'] = "Editing a Description";
$string['editingmatch'] = "Editing a Matching Question";
$string['editingmultichoice'] = "Editing a Multiple Choice question";
$string['editingnumerical'] = "Editing a numerical question";
$string['editingquiz'] = "Editing quiz";
$string['editingquestion'] = "Editing a question";
$string['editingrandom'] = "Editing a Random Question";
Expand Down Expand Up @@ -80,6 +83,7 @@
$string['marks'] = "Marks";
$string['match'] = "Matching";
$string['matchanswer'] = "Matching answer";
$string['missingcorrectanswer'] = "Correct answer must be specified";
$string['missingname'] = "Missing question name";
$string['missingquestiontext'] = "Missing question text";
$string['missingword'] = "Missing word format";
Expand All @@ -92,6 +96,7 @@
$string['noreviewuntil'] = "You are not allowed to review this quiz until \$a";
$string['notenoughsubquestions'] = "Not enough sub-questions have been defined!<br>
Do you want to go back and fix this question?";
$string['numerical'] = "Numerical";
$string['publish'] = "Publish";
$string['qti'] = "IMS QTI format";
$string['question'] = "Question";
Expand Down
12 changes: 12 additions & 0 deletions mod/quiz/db/mysql.php
Expand Up @@ -92,6 +92,18 @@ function quiz_upgrade($oldversion) {
table_column("quiz", "", "shuffleanswers", "INTEGER", "4", "UNSIGNED", "0", "NOT NULL", "shufflequestions");
}

if ($oldversion < 2003071000) {

modify_database ("", " CREATE TABLE `prefix_quiz_numerical` (
`id` int(10) unsigned NOT NULL auto_increment,
`answer` int(10) unsigned NOT NULL default '0',
`min` varchar(255) NOT NULL default '',
`max` varchar(255) NOT NULL default '',
PRIMARY KEY (`id`),
KEY `answer` (`answer`)
) TYPE=MyISAM COMMENT='Options for numerical questions'; ");
}

return true;
}

Expand Down
14 changes: 14 additions & 0 deletions mod/quiz/db/mysql.sql
Expand Up @@ -216,6 +216,20 @@ CREATE TABLE `prefix_quiz_shortanswer` (
) TYPE=MyISAM COMMENT='Options for short answer questions';
# --------------------------------------------------------

#
# Table structure for table `quiz_numerical`
#

CREATE TABLE `prefix_quiz_numerical` (
`id` int(10) unsigned NOT NULL auto_increment,
`answer` int(10) unsigned NOT NULL default '0',
`min` varchar(255) NOT NULL default '',
`max` varchar(255) NOT NULL default '',
PRIMARY KEY (`id`),
KEY `answer` (`answer`)
) TYPE=MyISAM COMMENT='Options for numerical questions';
# --------------------------------------------------------

#
# Table structure for table `quiz_truefalse`
#
Expand Down
141 changes: 119 additions & 22 deletions mod/quiz/lib.php
Expand Up @@ -20,14 +20,17 @@
define("MATCH", "5");
define("RANDOMSAMATCH", "6");
define("DESCRIPTION", "7");
define("NUMERICAL", "8");

$QUIZ_QUESTION_TYPE = array ( MULTICHOICE => get_string("multichoice", "quiz"),
TRUEFALSE => get_string("truefalse", "quiz"),
SHORTANSWER => get_string("shortanswer", "quiz"),
NUMERICAL => get_string("numerical", "quiz"),
MATCH => get_string("match", "quiz"),
DESCRIPTION => get_string("description", "quiz"),
RANDOM => get_string("random", "quiz"),
RANDOMSAMATCH => get_string("randomsamatch", "quiz"),
DESCRIPTION => get_string("description", "quiz") );
RANDOMSAMATCH => get_string("randomsamatch", "quiz")
);

$QUIZ_FILE_FORMAT = array ( "custom" => get_string("custom", "quiz"),
"missingword" => get_string("missingword", "quiz"),
Expand Down Expand Up @@ -293,6 +296,15 @@ function quiz_get_answers($question) {
AND q.id = a.question ");
break;

case NUMERICAL: // Logical support for multiple answers
return get_records_sql("SELECT a.*, n.min, n.max
FROM {$CFG->prefix}quiz_numerical n,
{$CFG->prefix}quiz_answers a
WHERE a.question = '$question->id'
AND n.answer = a.id ");
break;


default:
return false;
}
Expand Down Expand Up @@ -342,13 +354,13 @@ function quiz_get_attempt_responses($attempt, $quiz) {
function quiz_print_comment($text) {
global $THEME;

echo "<SPAN CLASS=feedbacktext>".text_to_html($text, true, false)."</SPAN>";
echo "<span class=feedbacktext>".text_to_html($text, true, false)."</span>";
}

function quiz_print_correctanswer($text) {
global $THEME;

echo "<P ALIGN=RIGHT><SPAN CLASS=highlight>$text</SPAN></P>";
echo "<p align=right><span class=highlight>$text</span></p>";
}

function quiz_print_question_icon($question, $editlink=true) {
Expand All @@ -357,33 +369,36 @@ function quiz_print_question_icon($question, $editlink=true) {
global $QUIZ_QUESTION_TYPE;

if ($editlink) {
echo "<A HREF=\"question.php?id=$question->id\" TITLE=\"".$QUIZ_QUESTION_TYPE[$question->qtype]."\">";
echo "<a href=\"question.php?id=$question->id\" title=\"".$QUIZ_QUESTION_TYPE[$question->qtype]."\">";
}
switch ($question->qtype) {
case SHORTANSWER:
echo "<IMG BORDER=0 HEIGHT=16 WIDTH=16 SRC=\"pix/sa.gif\">";
echo '<img border=0 height=16 width=16 src="pix/sa.gif">';
break;
case TRUEFALSE:
echo "<IMG BORDER=0 HEIGHT=16 WIDTH=16 SRC=\"pix/tf.gif\">";
echo '<img border=0 height=16 width=16 src="pix/tf.gif">';
break;
case MULTICHOICE:
echo "<IMG BORDER=0 HEIGHT=16 WIDTH=16 SRC=\"pix/mc.gif\">";
echo '<img border=0 height=16 width=16 src="pix/mc.gif">';
break;
case RANDOM:
echo "<IMG BORDER=0 HEIGHT=16 WIDTH=16 SRC=\"pix/rs.gif\">";
echo '<img border=0 height=16 width=16 src="pix/rs.gif">';
break;
case MATCH:
echo "<IMG BORDER=0 HEIGHT=16 WIDTH=16 SRC=\"pix/ma.gif\">";
echo '<img border=0 height=16 width=16 src="pix/ma.gif">';
break;
case RANDOMSAMATCH:
echo "<IMG BORDER=0 HEIGHT=16 WIDTH=16 SRC=\"pix/rm.gif\">";
echo '<img border=0 height=16 width=16 src="pix/rm.gif">';
break;
case DESCRIPTION:
echo "<IMG BORDER=0 HEIGHT=16 WIDTH=16 SRC=\"pix/de.gif\">";
echo '<img border=0 height=16 width=16 src="pix/de.gif">';
break;
case NUMERICAL:
echo '<img border=0 height=16 width=16 src="pix/nu.gif">';
break;
}
if ($editlink) {
echo "</A>\n";
echo "</a>\n";
}
}

Expand Down Expand Up @@ -413,15 +428,15 @@ function quiz_print_question($number, $question, $grade, $courseid,
$stranswer = get_string("answer", "quiz");
$strmarks = get_string("marks", "quiz");

echo "<TABLE WIDTH=100% CELLSPACING=10><TR><TD NOWRAP WIDTH=100 VALIGN=top>";
echo "<P ALIGN=CENTER><B>$number</B></P>";
echo "<table width=100% cellspacing=10><tr><td nowrap width=100 valign=top>";
echo "<p align=center><b>$number</b></p>";
if ($feedback or $response) {
echo "<P ALIGN=CENTER><FONT SIZE=1>$strmarks: $actualgrade/$grade</FONT></P>";
echo "<p align=center><font size=1>$strmarks: $actualgrade/$grade</font></p>";
} else {
echo "<P ALIGN=CENTER><FONT SIZE=1>$grade $strmarks</FONT></P>";
echo "<p align=center><font size=1>$grade $strmarks</font></p>";
}
print_spacer(1,100);
echo "</TD><TD VALIGN=TOP>";
echo "</td><td valign=top>";

if (empty($realquestion)) {
$realquestion->id = $question->id;
Expand All @@ -432,9 +447,7 @@ function quiz_print_question($number, $question, $grade, $courseid,
switch ($question->qtype) {

case SHORTANSWER:
if (!$options = get_record("quiz_shortanswer", "question", $question->id)) {
notify("Error: Missing question options!");
}
case NUMERICAL:
echo text_to_html($question->questiontext);
if ($question->image) {
print_file_picture($question->image, $courseid);
Expand Down Expand Up @@ -1423,7 +1436,7 @@ function quiz_grade_attempt_results($quiz, $questions) {
}
$response[0] = $question->answer;
$bestshortanswer = 0;
foreach($answers as $answer) { // There might be multiple right answers
foreach ($answers as $answer) { // There might be multiple right answers
if ($answer->fraction > $bestshortanswer) {
$correct[$answer->id] = $answer->answer;
$bestshortanswer = $answer->fraction;
Expand All @@ -1439,6 +1452,26 @@ function quiz_grade_attempt_results($quiz, $questions) {
}
break;

case NUMERICAL:
if ($question->answer) {
$question->answer = trim(stripslashes($question->answer[0]));
} else {
$question->answer = "";
}
$response[0] = $question->answer;
$bestshortanswer = 0;
foreach ($answers as $answer) { // There might be multiple right answers
if ($answer->fraction > $bestshortanswer) {
$correct[$answer->id] = $answer->answer;
$bestshortanswer = $answer->fraction;
}
if ( ((float)$question->answer >= (float)$answer->min) and
((float)$question->answer <= (float)$answer->max) ) {
$feedback[0] = $answer->feedback;
$grade = (float)$answer->fraction * $question->grade;
}
}
break;

case TRUEFALSE:
if ($question->answer) {
Expand Down Expand Up @@ -1641,6 +1674,70 @@ function quiz_save_question_options($question) {
}
break;

case NUMERICAL: // Note similarities to SHORTANSWER

if (!$oldanswers = get_records("quiz_answers", "question", $question->id, "id ASC")) {
$oldanswers = array();
}

$answers = array();
$maxfraction = -1;

// Insert all the new answers
foreach ($question->answer as $key => $dataanswer) {
if ($dataanswer != "") {
if ($oldanswer = array_shift($oldanswers)) { // Existing answer, so reuse it
$answer = $oldanswer;
$answer->answer = $dataanswer;
$answer->fraction = $question->fraction[$key];
$answer->feedback = $question->feedback[$key];
if (!update_record("quiz_answers", $answer)) {
$result->error = "Could not update quiz answer! (id=$answer->id)";
return $result;
}
} else { // This is a completely new answer
unset($answer);
$answer->answer = $dataanswer;
$answer->question = $question->id;
$answer->fraction = $question->fraction[$key];
$answer->feedback = $question->feedback[$key];
if (!$answer->id = insert_record("quiz_answers", $answer)) {
$result->error = "Could not insert quiz answer!";
return $result;
}
}
$answers[] = $answer->id;
if ($question->fraction[$key] > $maxfraction) {
$maxfraction = $question->fraction[$key];
}

if ($options = get_record("quiz_numerical", "answer", $answer->id)) {
$options->min= $question->min[$key];
$options->max= $question->max[$key];
if (!update_record("quiz_numerical", $options)) {
$result->error = "Could not update quiz numerical options! (id=$options->id)";
return $result;
}
} else { // completely new answer
unset($options);
$options->min= $question->min[$key];
$options->max= $question->max[$key];
$options->answer= $answer->id;
if (!insert_record("quiz_numerical", $options)) {
$result->error = "Could not insert quiz numerical options!";
return $result;
}
}
}
}

/// Perform sanity checks on fractional grades
if ($maxfraction != 1) {
$maxfraction = $maxfraction * 100;
$result->notice = get_string("fractionsnomax", "quiz", $maxfraction);
return $result;
}
break;


case TRUEFALSE:
Expand Down

0 comments on commit 361f649

Please sign in to comment.