Diff for /loncom/homework/response.pm between versions 1.126 and 1.159

version 1.126, 2005/11/01 21:33:49 version 1.159, 2007/02/24 01:44:14
Line 30  package Apache::response; Line 30  package Apache::response;
 use strict;  use strict;
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::lonnet;  use Apache::lonnet;
   use Apache::lonmaxima();
   
 BEGIN {  BEGIN {
     &Apache::lonxml::register('Apache::response',('responseparam','parameter','dataresponse'));      &Apache::lonxml::register('Apache::response',('responseparam','parameter','dataresponse','customresponse','mathresponse'));
 }  }
   
 sub start_response {  sub start_response {
     my ($parstack,$safeeval)=@_;      my ($parstack,$safeeval)=@_;
     my $id= &Apache::lonxml::get_param('id',$parstack,$safeeval);      my $id = &Apache::lonxml::get_id($parstack,$safeeval);
     if ($id eq '') { $id = $Apache::lonxml::curdepth; }  
     if ($#Apache::inputtags::import > -1) {      if ($#Apache::inputtags::import > -1) {
  &Apache::lonxml::debug("Turning :$id: into");   &Apache::lonxml::debug("Turning :$id: into");
  $id = join('_',@Apache::inputtags::import).'_'.$id;   $id = join('_',@Apache::inputtags::import).'_'.$id;
Line 69  sub end_response { Line 69  sub end_response {
   
 sub start_hintresponse {  sub start_hintresponse {
     my ($parstack,$safeeval)=@_;      my ($parstack,$safeeval)=@_;
     my $id= &Apache::lonxml::get_param('id',$parstack,$safeeval);      my $id = &Apache::lonxml::get_id($parstack,$safeeval);
     if ($id eq '') { $id = $Apache::lonxml::curdepth; }  
     push (@Apache::inputtags::hint,$id);      push (@Apache::inputtags::hint,$id);
     push (@Apache::inputtags::hintlist,$id);      push (@Apache::inputtags::hintlist,$id);
     push (@Apache::inputtags::paramstack,[%Apache::inputtags::params]);      push (@Apache::inputtags::paramstack,[%Apache::inputtags::params]);
Line 94  sub pushrandomnumber { Line 93  sub pushrandomnumber {
  # do nothing   # do nothing
     } else {      } else {
  my @seed=&Math::Random::random_get_seed();   my @seed=&Math::Random::random_get_seed();
  push (@randomseeds,\@seed);   push(@randomseeds,\@seed);
     }      }
     &Apache::response::setrandomnumber();      &Apache::response::setrandomnumber(@_);
 }  }
 sub poprandomnumber {  sub poprandomnumber {
     my $rand_alg=&Apache::lonnet::get_rand_alg();      my $rand_alg=&Apache::lonnet::get_rand_alg();
Line 113  sub poprandomnumber { Line 112  sub poprandomnumber {
 }  }
   
 sub setrandomnumber {  sub setrandomnumber {
       my ($ignore_id2) = @_;
     my $rndseed;      my $rndseed;
     $rndseed=&Apache::structuretags::setup_rndseed();      $rndseed=&Apache::structuretags::setup_rndseed();
     if (!defined($rndseed)) { $rndseed=&Apache::lonnet::rndseed(); }      if (!defined($rndseed)) { $rndseed=&Apache::lonnet::rndseed(); }
Line 129  sub setrandomnumber { Line 129  sub setrandomnumber {
  }   }
  $shift_amt=scalar(@Apache::inputtags::responselist);   $shift_amt=scalar(@Apache::inputtags::responselist);
     } elsif ($Apache::lonhomework::parsing_a_task) {      } elsif ($Apache::lonhomework::parsing_a_task) {
  $id1=$Apache::bridgetask::dimension;   $id1=&Apache::bridgetask::get_dim_id();
  if (defined($Apache::bridgetask::instance[-1])) {   if (!$ignore_id2 && ref($Apache::bridgetask::instance{$id1})) {
     $id2=$Apache::bridgetask::instance[-1];      $id2=$Apache::bridgetask::instance{$id1}[-1];
       $shift_amt=scalar(@{$Apache::bridgetask::instance{$id1}});
    } else {
       $shift_amt=0;
  }   }
  Apache->request->print("<p> $id1 $id2</p>");  
  $shift_amt=scalar(@Apache::bridgetask::instance);  
     }       } 
     &Apache::lonxml::debug("id1: $id1, id2: $id2, shift_amt: $shift_amt");      &Apache::lonxml::debug("id1: $id1, id2: $id2, shift_amt: $shift_amt");
     if (!$rand_alg || $rand_alg eq '32bit' || $rand_alg eq '64bit' ||      if (!$rand_alg || $rand_alg eq '32bit' || $rand_alg eq '64bit' ||
Line 152  sub setrandomnumber { Line 153  sub setrandomnumber {
  }   }
     } else {      } else {
  ($rndmod,$rndmod2)=&Apache::lonnet::digest("$id1,$id2");   ($rndmod,$rndmod2)=&Apache::lonnet::digest("$id1,$id2");
   
     }      }
   
     if ($rndseed =~/([,:])/) {      if ($rndseed =~/([,:])/) {
  my $char=$1;   my $char=$1;
  use integer;   use integer;
Line 306  sub handle_previous { Line 307  sub handle_previous {
 }  }
   
 sub view_or_modify {  sub view_or_modify {
     my ($symb,$courseid,$domain,$name) = &Apache::lonxml::whichuser();      my ($symb,$courseid,$domain,$name) = &Apache::lonnet::whichuser();
     my $myself=0;      my $myself=0;
     if ( ($name eq $env{'user.name'}) && ($domain eq $env{'user.domain'}) ) {      if ( ($name eq $env{'user.name'}) && ($domain eq $env{'user.domain'}) ) {
  $myself=1;   $myself=1;
Line 340  sub end_dataresponse { Line 341  sub end_dataresponse {
     if ( $target eq 'web' ) {      if ( $target eq 'web' ) {
     } elsif ($target eq 'grade' ) {      } elsif ($target eq 'grade' ) {
  if ( defined $env{'form.submitted'}) {   if ( defined $env{'form.submitted'}) {
     my ($symb,$courseid,$domain,$name)=&Apache::lonxml::whichuser();      my ($symb,$courseid,$domain,$name)=&Apache::lonnet::whichuser();
     my $allowed=&Apache::lonnet::allowed('mgr',$courseid);      my $allowed=&Apache::lonnet::allowed('mgr',$courseid);
     if ($allowed) {      if ($allowed) {
  &Apache::response::setup_params('dataresponse',$safeeval);   &Apache::response::setup_params('dataresponse',$safeeval);
Line 362  sub end_dataresponse { Line 363  sub end_dataresponse {
     return $result;      return $result;
 }  }
   
   sub start_customresponse {
       my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
       my $id = &Apache::response::start_response($parstack,$safeeval);
       push(@Apache::lonxml::namespace,'customresponse');
       my $result;
       @Apache::response::custom_answer=();
       @Apache::response::custom_answer_type=();
       &Apache::lonxml::register('Apache::response',('answer'));
       if ($target eq 'web') {
     if (  &Apache::response::show_answer() ) {
       my $answer = &Apache::lonxml::get_param('answerdisplay',$parstack,
      $safeeval);
       $Apache::inputtags::answertxt{$id}=[$answer];
    }
       } elsif ($target eq 'edit') {
    $result.=&Apache::edit::tag_start($target,$token);
    $result.=&Apache::edit::text_arg('String to display for answer:',
    'answerdisplay',$token);
    $result.=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
       } elsif ($target eq 'modified') {
    my $constructtag;
    $constructtag=&Apache::edit::get_new_args($token,$parstack,
     $safeeval,'answerdisplay');
    if ($constructtag) {
       $result = &Apache::edit::rebuild_tag($token);
       $result.=&Apache::edit::handle_insert();
    }
       } elsif ($target eq 'answer' || $target eq 'grade') {
    &Apache::response::reset_params();
       } elsif ($target eq 'meta') {
    $result .= &Apache::response::meta_package_write('customresponse');
       }
       return $result;
   }
   
   sub end_customresponse {
       my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
       my $result;
       my $part=$Apache::inputtags::part;
       my $id=$Apache::inputtags::response[-1];
       if ( $target eq 'grade' && &Apache::response::submitted() ) {
    my $response = &Apache::response::getresponse();
    if ($Apache::lonhomework::type eq 'exam' ||
       &Apache::response::submitted('scantron')) {
       &Apache::response::scored_response($part,$id);
    } elsif ( $response =~ /[^\s]/ && 
     $Apache::response::custom_answer_type[-1] eq 'loncapa/perl') {
       if (!$Apache::lonxml::default_homework_loaded) {
    &Apache::lonxml::default_homework_load($safeeval);
       }
       my %previous = &Apache::response::check_for_previous($response,
    $part,$id);
       $Apache::lonhomework::results{"resource.$part.$id.submission"}=
    $response;
       my $error;
       ${$safeeval->varglob('LONCAPA::customresponse_submission')}=
    $response;
       
       my $award = &Apache::run::run('{ my $submission=$LONCAPA::customresponse_submission;'.$Apache::response::custom_answer[-1].'}',$safeeval);
       if (!&Apache::inputtags::valid_award($award)) {
    $error = $award;
    $award = 'ERROR';
       }
       &Apache::response::handle_previous(\%previous,$award);
       $Apache::lonhomework::results{"resource.$part.$id.awarddetail"}=
    $award;
       if ($error) {
    $Apache::lonhomework::results{"resource.$part.$id.awardmsg"}=
       $error;
       }
    }
       } elsif ( $target eq 'answer') {
    $result  = &Apache::response::answer_header('customresponse');
    my $answer = &Apache::lonxml::get_param('answerdisplay',$parstack,
    $safeeval);
    if ($env{'form.answer_output_mode'} ne 'tex') {
       $answer = '<b>'.$answer.'</b>';
    }
    $result .= &Apache::response::answer_part('customresponse',$answer);
    $result .= &Apache::response::answer_footer('customresponse');
       }
       if ($target eq 'grade' || $target eq 'web' || $target eq 'answer' || 
    $target eq 'tex' || $target eq 'analyze') {
    &Apache::lonxml::increment_counter(&Apache::response::repetition());
       }
       pop(@Apache::lonxml::namespace);
       pop(@Apache::response::custom_answer);
       pop(@Apache::response::custom_answer_type);
       &Apache::lonxml::deregister('Apache::response',('answer'));
       &Apache::response::end_response();
       return $result;
   }
   
   
   sub start_mathresponse {
       my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
       my $id = &Apache::response::start_response($parstack,$safeeval);
       push(@Apache::lonxml::namespace,'mathresponse');
       my $result;
       @Apache::response::custom_answer=();
       @Apache::response::custom_answer_type=();
       &Apache::lonxml::register('Apache::response',('answer'));
       if ($target eq 'web') {
     if (  &Apache::response::show_answer() ) {
       my $answer = &Apache::lonxml::get_param('answerdisplay',$parstack,
      $safeeval);
       $Apache::inputtags::answertxt{$id}=[$answer];
    }
       } elsif ($target eq 'edit') {
    $result.=&Apache::edit::tag_start($target,$token);
    $result.=&Apache::edit::text_arg('String to display for answer:',
    'answerdisplay',$token);
    $result.=&Apache::edit::select_arg('Algebra System:',
      'cas',
      ['maxima'],
      $token);
    $result.=&Apache::edit::text_arg('Argument Array:',
    'args',$token);
    $result.=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
       } elsif ($target eq 'modified') {
    my $constructtag;
    $constructtag=&Apache::edit::get_new_args($token,$parstack,
     $safeeval,'answerdisplay','cas','args');
    if ($constructtag) {
       $result = &Apache::edit::rebuild_tag($token);
       $result.=&Apache::edit::handle_insert();
    }
       } elsif ($target eq 'answer' || $target eq 'grade') {
    &Apache::response::reset_params();
       } elsif ($target eq 'meta') {
    $result .= &Apache::response::meta_package_write('mathresponse');
       }
       return $result;
   }
   
   sub end_mathresponse {
       my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
       my $result;
       my $part=$Apache::inputtags::part;
       my $id=$Apache::inputtags::response[-1];
       if ( $target eq 'grade' && &Apache::response::submitted() ) {
    my $response = &Apache::response::getresponse();
    if ( $response =~ /[^\s]/ ) {
       if (!$Apache::lonxml::default_homework_loaded) {
    &Apache::lonxml::default_homework_load($safeeval);
       }
       my %previous = &Apache::response::check_for_previous($response,
    $part,$id);
       $Apache::lonhomework::results{"resource.$part.$id.submission"}=
    $response;
       my $error;
       my $award;
       my $cas = &Apache::lonxml::get_param('cas',$parstack,$safeeval);
               if ($cas eq 'maxima') {
                   my $args = [&Apache::lonxml::get_param_var('args',$parstack,$safeeval)];
                   $award=&Apache::lonmaxima::maxima_run($Apache::response::custom_answer[-1],$response,$args);
               }
       if (!&Apache::inputtags::valid_award($award)) {
    $error = $award;
    $award = 'ERROR';
       }
       &Apache::response::handle_previous(\%previous,$award);
       $Apache::lonhomework::results{"resource.$part.$id.awarddetail"}=
    $award;
       if ($error) {
    $Apache::lonhomework::results{"resource.$part.$id.awardmsg"}=
       $error;
       }
    }
       }
       pop(@Apache::lonxml::namespace);
       pop(@Apache::response::custom_answer);
       pop(@Apache::response::custom_answer_type);
       &Apache::lonxml::deregister('Apache::response',('answer'));
       &Apache::response::end_response();
       return $result;
   }
   
   sub implicit_multiplication {
       my ($expression)=@_;
   # Escape scientific notation, so 3e8 does not become 3*e*8
   # 3e8 -> 3&8; 3e-8 -> 3&-8; 3E+8 -> e&+8
       $expression=~s/(\d+)e([\+\-]*\d+)/$1\&\($2\)/gsi;
   # 3x10^8 -> 3&8; 3*10^-8 -> 3&-8
       $expression=~s/(\d+)(?:x|\*)10(?:\^|\*\*)([\+\-]*\d+)/$1\&\($2\)/gsi;
   # Fill in multiplication signs
   # a b -> a*b;3 b -> 3*b;3 4 -> 3*4
       $expression=~s/(\w)\s+(\w)/$1\*$2/gs;
   # )( -> )*(; ) ( -> )*(
       $expression=~s/\)\s*\(/\)\*\(/gs;
   # 3a -> 3*a; 3( -> 3*(; 3 ( -> 3*(; 3A -> 3*A
       $expression=~s/(\d)\s*([a-zA-Z\(])/$1\*$2/gs;
   # a ( -> a*(
       $expression=~s/(\w)\s+\(/$1\*\(/gs;
   # )a -> )*a; )3 -> )*3; ) 3 -> )*3
       $expression=~s/\)\s*(\w)/\)\*$1/gs;
   # 3&8 -> 3e8; 3&-4 -> 3e-4
       $expression=~s/(\d+)\&\(([\+\-]*\d+)\)/$1e$2/gs;
       return $expression;
   }
   
   sub start_answer {
       my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
       my $result;
       push(@Apache::response::custom_answer,
    &Apache::lonxml::get_all_text_unbalanced("/answer",$parser));
       push(@Apache::response::custom_answer_type,
    lc(&Apache::lonxml::get_param('type',$parstack,$safeeval)));
       $Apache::response::custom_answer_type[-1] =~ s/\s+//g;
       if ($target eq "edit" ) {
    $result=&Apache::edit::tag_start($target,$token,'Answer algorithm');
    $result.=&Apache::edit::editfield($token->[1],
     $Apache::response::custom_answer[-1],
     '',80,4);
       } elsif ( $target eq "modified" ) {
    $result=$token->[4].&Apache::edit::modifiedfield('/answer',$parser);
       }
       return $result;
   }
   
   sub end_answer {
       my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
       if ($target eq 'edit' ) {
    return &Apache::edit::end_table();
       }
   }
   
 sub decide_package {  sub decide_package {
     my ($tagstack)=@_;      my ($tagstack)=@_;
     my $package;      my $package;
Line 492  sub setup_params { Line 720  sub setup_params {
     }      }
 }  }
   
   {
       my @answer_bits;
       my $need_row_start;
   
 sub answer_header {  sub answer_header {
       my ($type,$increment,$rows) = @_;
       my $result;
       if ($env{'form.answer_output_mode'} eq 'tex') {
    undef(@answer_bits);
    my $bit;
    if ($Apache::lonhomework::type eq 'exam') {
       $bit = ($Apache::lonxml::counter+$increment).') ';
    } else {
       $bit .= ' Answer for Part: \verb|'.
    $Apache::inputtags::part.'| ';
    }
    push(@answer_bits,$bit);
       } else {
    my $td = '<td '.(defined($rows)?'rowspan="'.$rows.'"':'').'>';
    $result  = '<table border="1"><tr>';
    if ($Apache::lonhomework::type eq 'exam') {
       $result .= $td.($Apache::lonxml::counter+$increment). ')</td>';
    } else {
       $result .= $td.&mt('Answer for Part: [_1]',
          $Apache::inputtags::part).'</td>';
    }
    $result .= "\n";
    $need_row_start = 0;
       }
       return $result;
   }
   
   sub next_answer {
     my ($type) = @_;      my ($type) = @_;
     my $result;      my $result;
     if ($env{'form.answer_output_mode'} eq 'tex') {      if ($env{'form.answer_output_mode'} eq 'tex') {
  $result = ' \vskip 0 mm \begin{tabular}{|c|}\hline Answer for Part: \verb|'.   # FIXME ... need to do something with tex mode
                   $Apache::inputtags::part.'| \\\\ \hline ';  
     } else {      } else {
  $result = '<table border="1"><tr><td>Answer for Part:'.   $result .= "</tr>";
     $Apache::inputtags::part. '</td>'."\n";   $need_row_start = 1;
     }      }
     return $result;      return $result;
 }  }
   
 sub answer_part {  sub answer_part {
     my ($type,$answer) = @_;      my ($type,$answer,$args) = @_;
     my $result;      my $result;
     if ($env{'form.answer_output_mode'} eq 'tex') {      if ($env{'form.answer_output_mode'} eq 'tex') {
  my $to_use='|';   if (!$args->{'no_verbatim'}) {
  foreach my $value (32..126) {      my $to_use='|';
     my $char=pack('c',$value);      foreach my $value (32..126) {
     if ($answer !~ /\Q$char\E/) {   my $char=pack('c',$value);
  $to_use=$char;   if ($answer !~ /\Q$char\E/) {
  last;      $to_use=$char;
       last;
    }
       }
       if ($answer ne '') {
    $answer = '\verb'.$to_use.$answer.$to_use;
     }      }
  }   }
  $result = '\verb'.$to_use.$answer.$to_use.'\\\\ \hline ';   if ($answer ne '') {
       push(@answer_bits,$answer);
    }
     } else {      } else {
  $result = '<td>'.$answer.'</td>';   if ($need_row_start) {
       $result .= '<tr>';
       $need_row_start = 0;
    }
    $result .= '<td>'.$answer.'</td>';
     }      }
     return $result;      return $result;
 }  }
Line 528  sub answer_footer { Line 798  sub answer_footer {
     my ($type) = @_;      my ($type) = @_;
     my $result;      my $result;
     if ($env{'form.answer_output_mode'} eq 'tex') {      if ($env{'form.answer_output_mode'} eq 'tex') {
  $result = ' \end{tabular} \vskip 0 mm ';   my $columns = scalar(@answer_bits);
    $result  = ' \vskip 0 mm \noindent \begin{tabular}{|'.'c|'x$columns.'}\hline ';
    $result .= join(' & ',@answer_bits);
    $result .= ' \\\\ \\hline \end{tabular} \vskip 0 mm ';
     } else {      } else {
  $result = '</tr></table>';   $result = '</tr></table>';
     }      }
     return $result;      return $result;
 }  }
   
   }
   
 sub showallfoils {  sub showallfoils {
     if (defined($env{'form.showallfoils'})) {      if (defined($env{'form.showallfoils'})) {
  my ($symb)=&Apache::lonxml::whichuser();   my ($symb)=&Apache::lonnet::whichuser();
  if (($env{'request.state'} eq 'construct') ||    if (($env{'request.state'} eq 'construct') || 
     ($env{'user.adv'} && $symb eq '')      ||      ($env{'user.adv'} && $symb eq '')      ||
             ($Apache::lonhomework::viewgrades) ) {              ($Apache::lonhomework::viewgrades) ) {
Line 751  sub submitted { Line 1026  sub submitted {
     if ($who eq 'scantron') { return 0; }      if ($who eq 'scantron') { return 0; }
     # if the Submit Answer button for this particular part was pressed      # if the Submit Answer button for this particular part was pressed
     my $partid=$Apache::inputtags::part;      my $partid=$Apache::inputtags::part;
     if (defined($env{'form.submit_'.$partid})) { return 1; }      if ($env{'form.submitted'} eq "part_$partid") {
    return 1;
       }
       if ($env{'form.submitted'} eq "yes"
    && defined($env{'form.submit_'.$partid})) {
    return 1;
       }
     # Submit All button on a .page was pressed      # Submit All button on a .page was pressed
     if (defined($env{'form.all_submit'})) { return 1; }      if (defined($env{'form.all_submit'})) { return 1; }
     # otherwise no submission occured      # otherwise no submission occured
     return 0;      return 0;
 }  }
   
   sub add_to_gradingqueue {
       my ($symb,$courseid,$domain,$name) = &Apache::lonnet::whichuser();
       if (   $courseid eq ''
    || $symb eq ''
    || $env{'request.state'} eq 'construct'
    || $Apache::lonhomework::type ne 'problem') {
    return;
       }
   
       my %queue_info = ( 'type' => 'problem',
          'time' => time);
   
       if (exists($Apache::lonhomework::history{"resource.0.checkedin.slot"})) {
    $queue_info{'slot'}=
        $Apache::lonhomework::history{"resource.0.checkedin.slot"};
       }
   
       my $result=&Apache::bridgetask::add_to_queue('gradingqueue',\%queue_info);
       if ($result ne 'ok') {
    &Apache::lonxml::error("add_to_queue said $result");
       }
   }
   
 # basically undef and 0 (both false) mean that they still have work to do  # basically undef and 0 (both false) mean that they still have work to do
 # and all true values mean that they can't do any more work  # and all true values mean that they can't do any more work
 #  #
Line 768  sub submitted { Line 1072  sub submitted {
 # a return of 3 means it after the answer date  # a return of 3 means it after the answer date
 sub check_status {  sub check_status {
     my ($id)=@_;      my ($id)=@_;
     if (!$id) { $id=$Apache::linputtags::part; }      if (!defined($id)) { $id=$Apache::inputtags::part; }
     my $curtime=&Apache::lonnet::EXT('system.time');      my $curtime=&Apache::lonnet::EXT('system.time');
     my $opendate=&Apache::lonnet::EXT("resource.$id.opendate");      my $opendate=&Apache::lonnet::EXT("resource.$id.opendate");
     my $duedate=&Apache::lonnet::EXT("resource.$id.duedate");      my $duedate=&Apache::lonnet::EXT("resource.$id.duedate");

Removed from v.1.126  
changed lines
  Added in v.1.159


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.