mirror of
https://github.com/moodle/moodle.git
synced 2025-07-25 16:21:47 +02:00
MDL-35055 question import: slight error with the Match grades option.
Even in the 'Error if grade not listed case', it was applying a small tolerance. In the case of a fuzzy match, it was returning the inexact grade from the import file, rather than the precise grade that Moodle was expecting. That causes problems when the editing form is displayed, because the value from the database does not match any of the available options, so the grade is changed to 0%.
This commit is contained in:
@@ -209,39 +209,44 @@ function get_grade_options() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* match grade options
|
* Check whether a given grade is one of a list of allowed options. If not,
|
||||||
* if no match return error or match nearest
|
* depending on $matchgrades, either return the nearest match, or return false
|
||||||
|
* to signal an error.
|
||||||
* @param array $gradeoptionsfull list of valid options
|
* @param array $gradeoptionsfull list of valid options
|
||||||
* @param int $grade grade to be tested
|
* @param int $grade grade to be tested
|
||||||
* @param string $matchgrades 'error' or 'nearest'
|
* @param string $matchgrades 'error' or 'nearest'
|
||||||
* @return mixed either 'fixed' value or false if erro
|
* @return mixed either 'fixed' value or false if error.
|
||||||
*/
|
*/
|
||||||
function match_grade_options($gradeoptionsfull, $grade, $matchgrades='error') {
|
function match_grade_options($gradeoptionsfull, $grade, $matchgrades = 'error') {
|
||||||
|
|
||||||
if ($matchgrades == 'error') {
|
if ($matchgrades == 'error') {
|
||||||
// if we just need an error...
|
// (Almost) exact match, or an error.
|
||||||
foreach ($gradeoptionsfull as $value => $option) {
|
foreach ($gradeoptionsfull as $value => $option) {
|
||||||
// slightly fuzzy test, never check floats for equality :-)
|
// Slightly fuzzy test, never check floats for equality.
|
||||||
if (abs($grade - $value) < 0.00001) {
|
if (abs($grade - $value) < 0.00001) {
|
||||||
return $grade;
|
return $value; // Be sure the return the proper value.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// didn't find a match so that's an error
|
// Didn't find a match so that's an error.
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
} else if ($matchgrades == 'nearest') {
|
} else if ($matchgrades == 'nearest') {
|
||||||
// work out nearest value
|
// Work out nearest value
|
||||||
$hownear = array();
|
$best = false;
|
||||||
|
$bestmismatch = 2;
|
||||||
foreach ($gradeoptionsfull as $value => $option) {
|
foreach ($gradeoptionsfull as $value => $option) {
|
||||||
if ($grade==$value) {
|
$newmismatch = abs($grade - $value);
|
||||||
return $grade;
|
if ($newmismatch < $bestmismatch) {
|
||||||
|
$best = $value;
|
||||||
|
$bestmismatch = $newmismatch;
|
||||||
}
|
}
|
||||||
$hownear[ $value ] = abs( $grade - $value );
|
|
||||||
}
|
}
|
||||||
// reverse sort list of deltas and grab the last (smallest)
|
return $best;
|
||||||
asort( $hownear, SORT_NUMERIC );
|
|
||||||
reset( $hownear );
|
|
||||||
return key( $hownear );
|
|
||||||
} else {
|
} else {
|
||||||
return false;
|
// Unknow option passed.
|
||||||
|
throw new coding_exception('Unknown $matchgrades ' . $matchgrades .
|
||||||
|
' passed to match_grade_options');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -55,4 +55,19 @@ class questionlib_testcase extends basic_testcase {
|
|||||||
array(0 => 't1', 1 => 't2', 2 => 't3'));
|
array(0 => 't1', 1 => 't2', 2 => 't3'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_match_grade_options() {
|
||||||
|
$gradeoptions = question_bank::fraction_options_full();
|
||||||
|
|
||||||
|
$this->assertEquals(0.3333333, match_grade_options($gradeoptions, 0.3333333, 'error'));
|
||||||
|
$this->assertEquals(0.3333333, match_grade_options($gradeoptions, 0.333333, 'error'));
|
||||||
|
$this->assertEquals(0.3333333, match_grade_options($gradeoptions, 0.33333, 'error'));
|
||||||
|
$this->assertFalse(match_grade_options($gradeoptions, 0.3333, 'error'));
|
||||||
|
|
||||||
|
$this->assertEquals(0.3333333, match_grade_options($gradeoptions, 0.3333333, 'nearest'));
|
||||||
|
$this->assertEquals(0.3333333, match_grade_options($gradeoptions, 0.333333, 'nearest'));
|
||||||
|
$this->assertEquals(0.3333333, match_grade_options($gradeoptions, 0.33333, 'nearest'));
|
||||||
|
$this->assertEquals(0.3333333, match_grade_options($gradeoptions, 0.33, 'nearest'));
|
||||||
|
|
||||||
|
$this->assertEquals(-0.1428571, match_grade_options($gradeoptions, -0.15, 'nearest'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user