public function summarise_usage(question_usage_by_activity $quba, question_display_options $options) { $summarydata = parent::summarise_usage($quba, $options); if ($options->marks < question_display_options::MARK_AND_MAX) { return $summarydata; } // Prepare accumulators to hold the data we are about to collect. $notansweredcount = 0; $notansweredweight = 0; $attemptcount = array(question_cbm::HIGH => 0, question_cbm::MED => 0, question_cbm::LOW => 0); $totalweight = array(question_cbm::HIGH => 0, question_cbm::MED => 0, question_cbm::LOW => 0); $totalrawscore = array(question_cbm::HIGH => 0, question_cbm::MED => 0, question_cbm::LOW => 0); $totalcbmscore = array(question_cbm::HIGH => 0, question_cbm::MED => 0, question_cbm::LOW => 0); // Loop through the data, and add it to the accumulators. foreach ($quba->get_attempt_iterator() as $qa) { if (strpos($qa->get_behaviour_name(), 'cbm') === false || $qa->get_max_mark() < 5.0E-7) { continue; } $gradedstep = $qa->get_last_step_with_behaviour_var('_rawfraction'); if (!$gradedstep->has_behaviour_var('_rawfraction')) { $notansweredcount += 1; $notansweredweight += $qa->get_max_mark(); continue; } $certainty = $qa->get_last_behaviour_var('certainty'); if (is_null($certainty) || $certainty == -1) { // Certainty -1 has never been used in standard Moodle, but is // used in Tony-Gardiner Medwin's patches to mean 'No idea' which // we intend to implement: MDL-42077. In the mean time, avoid // errors for people who have used TGM's patches. $certainty = question_cbm::default_certainty(); } $attemptcount[$certainty] += 1; $totalweight[$certainty] += $qa->get_max_mark(); $totalrawscore[$certainty] += $qa->get_max_mark() * $gradedstep->get_behaviour_var('_rawfraction'); $totalcbmscore[$certainty] += $qa->get_mark(); } // Hence compute some statistics. $totalquestions = $notansweredcount + array_sum($attemptcount); $grandtotalweight = $notansweredweight + array_sum($totalweight); $accuracy = array_sum($totalrawscore) / $grandtotalweight; $averagecbm = array_sum($totalcbmscore) / $grandtotalweight; $cbmbonus = $this->calculate_bonus($averagecbm, $accuracy); $accuracyandbonus = $accuracy + $cbmbonus; // Now we can start generating some of the summary: overall values. $summarydata['qbehaviour_cbm_entire_quiz_heading'] = array('title' => '', 'content' => html_writer::tag('h3', get_string('forentirequiz', 'qbehaviour_deferredcbm', $totalquestions), array('class' => 'qbehaviour_deferredcbm_summary_heading'))); $summarydata['qbehaviour_cbm_entire_quiz_cbm_average'] = array('title' => get_string('averagecbmmark', 'qbehaviour_deferredcbm'), 'content' => format_float($averagecbm, $options->markdp)); $summarydata['qbehaviour_cbm_entire_quiz_accuracy'] = array('title' => get_string('accuracy', 'qbehaviour_deferredcbm'), 'content' => $this->format_probability($accuracy, 1)); $summarydata['qbehaviour_cbm_entire_quiz_cbm_bonus'] = array('title' => get_string('cbmbonus', 'qbehaviour_deferredcbm'), 'content' => $this->format_probability($cbmbonus, 1)); $summarydata['qbehaviour_cbm_entire_quiz_accuracy_and_bonus'] = array('title' => get_string('accuracyandbonus', 'qbehaviour_deferredcbm'), 'content' => $this->format_probability($accuracyandbonus, 1)); if ($notansweredcount && array_sum($attemptcount) > 0) { $totalquestions = array_sum($attemptcount); $grandtotalweight = array_sum($totalweight); $accuracy = array_sum($totalrawscore) / $grandtotalweight; $averagecbm = array_sum($totalcbmscore) / $grandtotalweight; $cbmbonus = $this->calculate_bonus($averagecbm, $accuracy); $accuracyandbonus = $accuracy + $cbmbonus; $summarydata['qbehaviour_cbm_answered_quiz_heading'] = array('title' => '', 'content' => html_writer::tag('h3', get_string('foransweredquestions', 'qbehaviour_deferredcbm', $totalquestions), array('class' => 'qbehaviour_deferredcbm_summary_heading'))); $summarydata['qbehaviour_cbm_answered_quiz_cbm_average'] = array('title' => get_string('averagecbmmark', 'qbehaviour_deferredcbm'), 'content' => format_float($averagecbm, $options->markdp)); $summarydata['qbehaviour_cbm_answered_quiz_accuracy'] = array('title' => get_string('accuracy', 'qbehaviour_deferredcbm'), 'content' => $this->format_probability($accuracy, 1)); $summarydata['qbehaviour_cbm_answered_quiz_cbm_bonus'] = array('title' => get_string('cbmbonus', 'qbehaviour_deferredcbm'), 'content' => $this->format_probability($cbmbonus, 1)); $summarydata['qbehaviour_cbm_answered_quiz_accuracy_and_bonus'] = array('title' => get_string('accuracyandbonus', 'qbehaviour_deferredcbm'), 'content' => $this->format_probability($accuracyandbonus, 1)); } // Now per-certainty level values. $summarydata['qbehaviour_cbm_judgement_heading'] = array('title' => '', 'content' => html_writer::tag('h3', get_string('breakdownbycertainty', 'qbehaviour_deferredcbm'), array('class' => 'qbehaviour_deferredcbm_summary_heading'))); foreach ($attemptcount as $certainty => $count) { $key = 'qbehaviour_cbm_judgement' . $certainty; $title = question_cbm::get_short_string($certainty); if ($count == 0) { $summarydata[$key] = array('title' => $title, 'content' => get_string('noquestions', 'qbehaviour_deferredcbm')); continue; } $lowerlimit = question_cbm::optimal_probablility_low($certainty); $upperlimit = question_cbm::optimal_probablility_high($certainty); $fraction = $totalrawscore[$certainty] / $totalweight[$certainty]; $a = new stdClass(); $a->responses = $count; $a->idealrangelow = $this->format_probability($lowerlimit); $a->idealrangehigh = $this->format_probability($upperlimit); $a->fraction = html_writer::tag('span', $this->format_probability($fraction), array('class' => 'qbehaviour_deferredcbm_actual_percentage')); if ($fraction < $lowerlimit - 5.0E-7) { if (pow($fraction - $lowerlimit, 2) * $count > 0.5) { // Rough indicator of significance: t > 1.5 or 1.8. $judgement = 'overconfident'; } else { $judgement = 'slightlyoverconfident'; } } else { if ($fraction > $upperlimit + 5.0E-7) { if (pow($fraction - $upperlimit, 2) * $count > 0.5) { $judgement = 'underconfident'; } else { $judgement = 'slightlyunderconfident'; } } else { $judgement = 'judgementok'; } } $a->judgement = html_writer::tag('span', get_string($judgement, 'qbehaviour_deferredcbm'), array('class' => 'qbehaviour_deferredcbm_' . $judgement)); $summarydata[$key] = array('title' => $title, 'content' => get_string('judgementsummary', 'qbehaviour_deferredcbm', $a)); } return $summarydata; }
public static function adjust_random_guess_score($fraction) { return question_cbm::adjust_fraction($fraction, question_cbm::default_certainty()); }
protected function do_grading(question_attempt_step $responsesstep, question_attempt_pending_step $pendingstep) { if (!$this->question->is_gradable_response($responsesstep->get_qt_data())) { $pendingstep->set_state(question_state::$gaveup); } else { $response = $responsesstep->get_qt_data(); list($fraction, $state) = $this->question->grade_response($response); if ($responsesstep->has_behaviour_var('certainty')) { $certainty = $responsesstep->get_behaviour_var('certainty'); } else { $certainty = question_cbm::default_certainty(); $pendingstep->set_behaviour_var('_assumedcertainty', $certainty); } $pendingstep->set_behaviour_var('_rawfraction', $fraction); $pendingstep->set_fraction(question_cbm::adjust_fraction($fraction, $certainty)); $pendingstep->set_state($state); $pendingstep->set_new_response_summary(question_cbm::summary_with_certainty($this->question->summarise_response($response), $responsesstep->get_behaviour_var('certainty'))); } return question_attempt::KEEP; }
public function process_finish(question_attempt_pending_step $pendingstep) { $status = parent::process_finish($pendingstep); if ($status == question_attempt::KEEP) { $fraction = $pendingstep->get_fraction(); if ($this->qa->get_last_step()->has_behaviour_var('certainty')) { $certainty = $this->qa->get_last_step()->get_behaviour_var('certainty'); } else { $certainty = question_cbm::default_certainty(); $pendingstep->set_behaviour_var('_assumedcertainty', $certainty); } if (!is_null($fraction)) { $pendingstep->set_behaviour_var('_rawfraction', $fraction); $pendingstep->set_fraction(question_cbm::adjust_fraction($fraction, $certainty)); } $pendingstep->set_new_response_summary(question_cbm::summary_with_certainty($pendingstep->get_new_response_summary(), $this->qa->get_last_step()->get_behaviour_var('certainty'))); } return $status; }
public function marked_out_of_max(question_attempt $qa, core_question_renderer $qoutput, question_display_options $options) { return get_string('basemark', 'qbehaviour_deferredcbm', $qa->format_fraction_as_mark(question_cbm::adjust_fraction(1, question_cbm::default_certainty()), $options->markdp)); }