WeBWorK Main Forum

Commas in Formulas

Commas in Formulas

by Rick Lynch -
Number of replies: 2

I'm trying to create a problem in which currency is used and hence it not unusual for students to include commas in their answers for big numbers over 999. The trouble is that this problem is asking for the cost, revenue and profit functions and students might try to use commas, but it gives a weird error that they will unlikely understand. We are fine if commas aren't allowed, and we'd just like to change the message since that seems to be the easiest. However, I tried to do so in both potential contexts (even though I think I only need it in the second), but it doesn't actually change the message. So my question is: can this message actually be changed, or can I make it so commas are in fact accepted in numbers inside of a formula doing something like what's on the wiki: https://webwork.maa.org/wiki/Modifying_Contexts_(advanced), or can I somehow disable commas for lists and adjust things that way? I should note that I'm only using the Limited Polynomial context to enforce simplifications.

Here's the code: 

################################################################################
#  Initialization
################################################################################
DOCUMENT();
loadMacros(
    "PGstandard.pl",
    "MathObjects.pl",
    "PGML.pl",
    "contextCurrency.pl",
    "contextLimitedPolynomial.pl",
);
TEXT(beginproblem());
################################################################################
#  Problem Setup
################################################################################
Context("Currency");
Context()->{error}{msg}{"Your answer isn't a formula that returns a number (it looks like a list of numbers)"} = "Commas should not appear in equations";
Context()->flags->set(trimTrailingZeros=>1);
Context()->noreduce('(-x)-y');
Context()->noreduce('(-x)-y','(-x)+y');
$fix = random(7500,15000,50);
$fixD = Currency($fix);
$prod = random(15,40);
$prodD = Currency($prod);
$sale = $prod+random(floor($prod/2),floor(5*$prod/6));
$saleD = Currency($sale);
$prof = $sale - $prod;
Context("LimitedPolynomial-Strict");
Context()->parens->redefine('(');
Context()->{error}{msg}{"Your answer isn't a formula that returns a number (it looks like a list of numbers)"} = "Commas should not appear in equations";
$C = Formula("$prod x + $fix")->reduce;
$R = Formula("$sale x")->reduce;
$P = Formula("$prof x - $fix")->reduce;
################################################################################
#  Text
################################################################################
BEGIN_PGML
A company has monthly fixed costs of [$fixD]. The production cost of each
item is [$prodD] and each item sells for [$saleD]. Let [`x`] be the number
of items that are produced and sold.
a. What is the company's monthly cost function? 
        [`C(x) = `] [__]{$C}
b. What is the company's monthly revenue function? 
        [`R(x) = `] [__]{$R}
c. What is the company's monthly profit function? 
        [`P(x) = `] [__]{$P}
        
END_PGML
ENDDOCUMENT();
In reply to Rick Lynch

Re: Commas in Formulas

by Davide Cervone -

I'm not sure why you are switching to the LimitedPolynomial context. If you stay with the Current context, then you will be able to enter things like $13,500 + $31 x as well as 13,500 + 31 x or 13500 + 31 x. I'm assuming that you are trying to force the student answer to be simplified, but is that really the critical idea, here?

If you must use LimitedPolynomial, then you can use

Context->operators->undefine(',');

to remove the comma from the context. This will give you an error Can't use ',' in this context if used, and you can redefine that with

Context()->{error}{msg}{"Can't use ',' in this context"} = "Commas should not appear in equations";

(The error message about the type of the object is produced outside of the system that uses {error}{msg}, and so can't be remapped that way. You would need to use a post-filter to change it.)

On the other hand, you can use the link you cited to allow commas in the numbers, but you have to convert \ to ~~ if you do it within the problem itself. (If you make a macro file that you load into the problems, you leave it as in the example in the link.) Here the in-problem version.

Context()->{pattern}{number} = '(?:(?:~~d{1,3}(?:~~,~~d{3})+|~~d+)(?:~~.~~d*)?|~~.~~d+)(?:E[-+]?~~d+)?';
Context()->{pattern}{signedNumber} = '[-+]?(?:(?:~~d{1,3}(?:~~,~~d{3})+|~~d+)(?:~~.~~d*)?|~~.~~d+)(?:E[-+]?~~d+)?';
Context()->flags->set(NumberCheck => sub {
  my $self = shift;                              # the Number object
  my $value = $self->{value_string};             # the original string
  $value =~ s/,//g;                              # remove commas
  $self->{value} = $value + 0;                   # make sure it is converted to a number
  $self->{isOne} = ($self->{value} == 1);        # set marker indicating if the value is 1
  $self->{isZero} = ($self->{value} == 0);       # set marker indicating if the value is 0
});
Context()->update;

You can combine that with the removal of the comma given above (commas will still be allowed in numbers). You should be able to modify this to allow a dollar sign at the beginning of a number and remove it along with the commas in the NumberCheck function above, if you want to allow currency-like numbers, but it's a little more fragile than using the Currency context itself.

In reply to Davide Cervone

Re: Commas in Formulas

by Rick Lynch -
Yeah, I set the LimitedPolynomial context due to what was asked of me by the educators. However, I agree in that I don't really find it critical for the problem at hand.

Your solution for allowing commas in the context works perfectly, so I'll go with that as they're okay with not allowing dollar signs in the answer. Thanks as always - you're such a great help!