WeBWorK Problems

Combining two or more problems into one

Combining two or more problems into one

by Alina Duca -
Number of replies: 5
Hi everyone,

I was wandering if anyone can advise on how could I combine two or more problems into a single problem that asks the student to choose the part he/she  wants to solve. For correct answer on any of the parts the student should get 100% even if the other answers are left blank or incorrect. Thanks.

Alina 
In reply to Alina Duca

Re: Combining two or more problems into one

by Paul Pearson -
Hi Alina,

You will probably want to use parserMultiAnswer.pl. A minimal working example is given below. Note that the answers are of two different types (one really should be a MathObject Real and the other should be a MathObject Formula), but we have declared that both of them are of MathObject Formula type in order to eliminate confusing type-checking errors from being reported to students. Also, notice that we used

allowBlankAnswers => 1,
checkTypes => 0,

so that blank answers don't cause problems, and so that we will have to do our own type checking later on in the answer evaluator, which is done using typeMatch. Also, we manually generate messages to tell students which of their entered answers are correct using setMessage, and turn off the automatic feedback on which answers are correct by setting $showPartialCorrectAnswers = 0;. If you have, say, 4 parts to your problem instead of just 2, you can increase the allowed values for $j by setting

foreach my $j (0..3) { .... }

I don't currently know how to change the message in the green bar that says "All of the answers above are correct." which isn't always consistent with the feedback the answer checker we wrote gives.

Notice that we used $multians->ans_rule(20) for each of the answer boxes.

Finally, we include a comment for instructors: "The student will receive full credit if any one of the answers is correct."

Good luck!

Paul Pearson

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

DOCUMENT();

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

TEXT(beginproblem());


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

Context("Numeric");

$a = Formula("4");
$b = Formula("x");

$multians = MultiAnswer($a, $b)->with(

singleResult => 0,
allowBlankAnswers => 1,
checkTypes => 0,

checker => sub {
my ( $correct, $student, $answerHash ) = @_;
my @c = @{$correct};
my @s = @{$student};
my @score = ();
my $totalscore = 0;
foreach my $j (0..1) {
my $j1 = $j + 1;
if ($c[$j]->typeMatch($s[$j]) && $c[$j] == $s[$j]) {
$score[$j] = 1;
$totalscore = $totalscore + 1;
}
if ($score[$j]==1) {
$answerHash->setMessage($j1,"This answer is correct");
} else {
$answerHash->setMessage($j1,"This answer is not correct");
}
}
return ($totalscore > 0);
}

);


######################
# Main text

Context()->texStrings;
BEGIN_TEXT
(a) Enter \( 4 \): \{ $multians->ans_rule(20) \}
$BR
$BR
(b) Or, enter \( x \): \{ $multians->ans_rule(20) \}
END_TEXT
Context()->normalStrings;


######################
# Answer evaluation

$showPartialCorrectAnswers = 0;

ANS( $multians->cmp() );

COMMENT("MathObject version. The student will receive full credit if any one of the answers is correct.");

ENDDOCUMENT();
In reply to Paul Pearson

Re: Combining two or more problems into one

by Alina Duca -
That's it! Thank you so much Paul. I want two combine different types of applications of DiffEq, so students from different majors can choose to solve the part that is closer to their area (mechanics, electrical engineering, physics ..) . 

Cheers,
Alina

PS: This example should probably be in the wiki.
In reply to Alina Duca

Re: Combining two or more problems into one

by Gavin LaRose -
Hi Alina,

For what it's worth, there is a page on parserMultiAnswer in the problem techniques section of the wiki (as are pages about many other things). See http://webwork.maa.org/wiki/Category:Problem_Techniques. It doesn't include Paul's nice example here, but does show how to use the code.

Gavin
In reply to Gavin LaRose

Re: Combining two or more problems into one

by Paul Pearson -
Hi Alina,

I realized that it's possible to do this with only one answer blank and avoiding parserMultiAnswer.pl altogether. The basic idea is to use a custom answer checker that will accept one of two correct answers (PG source code is given below -- look for the cmp(checker...) bit of code). For more background on custom answer checkers, see:

http://webwork.maa.org/wiki/CustomAnswerCheckers

Best Regards,

Paul


DOCUMENT();

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

TEXT(beginproblem());


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

Context("Numeric");

