F<contextPercent.pl>  Context for entering percentages using C<%>
From WeBWorK
NAME
contextPercent.pl  Context for entering percentages using %
DESCRIPTION
This file implements a context in which students can enter percentage
values using %
. There are a number of options that allow you to control
the number of decimal places, and whether mathematical operations are allowed.
To use the context, put
loadMacros("contextPercent.pl");
at the top of your problem file, and then issue the
Context("Percent");
command to select the context. To create a Percent value, use
$m = Compute("10%");
or
$m = Percent(.1);
and so on. Both of these produce equivalent values (10%).
There are also three limited contexts that can be obtained using one of the following:
Context("LimitedPercent"); Context("LimitedPercentstrict"); Context("Percentstrict");
The Percent
context allows you to use percentages rather freely
within an expression. For example
Compute("10% + 20%");
would produce the same result as Compute("30%")
, and so would
either of
Compute("10% + .2"); Compute("(5+5)% + (2^2*ln(e**5))%");
In this way, n%
is treated essentially as (n/100)
.
You can enforce more restrictive rules using the LimitedPercent
or
LimitedPercentstrict
contexts. The first of these allows
operations within the number that preceeds the percent sign, but does
not allow you to combine percentages with real numbers or other
percentages. In this way, (5+5)%
is legal, but 5% + 5%
is not.
The LimitedPercentstrict
context disallows all computations, and
only allows you to enter percentages as a single numeric constant
followed by a percent sign.
Finally, the Percentstrict
context allows you to combine percent
values, but the numeric part of the percent must be a constant, not an
expression. For example, 10% + 5%
is allowed, but not (10+5)%
.
As with all MathObjects, you obtain an answer checker for a Percent
object via the cmp
method, e.g.,
ANS($m>cmp);
There are a number of options that you can supply to control the details of the answer checker, listed below. These can also be set as flags within the Context so that they affect all Percent objects that you create. For example,
ANS($m>cmp(forceDecimals=>1));
or
Context()>flags>set(forceDecimals => 1); ANS($m>cmp)
would both produce answer checkers for $m
where the student would
have to enter decimals that include any trailing zeros.
decimalPlaces => 1

This controls the number of decimal places to use in output of Percent objects, and the number that a student will be required to enter (when the appropriate flags are given, as described below). The
tolerance
is set by default to be.0005
, so if you change the number of decimal places, you should change thetolerance
to correspond to it (two more zeros thandecimalPlaces
). For exampleContext()>flags>set( decimalPlaces => 2, tolerance => .00005, );
The default value is 1 decimal place.
forceDecimals => 0

This value controls whether students are forced to enter the full number of decimals, even if there are trailing zeros. When set to 0 (the default for the
Percent
,Percentstrict
, andLimitedPercent
contexts), trailing zeros may be left off, soCompute("10.0%")
could be entered as just10%
by a student. When set to 1 (the default for theLimitedPercentstrict
context), ifdecimalPlaces
is 2, thenCompute("10.00%")
would require the student to enter10.00%
rather than10%
or10.0%
. It really only makes sense to set this in theLimitedPercentstrict
context, since in the other two, percent values can be computed, and so the number of decimal places is not really known. noExtraDecimals => 0

This determines whether students are allowed to enter decimals beyond the number given by the
decimalPlaces
flag. If set to 0 (the default for thePercent
,Percentstrict
, andLimitedPercent
contexts), any number of decimals are allowed (but thetolerance
determines what values are meaningfull), while if set to 1 (the default for theLimitedPercentstrict
context), students are not allowed to enter more than the required number of decimals and receive a warning if they do. trimTrailingZeros => 1

This determines whether the output for Percent objects will have trailing zeros removed. When set to 1 (the default for the
Percent
,Percentstrict
, andLimitedPercent
contexts), ifdecimalPlaces
is 2, then10.00%
will display as10%
and10.30%
will display as10.3%
. When set to 0 (the default forLimitedPercentstrict
), trailing zeros will be retained, so the output will always have exactlydecimalPlaces
decimal values, even if they are zero. promoteReals => 1

This determines whether real numbers can be combined and compared with percentages. When set to 1 (the default for the
Percent
context), students could enterCompute("10%")
as either10%
or.1
or5% + .05
, while when set to 0 (the default for the Limited and strict contexts), students must enter percentages using the percent symbol (%
). strictPercent => 0

This controls whether the number preceding a percent sign can be a computation or whether it must be a numeric constant. When set to 0 (the default for the
Percent
andLimitedPercent
contexts), students can use formulas to create a percentage value, e.g.,(5 + 10)%
for15%
. When set to 1 (the default for thePercentstrict
andLimitedPercentstrict
context), only numeric constants can be followed by the percent sign. Note that setting this flag to 1 also requires that you setreduceConstants
andreduceConstantFunctions
to 0 as well.
The default tolerance
of .0005 works properly only if your original
percent values have no more than 1 decimal place. If you were to do
$m = Compute("10.15%");
for example, then $m would print as 10.2%
, but neither a student
answer of 10.1%
nor of 10.2%
would be marked correct. That is
because neither of these are less than .0005 away from the correct
answer of 10.15%
(remember that 10.15%
is .1015). If you create
percentages that have more decimal places than the usual one place,
you may want to round or truncate them. Percent objects have two
methods for accomplishing this: round()
and truncate()
, which
produce rounded or truncated copies of the original Percent object:
$m = Compute("34.127%")>round; # produces 34.13% $m = Compute("34.127%")>truncate; # produces 34.12%
These are particularly helpful if you are producing percentages via computations.