WeBWorK Main Forum

Question about debubbing/improving a custom grader that gives partial credit for wrong units.

by Christian Seberino -
Number of replies: 2

1. It gives 75% partial credit when I enter the wrong units...e.g. try entering "2 m".
However, if I add this question to an EXAM then it doesn't work.  What
is different about exam mode that makes it not give partial credit for
wrong units anymore?

2. How make it give 75% partial credit
if units are *missing*?  Right now it gives no credit in that case.

DOCUMENT();
"MathObjects.pl",
"PGstandard.pl",
"PGML.pl",
"PGcourse.pl",
"parserNumberWithUnits.pl",
"contextArbitraryString.pl",
"parserPopUp.pl",
);
TEXT(beginproblem());
$showPartialCorrectAnswers = 1; ###################################################################### Context("Numeric") ; Context()->flags->set(tolerance => 0.01);$A = NumberWithUnits("2 ft"); $A->{value} =$A->value;

$cmp =$A->cmp->withPostFilter(sub {
my $ans = shift; return$ans if $ans->{ans_message}; my$correct = $ans->{correct_value}; my$student = $ans->{student_value}; return$ans unless defined($correct) && defined($student);
if ($student->{units} ne$correct->{units}) {
if ($correct->{value} ==$student->value) {
$ans->{score} = .75;$ans->{ans_message} = "Has the correct number but incorrect units.";
} else {
$ans->{score} = 0; } } return$ans;
});

BEGIN_PGML
How many feet are equal to 24 inches?

[___________]{$cmp} END_PGML ###################################################################### ENDDOCUMENT(); In reply to Christian Seberino Re: Question about debubbing/improving a custom grader that gives partial credit for wrong units. by Davide Cervone - The problem here is that when the student doesn't enter units, the NumberWithUnits answer checker already creates the message "Your answer doesn't look like number with units", and so the line  return$ans if $ans->{ans_message};  causes the rest of the post-filter to be skipped. So you never do the check for partial credit. The first step is to change that line to  return$ans if $ans->{ans_message} &&$ans->{ans_message} ne

so that you will continue in the case where the student entered only a number (and lots of other cases as well, but we'll deal with that later).

Unfortunately, when this error occurs, the $ans->{student_value} will be undefined, since no MathObject gets created when the answer isn't of the correct form. So you will have to create it yourself. Here is on way: $cmp = $A->cmp->withPostFilter(sub { my$ans = shift;
return $ans if$ans->{ans_message} && $ans->{ans_message} ne "Your answer doesn't look like a number with units"; my$correct = $ans->{correct_value}; my$student = $ans->{student_value}; if (!defined($student)) {
my $num = "^ *".Context()->{pattern}{signedNumber}." *~~$";
$student = Compute($ans->{student_ans}) if $ans->{student_ans} =~ m/$num/;
}
return $ans unless defined($correct) && defined($student); if ($student->{units} ne $correct->{units}) { if ($correct->{value} == $student->value) {$ans->{score} = .75;
$ans->{ans_message} = "Has the correct number but incorrect units."; } else {$ans->{score} = 0;
}
}
return $ans; });  Here, we check for whether the student value isn't defined, and if not, check if it looks like a signed number (the $num variable is set to a pattern that checks for a number, and then if the student answer matches that pattern, we parse it into a MathObject using Compute().

The rest of the filter is the same, and will handle the case of a student answer with no units.

Re: Question about debubbing/improving a custom grader that gives partial credit for wrong units.

by Christian Seberino -
Below is a version given to me by Davide offline with some minor
changes by me that works and avoids some other problems.

Enjoy...

DOCUMENT();
"MathObjects.pl",
"PGstandard.pl",
"PGML.pl",
"PGcourse.pl",
"parserNumberWithUnits.pl",
"contextArbitraryString.pl",
"parserPopUp.pl",
);
TEXT(beginproblem());
$showPartialCorrectAnswers = 1; ###################################################################### Context("Numeric") ; Context()->flags->set(tolerance => 0.01);$A = NumberWithUnits("2 ft"); $A->{value} =$A->value;

$cmp =$A->cmp->withPostFilter(sub {
my $ans = shift; return$ans if $ans->{ans_message} && ($ans->{ans_message} ne
($ans->{ans_message} ne "The units for your answer are not correct"); my$correct = $ans->{correct_value}; my$student = $ans->{student_value}; if (!defined($student)) {
my $num = "^ *".Context()->{pattern}{signedNumber}." *~~$";
$student = Compute($ans->{student_ans}) if $ans->{student_ans} =~ m/$num/;
}
return $ans unless defined($correct) && defined($student); if ($student->{units} ne $correct->{units}) { if ($correct->{value} == $student->value) {$ans->{score} = .75;
} else {
$ans->{score} = 0; } } return$ans;
});

BEGIN_PGML
How many feet are equal to 24 inches?

[___________]{\$cmp}
END_PGML

######################################################################
ENDDOCUMENT();