$a = Formula("4");
$b = Formula("x");

######################
# Main text

Context()->texStrings;
BEGIN_TEXT
Enter \( 4 \) or \( x \) \{ ans_rule(20) \}
END_TEXT
Context()->normalStrings;


######################
# Answer evaluation

$showPartialCorrectAnswers = 0;

ANS( $a->cmp(checker=>sub {
my ( $correct, $student, $answerHash ) = @_;
return (($a == $student) || ($b == $student));
}) );

COMMENT("MathObject version");

ENDDOCUMENT();
In reply to Paul Pearson

Re: Combining two or more problems into one

by Alina Duca -
Paul and Gavin,

Thanks for your suggestions. I should tell you that I have almost zero experience in authoring WW problems... so here is what I could do by following your suggestions. I used the first template that Paul sent me (with parserMultiAnswer - thanks Gavin for the link ), stole some problems from the library, then I combined them into a a problem that asks the student to solve only ONE of the three parts. The only thing that doesn't come out right is the "results" column in the table after the answers are entered. If I enter a correct answer for one of the parts, it marks them all "correct" highlighted in green. However, under messages I do get the correct feedback. Any idea how I could fix that? 

Thanks again. 
Alina


DOCUMENT(); 

loadMacros(
"PGstandard.pl",
"MathObjects.pl",
"parserMultiAnswer.pl","parserAssignment.pl", "AnswerFormatHelp.pl",
"parserNumberWithUnits.pl",
);

TEXT(beginproblem());

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

Context("Numeric")->variables->add(
y=>"Real", k=>"Real"
);
parser::Assignment->Allow;

$a = random(2,9,1);
do { $b = random(2,5,1); } until ($b != $a);

$ab = $a * $b;

$ansa = Compute("y = k * e^(x^2/2 + $b x) - $a"); 

$ab=random(48,240,16);
$bb=$a/16;

$ansb= "-16*($bb/2)**2+$ab*($bb/2)"; 

Context("Numeric")->variables->add(y=>"Real");
parser::Assignment->Allow;

$ac = random(2,5,1);
do { $n = random(2,8,1); } until ($n != $ac);
$np1 = $n + 1;

$ansc = Compute("y = $ac e^((x^$np1 - 1)/ $np1 ) ");

$multians = MultiAnswer($ansa, $ansb, $ansc)->with(
singleResult => 0,
allowBlankAnswers => 1,
checkTypes => 0,

checker => sub {
my ( $correct, $student, $answerHash ) = @_;
my @c = @{$correct};
my @s = @{$student};
my @score = ();
my $totalscore = 0;
foreach my $j (0..2) {
my $j1 = $j + 1;
if ($c[$j]->typeMatch($s[$j]) && $c[$j] == $s[$j]) { 
$score[$j] = 1;
$totalscore = $totalscore + 1;
}
if ($score[$j]==1) {
$answerHash->setMessage($j1,"This answer is correct");
} else {
$answerHash->setMessage($j1,"This answer is not correct");
}
}
return ($totalscore > 0);
}

);


######################
# Main text

Context()->texStrings;

BEGIN_TEXT

Do ONLY ONE of the following problems, (a), (b), or (c).
$BR
$BR
$BR

(a) Find a solution to 
\( \displaystyle \frac{dy}{dx} = xy + $a x + $b y + $ab \).
$BR
$BR
\{ $multians->ans_rule(20) \}
$BR
$BR
$BR

(b) A pomegranate is thrown from ground level straight up into the air at
time \(t=0\) with velocity $ab feet per second. Its height in feet at \(t\)
seconds is \(f(t)=-16 t^2+$ab t\). Find the time it reaches its highest point 
$BR
$BR
\(t=\) \{ $multians->ans_rule(20)\}
$BR
$BR
$BR

(c) Find the equation of the solution to 
\( \displaystyle \frac{dy}{dx} = x^{$n} y \)
through the point \( (x,y) = (1,$ac) \).
$BR
$BR
\{ $multians->ans_rule(30) \}

END_TEXT

Context()->normalStrings;

######################
# Answer evaluation

$showPartialCorrectAnswers = 0;

ANS( $multians->cmp() );

COMMENT("MathObject version. The student will receive full credit if any one of the answers is correct.");

ENDDOCUMENT();