public function process_action(question_attempt_pending_step $pendingstep) { if ($pendingstep->has_behaviour_var('helpme')) { return $this->process_helpme($pendingstep); } else { return parent::process_action($pendingstep); } }
public function process_finish(question_attempt_pending_step $pendingstep) { if ($this->qa->get_state()->is_finished()) { return question_attempt::DISCARD; } $response = $this->qa->get_last_step()->get_qt_data(); if (!$this->question->is_complete_response($response)) { $pendingstep->set_state(question_state::$gaveup); } else { $pendingstep->set_state(question_state::$needsgrading); } $pendingstep->set_new_response_summary($this->question->summarise_response($response)); return question_attempt::KEEP; }
protected function adjust_fraction($fraction, question_attempt_pending_step $pendingstep) { $totaltries = $this->qa->get_step(0)->get_behaviour_var('_triesleft'); $responses = array(); $lastsave = array(); foreach ($this->qa->get_step_iterator() as $step) { if ($step->has_behaviour_var('submit') && $step->get_state() != question_state::$invalid) { $responses[] = $step->get_qt_data(); $lastsave = array(); } else { $lastsave = $step->get_qt_data(); } } $lastresponse = $pendingstep->get_qt_data(); if (!empty($lastresponse)) { $responses[] = $lastresponse; } else { if (!empty($lastsave)) { $responses[] = $lastsave; } } return $this->question->compute_final_grade($responses, $totaltries); }
public function process_seen(question_attempt_pending_step $pendingstep) { $pendingstep->set_state(question_state::$complete); return question_attempt::KEEP; }
public function process_finish(question_attempt_pending_step $pendingstep) { if ($this->qa->get_state()->is_finished()) { return question_attempt::DISCARD; } $prevtries = $this->qa->get_last_behaviour_var('_try', 0); $prevbest = $this->qa->get_fraction(); if (is_null($prevbest)) { $prevbest = 0; } $laststep = $this->qa->get_last_step(); $response = $laststep->get_qt_data(); if (!$this->question->is_gradable_response($response)) { $state = question_state::$gaveup; $fraction = 0; } else { if ($laststep->has_behaviour_var('_try')) { // Last answer was graded, we want to regrade it. Otherwise the answer // has changed, and we are grading a new try. $prevtries -= 1; } list($fraction, $state) = $this->question->grade_response($response); $pendingstep->set_behaviour_var('_try', $prevtries + 1); $pendingstep->set_behaviour_var('_rawfraction', $fraction); $pendingstep->set_new_response_summary($this->question->summarise_response($response)); } $pendingstep->set_state($state); $pendingstep->set_fraction(max($prevbest, $this->adjusted_fraction($fraction, $prevtries))); return question_attempt::KEEP; }
protected function process_parts_that_can_be_graded(question_attempt_pending_step $pendingstep, $finalsubmit) { // Get the response we are processing. if ($finalsubmit) { $laststep = $this->qa->get_last_step(); $response = $laststep->get_qt_data(); } else { $response = $pendingstep->get_qt_data(); } // Get last graded response for each part. $lastgradedresponses = array(); $currenttries = array(); $currentpenalties = array(); $currentfractions = array(); $currentrawfractions = array(); $prevseenresponse = array(); $steps = $this->qa->get_reverse_step_iterator(); if ($finalsubmit) { $steps->next(); } foreach ($steps as $step) { foreach ($step->get_behaviour_data() as $name => $value) { if (!preg_match('~_tries_(.*)$~', $name, $matches)) { continue; } $oldresponse = $step->get_qt_data(); $partname = $matches[1]; if (array_key_exists($partname, $currenttries)) { // We already have a most recent try for this part, but now // have an older response that was a try for this part, and // we want to know if the current response is the same as this. if ($this->question->is_same_response_for_part($partname, $oldresponse, $response)) { $prevseenresponse[$partname] = true; } continue; } $lastgradedresponses[$partname] = $oldresponse; $currenttries[$partname] = $value; $currentpenalties[$partname] = $step->get_behaviour_var('_penalty_' . $partname); $currentfractions[$partname] = $step->get_behaviour_var('_fraction_' . $partname); $currentrawfractions[$partname] = $step->get_behaviour_var('_rawfraction_' . $partname); } } $partscores = $this->question->grade_parts_that_can_be_graded($response, $lastgradedresponses, $finalsubmit); foreach ($partscores as $partname => $partscore) { if ($partscore->errors) { $pendingstep->set_behaviour_var('_errors_' . $partname, 1); continue; } if (!array_key_exists($partname, $currentpenalties)) { $currenttries[$partname] = 0; $currentpenalties[$partname] = 0; $currentfractions[$partname] = 0; } if (!empty($prevseenresponse[$partname])) { $partscore->penalty = 0; } $pendingstep->set_behaviour_var('_tries_' . $partname, $currenttries[$partname] + 1); if ($this->applypenalties) { $pendingstep->set_behaviour_var('_curpenalty_' . $partname, $partscore->penalty); $pendingstep->set_behaviour_var('_penalty_' . $partname, min($currentpenalties[$partname] + $partscore->penalty, 1)); // Cap cumulative penalty at 1. } else { $pendingstep->set_behaviour_var('_penalty_' . $partname, 0); } $pendingstep->set_behaviour_var('_rawfraction_' . $partname, $partscore->rawfraction); $currentrawfractions[$partname] = $partscore->rawfraction; $currentfractions[$partname] = max($partscore->rawfraction - $currentpenalties[$partname], $currentfractions[$partname]); // Current fraction never decreases. $pendingstep->set_behaviour_var('_fraction_' . $partname, $currentfractions[$partname]); } if (empty($currentfractions)) { $totalfraction = null; $overallstate = question_state::$gaveup; } else { $totalweight = 0; $totalfraction = 0; foreach ($this->question->get_parts_and_weights() as $index => $weight) { $totalweight += $weight; if (array_key_exists($index, $currentfractions)) { $totalfraction += $weight * $currentfractions[$index]; } } $totalfraction = $totalfraction / $totalweight; $allright = true; $allwrong = true; foreach ($this->question->get_parts_and_weights() as $index => $weight) { if (array_key_exists($index, $currentrawfractions)) { $partstate = question_state::graded_state_for_fraction($currentrawfractions[$index]); if ($partstate != question_state::$gradedright) { $allright = false; } if ($partstate != question_state::$gradedwrong) { $allwrong = false; } } else { $allright = false; } } if ($allright) { $overallstate = question_state::$gradedright; } else { if ($allwrong) { $overallstate = question_state::$gradedwrong; } else { $overallstate = question_state::$gradedpartial; } } } return array($totalfraction, $overallstate); }
public function process_finish(question_attempt_pending_step $pendingstep) { if ($this->qa->get_state()->is_finished()) { return question_attempt::DISCARD; } $response = $this->qa->get_last_step()->get_qt_data(); if (!$this->question->is_gradable_response($response)) { $pendingstep->set_state(question_state::$gaveup); } else { list($fraction, $state) = $this->question->grade_response($response); $pendingstep->set_fraction($fraction); $pendingstep->set_state($state); } $pendingstep->set_new_response_summary($this->question->summarise_response($response)); return question_attempt::KEEP; }
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) { if ($this->qa->get_state()->is_finished()) { return question_attempt::DISCARD; } $prevtries = $this->qa->get_last_behaviour_var('_try', 0); $prevbest = $this->qa->get_fraction(); if (is_null($prevbest)) { $prevbest = 0; } $laststep = $this->qa->get_last_step(); $response = $laststep->get_qt_data(); if (!$this->question->is_gradable_response($response)) { $state = question_state::$gaveup; $fraction = 0; } else { if ($laststep->has_behaviour_var('_try')) { // Last answer was graded, we want to regrade it. Otherwise the answer // has changed, and we are grading a new try. // There is a Moodle bug here, resulting in regrading of // already-graded questions. // See https://tracker.moodle.org/browse/MDL-42399 $prevtries -= 1; } // *** changed bit #2 begins *** // Cache extra data from grade response. $gradedata = $this->question->grade_response($response); list($fraction, $state) = $gradedata; if (count($gradedata) > 2) { foreach ($gradedata[2] as $name => $value) { $pendingstep->set_qt_var($name, $value); } } // *** end of changed bit #2 *** $pendingstep->set_behaviour_var('_try', $prevtries + 1); $pendingstep->set_behaviour_var('_rawfraction', $fraction); $pendingstep->set_new_response_summary($this->question->summarise_response($response)); } $pendingstep->set_state($state); $pendingstep->set_fraction(max($prevbest, $this->adjusted_fraction($fraction, $prevtries))); return question_attempt::KEEP; }
public function process_submit(question_attempt_pending_step $pendingstep) { // Must find out prevbest before parent function get in it's fraction. $prevbest = $pendingstep->get_fraction(); if (is_null($prevbest)) { $prevbest = 0; } $status = parent::process_submit($pendingstep); $response = $pendingstep->get_qt_data(); if ($this->question->is_gradable_response($response) && $status == question_attempt::KEEP) { // State was graded. $prevtotal = $this->qa->get_last_behaviour_var('_totalpenalties', 0); // The fraction = rawfraction - totalpenalties (already collected). $pendingstep->set_fraction(max($prevbest, $this->adjusted_fraction($pendingstep->get_behaviour_var('_rawfraction'), $prevtotal))); $pendingstep->set_behaviour_var('_totalpenalties', $prevtotal + $this->question->penalty); // For submit penalty is added after fraction is calculated. $pendingstep->set_behaviour_var('_penalty', $this->question->penalty); } return $status; }