Forum archive 2000-2006

Michal Charemza - Check formula up to multiple to 2pi

Michal Charemza - Check formula up to multiple to 2pi

by Arnold Pizer -
Number of replies: 0
inactiveTopicCheck formula up to multiple to 2pi topic started 9/3/2006; 4:27:24 PM
last post 9/4/2006; 10:48:52 AM
userMichal Charemza - Check formula up to multiple to 2pi  blueArrow
9/3/2006; 4:27:24 PM (reads: 286, responses: 1)
(Sorry that I seem to be taking over the message board)

Is there a (simple?) way of testing if a students formula is the same as the answer up to a multiple of 2 pi?

For example, if the answer is Formula("2 n pi + pi/2"), I would like to mark correct all answers such as "2 n pi + pi/2 + 2 pi" or "2 n pi + pi/2 + 4 pi" and so on.

Michal.

<| Post or View Comments |>


userDavide P. Cervone - Re: Check formula up to multiple to 2pi  blueArrow
9/4/2006; 10:48:52 AM (reads: 395, responses: 0)
I don't know now simple it is, but there are ways to do it.

One complication that you have is dealing with the "2 n pi" part. My feeling is that this is going to cause more trouble in your problem than it is worth. For example, if you haven't used "n" in the problem, how are you going to tell them to type their answer using an "n"? What if the student entered "2 k pi + pi/2" instead? Would you want that to be marked wrong? How about "pi/2 - 2 n pi"? It seems to me that the number of possible ways to specify this equivalence class is too large to handle effectively with the current tools in WeBWorK. I don't like the idea of asking a student to be precise about his answer, but not be able to be precise about the checking.

My recommendation would be to make the "2 n pi" be assumed, for example by asking something like "the angle is 2 n pi + [_____]" rather than have the students need to enter 2 n pi in their answers.

This checking is easily accomplished:

    BEGIN_TEXT
The angle is \(2 n \pi +\) \{ans_rule(20)\}
END_TEXT
ANS(Real(pi/2)->cmp(checker => sub {
my ($correct,$student) = @_;
return 0 unless $student->class eq 'Real';
my $a = ($correct-$student)/(2*pi)->value;
return abs($a - int($a)) < .00001;
}));
Here, we solve "correct = student + 2 a pi" for "a" and check if it is an integer (or near integer). The "checker" subroutine only runs if all the typechecking has been performed, but things like "infinity" and "none" pass the typechecking for reals (i.e., don't produce error messages about wrong types), so we need to check that the class of the student's answer is really a Real.

It might be easier to use the custom_cmp wrapper that does some extra typechecking like that for you:

    loadMacros("answerCustom.pl");
BEGIN_TEXT
The angle is \(2 n \pi +\) \{ans_rule(20)\}
END_TEXT
ANS(custom_cmp(Real(pi/2),sub {
my ($correct,$student) = @_;
my $a = ($correct-$student)/(2*pi)->value;
return abs($a - int($a)) < .00001;
}));
This only runs the checker if the class of the student answer already equals the class of the correct answer.

If you really must have the "2 n pi" as part of the answer, then you can try the following:

    ANS(custom_cmp($f,sub {
my ($correct,$student) = @_;
my $context = $correct->{context};
$context->variables->add(a => 'Parameter');
$context->flags->set(no_parameters => 0);
$__correct = $correct + "2 a pi"; $__student = $student;
my $equal = PG_restricted_eval('$__correct == $__student');
$context->flags->set(no_parameters => 1);
$context->variables->remove('a');
return 0 unless $equal;
my $d = $__correct->{test_values}[0] - $__student->{test_values}[0];
my $a = $d/(2*pi)->value;
return abs($a - int($a)) < .00001;
}));
This is more complicated. The idea is to use "adapting parameters" to check if the student answer is the correct answer up to a constant, and then check that that constant is 2 a pi for some integer (or near integer) a.

To do this, we temporarily add a parameter 'a' to the context (and enable the use of parameters, which has been turned off so that students can't enter them), and then create a new formula that is the old correct answer plus "2 a pi". (We could have just used "a", but this makes it clearer what you are going to be doing). We make global copies of this new function ($__correct) and the student function ($__student) so that we can do the comparison inside of PG_restricted_eval(), that way, if there are any error messages due to problems with the student answer, they will not appear on screen anywhere (and since PG_restricted_eval() operates in the main:: namespace, not the current one, the formulas can't be local to the checker subroutine).

We perform the check to see if the student's formulas does equal the professor's up to a constant, and then put the Context() back the way it was (we hope), and return incorrect if they were not equal. If they where equal up to a constant, we need to check if the constant is a multiple of 2pi, so we find the difference between two of the test points, and check if we get a (near) interger after dividing by 2pi.

You might want to report a special hint if the student has typed an answer without "2 n pi", since they are not going to think if this themselves. Here is one possible modification to allow that:

   ANS(custom_cmp($f,sub {
my ($correct,$student,$ans) = @_;
Value::Error("Remember that there is always more than one answer")
if $student->class eq 'Real' && !$ans->{isPreview};
return 0 unless $student->class eq 'Formula';
my $context = $correct->{context};
$context->variables->add(a => 'Parameter');
$context->flags->set(no_parameters => 0);
$__correct = $correct + "2 a pi"; $__student = $student;
my $equal = PG_restricted_eval('$__correct == $__student');
$context->flags->set(no_parameters => 1);
$context->variables->remove('a');
return 0 unless $equal;
my $d = $__correct->{test_values}[0] - $__student->{test_values}[0];
my $a = $d/(2*pi)->value;
return abs($a - int($a)) < .00001;
},sameClass => 0));
This is almost the same as the previous one, but this time we specify sameClass=>0 at the bottom so that the checker will run even when the student's and professor's answers are not the same class (in this case, the professor's answer is a Formula while the student's answer is a Real, meaning a constant without reference to "n"). We report an error message in that case suggesting that there is something more the student must think about. We also have to do the typecheck by hand, since custom_cmp() has been told not to, so return incorrect if the student's answer is not a Formula.

These last two solutions suffer from the problem I mentioned at the beginning: they require the student to use "n" as the variable, and they must use "2 n pi" and not "-2 n pi" or some other formula that gets the same set of points but in a different relation to n.

Davide

<| Post or View Comments |>