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.  

------------------------------------------------
loadMacros(
"PGstandard.pl",
"MathObjects.pl",
"AnswerFormatHelp.pl",
#"parserFormulaUpToConstant.pl",
"answerHints.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));


}));


In reply to Chrissy Safranski

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

In reply to Gavin LaRose

Re: diffeq/FormulaUpToConstants problem

by Chrissy Safranski -
Thank you!  Now that I understand what that does, I went back and rewrote my problem to ask for y=... since that's how I'll expect them to answer it on a test.