From 88427c077b7cbf63a520dc7bbc4a8de38e6c3582 Mon Sep 17 00:00:00 2001
From: mark-nielsen ".get_string('teacherongoingwarning', 'lesson').' ".get_string('teacherongoingwarning', 'lesson').' ".get_string("numberofpagesviewed", "lesson", $nviewed).
+
+ $gradeinfo = lesson_grade($lesson, $ntries);
+
+ if ($gradeinfo->attempts) {
+ echo " ".get_string("numberofpagesviewed", "lesson", $gradeinfo->nquestions).
"; (".get_string("youshouldview", "lesson", $lesson->minquestions).") ".get_string("numberofpagesviewed", "lesson", $nviewed).
+ echo " ".get_string("numberofpagesviewed", "lesson", $gradeinfo->nquestions).
" ".get_string("youshouldview", "lesson",
- $lesson->minquestions)." ".get_string("pages", "lesson")."
";
- } else {
- $ntries = count_records("lesson_grades", "lessonid", $lesson->id, "userid", $USER->id);
- if (isset($USER->modattempts[$lesson->id])) {
- $ntries--;
- }
- lesson_calculate_ongoing_score($lesson, $USER->id, $ntries);
- }
+ lesson_print_ongoing_score($lesson);
}
// display response (if there is one - there should be!)
diff --git a/mod/lesson/locallib.php b/mod/lesson/locallib.php
index ae80f14530..d6798da6ac 100644
--- a/mod/lesson/locallib.php
+++ b/mod/lesson/locallib.php
@@ -1204,123 +1204,155 @@ function lesson_print_tree($pageid, $lesson, $cmid) {
/**
* Calculates a user's grade for a lesson.
*
- * This is used for the ongoing score feature. It will calculate the user's
- * score based on how many points they have earned thus far in the lesson out
- * of the maximum that they could have earned. Example: user answers 4 questions out
- * of 20. Of the 4, the user earned 5 points out of a possible 12. So, their current
- * score would be 5 out of 12 and not 5 out of the total for the whole lesson.
- * This function is also used by essay grading. It is used to recalculate a students grade
- * after a teacher assigns a grade for an essay.
- *
* @param object $lesson The lesson that the user is taking.
- * @param int $userid Id of the user.
* @param int $retries The attempt number.
- * @param boolean $return A flag to return the grade or print it out.
- * @return float May return the grade.
- * @todo Break out the grading section of this code to use for grading lessons (also have grading code in view.php)
+ * @param int $userid Id of the user (optinal, default current user).
+ * @return object { nquestions => number of questions answered
+ attempts => number of question attempts
+ total => max points possible
+ earned => points earned by student
+ grade => calculated percentage grade
+ nmanual => number of manually graded questions
+ manualpoints => point value for manually graded questions }
*/
-function lesson_calculate_ongoing_score($lesson, $userid, $retries, $return=false) {
- if (!$lesson->custom) {
- $ncorrect = 0;
- $temp = array();
- if ($pagesanswered = get_records_select("lesson_attempts", "lessonid = $lesson->id AND
- userid = $userid AND retry = $retries order by timeseen")) {
-
- foreach ($pagesanswered as $pageanswered) {
- if (!array_key_exists($pageanswered->pageid, $temp)) {
- $temp[$pageanswered->pageid] = array($pageanswered->correct, 1);
- } else {
- if ($temp[$pageanswered->pageid][1] < $lesson->maxattempts) {
- $n = $temp[$pageanswered->pageid][1] + 1;
- $temp[$pageanswered->pageid] = array($pageanswered->correct, $n);
- }
- }
- }
- foreach ($temp as $value => $key) {
- if ($key[0] == 1) {
- $ncorrect += 1;
- }
- }
- }
- $nviewed = count($temp); // this counts number of Questions the user viewed
- if ($nviewed != 0) {
- $thegrade = round(100 * $ncorrect / $nviewed, 5);
- } else {
- $thegrade = 0;
- }
+function lesson_grade($lesson, $ntries, $userid = 0) {
+ global $USER;
- if ($return) {
- return $thegrade;
- } else {
- $output = new stdClass;
- $output->correct = $ncorrect;
- $output->viewed = $nviewed;
- print_simple_box(get_string("ongoingnormal", "lesson", $output), "center");
+ if (empty($userid)) {
+ $userid = $USER->id;
+ }
+
+ // Zero out everything
+ $ncorrect = 0;
+ $nviewed = 0;
+ $score = 0;
+ $nmanual = 0;
+ $manualpoints = 0;
+ $thegrade = 0;
+ $nquestions = 0;
+ $total = 0;
+ $earned = 0;
+
+ if ($useranswers = get_records_select("lesson_attempts", "lessonid = $lesson->id AND
+ userid = $userid AND retry = $ntries", "timeseen")) {
+ // group each try with its page
+ $attemptset = array();
+ foreach ($useranswers as $useranswer) {
+ $attemptset[$useranswer->pageid][] = $useranswer;
}
-
- } else {
- $score = 0;
- $essayquestions = 0;
- $essayquestionpoints = 0;
- $bestscore = 0;
- $thegrade = 0;
-
- if ($useranswers = get_records_select("lesson_attempts", "lessonid = $lesson->id AND
- userid = $userid AND retry = $retries", "timeseen")) {
- // group each try with its page
- foreach ($useranswers as $useranswer) {
- $attemptset[$useranswer->pageid][] = $useranswer;
- }
-
- $pageids = array_keys($attemptset);
- $pageids = implode(",", $pageids);
-
- // get only the pages and their answers that the user answered
- $answeredpages = get_records_select("lesson_pages", "lessonid = $lesson->id AND id IN($pageids)");
- $pageanswers = get_records_select("lesson_answers", "lessonid = $lesson->id AND pageid IN($pageids)");
-
- foreach ($attemptset as $attempts) {
- if(count($attempts) > $lesson->maxattempts) { // if there are more tries than the max that is allowed, grab the last "legal" attempt
- $attempt = $attempts[$lesson->maxattempts - 1];
- } else {
- // else, user attempted the question less than the max, so grab the last one
- $attempt = end($attempts);
- }
- // if essay question, handle it, otherwise add to score
- if ($answeredpages[$attempt->pageid]->qtype == LESSON_ESSAY) {
+
+ // Drop all attempts that go beyond max attempts for the lesson
+ foreach ($attemptset as $key => $set) {
+ $attemptset[$key] = array_slice($set, 0, $lesson->maxattempts);
+ }
+
+ $pageids = implode(",", array_keys($attemptset));
+
+ // get only the pages and their answers that the user answered
+ $pages = get_records_select("lesson_pages", "lessonid = $lesson->id AND id IN($pageids)");
+ $answers = get_records_select("lesson_answers", "lessonid = $lesson->id AND pageid IN($pageids)");
+
+ // Number of pages answered
+ $nquestions = count($pages);
+
+ foreach ($attemptset as $attempts) {
+ if ($lesson->custom) {
+ $attempt = end($attempts);
+ // If essay question, handle it, otherwise add to score
+ if ($pages[$attempt->pageid]->qtype == LESSON_ESSAY) {
$essayinfo = unserialize($attempt->useranswer);
- $score += $essayinfo->score;
- $essayquestions++;
- $essayquestionpoints += $pageanswers[$attempt->answerid]->score;
+ $earned += $essayinfo->score;
+ $nmanual++;
+ $manualpoints += $answers[$attempt->answerid]->score;
} else {
- $score += $pageanswers[$attempt->answerid]->score;
+ $earned += $answers[$attempt->answerid]->score;
+ }
+ } else {
+ foreach ($attempts as $attempt) {
+ $earned += $attempt->correct;
+ }
+ $attempt = end($attempts); // doesn't matter which one
+ // If essay question, increase numbers
+ if ($pages[$attempt->pageid]->qtype == LESSON_ESSAY) {
+ $nmanual++;
+ $manualpoints++;
}
}
+ // Number of times answered
+ $nviewed += count($attempts);
+ }
+
+ if ($lesson->custom) {
$bestscores = array();
- // find the highest possible score per page
- foreach ($pageanswers as $pageanswer) {
- if(isset($bestscores[$pageanswer->pageid])) {
- if ($bestscores[$pageanswer->pageid] < $pageanswer->score) {
- $bestscores[$pageanswer->pageid] = $pageanswer->score;
- }
+ // Find the highest possible score per page to get our total
+ foreach ($answers as $answer) {
+ if(isset($bestscores[$answer->pageid]) and $bestscores[$answer->pageid] < $answer->score) {
+ $bestscores[$answer->pageid] = $answer->score;
} else {
- $bestscores[$pageanswer->pageid] = $pageanswer->score;
+ $bestscores[$answer->pageid] = $answer->score;
}
}
-
- $bestscore = array_sum($bestscores);
- $thegrade = round(100 * $score / $bestscore, 5);
+ $total = array_sum($bestscores);
+ } else {
+ // Check to make sure the student has answered the minimum questions
+ if ($lesson->minquestions and $nquestions < $lesson->minquestions) {
+ // Nope, increase number viewed by the amount of unanswered questions
+ $total = $nviewed + ($lesson->minquestions - $nquestions);
+ } else {
+ $total = $nviewed;
+ }
}
-
+ }
+
+ if ($total) { // not zero
+ $thegrade = round(100 * $earned / $total, 5);
+ }
+
+ // Build the grade information object
+ $gradeinfo = new stdClass;
+ $gradeinfo->nquestions = $nquestions;
+ $gradeinfo->attempts = $nviewed;
+ $gradeinfo->total = $total;
+ $gradeinfo->earned = $earned;
+ $gradeinfo->grade = $thegrade;
+ $gradeinfo->nmanual = $nmanual;
+ $gradeinfo->manualpoints = $manualpoints;
+
+ return $gradeinfo;
+}
+
+/**
+ * Prints the on going message to the user.
+ *
+ * With custom grading On, displays points
+ * earned out of total points possible thus far.
+ * With custom grading Off, displays number of correct
+ * answers out of total attempted.
+ *
+ * @param object $lesson The lesson that the user is taking.
+ * @return void
+ **/
+function lesson_print_ongoing_score($lesson) {
+ global $USER;
+
+ if (isteacher($lesson->course)) {
+ echo "
";
// count the number of distinct correct pages
- if ($correctpages = get_records_select("lesson_attempts", "lessonid = $lesson->id
- AND userid = $USER->id AND retry = $ntries AND correct = 1")) {
- foreach ($correctpages as $correctpage) {
- $temp[$correctpage->pageid] = 1;
- }
- $ncorrect = count($temp);
- } else {
- $nccorrect = 0;
+ if ($gradeinfo->nquestions < $lesson->minquestions) {
+ $gradeinfo->nquestions = $lesson->minquestions;
}
- if ($nviewed < $lesson->minquestions) {
- $nviewed = $lesson->minquestions;
- }
- echo get_string("numberofcorrectanswers", "lesson", $ncorrect)."
\n";
- $thegrade = intval(100 * $ncorrect / $nviewed);
+ echo get_string("numberofcorrectanswers", "lesson", $gradeinfo->earned)."
\n";
echo get_string("yourcurrentgradeis", "lesson",
- number_format($thegrade * $lesson->grade / 100, 1)).
+ number_format($gradeinfo->grade * $lesson->grade / 100, 1)).
" (".get_string("outof", "lesson", $lesson->grade).")
".get_string("numberofcorrectanswers", "lesson", $ncorrect). + echo "
".get_string("numberofcorrectanswers", "lesson", $gradeinfo->earned). "
\n"; - $thegrade = round(100 * $ncorrect / $nviewed, 5); - echo "".get_string("gradeis", "lesson", - number_format($thegrade * $lesson->grade / 100, 1)). - " (".get_string("outof", "lesson", $lesson->grade).")
\n"; - + } + $a = new stdClass; + $a->score = $gradeinfo->earned; + $a->grade = $gradeinfo->total; + if ($gradeinfo->nmanual) { + $a->tempmaxgrade = $gradeinfo->total - $gradeinfo->manualpoints; + $a->essayquestions = $gradeinfo->nmanual; + echo "".get_string("gradeis", "lesson", - number_format($thegrade * $lesson->grade / 100, 1)). - " (".get_string("outof", "lesson", $lesson->grade).")
\n"; - + echo "".get_string("gradeis", "lesson", + number_format($gradeinfo->grade * $lesson->grade / 100, 1)). + " (".get_string("outof", "lesson", $lesson->grade).")
\n"; + $grade->lessonid = $lesson->id; $grade->userid = $USER->id; - $grade->grade = $thegrade; + $grade->grade = $gradeinfo->grade; $grade->completed = time(); if (!$lesson->practice) { if (isset($USER->modattempts[$lesson->id])) { // if reviewing, make sure update old grade record @@ -1821,10 +1734,9 @@ $grade = current($grades); - // I modded this function a bit so it would work here... :) ;) :P - $updategrade->grade = lesson_calculate_ongoing_score($lesson, $essay->userid, $essay->retry, true); + $gradeinfo = lesson_grade($lesson, $essay->retry, $essay->userid); $updategrade->id = $grade->id; - + $updategrade->grade = $gradeinfo->grade; if(update_record("lesson_grades", $updategrade)) { redirect("view.php?id=$cm->id&action=essayview", get_string("updatesuccess", "lesson")); } else { -- 2.39.5