'.&mt('Function Plot Question').' | '
.''.&mt('Delete?').' '
- .&Apache::edit::deletelist($target,$token)
+ .&Apache::edit::deletelist($target,$token).' '
+ .&Apache::edit::insertlist($target,$token)
.' | '
." "
.&Apache::edit::end_row()
@@ -744,7 +734,7 @@ sub start_functionplotresponse {
&Apache::edit::text_arg('Maximum x-value:','xmax',
$token,'4').' '.
&Apache::edit::select_arg('x-axis visible:','xaxisvisible',
- ['yes','no'],$token).' '.
+ ['yes','no'],$token).' '.
&Apache::edit::text_arg('Label y-axis:','ylabel',
$token,'6').' '.
&Apache::edit::text_arg('Minimum y-value:','ymin',
@@ -752,7 +742,7 @@ sub start_functionplotresponse {
&Apache::edit::text_arg('Maximum y-value:','ymax',
$token,'4').' '.
&Apache::edit::select_arg('y-axis visible:','yaxisvisible',
- ['yes','no'],$token).' '.
+ ['yes','no'],$token).' '.
&Apache::edit::select_arg('Grid visible:','gridvisible',
['yes','no'],$token).
&Apache::edit::end_row().&Apache::edit::start_spanning_row();
@@ -764,62 +754,254 @@ sub start_functionplotresponse {
} elsif ($target eq 'meta') {
$result=&Apache::response::meta_package_write('functionplotresponse');
- } elsif ($target eq 'web') {
-# paste in the update routine to receive stuff back from the applet
- $result.=&update_script($internalid);
-# start the initscript for this applet
- $result.=&start_init_script($internalid);
-# put the axis commands inside
- $result.=&axes_script($internalid,$xmin,$xmax,$ymin,$ymax,$xaxisvisible,$yaxisvisible,$gridvisible);
- $result.=&axes_label($internalid,$xlabel,$ylabel);
-# init script is left open
- }
+ } elsif (($target eq 'answer') &&
+ ($env{'form.answer_output_mode'} ne 'tex') &&
+ ($Apache::lonhomework::viewgrades == 'F')) {
+ my (undef,undef,$udom,$uname)=&Apache::lonnet::whichuser();
+ my $windowopen=&Apache::lonhtmlcommon::javascript_docopen();
+ my $start_page = &Apache::loncommon::start_page('Rules Log', undef,
+ {'only_body' => 1,
+ 'bgcolor' => '#FFFFFF',
+ 'js_ready' => 1,});
+ my $end_page = &Apache::loncommon::end_page({'js_ready' => 1,});
+ $uname =~s/\W//g;
+ $udom =~s/\W//g;
+ my $function_name =
+ join('_','LONCAPA_scriptvars',$uname,$udom,
+ $env{'form.counter'},$Apache::lonxml::curdepth);
+ my $rules_var ="".&mt('Rules Log')." ";
+ &Apache::lonxml::add_script_result($rules_var);
+ }
+
return $result;
}
-sub splinerulecheck {
- my ($rule)=@_;
+sub compare_rel {
+ my ($relationship,$value,$realval,$tol)=@_;
+# is the real value undefined?
+ unless (defined($realval)) {
+# the real value is not defined
+ if ($relationship eq 'eq') {
+ if ($value eq 'undef') {
+ return 1;
+ } else {
+ return 0;
+ }
+ } elsif ($relationship eq 'ne') {
+ if ($value eq 'undef') {
+ return 0;
+ } else {
+ return 1;
+ }
+ } else {
+ return 0;
+ }
+ }
+
+# is the expected value undefined?
+ if ($value eq 'undef') {
+# but by now we know that the real value is defined
+ return 0;
+ }
+
+# both are defined.
+ if ($relationship eq 'gt') {
+ return ($realval>$value);
+ } elsif ($relationship eq 'ge') {
+ return ($realval>$value-$tol);
+ } elsif ($relationship eq 'lt') {
+ return ($realval<$value);
+ } elsif ($relationship eq 'le') {
+ return ($realval<$value+$tol);
+ } elsif ($relationship eq 'ne') {
+ return (abs($value-$realval)>$tol);
+ } else {
+ return (abs($value-$realval)<$tol);
+ }
return 0;
}
+sub addlog {
+ my ($text)=@_;
+ $Apache::functionplotresponse::ruleslog.=$text.' ';
+}
-sub end_functionplotresponse {
- my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
- &Apache::response::end_response;
+sub actualval {
+ my ($i,$xmin,$xmax)=@_;
+ return $xmin+$i/400.*($xmax-$xmin);
+}
+
+sub functionplotrulecheck {
+ my ($rule,$xmin,$xmax,$ymin,$ymax)=@_;
- my $result;
- my $id=$Apache::inputtags::response[-1];
- my $partid=$Apache::inputtags::part;
- my $internalid = $partid.'_'.$id;
+ my ($label,$derivative,$xinitial,$xinitiallabel,$xfinal,$xfinallabel,$minimumlength,$maximumlength,$relationship,$value,$percent)
+ =split(/\:/,$rule);
+ $percent=($percent>0?$percent:5);
+ &addlog("=================");
+ &addlog("Rule $label for ".('function itself','first derivative','second derivative')[$derivative]." $relationship $value");
+ my $li=0;
+ my $lh=400;
+
+# Special case: the upper boundary was not defined
+# and needs to be set to the value where
+# the condition is not true anymore => set flag
+
+ my $findupper=0;
+ if (($xfinal eq '')
+ && (!defined($Apache::functionplotresponse::functionplotrulelabels{$xfinallabel}))
+ && ($xfinallabel)) {
+ $findupper=1;
+ }
- if ($target eq 'edit') { $result=&Apache::edit::end_table(); }
- if ($target eq 'grade'
- && &Apache::response::submitted()
- && $Apache::lonhomework::type eq 'exam') {
+# if a hard value is set for the boundaries, it overrides the label
+ if (($xinitial ne '') && ($xinitiallabel ne '') && ($xinitiallabel ne 'start')) {
+ $li=&array_index($xmin,$xmax,$xinitial);
+ $Apache::functionplotresponse::functionplotrulelabels{$xinitiallabel}=$li;
+ }
+ if (($xfinal ne '') && ($xfinallabel ne '') && ($xfinallabel ne 'end')) {
+ $lh=&array_index($xmin,$xmax,$xfinal);
+ $Apache::functionplotresponse::functionplotrulelabels{$xfinallabel}=$lh;
+ }
+# if the label is defined, use it
+ if (defined($Apache::functionplotresponse::functionplotrulelabels{$xinitiallabel})) {
+ &addlog("Using lower label $xinitiallabel");
+ $li=$Apache::functionplotresponse::functionplotrulelabels{$xinitiallabel};
+ } else {
+ $li=&array_index($xmin,$xmax,$xinitial);
+ }
+ unless ($findupper) {
+ if (defined($Apache::functionplotresponse::functionplotrulelabels{$xfinallabel})) {
+ &addlog("Using upper label $xfinallabel");
+ $lh=$Apache::functionplotresponse::functionplotrulelabels{$xfinallabel}-1;
+ } else {
+ $lh=&array_index($xmin,$xmax,$xfinal);
+ }
+ }
+# Basic sanity checks
+ if ($li<0) { $li=0; }
+ if ($lh>400) { $lh=400; }
+ if ($li>$lh) {
+ $lh=$li;
+ }
- #&Apache::response::scored_response($partid,$id);
+ &addlog("Boundaries: x=".&actualval($li,$xmin,$xmax)." (".$Apache::functionplotresponse::actualxval[$li]."; index $li)) to x=".
+ &actualval($lh,$xmin,$xmax)." (".$Apache::functionplotresponse::actualxval[$lh]."; index $lh))");
+ if ($findupper) {
+ &addlog("Looking for label $xfinallabel");
+ }
+ my $tol=$percent*($ymax-$ymin)/100;
+ if ($xmax>$xmin) {
+ if ($derivative==2) {
+ $tol=4.*$tol/($xmax-$xmin);
+ } elsif ($derivative==1) {
+ $tol=2.*$tol/($xmax-$xmin);
+ }
+ }
+ for (my $i=$li; $i<=$lh; $i++) {
+ my $val;
+ if ($derivative==2) {
+ $val=$Apache::functionplotresponse::d2funcdx2[$i];
+ } elsif ($derivative==1) {
+ $val=$Apache::functionplotresponse::dfuncdx[$i];
+ } else {
+ $val=$Apache::functionplotresponse::func[$i];
+ }
+ unless (&compare_rel($relationship,$value,$val,$tol)) {
+ &addlog("Actual value ".(defined($val)?$val:'undef').", expected $value, tolerance $tol");
+ &addlog("Condition not fulfilled at x=".&actualval($i,$xmin,$xmax)." (".$Apache::functionplotresponse::actualxval[$i]."; index $i)");
+ if (($findupper) && ($i>$li)) {
+# check for minimum and maximum lengths
+ my $length=&actualval($i,$xmin,$xmax)-&actualval($li,$xmin,$xmax);
+ if ($minimumlength) {
+ if ($length<$minimumlength) {
+ &addlog("Rule $label failed, actual length $length, minimum length $minimumlength");
+ return 0;
+ }
+ }
+ if ($maximumlength) {
+ if ($length>$maximumlength) {
+ &addlog("Rule $label failed, actual length $length, maximum length $maximumlength");
+ return 0;
+ }
+ }
+ $Apache::functionplotresponse::functionplotrulelabels{$xfinallabel}=$i;
+ &addlog("Rule $label passed, setting label $xfinallabel");
+ return 1;
+ } else {
+ &addlog("Rule $label failed.");
+ my $hintlabel=$label;
+ $hintlabel=~s/^R//;
+ push(@Apache::functionplotresponse::failedrules,$hintlabel);
+ &addlog("Set hint condition $hintlabel");
+ return 0;
+ }
+ }
+ }
+ &addlog("Rule $label passed.");
+ return 1;
+}
- } elsif ($target eq 'grade'
+sub start_functionplotruleset {
+ my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
+ if ($target eq 'edit') {
+ return &Apache::edit::start_table($token).
+ ' |
'.&mt('Function Plot Rule Set').' | '
+ .''.&mt('Delete?').' '
+ .&Apache::edit::deletelist($target,$token).' '.
+ &Apache::edit::insertlist($target,$token)
+ .' | '
+ ." "
+ .&Apache::edit::end_row()
+ .&Apache::edit::start_spanning_row()
+ ."\n";
+ }
+}
+
+sub end_functionplotruleset {
+ my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
+ my $id=$Apache::inputtags::response[-1];
+ my $partid=$Apache::inputtags::part;
+ my $internalid = $partid.'_'.$id;
+
+ if ($target eq 'edit' ) {
+ return &Apache::edit::end_table();
+ } elsif ($target eq 'grade'
&& &Apache::response::submitted()
&& $Apache::lonhomework::type ne 'exam') {
- my ($response,%coords)=&get_answer_from_form_fields($internalid);
- $Apache::lonhomework::results{"resource.$partid.$id.submission"}=$response;
- my %previous=&Apache::response::check_for_previous($response,$partid,$id);
#
# Actually grade
#
- my $xmin=&Apache::lonxml::get_param('xmin',$parstack,$safeeval);
+ my $xmin=&Apache::lonxml::get_param('xmin',$parstack,$safeeval,-2);
$xmin=(defined($xmin)?$xmin:-10);
- my $xmax=&Apache::lonxml::get_param('xmax',$parstack,$safeeval);
+ my $xmax=&Apache::lonxml::get_param('xmax',$parstack,$safeeval,-2);
$xmax=(defined($xmax)?$xmax:10);
+ my $ymin=&Apache::lonxml::get_param('ymin',$parstack,$safeeval,-2);
+ $ymin=(defined($ymin)?$ymin:-10);
+ my $ymax=&Apache::lonxml::get_param('ymax',$parstack,$safeeval,-2);
+ $ymax=(defined($ymax)?$ymax:10);
+
my $ad='';
+ undef %Apache::functionplotresponse::functionplotrulelabels;
+ $Apache::functionplotresponse::ruleslog='';
+ $Apache::functionplotresponse::functionplotrulelabels{'start'}=400;
+ $Apache::functionplotresponse::functionplotrulelabels{'end'}=0;
if (&populate_arrays($internalid,$xmin,$xmax) eq 'no_func') {
$ad='NOT_FUNCTION';
} else {
+ &addlog("Start of function ".&actualval($Apache::functionplotresponse::functionplotrulelabels{'start'},$xmin,$xmax)." (index ".
+ $Apache::functionplotresponse::functionplotrulelabels{'start'}.")");
+ &addlog("End of function ".&actualval($Apache::functionplotresponse::functionplotrulelabels{'end'},$xmin,$xmax)." (index ".
+ $Apache::functionplotresponse::functionplotrulelabels{'end'}.")");
+
# 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)) {
+ foreach my $rule (@Apache::functionplotresponse::functionplotrules) {
+ unless (&functionplotrulecheck($rule,$xmin,$xmax,$ymin,$ymax)) {
$ad='INCORRECT';
last;
}
@@ -827,13 +1009,60 @@ sub end_functionplotresponse {
# If it's not wrong, it's correct
unless ($ad) { $ad='EXACT_ANS' };
}
+ &addlog("Set hint conditions: ".join(",",@Apache::functionplotresponse::failedrules));
+ &addlog("Assigned award detail: $ad");
+# Store for later to be assigned at end_functionplotresponse
+ $Apache::functionplotresponse::awarddetail=$ad;
+ }
+}
+
+
+sub end_functionplotresponse {
+ my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
+ &Apache::response::end_response;
+
+ my $result;
+ my $id=$Apache::inputtags::response[-1];
+ my $partid=$Apache::inputtags::part;
+ my $internalid = $partid.'_'.$id;
+
+ if ($target eq 'edit') { $result=&Apache::edit::end_table(); }
+ if ($target eq 'grade'
+ && &Apache::response::submitted()
+ && $Apache::lonhomework::type eq 'exam') {
+ &Apache::response::scored_response($partid,$id);
+
+ } elsif ($target eq 'grade'
+ && &Apache::response::submitted()
+ && $Apache::lonhomework::type ne 'exam') {
+ my ($response,%coords)=&get_answer_from_form_fields($internalid);
+ $Apache::lonhomework::results{"resource.$partid.$id.submission"}=$response;
+ my %previous=&Apache::response::check_for_previous($response,$partid,$id);
+#
+# Assign grade
+#
+ my $ad=$Apache::functionplotresponse::awarddetail;
#
# Store grading info
#
$Apache::lonhomework::results{"resource.$partid.$id.awarddetail"}=$ad;
&Apache::response::handle_previous(\%previous,$ad);
} elsif ($target eq 'web') {
+ undef @Apache::functionplotresponse::failedrules;
+ }
+ return $result;
+}
+
+sub end_functionplotelements {
+ my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
+ my $result='';
+ my $id=$Apache::inputtags::response[-1];
+ my $partid=$Apache::inputtags::part;
+ my $internalid = $partid.'_'.$id;
+ if ($target eq 'edit' ) {
+ $result=&Apache::edit::end_table();
+ } elsif ($target eq 'web') {
# Now is the time to render all of the stored splines
foreach my $label (keys(%Apache::functionplotresponse::splineorder)) {
$result.=&generate_spline($internalid,$label);
@@ -860,6 +1089,58 @@ sub end_functionplotresponse {
}
return $result;
}
+
+sub start_functionplotelements {
+ my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
+ my $result='';
+ my $id=$Apache::inputtags::response[-1];
+ my $partid=$Apache::inputtags::part;
+ my $internalid = $partid.'_'.$id;
+
+ if ($target eq 'edit') {
+ return &Apache::edit::start_table($token).
+ ' |
'.&mt('Function Plot Elements').' | '
+ .''.&mt('Delete?').' '
+ .&Apache::edit::deletelist($target,$token).' '.
+ &Apache::edit::insertlist($target,$token)
+ .' | '
+ ." "
+ .&Apache::edit::end_row()
+ .&Apache::edit::start_spanning_row()
+ ."\n";
+ } elsif ($target eq 'web') {
+ my $xmin=&Apache::lonxml::get_param('xmin',$parstack,$safeeval,-2);
+ $xmin=(defined($xmin)?$xmin:-10);
+ my $xmax=&Apache::lonxml::get_param('xmax',$parstack,$safeeval,-2);
+ $xmax=(defined($xmax)?$xmax:10);
+ my $ymin=&Apache::lonxml::get_param('ymin',$parstack,$safeeval,-2);
+ $ymin=(defined($ymin)?$ymin:-10);
+ my $ymax=&Apache::lonxml::get_param('ymax',$parstack,$safeeval,-2);
+ $ymax=(defined($ymax)?$ymax:10);
+ if ($xmax<=$xmin) {
+ $xmax=$xmin+20;
+ }
+ if ($ymax<=$ymin) {
+ $ymax=$ymin+20;
+ }
+ my $xaxisvisible=(&Apache::lonxml::get_param('xaxisvisible',$parstack,$safeeval,-2)=~/on|true|yes|1/i?'true':'false');
+ my $yaxisvisible=(&Apache::lonxml::get_param('yaxisvisible',$parstack,$safeeval,-2)=~/on|true|yes|1/i?'true':'false');
+ my $gridvisible=(&Apache::lonxml::get_param('gridvisible',$parstack,$safeeval,-2)=~/on|true|yes|1/i?'true':'false');
+ my $xlabel=&Apache::lonxml::get_param('xlabel',$parstack,$safeeval,-2);
+ my $ylabel=&Apache::lonxml::get_param('ylabel',$parstack,$safeeval,-2);
+
+
+# paste in the update routine to receive stuff back from the applet
+ $result.=&update_script($internalid);
+# start the initscript for this applet
+ $result.=&start_init_script($internalid);
+# put the axis commands inside
+ $result.=&axes_script($internalid,$xmin,$xmax,$ymin,$ymax,$xaxisvisible,$yaxisvisible,$gridvisible);
+ $result.=&axes_label($internalid,$xlabel,$ylabel);
+# init script is left open
+ }
+ return $result;
+}
1;
|