function workshop_grade_assessments($workshop, $verbose = false) { global $WORKSHOP_EWEIGHTS; // timeout after 10 minutes @set_time_limit(600); $timenow = time(); // set minumim value for the variance (of the elements) $minvar = 0.05; // check when the standard deviations were calculated $oldtotalassessments = get_field("workshop_elements", "totalassessments", "workshopid", $workshop->id, "elementno", 0); $totalassessments = count_records("workshop_assessments", "workshopid", $workshop->id); // calculate the std. devs every 10 assessments for low numbers of assessments, thereafter every 100 new assessments if ($totalassessments < 100 and $totalassessments - $oldtotalassessments > 10 or $totalassessments - $oldtotalassessments > 100) { // calculate the means for each submission using just the "good" assessments if ($submissions = get_records("workshop_submissions", "workshopid", $workshop->id)) { foreach ($submissions as $submission) { $nassessments[$submission->id] = 0; if ($assessments = workshop_get_assessments($submission)) { foreach ($assessments as $assessment) { // test if assessment is "good", a teacher assessment always "good", but may be weighted out if (workshop_is_teacher($workshop, $assessment->userid)) { if (!$workshop->teacherweight) { // drop teacher's assessment as weight is zero continue; } } elseif (!$assessment->gradinggrade and $assessment->timegraded or $workshop->agreeassessments and !$assessment->timeagreed) { // it's a duff assessment, or it's not been agreed continue; } if (isset($num[$submission->id])) { if (workshop_is_teacher($workshop, $assessment->userid)) { $num[$submission->id] += $workshop->teacherweight; // weight teacher's assessment } else { $num[$submission->id]++; // number of assessments } $nassessments[$submission->id]++; } else { if (workshop_is_teacher($workshop, $assessment->userid)) { $num[$submission->id] = $workshop->teacherweight; } else { $num[$submission->id] = 1; } $nassessments[$submission->id] = 1; } for ($i = 0; $i < $workshop->nelements; $i++) { $grade = get_field("workshop_grades", "grade", "assessmentid", $assessment->id, "elementno", $i); if (isset($sum[$submission->id][$i])) { if (workshop_is_teacher($workshop, $assessment->userid)) { $sum[$submission->id][$i] += $workshop->teacherweight * $grade; // teacher's grade } else { $sum[$submission->id][$i] += $grade; // student's grade } } else { if (workshop_is_teacher($workshop, $assessment->userid)) { $sum[$submission->id][$i] = $workshop->teacherweight * $grade; // teacher's grade } else { $sum[$submission->id][$i] = $grade; // students's grade } } } } } } if (!isset($num)) { // no assessments yet return; } reset($num); // calculate the means for each submission $total = 0; foreach ($num as $submissionid => $n) { if ($n) { // stop division by zero for ($i = 0; $i < $workshop->nelements; $i++) { $mean[$submissionid][$i] = $sum[$submissionid][$i] / $n; // echo "Submission: $submissionid; Element: $i; Mean: {$mean[$submissionid][$i]}<br />\n"; } $total += $n; // weighted total } } if ($verbose) { echo "<p style=\"text-align:center\">" . get_string("numberofsubmissions", "workshop", count($num)) . "<br />\n"; echo get_string("numberofassessmentsweighted", "workshop", $total) . "</p>\n"; } // now get an estimate of the standard deviation of each element in the assessment // this is just a rough measure, all assessments are included and teacher's assesments are not weighted $n = 0; for ($i = 0; $i < $workshop->nelements; $i++) { $var[$i] = 0; } foreach ($submissions as $submission) { if ($assessments = workshop_get_assessments($submission)) { foreach ($assessments as $assessment) { $n++; for ($i = 0; $i < $workshop->nelements; $i++) { $grade = get_field("workshop_grades", "grade", "assessmentid", $assessment->id, "elementno", $i); $temp = $mean[$submission->id][$i] - $grade; $var[$i] += $temp * $temp; } } } } for ($i = 0; $i < $workshop->nelements; $i++) { if ($n > 1) { $sd[$i] = sqrt($var[$i] / ($n - 1)); } else { $sd[$i] = 0; } set_field("workshop_elements", "stddev", $sd[$i], "workshopid", $workshop->id, "elementno", $i); set_field("workshop_elements", "totalassessments", $totalassessments, "workshopid", $workshop->id, "elementno", $i); if ($verbose) { echo get_string("standarddeviationofelement", "workshop", $i + 1) . " {$sd[$i]}<br />"; if ($sd[$i] <= $minvar) { print_string("standarddeviationnote", "workshop") . "<br />\n"; } } } } } // this section looks at each submission if the number of assessments made has increased it recalculates the // grading grades for those assessments // first get the assignment elements for the weights and the stddevs... if ($elementsraw = get_records("workshop_elements", "workshopid", $workshop->id, "elementno ASC")) { foreach ($elementsraw as $element) { $weight[] = $element->weight; // to renumber index 0,1,2... $sd[] = $element->stddev; // to renumber index 0,1,2... } } unset($num); // may have been used in calculating stddevs unset($sum); // ditto if ($submissions = get_records("workshop_submissions", "workshopid", $workshop->id)) { foreach ($submissions as $submission) { // see if the number of assessments has changed $nassessments = workshop_count_assessments($submission); if ($submission->nassessments != $nassessments) { // ...if there are three or more assessments calculate the variance of each assessment. // Use the variance to find the "best" assessment. (When there is only one or two assessments they // are not altered by this routine.) if ($verbose) { echo "Processing submission {$submission->id} ({$nassessments} asessments)...\n"; } if ($nassessments > 2) { $num = 0; // weighted number of assessments for ($i = 0; $i < $workshop->nelements; $i++) { $sum[$i] = 0; // weighted sum of grades } if ($assessments = workshop_get_assessments($submission)) { // first calculate the mean grades for each element foreach ($assessments as $assessment) { // test if assessment is "good", a teacher assessment always "good", but may be weighted out if (workshop_is_teacher($workshop, $assessment->userid)) { if (!$workshop->teacherweight) { // drop teacher's assessment as weight is zero continue; } } else { if (!$assessment->gradinggrade and $assessment->timegraded or $workshop->agreeassessments and !$assessment->timeagreed) { // it's a duff assessment, or it's not been agreed continue; } } if (workshop_is_teacher($workshop, $assessment->userid)) { $num += $workshop->teacherweight; // weight teacher's assessment } else { $num++; // student assessment just add one } for ($i = 0; $i < $workshop->nelements; $i++) { $grade = get_field("workshop_grades", "grade", "assessmentid", $assessment->id, "elementno", $i); if (workshop_is_teacher($workshop, $assessment->userid)) { $sum[$i] += $workshop->teacherweight * $grade; // teacher's grade } else { $sum[$i] += $grade; // student's grade } } } if ($num) { // could all the assessments be duff? for ($i = 0; $i < $workshop->nelements; $i++) { $mean[$i] = $sum[$i] / $num; if ($verbose) { echo "Submission: {$submission->id}; Element: {$i}; Mean: {$mean[$i]}\n"; } } } else { continue; // move to the next submission } // run through the assessments again to see which is the "best" one (the one // closest to the mean) $lowest = 10000000000.0; foreach ($assessments as $assessment) { if ($workshop->agreeassessments and !$assessment->timeagreed) { // ignore assessments that have not been agreed continue; } $var = 0; for ($i = 0; $i < $workshop->nelements; $i++) { $grade = get_field("workshop_grades", "grade", "assessmentid", $assessment->id, "elementno", $i); if ($sd[$i] > $minvar) { $temp = ($mean[$i] - $grade) * $WORKSHOP_EWEIGHTS[$weight[$i]] / $sd[$i]; } else { $temp = 0; } $var += $temp * $temp; } // find the "best" assessment of this submission if ($lowest > $var) { $lowest = $var; $bestassessmentid = $assessment->id; } } if (!($best = get_record("workshop_assessments", "id", $bestassessmentid))) { notify("Workshop grade assessments: cannot find best assessment"); continue; } if ($verbose) { echo "Best assessment is {$bestassessmentid};\n"; } foreach ($assessments as $assessment) { // don't overwrite teacher's grade if ($assessment->teachergraded) { continue; } if ($assessment->id == $bestassessmentid) { // it's the best one, set the grading grade to the maximum set_field("workshop_assessments", "gradinggrade", 100, "id", $assessment->id); set_field("workshop_assessments", "timegraded", $timenow, "id", $assessment->id); } else { // it's one of the pack, compare with the best... $gradinggrade = round(workshop_compare_assessments($workshop, $best, $assessment)); // ...and save the grade for the assessment set_field("workshop_assessments", "gradinggrade", $gradinggrade, "id", $assessment->id); set_field("workshop_assessments", "timegraded", $timenow, "id", $assessment->id); } } } } else { // there are less than 3 assessments for this submission if ($assessments = workshop_get_assessments($submission)) { foreach ($assessments as $assessment) { if (!$assessment->timegraded and !$assessment->teachergraded) { // set the grading grade to the maximum and say it's been graded set_field("workshop_assessments", "gradinggrade", 100, "id", $assessment->id); set_field("workshop_assessments", "timegraded", $timenow, "id", $assessment->id); } } } } // set the number of assessments for this submission set_field("workshop_submissions", "nassessments", $nassessments, "id", $submission->id); } } } return; }
foreach ($assessments as $studentassessment) { // skip if it's not a student assessment if (!workshop_is_student($workshop, $studentassessment->userid)) { continue; } $gradinggrade = workshop_compare_assessments($workshop, $assessment, $studentassessment); set_field("workshop_assessments", "timegraded", $timenow, "id", $studentassessment->id); set_field("workshop_assessments", "gradinggrade", $gradinggrade, "id", $studentassessment->id); } } } else { //it's a student assessment, see if there's a corresponding teacher's assessment if ($assessments = workshop_get_assessments($submission)) { foreach ($assessments as $teacherassessment) { if (workshop_is_teacher($workshop, $teacherassessment->userid)) { $gradinggrade = workshop_compare_assessments($workshop, $assessment, $teacherassessment); set_field("workshop_assessments", "timegraded", $timenow, "id", $assessment->id); set_field("workshop_assessments", "gradinggrade", $gradinggrade, "id", $assessment->id); break; // only look for the first teacher assessment } } } } } // any comment? if (!empty($form->generalcomment)) { set_field("workshop_assessments", "generalcomment", clean_param($form->generalcomment, PARAM_CLEAN), "id", $assessment->id); } add_to_log($course->id, "workshop", "assess", "viewassessment.php?id={$cm->id}&aid={$assessment->id}", "{$assessment->id}", "{$cm->id}"); // set up return address