Skip to content

Typical WeBWorK problem with InexactValue

Lee McPherson edited this page Sep 1, 2023 · 10 revisions

Simple version

You will need to add the "contextInexactValue.pl" macro at the very least in addition to the standard macros:

DOCUMENT();

loadMacros(
"PGstandard.pl",
"MathObjects.pl",
"PGML.pl",
"contextInexactValue.pl"
);

Start with declaring the InexactValue context. You can follow up with several options that determine how the problem will be graded:

Context("InexactValue");
Context()->flags->set(failOnValueWrong=>1);  # must have value correct (no partial credit for getting sig figs only)
Context()->flags->set(creditValue=>0.75);    # 75% credit for correct answer (default is 50%)
Context()->flags->set(creditSigFigs=>0.25);  # 25% credit for sig figs

The failOnValueWrong gives zero credit if the answer doesn't match with the exception of sig fig errors and some rounding errors. You will always want this to be true (1) unless you are making a problem where the intention is to grade sig figs only. i.e. the problem is about correct sig figs.

Next, start generating your values for your problems using the shortcut InexactValue. There are two ways to use it:

  • string (text) values
  • number values with explicit sig figs as a second parameter

I would almost always recommend entering values as a string. There are potential side-effects to entering values as numbers that are discussed on the main page, so avoid it if possible.

$mass = InexactValue('2.40');
$volume = InexactValue('3.5');

You can now do any type of math with these variables and significant figures will be calculated automatically.

$density = $mass / $volume;

Now, let's put these into a PGML Question:

BEGIN_PGML

Determine the density of an unknown liquid that has a mass of [$mass] grams and a volume of [$volume] milliliters.

[______]{$density} g/mL

Enter the value with the appropriate number of significant figures.

END_PGML

That's it! The calculator answer is 0.685714... and it keeps going. This value is stored within $density, but the student will only get it right if they enter within 2 decimals of the correct number of significant figures. So, 0.7, 0.686, and 0.6857 are correct for 75% of credit. They lose 25% of credit for incorrect sig figs. To get 100%, they would need to enter 0.69.

Algorithmic version

Everything is the same except how we create the InexactValue. We're going to use the WeBWorK random utility and a built-in Perl function called sprintf. sprintf documentation here!

For a random mass: First, create a random value. First value is the minimum, second is the maximum, third is the smallest step between those two... The following creates a random value between 2 and 3 that varies by the hundredths place. i.e. 2.00, 2.01, ... , 2.99, 3.00

$massNumber = random(2, 3, 0.01);

Next, since $massNumber is a number, not a string, it will output 2.00 as 2 only. This is bad. Let's force it to output those extra places. sprintf is used for that. %.2f means output a fixed decimal number with 2 decimal places.

$massString = sprintf('%.2f', $massNumber);

Finally, since the $massString variable is a string, we can use it in InexactValue.

$mass = InexactValue($massString);

We can condense this entire process as much as needed, sacrificing readability:

$mass = InexactValue(sprintf('%.2f', random(2,3,0.01)));

sprintf tips

Randomize the number of sig figs

# random number: 2, 3, or 4
$randomSigfigs = random(2,4,1);

# Notice below, we switched from using single quotes to double quotes.  Double quotes allows string interpolation, 
# meaning we can put variables inside the string. The dollar sign defines the beginning of the variable. 
# The curly braces defined the end of the variable name.

$massString = sprintf("%.${randomSigfigs}f", $massNumber);

Scientific notation

Switch from using f to e

$sciText = sprintf('%.3e', 234567);

$sciText will contain the string: 2.346e+05. The number of zeros in the exponent and whether the plus sign shows depends on the system where Perl is installed, but InexactValue will understand it in many formats.

Whole numbers with trailing zeros

This is slightly tricky. If you want to generate a random number that has trailing zeros in the whole number position like 25000 and have those zeros be significant, it's probably better to generate scientific notation. However, if you need them in decimal form for display purposes, you can do the following:

# generate random number: 24000, 25000, ...., 38000, 39000
$randomNumber = random(24000, 39000, 1000);

# force a string in decimal format with a trailing decimal place
$wholeNumberString = sprintf('%0f', $randomNumber) . '.';

Notice the appending of a decimal point after the sprintf function. This would actually work without using the sprintf function, too. I have included it just in case.

Clone this wiki locally