Diff for /loncom/homework/functionplotresponse.pm between versions 1.20 and 1.24

version 1.20, 2010/10/30 23:43:29 version 1.24, 2010/11/06 16:12:39
Line 344  sub end_backgroundplot { Line 344  sub end_backgroundplot {
 sub start_splinerule {  sub start_splinerule {
    my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
    my $result='';     my $result='';
    my $internalid = $Apache::inputtags::part.'_'.$Apache::inputtags::response[-1];     my $label=&Apache::lonxml::get_param('index',$parstack,$safeeval);
    if ($target eq 'edit') {     $Apache::functionplotresponse::counter++;
         $result=&Apache::edit::tag_start($target,$token,'Spline Evaluation Rule').     if ($label=~/\W/) {
                 &Apache::edit::end_row();        &Apache::lonxml::warning(&mt('Spline Rule indices should only contain alphanumeric characters.'));
      }
      $label=~s/\W//gs;
      unless ($label) {
         $label='R'.$Apache::functionplotresponse::counter;
      } else {
         $label='R'.$label;
      }
      if ($Apache::functionplotresponse::splineorder{$label}) {
          &Apache::lonxml::error(&mt('Spline 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);
         if (($beginninglabel=~/\W/) || ($endinglabel=~/W/)) {
             &Apache::lonxml::warning(&mt('Spline Rule labels must be alphanumeric.'));
         }
         $beginninglabel=~s/\W//gs;
         $endinglabel=~s/\W//gs;
         my $relationship=&Apache::lonxml::get_param('relationship',$parstack,$safeeval);
         $relationship=~s/\W//gs;
         $relationship=lc($relationship);
         unless ($relationship=~/^(eq|ge|gt|le|lt|ne)$/) {
             &Apache::lonxml::warning(&mt('Spline 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.'));
            $derivative=0;
         }
         push(@Apache::functionplotresponse::splinerules,join(':',(
              $label,
              $derivative,
              &Apache::lonxml::get_param('beginningvalue',$parstack,$safeeval),
              $beginninglabel,
              &Apache::lonxml::get_param('endingvalue',$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').
                 &Apache::edit::end_row();
    }     }
    return $result;     return $result;
 }  }
Line 363  sub end_splinerule { Line 409  sub end_splinerule {
   
   
 #  #
 # <spline label="..." order="1,2,3,4" initx="..." inity="..." scalex="..." scaley="..." />  # <spline index="..." order="1,2,3,4" initx="..." inity="..." scalex="..." scaley="..." />
 #  #
 # Unfortunately, GeoGebra seems to want all splines after everything else, so we need to store them  # Unfortunately, GeoGebra seems to want all splines after everything else, so we need to store them
 #  #
Line 371  sub start_spline { Line 417  sub start_spline {
    my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
    my $result='';     my $result='';
    if ($target eq 'web') {     if ($target eq 'web') {
       my $label=&Apache::lonxml::get_param('label',$parstack,$safeeval);        my $label=&Apache::lonxml::get_param('index',$parstack,$safeeval);
       $Apache::functionplotresponse::counter++;        $Apache::functionplotresponse::counter++;
       if ($label=~/\W/) {        if ($label=~/\W/) {
          &Apache::lonxml::warning(&mt('Spline labels should only contain alphanumeric characters.'));           &Apache::lonxml::warning(&mt('Spline indices should only contain alphanumeric characters.'));
       }        }
       $label=~s/\W//gs;        $label=~s/\W//gs;
       unless ($label) { $label='S'.$Apache::functionplotresponse::counter; }        unless ($label) { 
            $label='S'.$Apache::functionplotresponse::counter; 
         } else {
            $label='S'.$label;
         }
       if ($Apache::functionplotresponse::splineorder{$label}) {        if ($Apache::functionplotresponse::splineorder{$label}) {
          &Apache::lonxml::error(&mt('Spline labels must be unique.'));           &Apache::lonxml::error(&mt('Spline indices must be unique.'));
       }        }
   
       my $order=&Apache::lonxml::get_param('order',$parstack,$safeeval);        my $order=&Apache::lonxml::get_param('order',$parstack,$safeeval);
Line 404  sub start_spline { Line 454  sub start_spline {
       $Apache::functionplotresponse::splinescaley{$label}=$sy;        $Apache::functionplotresponse::splinescaley{$label}=$sy;
    } elsif ($target eq 'edit') {     } elsif ($target eq 'edit') {
         $result=&Apache::edit::tag_start($target,$token,'Spline').          $result=&Apache::edit::tag_start($target,$token,'Spline').
              &Apache::edit::text_arg('Label:','label',               &Apache::edit::text_arg('Index:','index',
                                      $token,'4').'&nbsp;'.                                       $token,'4').'&nbsp;'.
              &Apache::edit::select_arg('Order:','order',               &Apache::edit::select_arg('Order:','order',
                                   ['2','3','4','5','6','7','8','9'],$token).'&nbsp;'.                                    ['2','3','4','5','6','7','8','9'],$token).'&nbsp;'.
Line 419  sub start_spline { Line 469  sub start_spline {
              &Apache::edit::end_row();               &Apache::edit::end_row();
   } elsif ($target eq 'modified') {    } elsif ($target eq 'modified') {
     my $constructtag=&Apache::edit::get_new_args($token,$parstack,      my $constructtag=&Apache::edit::get_new_args($token,$parstack,
                                                  $safeeval,'label','order','initx','inity',                                                   $safeeval,'index','order','initx','inity',
                                                            'scalex','scaley');                                                             'scalex','scaley');
     if ($constructtag) { $result=&Apache::edit::rebuild_tag($token); }      if ($constructtag) { $result=&Apache::edit::rebuild_tag($token); }
   }    }
Line 524  sub indices_scale { Line 574  sub indices_scale {
    my ($xmin,$xmax,$x)=@_;     my ($xmin,$xmax,$x)=@_;
    my $i=&array_index($xmin,$xmax,$x);     my $i=&array_index($xmin,$xmax,$x);
    my $xr=&index_x($xmin,$xmax,$i);     my $xr=&index_x($xmin,$xmax,$i);
    &Apache::lonnet::logthis("x:$x i:$i xr:$xr");  
    if ($xr<$x) {     if ($xr<$x) {
 # Desired x is right of array index  # Desired x is right of array index
       if ($i>=200) { return (200,200,0); }        if ($i>=200) { return (200,200,0); }
Line 553  sub func_val { Line 602  sub func_val {
    unless (defined($fl) || defined($fh)) { return undef; }     unless (defined($fl) || defined($fh)) { return undef; }
    unless (defined($fl)) { return $fh; }     unless (defined($fl)) { return $fh; }
    unless (defined($fh)) { return $fl; }     unless (defined($fh)) { return $fl; }
    my $func=$fl+$factor*($fh-$fl);     return $fl+$factor*($fh-$fl);
    &Apache::lonnet::logthis("x:$x func:$func factor:$factor il:$il ih:$ih fil:$fl fih:$fh");  }
    return $func;  
   #
   # 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 566  sub populate_arrays { Line 643  sub populate_arrays {
     my ($id,$xmin,$xmax)=@_;      my ($id,$xmin,$xmax)=@_;
     for (my $i=0; $i<=200; $i++) {      for (my $i=0; $i<=200; $i++) {
        $Apache::functionplotresponse::func[$i]=undef;         $Apache::functionplotresponse::func[$i]=undef;
        $Apache::functionplotresponse::dfunddx[$i]=undef;         $Apache::functionplotresponse::dfuncdx[$i]=undef;
        $Apache::functionplotresponse::d2funcd2x[$i]=undef;         $Apache::functionplotresponse::d2funcd2x[$i]=undef;
     }      }
     unless ($xmax>$xmin) { return 'no_func'; }      unless ($xmax>$xmin) { return 'no_func'; }
Line 591  sub populate_arrays { Line 668  sub populate_arrays {
                 if (($xi>$xiold) && ($xi>=0) && ($xi<=200)) {                  if (($xi>$xiold) && ($xi>=0) && ($xi<=200)) {
                    if (defined($Apache::functionplotresponse::func[$xi])) { return 'no_func'; }                     if (defined($Apache::functionplotresponse::func[$xi])) { return 'no_func'; }
                    $xiold=$xi;                     $xiold=$xi;
   # Function value
                    $Apache::functionplotresponse::func[$xi]=&cubic_hermite($t,@yparms);                     $Apache::functionplotresponse::func[$xi]=&cubic_hermite($t,@yparms);
   # dy/dx=dy/dt/(dx/dt)
                      my $dxdt=&ddt_cubic_hermite($t,@xparms);
                      if ($dxdt) {
                         $Apache::functionplotresponse::dfuncdx[$xi]=&ddt_cubic_hermite($t,@yparms)/$dxdt;
                      }
   # d^2y/dx^2
                      my $d2xdt2=&d2dt2_cubic_hermite($t,@xparms);
                      if ($d2xdt2) {
                         $Apache::functionplotresponse::d2funcd2x[$xi]=&d2dt2_cubic_hermite($t,@yparms)/$d2xdt2;
                      }
                 }                  }
             }              }
         }          }
Line 615  sub start_functionplotresponse { Line 703  sub start_functionplotresponse {
   undef %Apache::functionplotresponse::previous;    undef %Apache::functionplotresponse::previous;
   $Apache::functionplotresponse::inputfields='';    $Apache::functionplotresponse::inputfields='';
   $Apache::functionplotresponse::counter=0;    $Apache::functionplotresponse::counter=0;
   # Remember rules
     undef @Apache::functionplotresponse::splinerules;
 # 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 687  sub start_functionplotresponse { Line 777  sub start_functionplotresponse {
   return $result;    return $result;
 }  }
   
   sub splinerulecheck {
      my ($rule)=@_;
      return 0;
   }
   
   
 sub end_functionplotresponse {  sub end_functionplotresponse {
   my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;    my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
   &Apache::response::end_response;    &Apache::response::end_response;
Line 716  sub end_functionplotresponse { Line 812  sub end_functionplotresponse {
         $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);
         $xmax=(defined($xmax)?$xmax:10);          $xmax=(defined($xmax)?$xmax:10);
         my $ad;          my $ad='';
         if (&populate_arrays($internalid,$xmin,$xmax) eq 'no_func') {          if (&populate_arrays($internalid,$xmin,$xmax) eq 'no_func') {
            $ad='BAD_FORMULA';             $ad='NOT_FUNCTION';
         } else {          } else {
            $ad='INCORRECT';  # 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)) {
                    $ad='INCORRECT';
                    last;
                 }
              }
   # If it's not wrong, it's correct 
              unless ($ad) { $ad='EXACT_ANS' };
         }          }
         &func_val($xmin,$xmax,3.96);  
   
         &func_val($xmin,$xmax,3.965);  
   
         &func_val($xmin,$xmax,3.97);  
         &func_val($xmin,$xmax,3.975);  
         &func_val($xmin,$xmax,3.98);  
   
         &func_val($xmin,$xmax,3.985);  
         &func_val($xmin,$xmax,3.99);  
         &func_val($xmin,$xmax,3.995);  
   
         &func_val($xmin,$xmax,4);  
         &func_val($xmin,$xmax,4.05);  
         &func_val($xmin,$xmax,4.1);  
   
         &func_val($xmin,$xmax,4.15);  
         &func_val($xmin,$xmax,4.2);  
         &func_val($xmin,$xmax,4.25);  
   
 #  #
 # Store grading info  # Store grading info

Removed from v.1.20  
changed lines
  Added in v.1.24


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>