]> git.mjollnir.org Git - moodle.git/commitdiff
Just to show that something is happening!
authormoodler <moodler>
Sun, 13 Oct 2002 07:17:48 +0000 (07:17 +0000)
committermoodler <moodler>
Sun, 13 Oct 2002 07:17:48 +0000 (07:17 +0000)
At this stage this module:

  - prints quizzes,
  - accepts answers (for multiple attempts) and grades them,
  - stores the grades.

Really, it's usable as long as you don't mind using the database manually. :)

Next up is quiz reports, then I'll tackle quiz creation.

mod/quiz/attempt.php
mod/quiz/db/mysql.sql
mod/quiz/lib.php
mod/quiz/version.php
mod/quiz/view.php

index b5ee176bce946631fe82ac310264f174b9c5ef22..da1f7e6244e4b12a764e926537a63a1844d4c67f 100644 (file)
 
     require_login($course->id);
 
-    add_to_log($course->id, "quiz", "attempt", "attempt.php?id=$cm->id", "$quiz->id");
 
-    if ($course->format == "weeks" and $quiz->days) {
-        $timenow = time();
-        $timestart = $course->startdate + (($cw->section - 1) * 608400);
-        $timefinish = $timestart + (3600 * 24 * $quiz->days);
-        $available = ($timestart < $timenow and $timenow < $timefinish);
-    } else {
-        $available = true;
-    }
 
 // Print the page header
 
 
     print_header("$course->shortname: $quiz->name", "$course->fullname",
                  "$navigation <A HREF=index.php?id=$course->id>$strquizzes</A> -> $quiz->name", 
-                  "", "", true, update_module_icon($cm->id, $course->id));
+                  "", "", true);
 
-/// Print the headings and so on
-
-    print_heading($quiz->name);
-
-    if (!$available) {
-        error("Sorry, this quiz is not available", "view.php?id=$cm->id");
-    }
+/// Check some quiz parameters
 
     if ($attempts = quiz_get_user_attempts($quiz->id, $USER->id)) {
         $numattempts = count($attempts) + 1;
         error("Sorry, you've had $quiz->attempts attempts already.", "view.php?id=$cm->id");
     }
 
-    print_heading("Attempt $numattempts out of $quiz->attempts");
+    if ($course->format == "weeks" and $quiz->days) {
+        $timenow = time();
+        $timestart = $course->startdate + (($cw->section - 1) * 608400);
+        $timefinish = $timestart + (3600 * 24 * $quiz->days);
+        $available = ($timestart < $timenow and $timenow < $timefinish);
+    } else {
+        $available = true;
+    }
 
