WeBWorK Problems

bizarro math for sine or cosine?

bizarro math for sine or cosine?

by Paul Seeburger -
Number of replies: 5
I am trying to require students to enter a spring problem function involving sine and cosine terms as a single sine function or a single cosine function.

But the question is currently allowing the students to just enter the function as it was and giving them credit for it.

Is there a way to use bizarro math to require only a single sine function?

Or maybe just a way to check that the function includes a "sin" but not a "cos"? Maybe with a custom grader?

Can I check the string of their answer contains "sin" and not "cos" this way and still check the functional answer using a MathObject Function? If so, this may be the easiest way to make this problem behave as it should without making it require a number of answer blanks.

Thanks!

Paul
In reply to Paul Seeburger

Re: bizarro math for sine or cosine?

by Alex Jordan -
Hi Paul,

Can you give the specifics of what the question might ask or expect as an answer? And maybe one example of what you would like to count as incorrect? With a little more understanding, I may be able to advise if bizarro can help.

Alex
In reply to Paul Seeburger

Re: bizarro math for sine or cosine?

by Danny Glin -
One simple thing you can do to force them to write their answer in terms of "sin" is to disable "cos" in the context (see http://webwork.maa.org/wiki/Introduction_to_Contexts#Functions) using

Context()->functions->disable("cos");

This doesn't prevent them from entering responses other than what you had in mind, but it at least prevents them from just retyping the function.
In reply to Danny Glin

Re: bizarro math for sine or cosine?

by Paul Seeburger -
That helps, Danny!

Alex, I am trying to have students enter the single sine version of something like, x(t) = 3 sin 4t - 4 cos 4t.

And then also to enter the single cosine version in another answer blank. Here the single cosine form would be: x(t) = 5cos (4t - 2.21430).

Currently I see that entering either version or the original version is counted correct in both answer blanks, although most students don't realize this since it is not obvious that they should try it, some have gotten credit this way.

Thanks!

Paul
In reply to Paul Seeburger

Re: bizarro math for sine or cosine?

by Davide Cervone -
You can use a custom checker to do this kind of ad hoc testing, even when there is no specific context that handles the answer form directly.

Here is an example:

ANS($f->cmp(checker=>sub {
  my ($c,$s,$ans) = @_;
  return 0 unless $c == $s;
  return 1 if $s->{tree}->class eq 'Function' && $s->{tree}{name} eq 'sin';
  Value->Error('Your answer should be the sine of something');
  return 0;
}));
This one checks that the answer is correct, and is sin(...). If you need to check for a constant times the sine of something, then you need to walk the tree a little further (check that the top node is of class BOP with its bop equal to *, and the its lop or rop is the sine function, and the other is of class Number.

As I said, it takes a bit more work.

In reply to Paul Seeburger

Re: bizarro math for sine or cosine?

by Andrew Parker -
It might be possible to overwrite the functions for sine and cosine as Davide did for handling square root simplifications (just do this for sine and cosine instead of sqrt):

# code essentially from Davide Cervone 4/25/10
###########################
#
# Subclass the numeric functions
#
package my::Function::numeric;
our @ISA = ('Parser::Function::numeric');

#
# Override sqrt() to return a special value (usually 1) when evaluated
# effectively eliminating it from the product.
#
sub sqrt {
my $self = shift;
my $value = $self->context->flag("setSqrt");
return $value+2 if $value && $_[0] == 1; # force sqrt(1) to be incorrect
return $value if $value;
return $self->SUPER::sqrt(@_);
}

#
# end of subclass
#
package main;

Context("Numeric")->variables->are(
x => ["Real", limits => [0,2]], # only needed if x is used in the square roots
);
#
# make sqrt() use our subclass
#
Context()->functions->set(sqrt=>{class=>'my::Function::numeric'});
Context()->flags->set(reduceConstantFunctions=>0);
#
#
# Don't allow fractional powers (avoids 1/2 power)
# [Could subclass exponentiation to handle that as well]
#
LimitedPowers::OnlyPositiveIntegers();

$reducedSqrt = sub {
my ($correct,$student,$ans) = @_;
return 0 if $ans->{isPreview} || $correct != $student;
#
# Get parsed formula for student and correct answers
#
$student = $ans->{student_formula};
$correct = $correct->{original_formula} if defined $correct->{original_formula};
#
# check if equal when sqrt's are replaced by 1
#
Context()->flags->set(setSqrt => 1);
delete $correct->{test_values}, $student->{test_values};
my $OK = ($correct == $student);
Context()->flags->set(setSqrt => 0);
#
Value::Error("Check to see if your answer is simplified.") unless $OK;
return $OK;
};

ANS($ans1->cmp(checker => $reducedSqrt,formatStudentAnswer=>"reduced"));