WeBWorK Problems

extra parens in a formula with fractions

extra parens in a formula with fractions

by Alex Jordan -
Number of replies: 7

Consider this MWE.

DOCUMENT();

loadMacros(qw(PGstandard.pl PGML.pl contextFraction.pl));

Context("Fraction");
$f = Fraction(1/2);
$g = Compute("$f x");

BEGIN_PGML
[`[$g]`]
END_PGML

ENDDOCUMENT();


This displays $g as
\left({\frac{1}{2}}\right)x

rather than
{\frac{1}{2}}x

Parentheses are introduced because the string interpolation for "$f x" adds parentheses around $f. Then they are in the string passed to Compute, so I suspect that the hadParens property on the division operator in the parse tree is set to 1 (or something like that) and this leads to the string or TeX method on $g using those parens, even if they are not needed for order of operations precedence.

Or maybe they *are* needed for precedence? Is the implied multiplication operator a higher precedence than the division operator?

In any case, I'm wondering if there is a way to manipulate the context so that the above comes out as just

{\frac{1}{2}}x
I've tried the flag showExtraParens=>0 but that does not suppress the parens here in this case.

I know I could construct $g a different way to make the parens disappear, but there is a whole block of exercises that I'd like to change without micromanaging their code. If there is a context solution to this, it would be better for what I have to do here.


In reply to Alex Jordan

Re: extra parens in a formula with fractions

by Jaimos Skriletz -

It appears that contextFraction handles parens a bit different than other objects, and will always show them if the original string had them. There is a parser flag hadParens that is set if the original string had parens and contextFraction will show parens in the string and TeX output in this case. Looking through the code I don't see any context way to modify this behavior, but I was able to test and remove the parens by adding the following to your example right under the definition of $g.

$g->{tree}{lop}{hadParens} = 0;

If you look at the TeX and string methods of contextFraction.pl you will see that parenthesis are always shown in the output if this is set.

In reply to Alex Jordan

Re: extra parens in a formula with fractions

by Davide Cervone -

You and Jaimos are correct that this comes from the hadParens property. It is possible to remove this programmatically, if your problems include PGcourse.pl as the final macro file being loaded, you could add

$context{Fraction}{parser}{Value} = 'my::context::Frac::Parser::Value'
	if defined $context{Fraction};

package my::context::Frac::Parser::Value;
our @ISA = ('context::Fraction::Parser::Value');

sub string {
	my $self = shift;
	delete $self->{hadParens} if $self->{value}->classMatch('Fraction');
	$self->SUPER::string(@_);
}

sub TeX {
	my $self = shift;
	delete $self->{hadParens} if $self->{value}->classMatch('Fraction');
	$self->SUPER::TeX(@_);
}

package main;
This overrides the object class that is inserting the parentheses and subclasses it, replacing the string and TeX methods to clear the hadParens property. Alternatively, you could make a separate macro file that contains these lines and use loadMacros() to load it in all the problems you are wanting to modify. Or you could put a copy of contextFraction.pl in your course's templates/macros directory and edit it to remove the two references to hadParens. Any of those should work.
In reply to Davide Cervone

Re: extra parens in a formula with fractions

by Alex Jordan -

Can you comment on why we would not want these changes for the distribution in general? Is it because something like Formula("x 2/3") would come out like (x 2)/3 instead of like x (2/3)?

In reply to Davide Cervone

Re: extra parens in a formula with fractions

by Larry Riddle -

I tried creating a macro in the template/macros directory that consists just with suggested code in Davide's response. But when I loaded the macro in a pg file, I got the following error message:

Can't locate object method "new" via package "my::context::Frac::Parser::Value" at [PG]/lib/Parser.pm line 50

I've never created my own macro file before so I'm not sure if I need to include any additional text beyond just what I copied from Davide's response. Any suggestions?

In reply to Larry Riddle

Re: extra parens in a formula with fractions

by Danny Glin -

I was not able to reproduce what you're seeing.  When I copy that code into a macro file on my WW 2.20 server it works as described.

Did you copy all of the code in Davide's post?  Also you will need to make sure that you load your custom macro after contextFraction.pl is loaded.

In reply to Danny Glin

Re: extra parens in a formula with fractions

by Larry Riddle -
Yes, I copied the code in Davide's post verbatim and just pasted it in a new file created in the template/macro directory from the course file manager. And the custom macro is loaded after contextFraction.pl. We are on WW 2.19.

I simplified the pg file I was experimenting with so that it just contains Alex's original fraction example. Here it is.

DOCUMENT();
loadMacros(
"PGstandard.pl",
"PGML.pl",
"MathObjects.pl",
"contextFraction.pl",
"noFractionParens.pl",
"PGcourse.pl",
);
Context("Fraction") ;

$f = Fraction(1/2);
$g = Compute("$f x");

BEGIN_PGML
[`[$g]`]
END_PGML

ENDDOCUMENT();

Now when I load this I get the message
ERRORS from evaluating PG file:
Can't locate object method "new" via package "my::context::Frac::Parser::Value" at [PG]/lib/Parser/BOP.pm line 50
from within main::Formula called at line 105 of [PG]/macros/core/Parser.pl
from within main::Compute called at line 13 of setFirstOrderProficiency/testfractions.pg

Here is the local macro info from the terminal, if that makes any difference:
wwadmin@swoop:/opt/webwork/courses/Math309_F24/templates/macros$ lf
total 4
-rw-r--r-- 1 www-data www-data 468 Jul 23 14:42 noFractionParens.pl

If I comment out the load of the local macro, the problem runs and gives the output (1/2)x (as a fraction with the parentheses). If I don't load the local macro but add "->string" to the definition of $f, then the output is 1/2 x as a fraction without parentheses (the desired result).  
In reply to Larry Riddle

Re: extra parens in a formula with fractions

by Danny Glin -

If I use Davide's suggested code in WW2.19 I get the same error.

The fraction context was reworked for WW2.20 as part of the new Context extension system so that fractions would work well within other Contexts.  I suspect that Davide's suggested code was written for the new version of contextFraction.pl.  He'll have to chime in on whether there is an easy tweak to make it work for WW2.19.