-    print_simple_box($quiz->intro, "CENTER");
+/// Check to see if they are submitting answers
+    if (match_referer() && isset($HTTP_POST_VARS)) {
+        add_to_log($course->id, "quiz", "submit", "attempt.php?id=$cm->id", "$quiz->id");
 
+        $rawanswers = $HTTP_POST_VARS;
+        unset($rawanswers["q"]);  // quiz id
+        if (! count($rawanswers)) {
+            print_heading(get_string("noanswers", "quiz"));
+            print_continue("attempt.php?q=$quiz->id");
+            exit;
+        }   
 
-/// Print all the questions
+        if (!$questions = get_records_list("quiz_questions", "id", $quiz->questions)) {
+            error("No questions found!");
+        }
 
-    echo "<BR>";
+        foreach ($rawanswers as $key => $value) {    // Parse input for question -> answers
+            if (substr($key, 0, 1) == "q") {
+                $key = substr($key,1);
+                if (!isset($questions[$key])) {
+                    if (substr_count($key, "a")) {   // checkbox style multiple answers
+                        $check = explode("a", $key);
+                        $key   = $check[0];
+                        $value = $check[1];
+                    } else {
+                        error("Answer received for non-existent question ($key)!");
+                    }
+                }
+                $questions[$key]->answer[] = $value;  // Store answers in array
+            }
+        }
 
-    if (!$quiz->questions) {
-        error("No questions have been defined!", "view.php?id=$cm->id");
-    }
+        if (!$result = quiz_grade_attempt_results($quiz, $questions)) {
+            error("Could not grade your quiz attempt!");
+        }
+
+        if (! $attempt = quiz_save_attempt($quiz, $questions, $result, $numattempts)) {
+            error("Sorry! Could not save your attempt!");
+        }
+
+        if (! quiz_save_best_grade($quiz, $USER)) {
+            error("Sorry! Could not calculate your best grade!");
+        }
 
-    $questions = explode(",", $quiz->questions);
+        print_heading(get_string("grade", "quiz").": $result->grade/$quiz->grade  ($result->sumgrades / $quiz->sumgrades = $percent %)");
 
-    if (!$grades = get_records_sql("SELECT question, grade FROM quiz_question_grades WHERE question in ($quiz->questions)")) {
-        error("No grades were found for these questions!");
+        print_continue("view.php?id=$cm->id");
+
+        if ($quiz->correctanswers) {
+            quiz_print_quiz_questions($quiz, $result);
+            print_continue("view.php?id=$cm->id");
+        }
+
+        exit;
     }
 
-    echo "<FORM METHOD=POST ACTION=attempt.php>";
-    echo "<INPUT TYPE=hidden NAME=q VALUE=\"$quiz->id\">";
-    foreach ($questions as $key => $questionid) {
-        print_simple_box_start("CENTER", "90%");
-        quiz_print_question($key+1, $questionid, $grades[$questionid]->grade, $course->id);
-        print_simple_box_end();
-        echo "<BR>";
+    add_to_log($course->id, "quiz", "attempt", "attempt.php?id=$cm->id", "$quiz->id");
+
+/// Print the quiz page
+
+/// First print the headings and so on
+
+    print_heading($quiz->name);
+
+    if (!$available) {
+        error("Sorry, this quiz is not available", "view.php?id=$cm->id");
     }
-    echo "<CENTER><INPUT TYPE=submit VALUE=\"".get_string("savemyanswers", "quiz")."\"></CENTER>";
-    echo "</FORM>";
+
+    print_heading("Attempt $numattempts out of $quiz->attempts");
+
+    print_simple_box($quiz->intro, "CENTER");
+
+
+/// Print all the questions
+
+    echo "<BR>";
+
+    quiz_print_quiz_questions($quiz);
 
 
-// Finish the page
+/// Finish the page
     print_footer($course);
 
 ?>
index ddb835fb1cc821a97ddf489f4c37942f8d607159..e1e192e153513cbe3d52bceb0d4128cf42a1560a 100644 (file)
@@ -3,7 +3,7 @@
 # http://www.phpmyadmin.net/ (download page)
 #
 # Host: localhost
-# Generation Time: Oct 07, 2002 at 12:23 AM
+# Generation Time: Oct 13, 2002 at 03:11 PM
 # Server version: 3.23.49
 # PHP Version: 4.2.3
 # Database : `moodle`
@@ -40,10 +40,11 @@ CREATE TABLE `quiz_answers` (
   `id` int(10) unsigned NOT NULL auto_increment,
   `question` int(10) unsigned NOT NULL default '0',
   `answer` varchar(255) NOT NULL default '',
-  `grade` float NOT NULL default '0',
+  `fraction` float NOT NULL default '0',
   `feedback` varchar(255) NOT NULL default '',
   PRIMARY KEY  (`id`)
-) TYPE=MyISAM COMMENT='Answers, with a percentage grade and feedback';
+
+) TYPE=MyISAM COMMENT='Answers, with a fractional grade (0-1) and feedback';
 # --------------------------------------------------------
 
 #
@@ -55,7 +56,7 @@ CREATE TABLE `quiz_attempts` (
   `quiz` int(10) unsigned NOT NULL default '0',
   `user` int(10) unsigned NOT NULL default '0',
   `attempt` smallint(6) NOT NULL default '0',
-  `grade` float NOT NULL default '0',
+  `sumgrades` float NOT NULL default '0',
   `timemodified` int(10) unsigned NOT NULL default '0',
   PRIMARY KEY  (`id`)
 ) TYPE=MyISAM COMMENT='Stores various attempts on a quiz';
@@ -173,4 +174,3 @@ CREATE TABLE `quiz_truefalse` (
   KEY `question` (`question`)
 ) TYPE=MyISAM COMMENT='Options for True-False questions';
 
-
index de777a0a57a3c0208f72a309d36c042fdd77a2b0..f34fda82c4865672295f99e1a748ad34a6be2582 100644 (file)
@@ -1,19 +1,34 @@
 <?PHP  // $Id$
 
-// Library of function for module quiz
+/// Library of function for module quiz
 
-$QUIZ_GRADE_METHOD = array ( "1" => get_string("gradehighest", "quiz"),
-                             "2" => get_string("gradeaverage", "quiz"),
-                             "3" => get_string("attemptfirst", "quiz"),
-                             "4" => get_string("attemptlast", "quiz")
-                           );
+/// CONSTANTS ///////////////////////////////////////////////////////////////////
 
+define("GRADEHIGHEST", "1");
+define("GRADEAVERAGE", "2");
+define("ATTEMPTFIRST", "3");
+define("ATTEMPTLAST",  "4");
+$QUIZ_GRADE_METHOD = array ( GRADEHIGHEST => get_string("gradehighest", "quiz"),
+                             GRADEAVERAGE => get_string("gradeaverage", "quiz"),
+                             ATTEMPTFIRST => get_string("attemptfirst", "quiz"),
+                             ATTEMPTLAST  => get_string("attemptlast", "quiz"));
+
+define("SHORTANSWER", "1");
+define("TRUEFALSE",   "2");
+define("MULTICHOICE", "3");
+$QUIZ_QUESTION_TYPE = array ( SHORTANSWER => get_string("shortanswer", "quiz"),
+                              TRUEFALSE   => get_string("truefalse", "quiz"),
+                              MULTICHOICE => get_string("multichoice", "quiz"));
+
+
+
+/// FUNCTIONS ///////////////////////////////////////////////////////////////////
 
 function quiz_add_instance($quiz) {
-// Given an object containing all the necessary data, 
-// (defined by the form in mod.html) this function 
-// will create a new instance and return the id number 
-// of the new instance.
+/// Given an object containing all the necessary data, 
+/// (defined by the form in mod.html) this function 
+/// will create a new instance and return the id number 
+/// of the new instance.
 
     $quiz->timemodified = time();
 
@@ -24,9 +39,9 @@ function quiz_add_instance($quiz) {
 
 
 function quiz_update_instance($quiz) {
-// Given an object containing all the necessary data, 
-// (defined by the form in mod.html) this function 
-// will update an existing instance with new data.
+/// Given an object containing all the necessary data, 
+/// (defined by the form in mod.html) this function 
+/// will update an existing instance with new data.
 
     $quiz->timemodified = time();
     $quiz->id = $quiz->instance;
@@ -38,9 +53,9 @@ function quiz_update_instance($quiz) {
 
 
 function quiz_delete_instance($id) {
-// Given an ID of an instance of this module, 
-// this function will permanently delete the instance 
-// and any data that depends on it.  
+/// Given an ID of an instance of this module, 
+/// this function will permanently delete the instance 
+/// and any data that depends on it.  
 
     if (! $quiz = get_record("quiz", "id", "$id")) {
         return false;
@@ -58,27 +73,27 @@ function quiz_delete_instance($id) {
 }
 
 function quiz_user_outline($course, $user, $mod, $quiz) {
-// Return a small object with summary information about what a 
-// user has done with a given particular instance of this module
-// Used for user activity reports.
-// $return->time = the time they did it
-// $return->info = a short text description
+/// Return a small object with summary information about what a 
+/// user has done with a given particular instance of this module
+/// Used for user activity reports.
+/// $return->time = the time they did it
+/// $return->info = a short text description
 
     return $return;
 }
 
 function quiz_user_complete($course, $user, $mod, $quiz) {
-// Print a detailed representation of what a  user has done with 
-// a given particular instance of this module, for user activity reports.
+/// Print a detailed representation of what a  user has done with 
+/// a given particular instance of this module, for user activity reports.
 
     return true;
 }
 
 function quiz_print_recent_activity(&$logs, $isteacher=false) {
-// Given a list of logs, assumed to be those since the last login 
-// this function prints a short list of changes related to this module
-// If isteacher is true then perhaps additional information is printed.
-// This function is called from course/lib.php: print_recent_activity()
+/// Given a list of logs, assumed to be those since the last login 
+/// this function prints a short list of changes related to this module
+/// If isteacher is true then perhaps additional information is printed.
+/// This function is called from course/lib.php: print_recent_activity()
 
     global $CFG, $COURSE_TEACHER_COLOR;
 
@@ -86,9 +101,9 @@ function quiz_print_recent_activity(&$logs, $isteacher=false) {
 }
 
 function quiz_cron () {
-// Function to be run periodically according to the moodle cron
-// This function searches for things that need to be done, such 
-// as sending out mail, toggling flags etc ... 
+/// Function to be run periodically according to the moodle cron
+/// This function searches for things that need to be done, such 
+/// as sending out mail, toggling flags etc ... 
 
     global $CFG;
 
@@ -97,10 +112,11 @@ function quiz_cron () {
 
 
 //////////////////////////////////////////////////////////////////////////////////////
-// Any other quiz functions go here.  Each of them must have a name that 
-// starts with quiz_
+/// Any other quiz functions go here.  Each of them must have a name that 
+/// starts with quiz_
 
 function  quiz_print_question($number, $questionid, $grade, $courseid) {
+/// Prints a quiz question, any format
     
     if (!$question = get_record("quiz_questions", "id", $questionid)) {
         notify("Error: Question not found!");
@@ -115,13 +131,10 @@ function  quiz_print_question($number, $questionid, $grade, $courseid) {
     echo "</TD><TD VALIGN=TOP>";
 
     switch ($question->type) {
-       case 1: // shortanswer
+       case SHORTANSWER: 
            if (!$options = get_record("quiz_shortanswer", "question", $question->id)) {
                notify("Error: Missing question options!");
            }
-           if (!$answer = get_record("quiz_answers", "id", $options->answer)) {
-               notify("Error: Missing question answers!");
-           }
            echo "<P>$question->question</P>";
            if ($question->image) {
                print_file_picture($question->image, $courseid, 200);
@@ -129,7 +142,7 @@ function  quiz_print_question($number, $questionid, $grade, $courseid) {
            echo "<P ALIGN=RIGHT>$stranswer: <INPUT TYPE=TEXT NAME=q$question->id SIZE=20></P>";
            break;
 
-       case 2: // true-false
+       case TRUEFALSE:
            if (!$options = get_record("quiz_truefalse", "question", $question->id)) {
                notify("Error: Missing question options!");
            }
@@ -155,11 +168,11 @@ function  quiz_print_question($number, $questionid, $grade, $courseid) {
            echo "<INPUT TYPE=RADIO NAME=\"q$question->id\" VALUE=\"$false->id\">$false->answer</P>";
            break;
 
-       case 3: // multiple-choice
+       case MULTICHOICE:
            if (!$options = get_record("quiz_multichoice", "question", $question->id)) {
                notify("Error: Missing question options!");
            }
-           if (!$answers = get_records_sql("SELECT * from quiz_answers WHERE id in ($options->answers)")) {
+           if (!$answers = get_records_list("quiz_answers", "id", $options->answers)) {
                notify("Error: Missing question answers!");
            }
            echo "<P>$question->question</P>";
@@ -174,10 +187,10 @@ function  quiz_print_question($number, $questionid, $grade, $courseid) {
                $answer = $answers[$answerid];
                $qnum = $key + 1;
                echo "<TR><TD valign=top>";
-               if (!$options->single) {
+               if ($options->single) {
                    echo "<INPUT TYPE=RADIO NAME=q$question->id VALUE=\"$answer->id\">";
                } else {
-                   echo "<INPUT TYPE=CHECKBOX NAME=q$question->id VALUE=\"$answer->id\">";
+                   echo "<INPUT TYPE=CHECKBOX NAME=q$question->id"."a$answer->id VALUE=\"$answer->id\">";
                }
                echo "</TD>";
                echo "<TD valign=top>$qnum. $answer->answer</TD>";
@@ -194,12 +207,40 @@ function  quiz_print_question($number, $questionid, $grade, $courseid) {
     echo "</TD></TR></TABLE>";
 }
 
+function quiz_print_quiz_questions($quiz, $results=NULL) {
+// Prints a whole quiz on one page.
+
+    if (!$quiz->questions) {
+        error("No questions have been defined!", "view.php?id=$cm->id");
+    }
+
+    $questions = explode(",", $quiz->questions);
+
+    if (!$grades = get_records_list("quiz_question_grades", "question", $quiz->questions, "", "question,grade")) {
+        error("No grades were found for these questions!");
+    }
+
+    echo "<FORM METHOD=POST ACTION=attempt.php>";
+    echo "<INPUT TYPE=hidden NAME=q VALUE=\"$quiz->id\">";
+    foreach ($questions as $key => $questionid) {
+        print_simple_box_start("CENTER", "90%");
+        quiz_print_question($key+1, $questionid, $grades[$questionid]->grade, $course->id);
+        print_simple_box_end();
+        echo "<BR>";
+    }
+    echo "<CENTER><INPUT TYPE=submit VALUE=\"".get_string("savemyanswers", "quiz")."\"></CENTER>";
+    echo "</FORM>";
+}
+
+
 
 function quiz_get_user_attempts($quizid, $userid) {
+// Returns a list of all attempts by a user
     return get_records_sql("SELECT * FROM quiz_attempts WHERE quiz = '$quizid' and user = '$userid' ORDER by attempt ASC");
 }
 
-function quiz_get_grade($quizid, $userid) {
+function quiz_get_best_grade($quizid, $userid) {
+/// Get the best current grade for a particular user in a quiz
     if (!$grade = get_record_sql("SELECT * FROM quiz_grades WHERE quiz = '$quizid' and user = '$userid'")) {
         return 0;
     }
@@ -207,41 +248,236 @@ function quiz_get_grade($quizid, $userid) {
     return $grade->grade;
 }
 
+function quiz_save_best_grade($quiz, $user) {
+/// Calculates the best grade out of all attempts at a quiz for a user,
+/// and then saves that grade in the quiz_grades table.
+
+    if (!$attempts = quiz_get_user_attempts($quiz->id, $user->id)) {
+        return false;
+    }
+
+    $bestgrade = quiz_calculate_best_grade($quiz, $attempts);
+    $bestgrade = (($bestgrade / $quiz->sumgrades) * $quiz->grade);
+
+    if ($grade = get_record_sql("SELECT * FROM quiz_grades WHERE quiz='$quiz->id' AND user='$user->id'")) {
+        $grade->grade = $bestgrade;
+        $grade->timemodified = time();
+        if (!update_record("quiz_grades", $grade)) {
+            return false;
+        }
+    } else {
+        $grade->quiz = $quiz->id;
+        $grade->user = $user->id;
+        $grade->grade = $bestgrade;
+        $grade->timemodified = time();
+        if (!insert_record("quiz_grades", $grade)) {
+            return false;
+        }
+    }
+    return true;
+}
+
+
+function quiz_get_answer($question) {
+// Given a question, returns the correct answers and grades
+    switch ($question->type) {
+        case SHORTANSWER;       // Could be multiple answers
+            return get_records_sql("SELECT a.*, sa.case, g.grade
+                                      FROM quiz_shortanswer sa, quiz_answers a, quiz_question_grades g
+                                     WHERE sa.question = '$question->id' 
+                                       AND sa.question = a.question
+                                       AND sa.question = g.question");
+            break;
+
+        case TRUEFALSE;         // Should be always two answers
+            return get_records_sql("SELECT a.*, g.grade
+                                      FROM quiz_answers a, quiz_question_grades g
+                                     WHERE a.question = '$question->id' 
+                                       AND a.question = g.question");
+            break;
+
+        case MULTICHOICE;       // Should be multiple answers
+            return get_records_sql("SELECT a.*, mc.single, g.grade
+                                      FROM quiz_multichoice mc, quiz_answers a, quiz_question_grades g
+                                     WHERE mc.question = '$question->id' 
+                                       AND mc.question = a.question 
+                                       AND mc.question = g.question");
+            break;
+
+        default:
+            return false;
+    }
+}
+
 function quiz_calculate_best_grade($quiz, $attempts) {
-// Calculate the best grade for a quiz given a number of attempts by a particular user.
+/// Calculate the best grade for a quiz given a number of attempts by a particular user.
 
     switch ($quiz->grademethod) {
-        case "1": // Use highest score
-            $max = 0;
+
+        case ATTEMPTFIRST:
             foreach ($attempts as $attempt) {
-                if ($attempt->grade > $max) {
-                    $max = $attempt->grade;
-                }
+                return $attempt->sumgrades;
             }
-            return $max;
+            break;
+
+        case ATTEMPTLAST:
+            foreach ($attempts as $attempt) {
+                $final = $attempt->sumgrades;
+            }
+            return $final;
 
-        case "2": // Use average score
+        case GRADEAVERAGE:
             $sum = 0;
             $count = 0;
             foreach ($attempts as $attempt) {
-                $sum += $attempt->grade;
+                $sum += $attempt->sumgrades;
                 $count++;
             }
             return (float)$sum/$count;
 
-        case "3": // Use first attempt
-            foreach ($attempts as $attempt) {
-                return $attempt->attempt;
-            }
-            break;
-
         default:
-        case "4": // Use last attempt
+        case GRADEHIGHEST:
+            $max = 0;
             foreach ($attempts as $attempt) {
-                $final = $attempt->attempt;
+                if ($attempt->sumgrades > $max) {
+                    $max = $attempt->sumgrades;
+                }
             }
-            return $final;
+            return $max;
+    }
+}
+
+function quiz_save_attempt($quiz, $questions, $result, $attemptnum) {
+/// Given a quiz, a list of attempted questions and a total grade 
+/// this function saves EVERYTHING so it can be reconstructed later
+/// if necessary.
+
+    global $USER;
+
+    // First let's save the attempt record itself
+
+    $attempt->quiz = $quiz->id;
+    $attempt->user = $USER->id;
+    $attempt->attempt = $attemptnum;
+    $attempt->sumgrades = $result->sumgrades;
+    $attempt->timemodified = time();
+
+    if (!$attempt->id = insert_record("quiz_attempts", $attempt)) {
+        return false;
+    }
+
+    // Now let's save all the questions for this attempt
+
+    foreach ($questions as $question) {
+        $response->attempt = $attempt->id;
+        $response->question = $question->id;
+        $response->grade = $result->grades[$question->id];
+        if ($question->answer) {
+            $response->answer = implode(",",$question->answer);
+        } else {
+            $response->answer = "";
+        }
+        if (!insert_record("quiz_responses", $response)) {
+            return false;
+        }
     }
+    return true;
 }
 
+
+function quiz_grade_attempt_results($quiz, $questions) {
+/// Given a list of questions (including answers for each one)
+/// this function does all the hard work of calculating the 
+/// grades for each question, as well as a total grade for 
+/// for the whole quiz.  It returns everything in a structure 
+/// that looks like:
+/// $result->sumgrades    (sum of all grades for all questions)
+/// $result->percentage   (Percentage of grades that were correct)
+/// $result->grade        (final grade result for the whole quiz)
+/// $result->grades[]     (array of grades, indexed by question id)
+/// $result->feedback[]   (array of feedback arrays, indexed by question id)
+
+    if (!$questions) {
+        error("No questions!");
+    }
+    
+    $result->sumgrades = 0;
+
+    foreach ($questions as $question) {
+        if (!$answers = quiz_get_answer($question)) {
+            error("No answer defined for question id $question->id!");
+        }
+
+        $grade    = 0;   // default
+        $feedback = array ();
+
+        switch ($question->type) {
+            case SHORTANSWER:
+                if ($question->answer) {
+                    $question->answer = $question->answer[0];
+                } else {
+                    $question->answer = NULL;
+                }
+                foreach($answers as $answer) {  // There might be multiple right answers
+                    $feedback[$answer->id] = $answer->feedback;
+                    if (!$answer->case) {       // Don't compare case
+                        $answer->answer = strtolower($answer->answer);
+                        $question->answer = strtolower($question->answer);
+                    }
+                    if ($question->answer == $answer->answer) {
+                        $grade = (float)$answer->fraction * $answer->grade;
+                    }
+                }
+                break;
+
+
+            case TRUEFALSE:
+                if ($question->answer) {
+                    $question->answer = $question->answer[0];
+                } else {
+                    $question->answer = NULL;
+                }
+                foreach($answers as $answer) {  // There should be two answers (true and false)
+                    $feedback[$answer->id] = $answer->feedback;
+                    if ($question->answer == $answer->id) {
+                        $grade = (float)$answer->fraction * $answer->grade;
+                    }
+                }
+                break;
+
+
+            case MULTICHOICE:
+                foreach($answers as $answer) {  // There will be multiple answers, perhaps more than one is right
+                    $feedback[$answer->id] = $answer->feedback;
+                    if ($question->answer) {
+                        foreach ($question->answer as $questionanswer) {
+                            if ($questionanswer == $answer->id) {
+                                if ($answer->single) {
+                                    $grade = (float)$answer->fraction * $answer->grade;
+                                    continue;
+                                } else {
+                                    $grade += (float)$answer->fraction * $answer->grade;
+                                }
+                            }
+                        }
+                    }
+                }
+                break;
+
+            
+        }
+        if ($grade < 0.0) {   // No negative grades
+            $grade = 0.0;
+        }
+        $result->grades[$question->id] = $grade;
+        $result->sumgrades += $grade;
+        $result->feedback[$question->id] = $feedback;
+    }
+
+    $result->percentage = ($result->sumgrades / $quiz->sumgrades);
+    $result->grade      = $result->percentage * $quiz->grade;
+
+    return $result;
+}
+    
 ?>
index d11556c041f4c37f674c594e8ee246b712c19595..50c7c0af4804a537a55d605c6152d2a24dda0c45 100644 (file)
@@ -5,7 +5,7 @@
 //  This fragment is called by moodle_needs_upgrading() and /admin/index.php
 ////////////////////////////////////////////////////////////////////////////////
 
-$module->version  = 2002100600;   // The (date) version of this module
+$module->version  = 2002101300;   // The (date) version of this module
 $module->cron     = 0;            // How often should cron check this module (seconds)?
 
 ?>
index 2fff1da035813d67cd0d06f5d364241b13fff53c..03d3ff2dd10adf69a8e50a5a649a4097aa162d1b 100644 (file)
 
     echo "<P ALIGN=CENTER>You have attempted this quiz $numattempts times, out of $quiz->attempts allowed attempts.</P>";
     if ($numattempts) { 
-        $table->data = array("Attempt", "Time", "Grade");
+        $table->head = array("Attempt", "Time", "Grade");
+        $table->align = array("CENTER", "LEFT", "RIGHT");
         foreach ($attempts as $attempt) {
-            $table->data = array($attempt->attempt, userdate($attempt->timemodified), $attempt->grade);
+            $table->data[] = array( $attempt->attempt, 
+                                    userdate($attempt->timemodified), 
+                                    ($attempt->sumgrades/$quiz->sumgrades)*$quiz->grade );
         }
         print_table($table);
     }
 
-    $mygrade = quiz_get_grade($quiz->id, $USER->id);
+    $mygrade = quiz_get_best_grade($quiz->id, $USER->id);
 
     if ($numattempts < $quiz->attempts) { 
         $options["id"] = $quiz->id;