Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions classes/local/evaluator.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,13 @@ public function substitute_variables_in_text(string $text, bool $skiplists = tru
if ($skiplists && in_array($result->type, [token::LIST, token::SET])) {
continue;
}
// If the result is a numeric string, we convert it back to a number, in order for
// the standard PHP formatting to apply: numbers with an absolute value ≥ 1e14
// or < 0.0001 would normally be printed in scientific notation.
if ($result->type === token::STRING && is_numeric($result->value)) {
$result->type = token::NUMBER;
$result->value = floatval($result->value);
}
// If the result is a number, we try to localize it, unless the admin settings do not
// allow the decimal comma.
if ($result->type === token::NUMBER) {
Expand Down
27 changes: 27 additions & 0 deletions tests/evaluator_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -1348,6 +1348,33 @@ public function test_substitute_variables_in_text(): void {
self::assertEquals($expected, $output);
}

public function test_substitute_variables_in_text_with_sigfig(): void {
$this->resetAfterTest();
$this->setAdminUser();

// Define, parse and evaluate some variables.
$vars = 'a=0.3; b=sigfig(a, 2); c=0.000005; d=sigfig(c, 8); e=fact(19); f=sigfig(e, 3)';
$parser = new parser($vars);
$statements = $parser->get_statements();
$evaluator = new evaluator();
$evaluator->evaluate($statements);

// We only test the correct replacement of the numbers; correct interpretation of
// placeholders is covered in another test.
$text = '{a} -- {b} -- {c} -- {d} -- {e} -- {f}';
$output = $evaluator->substitute_variables_in_text($text);
$expected = '0.3 -- 0.3 -- 5.0E-6 -- 5.0E-6 -- 1.2164510040883E+17 -- 1.22E+17';
self::assertEquals($expected, $output);

// Setting the localised decimal separator, but disallow the decimal comma in the admin settings.
qtype_formulas_test_helper::define_local_decimal_separator();
set_config('allowdecimalcomma', 1, 'qtype_formulas');
self::assertEquals('1', get_config('qtype_formulas', 'allowdecimalcomma'));
$output = $evaluator->substitute_variables_in_text($text);
$expected = '0,3 -- 0,3 -- 5,0E-6 -- 5,0E-6 -- 1,2164510040883E+17 -- 1,22E+17';
self::assertEquals($expected, $output);
}

public function test_substitute_variables_in_algebraic_formula(): void {
// Define, parse and evaluate some variables.
$vars = 'a=1; b=[2,3,4]; c={1,2,3}; x={1:10}; y={1:10}; k = [[1,2],[3,4]];';
Expand Down
27 changes: 27 additions & 0 deletions tests/renderer_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,33 @@ public function test_substitution_of_local_variables(): void {
$this->check_output_does_not_contain_stray_placeholders();
}

public function test_right_answer_feedback_uses_appropriate_decimal_separator(): void {
// Setting the localised decimal separator, but disallow the decimal comma in the admin settings.
qtype_formulas_test_helper::define_local_decimal_separator();
self::assertEquals('0', get_config('qtype_formulas', 'allowdecimalcomma'));

$q = $this->get_test_formulas_question('testsinglenum');
$q->parts[0]->answer = '3.5';

$this->start_attempt_at_question($q, 'immediatefeedback', 1);
$this->process_submission(['0_0' => '42', '-submit' => 1]);
$this->check_output_contains_lang_string('correctansweris', 'qtype_formulas', '3.5');

// Now allowing the decimal comma to be used.
set_config('allowdecimalcomma', 1, 'qtype_formulas');
$this->start_attempt_at_question($q, 'immediatefeedback', 1);
$this->process_submission(['0_0' => '42', '-submit' => 1]);
$this->check_output_contains_lang_string('correctansweris', 'qtype_formulas', '3,5');

// Make sure the decimal comma is also applied for numbers that are string tokens.
// Note that we *should* have 3,50 as the model answer, but as we are converting
// the string output from sigfig() back to a number, trailing zeroes will be lost.
$q = $this->get_test_formulas_question('testsinglenum');
$q->parts[0]->answer = 'sigfig(3.5, 3)';
$this->process_submission(['0_0' => '42', '-submit' => 1]);
$this->check_output_contains_lang_string('correctansweris', 'qtype_formulas', '3,5');
}

public function test_render_question_with_separate_unit_field(): void {
$q = $this->get_test_formulas_question('testsinglenumunitsep');
$q->parts[0]->unitpenalty = 0.5;
Expand Down
Loading