openwebwork/pg — pull request #154 by dpvc (2014-08-21 20:13:34+00:00)
Title: Update compound problem macros

Update compound problem macros to record which answers are used, so that the `incorrect` and `canshow` options aren't needed. Add PGML support. Add documentation.

This should be backward compatible with existing problems that use `compoundProblem5.pl`, though it is possible there is usage that differs from what I understand as the usage patterns for the macros. These simplify the use of the scaffold macros so that authors don't have to keep track of the answer numbers for the sections (this was a source of considerable headaches for authors as they modify their problems).

Here is a sample problem:

```
DOCUMENT();

loadMacros(
"PGstandard.pl",
"MathObjects.pl",
"parserMultiAnswer.pl",
"compoundProblem5.pl",
"PGcourse.pl",
);

TEXT(beginproblem());

$showPartialCorrectAnswers = 1;

###########################################################################################
# Initialize sections
###########################################################################################

$scaffold = Scaffold();

##############################################################
#
# Setup
#

Context("Numeric");
Context()->variables->are(x => 'Real');

$a = Compute(random(2,9,1));
$c = Compute(random(1,9,1));
$b = Compute(random(2,6,1));
if ($a*$c > 0) {$b += floor(sqrt(4*$a*$c))}

$quadratic = Formula("$a x^2 + $b x + $c");
$x1 = (-$b + sqrt($b**2-4*$a*$c))/(2*$a);
$x2 = (-$b - sqrt($b**2-4*$a*$c))/(2*$a);

###########################################################################################
# Section 1: Identify coefficients
###########################################################################################

Context()->texStrings;

DISPLAY_SECTION("1: Identify the coefficients", <<'END_SECTION');

Consider the quadratic equation given by \($quadratic=0\).
$PAR
In this exercise, we will consider three different ways to solve this expression.
$PAR
First, identify the coefficients for the quadratic using the standard form
\(ax^2+bx+c=0\):
$BR

\(a =\) \{ ANS($a->cmp); ans_rule(2) \}
\(b =\) \{ NAMED_ANS(b => $b->cmp); NAMED_ANS_RULE("b",2) \}
\(c =\) \{ ANS($c->cmp); ans_rule(2) \}

END_SECTION

###############################################

SECTION_SOLUTION(<<'END_SOLUTION');

Take the coefficient of \(x^2\) for the value of \(a\), the coefficient
of \(x\) for \(b\), and the constant for \(c\). In this case, they
are \(a = $a\), \(b = $b\), and \(c = $c\).

END_SOLUTION

Context()->normalStrings;

#########################################################################################
# Section 2 -- Solve by plugging into the Quadratic formula, no simplify
#########################################################################################

$multians1 = MultiAnswer($x1,$x2)->with(
singleResult => 0,
allowBlankAnswers => 1,
checker => sub {
my ($correct,$student,$self) = @_;
my ($s1, $s2) = @{$student};
my ($c1, $c2) = @{$correct};

return (1,1) if ($c1 == $s1 and $c2 == $s2) or
($c1 == $s2 and $c2 == $s1);
return (1,0) if $c1 == $s1 or $c2 == $s1;
return (0,1) if $c1 == $s2 or $c2 == $s2;
return (0,0);
}
);

###############################################

Context()->texStrings;

DISPLAY_SECTION("2: Solve using the quadratic formula", <<'END_SECTION');

Using the quadratic formula, solve \($quadratic=0\)
$PAR
$BCENTER
\(x\) = \{$multians1->ans_rule(5)\} or \(x\) = \{$multians1->ans_rule(5)\}
$ECENTER

\{ANS($multians1->cmp);''\}

END_SECTION

SECTION_SOLUTION(<<'END_SOLUTION');

Recall that the quadratic equation is
\[x = {-b \pm \sqrt{b^2 - 4ac} \over 2a}.\]
$PAR
You already identified \(a = $a\), \(b = $b\), and \(c = $c\),
so the results are:
\[x = {-$b + \sqrt{$b^2 - 4$a$c} \over 2$a} = $x1\]
or
\[x = {-$b - \sqrt{$b^2 - 4$a$c} \over 2$a} = $x2.\]

END_SOLUTION

Context()->normalStrings;

#########################################################################################

PROCESS_SCAFFOLD();

ENDDOCUMENT();
```

