Permalink
Browse files

New quiz option - "Each attempt builds on the last"

This makes it possible for students to take a tedious quiz, save it half-way and have it graded. The student can then, at a later point, get back to the quiz and have the previous answers already filled in and graded. The student can then continue with the remaining questions as well as redo all the answers that got wrong at the previous attempt.
It seems to work fine with one little twisted exception:
Say that the student attempts the quiz first and that the teacher thereafter edits the quiz and removes or adds a few questions. This will work out fine for as long as the teacher do not get the idea of adding a question with question type RANDOM. The quiz will be fully functional again after removing that RANDOM question or resetting the option 'Each attempt builds on the last" to NO.
Not a very serious problem but it takes someone with greater insight in question type RANDOM to resolve it.

As always, I can not commit lang/en/quiz.php.
---
As I was using the function quiz_get_attempt_responses I had it refactored removing the obsolete argument $quiz. I also changed the call from review.php
  • Loading branch information...
1 parent da2ad42 commit 586b2c82ed58196ad9df5f91da6ab5c451b10afd kaipe committed Aug 3, 2003
Showing with 65 additions and 7 deletions.
  1. +41 −1 mod/quiz/attempt.php
  2. +4 −4 mod/quiz/lib.php
  3. +18 −0 mod/quiz/mod.html
  4. +1 −1 mod/quiz/review.php
  5. +1 −1 mod/quiz/version.php
View
@@ -191,7 +191,47 @@
echo "<br />";
- if (! quiz_print_quiz_questions($quiz)) {
+ $result = NULL; // Default
+ $questions = NULL; // Default
+ if ($quiz->eachattemptbuildsonthelast) {
+ $latestfinishedattempt->attempt = 0;
+ foreach ($attempts as $attempt) {
+ if ($attempt->timefinish
+ && $attempt->attempt > $latestfinishedattempt->attempt)
+ {
+ $latestfinishedattempt = $attempt;
+ }
+ }
+ if ($latestfinishedattempt->attempt > 0
+ and $questions =
+ quiz_get_attempt_responses($latestfinishedattempt))
+ {
+ // An previous attempt to continue on is found:
+ quiz_remove_unwanted_questions($questions, $quiz); // In case the quiz has been changed
+
+ if (!($result = quiz_grade_attempt_results($quiz, $questions))) {
+ // No results, reset to defaults:
+ $questions = NULL;
+ $result = NULL;
+
+ } else {
+ // We're on, latest attempt responses are to be included.
+ // In order to have this accomplished by
+ // the method quiz_print_quiz_questions we need to
+ // temporarilly change some of the $quiz attributes
+ // and remove some of the information from result.
+
+ $quiz->correctanswers = false; // Not a good idea to show them, huh?
+ $result->feedback = array(); // Not to be printed
+ $result->attemptbuildsonthelast = true;
+ }
+
+ } else {
+ // No latest attempt, or latest attempt was empty - Reset to defaults
+ $questions = NULL;
+ }
+ }
+ if (! quiz_print_quiz_questions($quiz, $result, $questions)) {
print_continue("view.php?id=$cm->id");
}
View
@@ -338,7 +338,7 @@ function quiz_get_answers($question, $answerids=NULL) {
}
-function quiz_get_attempt_responses($attempt, $quiz) {
+function quiz_get_attempt_responses($attempt) {
// Given an attempt object, this function gets all the
// stored responses and returns them in a format suitable
// for regrading using quiz_grade_attempt_results()
@@ -598,7 +598,7 @@ function quiz_print_question($number, $question, $grade, $courseid,
$answer = $answers[$answerid];
$qnumchar = chr(ord('a') + $key);
- if (empty($feedback) or empty($response[$answerid])) {
+ if (empty($response[$answerid])) {
$checked = "";
} else {
$checked = "CHECKED";
@@ -990,7 +990,7 @@ function quiz_print_quiz_questions($quiz, $results=NULL, $questions=NULL, $shuff
echo "<br \>";
}
- if (empty($results)) {
+ if (empty($results) || $results->attemptbuildsonthelast) {
if (!empty($quiz->shufflequestions)) { // Things have been mixed up, so pass the question order
$shuffleorder = implode(',', $questionorder);
echo "<input type=hidden name=shuffleorder value=\"$shuffleorder\">\n";
@@ -2234,7 +2234,7 @@ function quiz_save_question_options($question) {
function quiz_remove_unwanted_questions(&$questions, $quiz) {
/// Given an array of questions, and a list of question IDs,
/// this function removes unwanted questions from the array
-/// Used by review.php to counter changing quizzes
+/// Used by review.php and attempt.php to counter changing quizzes
$quizquestions = array();
$quizids = explode(",", $quiz->questions);
View
@@ -19,6 +19,9 @@
if (!isset($form->attempts)) {
$form->attempts = 0;
}
+ if (!isset($form->eachattemptbuildsonthelast)) {
+ $form->eachattemptbuildsonthelast = 0;
+ }
if (!isset($form->grademethod)) {
$form->grademethod = "";
}
@@ -131,6 +134,21 @@
</td>
</tr>
<tr valign=top>
+ <td align=right><p><b><?php print_string("eachattemptbuildsonthelast", "quiz") ?>:</b></p></td>
+ <td>
+ <?php
+ $options = array();
+ $options[0] = get_string("no");
+ $options[1] = get_string("yes");
+ choose_from_menu($options, "eachattemptbuildsonthelast",
+ "$form->eachattemptbuildsonthelast", "");
+ helpbutton("eachattemptbuildsonthelast",
+ get_string("eachattemptbuildsonthelast", "quiz"),
+ "quiz");
+ ?>
+ </td>
+</tr>
+<tr valign=top>
<td align=right><p><b><?php print_string("grademethod", "quiz") ?>:</b></p></td>
<td>
<?php
View
@@ -83,7 +83,7 @@
print_heading($quiz->name);
- if (! $questions = quiz_get_attempt_responses($attempt, $quiz)) {
+ if (! $questions = quiz_get_attempt_responses($attempt)) {
error("Could not reconstruct quiz results for attempt $attempt->id!");
}
View
@@ -5,7 +5,7 @@
// This fragment is called by moodle_needs_upgrading() and /admin/index.php
////////////////////////////////////////////////////////////////////////////////
-$module->version = 2003072901; // The (date) version of this module
+$module->version = 2003080301; // The (date) version of this module
$module->cron = 0; // How often should cron check this module (seconds)?
?>

0 comments on commit 586b2c8

Please sign in to comment.