version 1.25, 2010/11/07 01:57:50
|
version 1.37, 2010/11/13 03:22:58
|
Line 31 use strict;
|
Line 31 use strict;
|
use Apache::response(); |
use Apache::response(); |
use Apache::lonlocal; |
use Apache::lonlocal; |
use Apache::lonnet; |
use Apache::lonnet; |
|
|
BEGIN { |
BEGIN { |
&Apache::lonxml::register('Apache::functionplotresponse',('functionplotresponse','backgroundplot','spline','functionplotrule')); |
&Apache::lonxml::register('Apache::functionplotresponse',('functionplotresponse','backgroundplot','spline', |
|
'functionplotrule','functionplotruleset', |
|
'functionplotelements')); |
} |
} |
|
|
# |
# |
Line 376 sub start_functionplotrule {
|
Line 378 sub start_functionplotrule {
|
&Apache::lonxml::warning(&mt('Rule relationship not defined.')); |
&Apache::lonxml::warning(&mt('Rule relationship not defined.')); |
$relationship='eq'; |
$relationship='eq'; |
} |
} |
my $derivative=&Apache::lonxml::get_param('derivative',$parstack,$safeeval); |
my $derivative=&Apache::lonxml::get_param('derivativeorder',$parstack,$safeeval); |
unless (($derivative==0) || ($derivative==1) || ($derivative==2)) { |
unless (($derivative==0) || ($derivative==1) || ($derivative==2)) { |
&Apache::lonxml::warning(&mt('Rule derivative not defined.')); |
&Apache::lonxml::warning(&mt('Rule derivative not defined.')); |
$derivative=0; |
$derivative=0; |
Line 388 sub start_functionplotrule {
|
Line 390 sub start_functionplotrule {
|
$beginninglabel, |
$beginninglabel, |
&Apache::lonxml::get_param('xfinal',$parstack,$safeeval), |
&Apache::lonxml::get_param('xfinal',$parstack,$safeeval), |
$endinglabel, |
$endinglabel, |
|
&Apache::lonxml::get_param('minimumlength',$parstack,$safeeval), |
|
&Apache::lonxml::get_param('maximumlength',$parstack,$safeeval), |
$relationship, |
$relationship, |
&Apache::lonxml::get_param('value',$parstack,$safeeval) |
&Apache::lonxml::get_param('value',$parstack,$safeeval), |
|
&Apache::lonxml::get_param('percenterror',$parstack,$safeeval) |
))); |
))); |
} elsif ($target eq 'edit') { |
} elsif ($target eq 'edit') { |
$result=&Apache::edit::tag_start($target,$token,'Function Plot Evaluation Rule'). |
$result=&Apache::edit::tag_start($target,$token,'Function Plot Evaluation Rule'). |
&Apache::edit::end_row(); |
&Apache::edit::text_arg('Index/Name:','index', |
|
$token,'10').' '. |
|
&Apache::edit::select_arg(&mt('Function:'),'derivativeorder', |
|
[['0','Function itself'], |
|
['1','First derivative'], |
|
['2','Second derivative']],$token).'<br />'. |
|
&Apache::edit::text_arg('(Initial) x-value:','xinitial', |
|
$token,'8'). |
|
&Apache::edit::select_or_text_arg('(Initial) x-value label:','xinitiallabel', |
|
[['start','Start of Plot']],$token,'8').'<br />'. |
|
|
|
&Apache::edit::text_arg('Optional final x-value for ranges:','xfinal', |
|
$token,'8'). |
|
&Apache::edit::select_or_text_arg('Optional final x-value label:','xfinallabel', |
|
[['end','End of Plot']],$token,'8').'<br />'. |
|
&Apache::edit::text_arg('Optional minimum length for range:','minimumlength', |
|
$token,'8'). |
|
&Apache::edit::text_arg('Optional maximum length for range:','maximumlength', |
|
$token,'8').'<br />'. |
|
&Apache::edit::select_arg(&mt('Relationship:'),'relationship', |
|
[['eq','equal'], |
|
['ne','not equal'], |
|
['ge','greater than or equal'], |
|
['gt','greater than'], |
|
['lt','less than'], |
|
['le','less than or equal']],$token). |
|
$result.= &Apache::edit::select_or_text_arg('Value:','value', |
|
[['undef','not defined']],$token,'8'). |
|
&Apache::edit::text_arg('Percent error:','percenterror', |
|
$token,'8'). |
|
&Apache::edit::end_row(); |
|
} elsif ($target eq 'modified') { |
|
my $constructtag=&Apache::edit::get_new_args($token,$parstack, |
|
$safeeval,'index','derivativeorder', |
|
'xinitial','xinitiallabel','xfinal','xfinallabel', |
|
'minimumlength','maximumlength', |
|
'relationship','value','percenterror'); |
|
if ($constructtag) { $result=&Apache::edit::rebuild_tag($token); } |
} |
} |
return $result; |
return $result; |
} |
} |
Line 553 sub d2dt2_cubic_hermite {
|
Line 595 sub d2dt2_cubic_hermite {
|
# |
# |
sub array_index { |
sub array_index { |
my ($xmin,$xmax,$x)=@_; |
my ($xmin,$xmax,$x)=@_; |
return int(($x-$xmin)/($xmax-$xmin)*200.+0.5); |
return int(($x-$xmin)/($xmax-$xmin)*400.+0.5); |
} |
|
|
|
# |
|
# Actual x-value of array index |
|
# |
|
|
|
sub index_x { |
|
my ($xmin,$xmax,$i)=@_; |
|
return $i*($xmax-$xmin)/200.+$xmin; |
|
} |
|
|
|
# |
|
# Assume function to be linear between array points |
|
# Return the two indices and the scale factor |
|
# |
|
|
|
sub indices_scale { |
|
my ($xmin,$xmax,$x)=@_; |
|
my $i=&array_index($xmin,$xmax,$x); |
|
my $xr=&index_x($xmin,$xmax,$i); |
|
if ($xr<$x) { |
|
# Desired x is right of array index |
|
if ($i>=200) { return (200,200,0); } |
|
return($i,$i+1,200.*($x-$xr)/($xmax-$xmin)); |
|
} elsif ($xr>$x) { |
|
# Desired x is left of array index |
|
if ($i<=0) { return (0,0,0); } |
|
return($i-1,$i,1.-200.*($xr-$x)/($xmax-$xmin)); |
|
} else { |
|
# Desired x is at array index (unlikely, but ...) |
|
if ($i>=200) { return (200,200,0); } |
|
if ($i<=0) { return (0,0,0); } |
|
return ($i,$i,0); |
|
} |
|
} |
|
|
|
# |
|
# Function value |
|
# |
|
|
|
sub func_val { |
|
my ($xmin,$xmax,$x)=@_; |
|
my ($il,$ih,$factor)=&indices_scale($xmin,$xmax,$x); |
|
my $fl=$Apache::functionplotresponse::func[$il]; |
|
my $fh=$Apache::functionplotresponse::func[$ih]; |
|
unless (defined($fl) || defined($fh)) { return undef; } |
|
unless (defined($fl)) { return $fh; } |
|
unless (defined($fh)) { return $fl; } |
|
return $fl+$factor*($fh-$fl); |
|
} |
|
|
|
# |
|
# First derivative |
|
# |
|
|
|
sub dfuncdx_val { |
|
my ($xmin,$xmax,$x)=@_; |
|
my ($il,$ih,$factor)=&indices_scale($xmin,$xmax,$x); |
|
my $fl=$Apache::functionplotresponse::dfuncdx[$il]; |
|
my $fh=$Apache::functionplotresponse::dfuncdx[$ih]; |
|
unless (defined($fl) || defined($fh)) { return undef; } |
|
unless (defined($fl)) { return $fh; } |
|
unless (defined($fh)) { return $fl; } |
|
return $fl+$factor*($fh-$fl); |
|
} |
|
|
|
# |
|
# Second derivative |
|
# |
|
|
|
sub d2funcdx2_val { |
|
my ($xmin,$xmax,$x)=@_; |
|
my ($il,$ih,$factor)=&indices_scale($xmin,$xmax,$x); |
|
my $fl=$Apache::functionplotresponse::d2funcdx2[$il]; |
|
my $fh=$Apache::functionplotresponse::d2funcdx2[$ih]; |
|
unless (defined($fl) || defined($fh)) { return undef; } |
|
unless (defined($fl)) { return $fh; } |
|
unless (defined($fh)) { return $fl; } |
|
return $fl+$factor*($fh-$fl); |
|
} |
} |
|
|
# |
# |
Line 641 sub d2funcdx2_val {
|
Line 604 sub d2funcdx2_val {
|
|
|
sub populate_arrays { |
sub populate_arrays { |
my ($id,$xmin,$xmax)=@_; |
my ($id,$xmin,$xmax)=@_; |
for (my $i=0; $i<=200; $i++) { |
for (my $i=0; $i<=400; $i++) { |
|
$Apache::functionplotresponse::actualxval[$i]=undef; |
$Apache::functionplotresponse::func[$i]=undef; |
$Apache::functionplotresponse::func[$i]=undef; |
$Apache::functionplotresponse::dfuncdx[$i]=undef; |
$Apache::functionplotresponse::dfuncdx[$i]=undef; |
$Apache::functionplotresponse::d2funcd2x[$i]=undef; |
$Apache::functionplotresponse::d2funcd2x[$i]=undef; |
Line 662 sub populate_arrays {
|
Line 626 sub populate_arrays {
|
$env{'form.HWVAL_'.$id.'_'.$label.'P'.$ni.'_y'}, |
$env{'form.HWVAL_'.$id.'_'.$label.'P'.$ni.'_y'}, |
$env{'form.HWVAL_'.$id.'_'.$label.'S'.$ni.'_y'}); |
$env{'form.HWVAL_'.$id.'_'.$label.'S'.$ni.'_y'}); |
# Run in small steps over spline parameter |
# Run in small steps over spline parameter |
for (my $t=0; $t<=1; $t+=0.00025) { |
for (my $t=0; $t<=1; $t+=0.0001) { |
my $xi=&array_index($xmin,$xmax,&cubic_hermite($t,@xparms)); |
my $xreal=&cubic_hermite($t,@xparms); |
|
my $xi=&array_index($xmin,$xmax,$xreal); |
if ($xi<$xiold) { return 'no_func'; } |
if ($xi<$xiold) { return 'no_func'; } |
if (($xi>$xiold) && ($xi>=0) && ($xi<=200)) { |
if (($xi>$xiold) && ($xi>=0) && ($xi<=400)) { |
if (defined($Apache::functionplotresponse::func[$xi])) { return 'no_func'; } |
if (defined($Apache::functionplotresponse::func[$xi])) { return 'no_func'; } |
$xiold=$xi; |
$xiold=$xi; |
|
$Apache::functionplotresponse::actualxval[$xi]=$xreal; |
# Function value |
# Function value |
$Apache::functionplotresponse::func[$xi]=&cubic_hermite($t,@yparms); |
my $funcval=&cubic_hermite($t,@yparms); |
|
$Apache::functionplotresponse::func[$xi]=$funcval; |
|
if (defined($funcval)) { |
|
if ($xi<$Apache::functionplotresponse::functionplotrulelabels{'start'}) { |
|
$Apache::functionplotresponse::functionplotrulelabels{'start'}=$xi; |
|
} |
|
if ($xi>$Apache::functionplotresponse::functionplotrulelabels{'end'}) { |
|
$Apache::functionplotresponse::functionplotrulelabels{'end'}=$xi; |
|
} |
|
} |
|
# Chain rule |
# dy/dx=dy/dt/(dx/dt) |
# dy/dx=dy/dt/(dx/dt) |
my $dxdt=&ddt_cubic_hermite($t,@xparms); |
my $dxdt=&ddt_cubic_hermite($t,@xparms); |
if ($dxdt) { |
if ($dxdt) { |
$Apache::functionplotresponse::dfuncdx[$xi]=&ddt_cubic_hermite($t,@yparms)/$dxdt; |
$Apache::functionplotresponse::dfuncdx[$xi]=&ddt_cubic_hermite($t,@yparms)/$dxdt; |
} |
# Second derivative |
# d^2y/dx^2 |
$Apache::functionplotresponse::d2funcdx2[$xi]= |
my $d2xdt2=&d2dt2_cubic_hermite($t,@xparms); |
($dxdt*&d2dt2_cubic_hermite($t,@yparms)-&ddt_cubic_hermite($t,@yparms)*&d2dt2_cubic_hermite($t,@xparms))/ |
if ($d2xdt2) { |
($dxdt*$dxdt*$dxdt); |
$Apache::functionplotresponse::d2funcd2x[$xi]=&d2dt2_cubic_hermite($t,@yparms)/$d2xdt2; |
|
} |
} |
} |
} |
} |
} |
Line 687 sub populate_arrays {
|
Line 662 sub populate_arrays {
|
} |
} |
|
|
# |
# |
# Implentation of <functionplotresponse> |
# Implementation of <functionplotresponse> |
# |
# |
|
|
sub start_functionplotresponse { |
sub start_functionplotresponse { |
Line 705 sub start_functionplotresponse {
|
Line 680 sub start_functionplotresponse {
|
$Apache::functionplotresponse::counter=0; |
$Apache::functionplotresponse::counter=0; |
# Remember rules |
# Remember rules |
undef @Apache::functionplotresponse::functionplotrules; |
undef @Apache::functionplotresponse::functionplotrules; |
|
# Remember failed rules |
|
if ($target eq 'grade') { |
|
undef @Apache::functionplotresponse::failedrules; |
|
} |
|
# Delete previous awards |
|
undef $Apache::functionplotresponse::awarddetail; |
# Part and ID |
# Part and ID |
my $partid=$Apache::inputtags::part; |
my $partid=$Apache::inputtags::part; |
my $id=&Apache::response::start_response($parstack,$safeeval); |
my $id=&Apache::response::start_response($parstack,$safeeval); |
Line 739 sub start_functionplotresponse {
|
Line 720 sub start_functionplotresponse {
|
$result.=&Apache::edit::start_table($token) |
$result.=&Apache::edit::start_table($token) |
.'<tr><td><span class="LC_nobreak">'.&mt('Function Plot Question').'</span></td>' |
.'<tr><td><span class="LC_nobreak">'.&mt('Function Plot Question').'</span></td>' |
.'<td><span class="LC_nobreak">'.&mt('Delete?').' ' |
.'<td><span class="LC_nobreak">'.&mt('Delete?').' ' |
.&Apache::edit::deletelist($target,$token) |
.&Apache::edit::deletelist($target,$token).' ' |
|
.&Apache::edit::insertlist($target,$token) |
.'</span></td>' |
.'</span></td>' |
."<td> " |
."<td> " |
.&Apache::edit::end_row() |
.&Apache::edit::end_row() |
Line 752 sub start_functionplotresponse {
|
Line 734 sub start_functionplotresponse {
|
&Apache::edit::text_arg('Maximum x-value:','xmax', |
&Apache::edit::text_arg('Maximum x-value:','xmax', |
$token,'4').' '. |
$token,'4').' '. |
&Apache::edit::select_arg('x-axis visible:','xaxisvisible', |
&Apache::edit::select_arg('x-axis visible:','xaxisvisible', |
['yes','no'],$token).' '. |
['yes','no'],$token).'<br />'. |
&Apache::edit::text_arg('Label y-axis:','ylabel', |
&Apache::edit::text_arg('Label y-axis:','ylabel', |
$token,'6').' '. |
$token,'6').' '. |
&Apache::edit::text_arg('Minimum y-value:','ymin', |
&Apache::edit::text_arg('Minimum y-value:','ymin', |
Line 760 sub start_functionplotresponse {
|
Line 742 sub start_functionplotresponse {
|
&Apache::edit::text_arg('Maximum y-value:','ymax', |
&Apache::edit::text_arg('Maximum y-value:','ymax', |
$token,'4').' '. |
$token,'4').' '. |
&Apache::edit::select_arg('y-axis visible:','yaxisvisible', |
&Apache::edit::select_arg('y-axis visible:','yaxisvisible', |
['yes','no'],$token).' '. |
['yes','no'],$token).'<br />'. |
&Apache::edit::select_arg('Grid visible:','gridvisible', |
&Apache::edit::select_arg('Grid visible:','gridvisible', |
['yes','no'],$token). |
['yes','no'],$token). |
&Apache::edit::end_row().&Apache::edit::start_spanning_row(); |
&Apache::edit::end_row().&Apache::edit::start_spanning_row(); |
Line 772 sub start_functionplotresponse {
|
Line 754 sub start_functionplotresponse {
|
|
|
} elsif ($target eq 'meta') { |
} elsif ($target eq 'meta') { |
$result=&Apache::response::meta_package_write('functionplotresponse'); |
$result=&Apache::response::meta_package_write('functionplotresponse'); |
} elsif ($target eq 'web') { |
} elsif (($target eq 'answer') && |
# paste in the update routine to receive stuff back from the applet |
($env{'form.answer_output_mode'} ne 'tex') && |
$result.=&update_script($internalid); |
($Apache::lonhomework::viewgrades == 'F')) { |
# start the initscript for this applet |
my (undef,undef,$udom,$uname)=&Apache::lonnet::whichuser(); |
$result.=&start_init_script($internalid); |
my $windowopen=&Apache::lonhtmlcommon::javascript_docopen(); |
# put the axis commands inside |
my $start_page = &Apache::loncommon::start_page('Rules Log', undef, |
$result.=&axes_script($internalid,$xmin,$xmax,$ymin,$ymax,$xaxisvisible,$yaxisvisible,$gridvisible); |
{'only_body' => 1, |
$result.=&axes_label($internalid,$xlabel,$ylabel); |
'bgcolor' => '#FFFFFF', |
# init script is left open |
'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 ="<script type=\"text/javascript\"> |
|
// <![CDATA[ |
|
function $function_name() {newWindow=open('','new_W','width=500,height=500,scrollbars=1,resizable=yes');newWindow.$windowopen;newWindow.document.writeln('$start_page<pre>". |
|
$Apache::functionplotresponse::ruleslog. |
|
"<\\/pre>$end_page');newWindow.document.close();newWindow.focus()} |
|
// ]]> |
|
</script><a href=\"javascript:$function_name();void(0);\">".&mt('Rules Log')."</a><br />"; |
|
&Apache::lonxml::add_script_result($rules_var); |
|
} |
|
|
return $result; |
return $result; |
} |
} |
|
|
sub compare_rel { |
sub compare_rel { |
my ($relationship,$value,$val,$tol)=@_; |
my ($relationship,$value,$realval,$tol)=@_; |
if (abs($value-$val)<$tol) { return 1; } |
# 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; |
return 0; |
} |
} |
|
|
|
sub addlog { |
|
my ($text)=@_; |
|
$Apache::functionplotresponse::ruleslog.=$text.'<br />'; |
|
} |
|
|
|
sub actualval { |
|
my ($i,$xmin,$xmax)=@_; |
|
return $xmin+$i/400.*($xmax-$xmin); |
|
} |
|
|
sub functionplotrulecheck { |
sub functionplotrulecheck { |
my ($rule,$xmin,$xmax,$tolfunc,$toldfdx,$told2fdx2)=@_; |
my ($rule,$xmin,$xmax,$ymin,$ymax)=@_; |
&Apache::lonnet::logthis("Rule $rule TolFunc $tolfunc TolDfDx $toldfdx TolD2fDx2 $told2fdx2"); |
|
my ($label,$derivative,$xinitial,$xinitiallabel,$xfinal,$xfinallabel,$relationship,$value) |
my ($label,$derivative,$xinitial,$xinitiallabel,$xfinal,$xfinallabel,$minimumlength,$maximumlength,$relationship,$value,$percent) |
=split(/\:/,$rule); |
=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 a hard value is set for the boundaries, it overrides the label |
# if a hard value is set for the boundaries, it overrides the label |
if (($xinitial ne '') && ($xinitiallabel ne '')) { |
if (($xinitial ne '') && ($xinitiallabel ne '') && ($xinitiallabel ne 'start')) { |
$Apache::functionplotresponse::functionplotrulelabels{$xinitiallabel}=$xinitial; |
$li=&array_index($xmin,$xmax,$xinitial); |
|
$Apache::functionplotresponse::functionplotrulelabels{$xinitiallabel}=$li; |
} |
} |
if (($xfinal ne '') && ($xfinallabel ne '')) { |
if (($xfinal ne '') && ($xfinallabel ne '') && ($xfinallabel ne 'end')) { |
$Apache::functionplotresponse::functionplotrulelabels{$xfinallabel}=$xfinal; |
$lh=&array_index($xmin,$xmax,$xfinal); |
|
$Apache::functionplotresponse::functionplotrulelabels{$xfinallabel}=$lh; |
} |
} |
|
# if the label is defined, use it |
if (defined($Apache::functionplotresponse::functionplotrulelabels{$xinitiallabel})) { |
if (defined($Apache::functionplotresponse::functionplotrulelabels{$xinitiallabel})) { |
$xinitial=$Apache::functionplotresponse::functionplotrulelabels{$xinitiallabel}; |
&addlog("Using lower label $xinitiallabel"); |
|
$li=$Apache::functionplotresponse::functionplotrulelabels{$xinitiallabel}; |
|
} else { |
|
$li=&array_index($xmin,$xmax,$xinitial); |
} |
} |
if (defined($Apache::functionplotresponse::functionplotrulelabels{$xfinallabel})) { |
unless ($findupper) { |
$xfinal=$Apache::functionplotresponse::functionplotrulelabels{$xfinallabel}; |
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 |
# Basic sanity checks |
if ($xinitial eq '') { |
if ($li<0) { $li=0; } |
$xinitial=0; |
if ($lh>400) { $lh=400; } |
|
if ($li>$lh) { |
|
$lh=$li; |
|
} |
|
|
|
&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"); |
} |
} |
if ($xfinal ne '') { |
my $tol=$percent*($ymax-$ymin)/100; |
if ($xinitial>$xfinal) { |
if ($xmax>$xmin) { |
$xfinal=$xinitial; |
if ($derivative==2) { |
|
$tol=4.*$tol/($xmax-$xmin); |
|
} elsif ($derivative==1) { |
|
$tol=2.*$tol/($xmax-$xmin); |
} |
} |
} |
} |
&Apache::lonnet::logthis("Init $xinitial Final $xfinal"); |
for (my $i=$li; $i<=$lh; $i++) { |
if (($xfinal eq '') || ($xinitial==$xfinal)) { |
|
# This is only one point |
|
&Apache::lonnet::logthis("One point $xinitial"); |
|
my $tol; |
|
my $val; |
my $val; |
if ($derivative==2) { |
if ($derivative==2) { |
$val=&d2funcdx2_val($xmin,$xmax,$xinitial); |
$val=$Apache::functionplotresponse::d2funcdx2[$i]; |
$tol=$told2fdx2; |
|
} elsif ($derivative==1) { |
} elsif ($derivative==1) { |
$val=&dfuncdx_val($xmin,$xmax,$xinitial); |
$val=$Apache::functionplotresponse::dfuncdx[$i]; |
$tol=$toldfdx; |
|
} else { |
} else { |
$val=&func_val($xmin,$xmax,$xinitial); |
$val=$Apache::functionplotresponse::func[$i]; |
$tol=$tolfunc; |
} |
|
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; |
|
} |
} |
} |
&Apache::lonnet::logthis("Value $value ActVal $val Tol $tol"); |
|
return &compare_rel($relationship,$value,$val,$tol); |
|
} else { |
|
# This is a range |
|
} |
} |
return 0; |
&addlog("Rule $label passed."); |
|
return 1; |
} |
} |
|
|
|
sub start_functionplotruleset { |
|
my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; |
|
if ($target eq 'edit') { |
|
return &Apache::edit::start_table($token). |
|
'<tr><td><span class="LC_nobreak">'.&mt('Function Plot Rule Set').'</span></td>' |
|
.'<td><span class="LC_nobreak">'.&mt('Delete?').' ' |
|
.&Apache::edit::deletelist($target,$token).' '. |
|
&Apache::edit::insertlist($target,$token) |
|
.'</span></td>' |
|
."<td> " |
|
.&Apache::edit::end_row() |
|
.&Apache::edit::start_spanning_row() |
|
."\n"; |
|
} |
|
} |
|
|
sub end_functionplotresponse { |
sub end_functionplotruleset { |
my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; |
my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_; |
&Apache::response::end_response; |
my $id=$Apache::inputtags::response[-1]; |
|
my $partid=$Apache::inputtags::part; |
my $result; |
my $internalid = $partid.'_'.$id; |
my $id=$Apache::inputtags::response[-1]; |
|
my $partid=$Apache::inputtags::part; |
if ($target eq 'edit' ) { |
my $internalid = $partid.'_'.$id; |
return &Apache::edit::end_table(); |
|
} elsif ($target eq 'grade' |
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::response::submitted() |
&& $Apache::lonhomework::type ne 'exam') { |
&& $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 |
# 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); |
$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); |
$xmax=(defined($xmax)?$xmax:10); |
my $ymin=&Apache::lonxml::get_param('ymin',$parstack,$safeeval); |
my $ymin=&Apache::lonxml::get_param('ymin',$parstack,$safeeval,-2); |
$ymin=(defined($ymin)?$ymin:-10); |
$ymin=(defined($ymin)?$ymin:-10); |
my $ymax=&Apache::lonxml::get_param('ymax',$parstack,$safeeval); |
my $ymax=&Apache::lonxml::get_param('ymax',$parstack,$safeeval,-2); |
$ymax=(defined($ymax)?$ymax:10); |
$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=''; |
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') { |
if (&populate_arrays($internalid,$xmin,$xmax) eq 'no_func') { |
$ad='NOT_FUNCTION'; |
$ad='NOT_FUNCTION'; |
} else { |
} 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. |
# We have a function that we can actually grade, go through the spline rules. |
undef %Apache::functionplotresponse::functionplotrulelabels; |
|
foreach my $rule (@Apache::functionplotresponse::functionplotrules) { |
foreach my $rule (@Apache::functionplotresponse::functionplotrules) { |
unless (&functionplotrulecheck($rule,$xmin,$xmax,$tolfunc,$toldfdx,$told2fdx2)) { |
unless (&functionplotrulecheck($rule,$xmin,$xmax,$ymin,$ymax)) { |
$ad='INCORRECT'; |
$ad='INCORRECT'; |
last; |
last; |
} |
} |
Line 899 sub end_functionplotresponse {
|
Line 1009 sub end_functionplotresponse {
|
# If it's not wrong, it's correct |
# If it's not wrong, it's correct |
unless ($ad) { $ad='EXACT_ANS' }; |
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 |
# Store grading info |
# |
# |
$Apache::lonhomework::results{"resource.$partid.$id.awarddetail"}=$ad; |
$Apache::lonhomework::results{"resource.$partid.$id.awarddetail"}=$ad; |
&Apache::response::handle_previous(\%previous,$ad); |
&Apache::response::handle_previous(\%previous,$ad); |
} elsif ($target eq 'web') { |
} 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 |
# Now is the time to render all of the stored splines |
foreach my $label (keys(%Apache::functionplotresponse::splineorder)) { |
foreach my $label (keys(%Apache::functionplotresponse::splineorder)) { |
$result.=&generate_spline($internalid,$label); |
$result.=&generate_spline($internalid,$label); |
Line 932 sub end_functionplotresponse {
|
Line 1089 sub end_functionplotresponse {
|
} |
} |
return $result; |
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). |
|
'<tr><td><span class="LC_nobreak">'.&mt('Function Plot Elements').'</span></td>' |
|
.'<td><span class="LC_nobreak">'.&mt('Delete?').' ' |
|
.&Apache::edit::deletelist($target,$token).' '. |
|
&Apache::edit::insertlist($target,$token) |
|
.'</span></td>' |
|
."<td> " |
|
.&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; |
1; |
|
|