Here is one using PGML:

```
DOCUMENT();

loadMacros(
"PGstandard.pl",
"PGML.pl",
"MathObjects.pl",
"parserMultiAnswer.pl",
"compoundProblem5.pl",
"PGcourse.pl",
);

TEXT(beginproblem());

$showPartialCorrectAnswers = 1;

###########################################################################################
# Initialize sections
###########################################################################################

$scaffold = Scaffold();

##############################################################
#
# Setup
#

Context("Numeric");
Context()->variables->are(x => 'Real');

$a = Compute(random(2,9,1));
$c = Compute(random(1,9,1));
$b = Compute(random(2,6,1));
if ($a*$c > 0) {$b += floor(sqrt(4*$a*$c))}

$quadratic = Formula("$a x^2 + $b x + $c");
$x1 = (-$b + sqrt($b**2-4*$a*$c))/(2*$a);
$x2 = (-$b - sqrt($b**2-4*$a*$c))/(2*$a);

###########################################################################################
# Section 1: Identify coefficients
###########################################################################################

DISPLAY_PGML_SECTION("1: Identify the coefficients", <<'END_SECTION');

Consider the quadratic equation given by [`[$quadratic] = 0`].

In this exercise, we will consider three different ways to solve this expression.

First, identify the coefficients for the quadratic using the standard form
[`ax^2 + bx + c = 0`]:

[`a`] = [____]{$a}, [`b`] = [____]{$b}, [`c`] = [____]{$c}

END_SECTION

###############################################

SECTION_PGML_SOLUTION(<<'END_SOLUTION');

Take the coefficient of [`x^2`] for the value of [`a`], the coefficient
of [`x`] for [`b`], and the constant for [`c`]. In this case, they
are [`a = [$a]`], [`b = [$b]`], and [`c = [$c]`].

END_SOLUTION

#########################################################################################
# Section 2 -- Solve by plugging into the Quadratic formula, no simplify
#########################################################################################

$multians1 = MultiAnswer($x1,$x2)->with(
singleResult => 0,
allowBlankAnswers => 1,
checker => sub {
my ($correct,$student,$self) = @_;
my ($s1, $s2) = @{$student};
my ($c1, $c2) = @{$correct};

return (1,1) if ($c1 == $s1 and $c2 == $s2) or
($c1 == $s2 and $c2 == $s1);
return (1,0) if $c1 == $s1 or $c2 == $s1;
return (0,1) if $c1 == $s2 or $c2 == $s2;
return (0,0);
}
);

###############################################

DISPLAY_PGML_SECTION("2: Solve using the quadratic formula", <<'END_SECTION');

Using the quadratic formula, solve [`[$quadratic] = 0`]

>> [`x`] = [______]{$multians1} or [`x`] = [______]{$multians1} <<

END_SECTION

SECTION_PGML_SOLUTION(<<'END_SOLUTION');

Recall that the quadratic equation is

[``x = {-b \pm \sqrt{b^2 - 4ac} \over 2a}``].

You already identified [`a = [$a]`], [`b = [$b]`], and [`c = [$c]`],
so the results are:

[``x = {-[$b] + \sqrt{[$b]^2 - 4[$a][$c]} \over 2[$a]} = [$x1]``]

or

[``x = {-[$b] - \sqrt{[$b]^2 - 4[$a][$c]} \over 2[$a]} = [$x2]``].

END_SOLUTION

#########################################################################################

PROCESS_SCAFFOLD();

ENDDOCUMENT();
```