MDL-63186 question: Calculate extremums of summarised questions

Modified calculated_random_question_summary class so that it can return minimum and maximum
of each attribute of the sub questions it is summarising.

Part of MDL-62610
This commit is contained in:
Shamim Rezaie
2018-09-28 11:07:21 +08:00
committed by Simey Lameze
parent 6ee2b972c9
commit d79fef2ab5
2 changed files with 85 additions and 8 deletions
@@ -405,7 +405,7 @@ class all_calculated_for_qubaid_condition {
*
* @param int $slot the slot no
* @param bool $limited limit number of variants and sub-questions displayed?
* @return calculated|calculated_for_subquestion[] stats to display
* @return calculated|calculated_for_subquestion|calculated_random_question_summary[] stats to display
*/
protected function all_subq_and_variant_stats_for_slot($slot, $limited) {
// Random question in this slot?
@@ -414,10 +414,6 @@ class all_calculated_for_qubaid_condition {
if ($limited) {
$randomquestioncalculated = $this->for_slot($slot);
// If we're showing a limited view of the statistics then add a
// random question summary stat rather than a stat for each
// subquestion.
$toreturn[] = $this->make_new_random_question_summary_stat($randomquestioncalculated);
if ($subqvariantstats = $this->all_subq_variants_for_one_slot($slot)) {
$subqvariantfacilitystats = $this->find_min_median_and_max_facility_stats_objects($subqvariantstats);
@@ -429,6 +425,12 @@ class all_calculated_for_qubaid_condition {
$toreturn = array_merge($toreturn, $subqfacilitystats);
}
// If we're showing a limited view of the statistics then add a
// random question summary stat rather than a stat for each
// subquestion.
$summarystat = $this->make_new_random_question_summary_stat($randomquestioncalculated, $subqstats);
$toreturn = array_merge([$summarystat], $toreturn);
foreach ($toreturn as $index => $calculated) {
$calculated->subqdisplayorder = $index;
}
@@ -479,13 +481,13 @@ class all_calculated_for_qubaid_condition {
* subquestion directly.
*
* @param calculated $randomquestioncalculated The calculated instance for the random question slot.
* @param calculated[] $subquestionstats The instances of the calculated stats of the questions that are being summarised.
* @return calculated_random_question_summary
*/
protected function make_new_random_question_summary_stat($randomquestioncalculated) {
protected function make_new_random_question_summary_stat($randomquestioncalculated, $subquestionstats) {
$question = $randomquestioncalculated->question;
$slot = $randomquestioncalculated->slot;
$calculatedsummary = new calculated_random_question_summary($question, $slot);
$calculatedsummary->subquestions = $randomquestioncalculated->subquestions;
$calculatedsummary = new calculated_random_question_summary($question, $slot, $subquestionstats);
return $calculatedsummary;
}
@@ -44,6 +44,25 @@ class calculated_random_question_summary extends calculated {
*/
public $subqdisplayorder;
/**
* @var calculated[] The instances storing the calculated stats of the questions that are being summarised.
*/
protected $subqstats;
/**
* calculated_random_question_summary constructor.
*
* @param \stdClass $question
* @param int $slot
* @param calculated[] $subqstats The instances of the calculated stats of the questions that are being summarised.
*/
public function __construct($question, $slot, $subqstats) {
parent::__construct($question, $slot);
$this->subqstats = $subqstats;
$this->subquestions = implode(',', array_column($subqstats, 'questionid'));
}
/**
* This is a summary stat so never breakdown by variant.
*
@@ -52,4 +71,60 @@ class calculated_random_question_summary extends calculated {
public function break_down_by_variant() {
return false;
}
/**
* Returns the minimum and maximum values of the given attribute in the summarised calculated stats.
*
* @param string $attribute The attribute that we are looking for its extremums.
* @return array An array of [min,max]
*/
public function get_min_max_of($attribute) {
$getmethod = 'get_min_max_of_' . $attribute;
if (method_exists($this, $getmethod)) {
return $this->$getmethod();
} else {
$min = $max = null;
// We cannot simply use min or max functions because, in theory, some attributes might be non-scalar.
foreach (array_column($this->subqstats, $attribute) as $value) {
if (is_scalar($value)) {
if (!isset($min)) {
$min = $value;
}
if (!isset($max)) {
$max = $value;
}
$min = min($min, $value);
$max = max($max, $value);
}
}
return [$min, $max];
}
}
/**
* Returns the minimum and maximum values of the standard deviation in the summarised calculated stats.
* @return array An array of [min,max]
*/
protected function get_min_max_of_sd() {
$min = $max = null;
foreach ($this->subqstats as $subqstat) {
if (isset($subqstat->sd) && $subqstat->maxmark) {
if (!isset($min)) {
$min = $subqstat->sd / $subqstat->maxmark;
}
if (!isset($max)) {
$max = $subqstat->sd / $subqstat->maxmark;
}
$min = min($min, $subqstat->sd / $subqstat->maxmark);
$max = max($max, $subqstat->sd / $subqstat->maxmark);
}
}
return [$min, $max];
}
}