diff --git a/doc/en/Authoring/Question_options.md b/doc/en/Authoring/Question_options.md index ec105c234e..7eee340471 100644 --- a/doc/en/Authoring/Question_options.md +++ b/doc/en/Authoring/Question_options.md @@ -91,16 +91,27 @@ This option sets the value of [Maxima](../CAS/Maxima_background.md)'s sqrtdispflag -When false the prefix function `sqrt(x)` will be displayed as \(x^{1/2}\). -Please note that Maxima (by default) does not like to use the \(\sqrt{}\) symbol. -The internal representation favours fractional powers, for very good reasons. -In Maxima 5.19.1 we get: +When false the prefix function `sqrt(x)` will be displayed as \(x^{1/2}\). This setting is _global_ to the question, and having both notations co-exist in one question is very tricky. You need to have `simp:false` throughout the question. + +By default Maxima does not like to use the \(\sqrt{}\) symbol. The internal representation favours fractional powers, for very good reasons. In Maxima we get: (%i1) 4*sqrt(2); (%o1) 2^(5/2) (%i2) 6*sqrt(2); (%o2) 3*2^(3/2) +Furthermore, if you execute this in a Maxima session + + simp:true; + p:1+sqrt(x); + ?print(p); + +Then the displayed value of `p` is \(\sqrt{x}+1\) whereas the internal representation of `p` is + + ((MPLUS SIMP) 1 ((MEXPT SIMP) $X ((RAT SIMP) 1 2))) + +This means that internally Maxima has converted `sqrt(x)` to `x^(1/2)`, even though it is by default displayed as `sqrt`. This is an example where the displayed form (text and LaTeX) does not match Maxima's internal representation. + Do you really want to continue using \(\sqrt{}\) in your teaching? In his *Elements of Algebra*, L. Euler wrote the following. > \(\S 200\) We may therefore entirely reject the radical signs at present made use of, and employ in their stead diff --git a/tests/castext_test.php b/tests/castext_test.php index 404a5e4373..21abf911c3 100644 --- a/tests/castext_test.php +++ b/tests/castext_test.php @@ -2546,4 +2546,73 @@ public function test_format_moodle_parsons() { $expected = $txt; $this->assertEquals($expected, $at1->get_rendered()); } + + /** + * @covers \qtype_stack\stack_cas_castext2_latex + * @covers \qtype_stack\stack_cas_keyval + */ + public function test_sqrtdispflag() { + // Test 1. + $a2 = ['p1:1+sqrt(x)']; + $s2 = []; + foreach ($a2 as $s) { + $cs = stack_ast_container::make_from_teacher_source($s, '', new stack_cas_security(), []); + $this->assertTrue($cs->get_valid()); + $s2[] = $cs; + } + $options = new stack_options(); + $options->set_option('simplify', true); + $cs2 = new stack_cas_session2($s2, $options, 7); + + $txtinput = '{@p1@}, {@(sqrtdispflag:false,p1)@}, {@p1@}'; + // Notice the 3rd expression is still using ^(1/2) because the sqrtdispflag:false becomes global. + $expected = '\({\sqrt{x}+1}\), \({x^{\frac{1}{2}}+1}\), \({x^{\frac{1}{2}}+1}\)'; + $at1 = castext2_evaluatable::make_from_source($txtinput, 'test-case'); + $this->assertTrue($at1->get_valid()); + $cs2->add_statement($at1); + $cs2->instantiate(); + $this->assertEquals($expected, $at1->get_rendered()); + + // Test 2. + $a2 = ['p1:1+sqrt(x)']; + $s2 = []; + foreach ($a2 as $s) { + $cs = stack_ast_container::make_from_teacher_source($s, '', new stack_cas_security(), []); + $this->assertTrue($cs->get_valid()); + $s2[] = $cs; + } + $options = new stack_options(); + $options->set_option('simplify', true); + $cs2 = new stack_cas_session2($s2, $options, 7); + + $txtinput = '{@p1@}, {@block([sqrtdispflag],sqrtdispflag:false,p1)@}, {@p1@}'; + // None of the expressions use ^(1/2) because the sqrtdispflag:false is a local variable. + $expected = '\({\sqrt{x}+1}\), \({\sqrt{x}+1}\), \({\sqrt{x}+1}\)'; + $at1 = castext2_evaluatable::make_from_source($txtinput, 'test-case'); + $this->assertTrue($at1->get_valid()); + $cs2->add_statement($at1); + $cs2->instantiate(); + $this->assertEquals($expected, $at1->get_rendered()); + + // Test 3. + $a2 = ['p1:1+sqrt(x)']; + $s2 = []; + foreach ($a2 as $s) { + $cs = stack_ast_container::make_from_teacher_source($s, '', new stack_cas_security(), []); + $this->assertTrue($cs->get_valid()); + $s2[] = $cs; + } + $options = new stack_options(); + $options->set_option('simplify', true); + $cs2 = new stack_cas_session2($s2, $options, 7); + + $txtinput = '{@p1@}, {@(sqrtdispflag:false,p1)@}, {@(sqrtdispflag:true,p1)@}'; + // Need to explicitly switch back in the _next_ expresion. Akward. + $expected = '\({\sqrt{x}+1}\), \({x^{\frac{1}{2}}+1}\), \({\sqrt{x}+1}\)'; + $at1 = castext2_evaluatable::make_from_source($txtinput, 'test-case'); + $this->assertTrue($at1->get_valid()); + $cs2->add_statement($at1); + $cs2->instantiate(); + $this->assertEquals($expected, $at1->get_rendered()); + } }