## PREP 2014 Question Authoring - Archived

### diffeq/FormulaUpToConstants problem ### diffeq/FormulaUpToConstants problem

by Chrissy Safranski -
Number of replies: 3
I was writing an introductory separable differential equation problem, and I ran into a dilemma:  If I use FormulaUpToConstant then the students can use any constant, K, or even y, and I want them to use C and get reasonable error messages when they use other letters.  But, I don't want to use the older style checker, because I want to use MathObjects to use answerHint and customize error messages.

My first attempt just made it a Formula of t and C, and that worked fine, and I was happy with the error messages and hints I had customized, and I thought I was done with the problem.  But it nagged at me that how I had written it wasn't fully correct, since, for example, a student really should be able to replace the constant 3C by C if they desire, but those would be different as Formulas.  Then I remembered Paul's problem from Workshop 4 AM with a custom answer checker where you check that the student's answer satisfies the given differential equation, and that seems like a perfect solution.

So I attempted to use that, but I can't get it to accept the correct answer as correct.  I also don't know if I need all those things that he had in his problem.  My guess was maybe there's a domain problem since one side has ln and one side doesn't but I'm stuck for how to fix it.  Sorry for all the commented out stuff - I can streamline this if I need to, but I didn't know if something I thought was unrelated could be affecting it.

------------------------------------------------
"PGstandard.pl",
"MathObjects.pl",
#"parserFormulaUpToConstant.pl",
# "contextFraction.pl",
"parserAssignment.pl",
);

# sub context::Fraction::Real::cmp_defaults
# {Value::Real::cmp_defaults(@_)};

# Print problem number and point value (weight) for the problem
TEXT(beginproblem());

# Show which answers are correct and which ones are incorrect
$showPartialCorrectAnswers = 1; ############################################################## # # Setup # # Context("Numeric"); Context()->variables->are(t =>'Real', C=>'Real'); Context()->variables->set('C'=>{limits=>[100,102]}); Context()->variables->set('t'=>{limits=>[10,20]}); Context()->flags->set( formatStudentAnswer=>'parsed', reduceConstants=>0, reduceConstantFunctions=>0, ); parser::Assignment->Allow; Context()->{error}{msg}{"Variable 'y' is not defined in this context"} = "Your answer should not have 'y' on the right-hand-side.";$aa = random(2,8,1);
$c=random(-5,-2,1);$posc = $c*(-1); if ($aa==$c){$aa++;}

$answer = Compute("ln($posc*(t**2/2-$aa t +C))/$posc");

Context()->texStrings;
BEGIN_TEXT
Find the general solution of the differential equation below.  Use 'C' as your constant.
$\frac{dy}{dt} = (t-aa)e^{c y}$
$PAR Another hint will appear after 2 attempts, and another one after 4 attempts.$BR
$BR $$y =$$ \{ ans_rule(20) \} \{ AnswerFormatHelp("formulas") \} END_TEXT Context()->normalStrings; ############################################################## # # Answers # #$showPartialCorrectAnswers = 1;
# ANS( $answer->cmp()->withPostFilter(AnswerHints( # sub { # my ($correct,$student,$ans) = @_;
#                        return $student->D('C') == Formula(0); # } => ["Don't forget +C at the step when you integrate!"] # ))); ANS($answer->cmp(checker => sub {

my ( $correct,$student, $answerHash ) = @_; my$stu   = Formula($student->{tree}{rop}); ################################# # Check for arbitrary constants # Value->Error("Don't forget +C at the step when you integrate!") if ( Formula($student->D('C'))==Formula(0) );

#################################
#  Check that the student answer is a solution to the DE
#
my $stu1 = Formula($stu->D('t'));
# return ($stu1 == Formula("(t-$aa)*e**($c*$stu)"));

my $stuDE = Formula("$stu1-(t-$aa)*e**($c*$stu)")->with(test_points=>[[20,1],[25,2],[50,-1],[100,-2]]); return ($stuDE==Formula(0));

})); ### Re: diffeq/FormulaUpToConstants problem

by Chrissy Safranski -
I got it!  It was the "my $stu = Formula($student->{tree}{rop}" line.  I realized that both of the problems I was looking at by Paul wanted the answer to be "y=...." or "r=..." and I just wanted the formula.  I didn't know what that line did anyway, but I guess it was related to that, because I commented that line out and used the other version of the return value, and it worked!  My final answer checker is this:

ANS( $answer->cmp(checker => sub { my ($correct, $student,$answerHash ) = @_;
# my $stu = Formula($student->{tree}{rop});

#################################
#  Check for arbitrary constants
#
Value->Error("Don't forget +C at the step when you integrate!")
if ( Formula($student->D('C'))==Formula(0) ); ################################# # Check that the student answer is a solution to the DE # my$stu1 = $student->D('t'); my$t = Formula(t); # we can't just use 't' below, we need '$t' return ($stu1)  == (($t-$aa) * e**($c*$student));

# my $stuDE = Formula("$stu1-($t-$aa)*e**($c*$stu)")->with(test_points=>[[20,1],[25,2],[50,-1], [100,-2]]);
# return ($stuDE==Formula(0)); })); In reply to Chrissy Safranski ### Re: diffeq/FormulaUpToConstants problem by Gavin LaRose - Hi Chrissy, The my$stu = Formula(\$student->{tree}{rop}) line looks as if it is left over from Paul's equation checker example, in which the student is entering something like y = f(x). In that case, we're reading the tree showing the different pieces of the student's answer, and returning the branch on the right-hand side of the operator.

Gavin 