--- loncom/homework/functionplotresponse.pm 2010/11/06 16:12:39 1.24 +++ loncom/homework/functionplotresponse.pm 2010/11/07 01:57:50 1.25 @@ -1,7 +1,7 @@ # LearningOnline Network with CAPA # option list style responses # -# $Id: functionplotresponse.pm,v 1.24 2010/11/06 16:12:39 www Exp $ +# $Id: functionplotresponse.pm,v 1.25 2010/11/07 01:57:50 www Exp $ # # Copyright Michigan State University Board of Trustees # @@ -33,7 +33,7 @@ use Apache::lonlocal; use Apache::lonnet; BEGIN { - &Apache::lonxml::register('Apache::functionplotresponse',('functionplotresponse','backgroundplot','spline','splinerule')); + &Apache::lonxml::register('Apache::functionplotresponse',('functionplotresponse','backgroundplot','spline','functionplotrule')); } # @@ -339,15 +339,15 @@ sub end_backgroundplot { } # -# +# # -sub start_splinerule { +sub start_functionplotrule { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result=''; my $label=&Apache::lonxml::get_param('index',$parstack,$safeeval); $Apache::functionplotresponse::counter++; if ($label=~/\W/) { - &Apache::lonxml::warning(&mt('Spline Rule indices should only contain alphanumeric characters.')); + &Apache::lonxml::warning(&mt('Rule indices should only contain alphanumeric characters.')); } $label=~s/\W//gs; unless ($label) { @@ -356,16 +356,16 @@ sub start_splinerule { $label='R'.$label; } if ($Apache::functionplotresponse::splineorder{$label}) { - &Apache::lonxml::error(&mt('Spline Rule indices must be unique.')); + &Apache::lonxml::error(&mt('Rule indices must be unique.')); } if ($target eq 'grade') { # Simply remember - in order - for later - my $beginninglabel=&Apache::lonxml::get_param('beginninglabel',$parstack,$safeeval); - my $endinglabel=&Apache::lonxml::get_param('endinglabel',$parstack,$safeeval); + my $beginninglabel=&Apache::lonxml::get_param('xinitiallabel',$parstack,$safeeval); + my $endinglabel=&Apache::lonxml::get_param('xfinallabel',$parstack,$safeeval); if (($beginninglabel=~/\W/) || ($endinglabel=~/W/)) { - &Apache::lonxml::warning(&mt('Spline Rule labels must be alphanumeric.')); + &Apache::lonxml::warning(&mt('Rule labels must be alphanumeric.')); } $beginninglabel=~s/\W//gs; $endinglabel=~s/\W//gs; @@ -373,32 +373,32 @@ sub start_splinerule { $relationship=~s/\W//gs; $relationship=lc($relationship); unless ($relationship=~/^(eq|ge|gt|le|lt|ne)$/) { - &Apache::lonxml::warning(&mt('Spline Rule relationship not defined.')); + &Apache::lonxml::warning(&mt('Rule relationship not defined.')); $relationship='eq'; } my $derivative=&Apache::lonxml::get_param('derivative',$parstack,$safeeval); unless (($derivative==0) || ($derivative==1) || ($derivative==2)) { - &Apache::lonxml::warning(&mt('Spline Rule derivative not defined.')); + &Apache::lonxml::warning(&mt('Rule derivative not defined.')); $derivative=0; } - push(@Apache::functionplotresponse::splinerules,join(':',( + push(@Apache::functionplotresponse::functionplotrules,join(':',( $label, $derivative, - &Apache::lonxml::get_param('beginningvalue',$parstack,$safeeval), + &Apache::lonxml::get_param('xinitial',$parstack,$safeeval), $beginninglabel, - &Apache::lonxml::get_param('endingvalue',$parstack,$safeeval), + &Apache::lonxml::get_param('xfinal',$parstack,$safeeval), $endinglabel, $relationship, &Apache::lonxml::get_param('value',$parstack,$safeeval) ))); } elsif ($target eq 'edit') { - $result=&Apache::edit::tag_start($target,$token,'Spline Evaluation Rule'). + $result=&Apache::edit::tag_start($target,$token,'Function Plot Evaluation Rule'). &Apache::edit::end_row(); } return $result; } -sub end_splinerule { +sub end_functionplotrule { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result=''; if ($target eq 'edit') { @@ -704,7 +704,7 @@ sub start_functionplotresponse { $Apache::functionplotresponse::inputfields=''; $Apache::functionplotresponse::counter=0; # Remember rules - undef @Apache::functionplotresponse::splinerules; + undef @Apache::functionplotresponse::functionplotrules; # Part and ID my $partid=$Apache::inputtags::part; my $id=&Apache::response::start_response($parstack,$safeeval); @@ -722,6 +722,14 @@ sub start_functionplotresponse { $ymin=(defined($ymin)?$ymin:-10); my $ymax=&Apache::lonxml::get_param('ymax',$parstack,$safeeval); $ymax=(defined($ymax)?$ymax:10); + if ($xmax<=$xmin) { + &Apache::lonxml::warning('Maximum x-value needs to be larger than minimum value.'); + $xmax=$xmin+20; + } + if ($ymax<=$ymin) { + &Apache::lonxml::warning('Maximum y-value needs to be larger than minimum value.'); + $ymax=$ymin+20; + } my $xaxisvisible=(&Apache::lonxml::get_param('xaxisvisible',$parstack,$safeeval)=~/on|true|yes|1/i?'true':'false'); my $yaxisvisible=(&Apache::lonxml::get_param('yaxisvisible',$parstack,$safeeval)=~/on|true|yes|1/i?'true':'false'); my $gridvisible=(&Apache::lonxml::get_param('gridvisible',$parstack,$safeeval)=~/on|true|yes|1/i?'true':'false'); @@ -777,8 +785,60 @@ sub start_functionplotresponse { return $result; } -sub splinerulecheck { - my ($rule)=@_; +sub compare_rel { + my ($relationship,$value,$val,$tol)=@_; + if (abs($value-$val)<$tol) { return 1; } + return 0; +} + +sub functionplotrulecheck { + my ($rule,$xmin,$xmax,$tolfunc,$toldfdx,$told2fdx2)=@_; + &Apache::lonnet::logthis("Rule $rule TolFunc $tolfunc TolDfDx $toldfdx TolD2fDx2 $told2fdx2"); + my ($label,$derivative,$xinitial,$xinitiallabel,$xfinal,$xfinallabel,$relationship,$value) + =split(/\:/,$rule); +# if a hard value is set for the boundaries, it overrides the label + if (($xinitial ne '') && ($xinitiallabel ne '')) { + $Apache::functionplotresponse::functionplotrulelabels{$xinitiallabel}=$xinitial; + } + if (($xfinal ne '') && ($xfinallabel ne '')) { + $Apache::functionplotresponse::functionplotrulelabels{$xfinallabel}=$xfinal; + } + if (defined($Apache::functionplotresponse::functionplotrulelabels{$xinitiallabel})) { + $xinitial=$Apache::functionplotresponse::functionplotrulelabels{$xinitiallabel}; + } + if (defined($Apache::functionplotresponse::functionplotrulelabels{$xfinallabel})) { + $xfinal=$Apache::functionplotresponse::functionplotrulelabels{$xfinallabel}; + } +# Basic sanity checks + if ($xinitial eq '') { + $xinitial=0; + } + if ($xfinal ne '') { + if ($xinitial>$xfinal) { + $xfinal=$xinitial; + } + } + &Apache::lonnet::logthis("Init $xinitial Final $xfinal"); + if (($xfinal eq '') || ($xinitial==$xfinal)) { +# This is only one point + &Apache::lonnet::logthis("One point $xinitial"); + my $tol; + my $val; + if ($derivative==2) { + $val=&d2funcdx2_val($xmin,$xmax,$xinitial); + $tol=$told2fdx2; + } elsif ($derivative==1) { + $val=&dfuncdx_val($xmin,$xmax,$xinitial); + $tol=$toldfdx; + } else { + $val=&func_val($xmin,$xmax,$xinitial); + $tol=$tolfunc; + } + &Apache::lonnet::logthis("Value $value ActVal $val Tol $tol"); + return &compare_rel($relationship,$value,$val,$tol); + } else { +# This is a range + } return 0; } @@ -812,14 +872,26 @@ sub end_functionplotresponse { $xmin=(defined($xmin)?$xmin:-10); my $xmax=&Apache::lonxml::get_param('xmax',$parstack,$safeeval); $xmax=(defined($xmax)?$xmax:10); + my $ymin=&Apache::lonxml::get_param('ymin',$parstack,$safeeval); + $ymin=(defined($ymin)?$ymin:-10); + my $ymax=&Apache::lonxml::get_param('ymax',$parstack,$safeeval); + $ymax=(defined($ymax)?$ymax:10); + my $tolfunc=($ymax-$ymin)/100.; + my $toldfdx=1; + my $told2fdx2=1; + if ($xmax>$xmin) { + $toldfdx=$tolfunc/($xmax-$xmin); + $told2fdx2=$toldfdx/($xmax-$xmin); + } + my $ad=''; if (&populate_arrays($internalid,$xmin,$xmax) eq 'no_func') { $ad='NOT_FUNCTION'; } else { # We have a function that we can actually grade, go through the spline rules. - undef %Apache::functionplotresponse::splinerulelabels; - foreach my $rule (@Apache::functionplotresponse::splinerules) { - unless (&splinerulecheck($rule)) { + undef %Apache::functionplotresponse::functionplotrulelabels; + foreach my $rule (@Apache::functionplotresponse::functionplotrules) { + unless (&functionplotrulecheck($rule,$xmin,$xmax,$tolfunc,$toldfdx,$told2fdx2)) { $ad='INCORRECT'; last; }