--- loncom/homework/inputtags.pm 2006/07/19 20:54:19 1.203 +++ loncom/homework/inputtags.pm 2007/03/13 00:21:28 1.218 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # input definitons # -# $Id: inputtags.pm,v 1.203 2006/07/19 20:54:19 www Exp $ +# $Id: inputtags.pm,v 1.218 2007/03/13 00:21:28 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -70,6 +70,10 @@ BEGIN { # %Apache::inputtags::answertxt - <*response> tags store correct # answer strings for display by # in this hash. +# %Apache::inputtags::submission_display +# - <*response> tags store improved display +# of submission strings for display by part +# end. sub initialize_inputtags { @Apache::inputtags::input=(); @@ -88,6 +92,7 @@ sub initialize_inputtags { @Apache::inputtags::importlist=(); $Apache::inputtags::response_with_no_part=0; %Apache::inputtags::answertxt=(); + %Apache::inputtags::submission_display=(); } sub check_for_duplicate_ids { @@ -140,9 +145,9 @@ sub start_textfield { my $resid=$Apache::inputtags::response[-1]; if ($target eq 'web') { $Apache::lonxml::evaluate--; + my $partid=$Apache::inputtags::part; + my $oldresponse = &HTML::Entities::encode($Apache::lonhomework::history{"resource.$partid.$resid.submission"},'<>&"'); if ($Apache::inputtags::status[-1] eq 'CAN_ANSWER') { - my $partid=$Apache::inputtags::part; - my $oldresponse = &HTML::Entities::encode($Apache::lonhomework::history{"resource.$partid.$resid.submission"},'<>&"'); my $cols = &Apache::lonxml::get_param('cols',$parstack,$safeeval); if ( $cols eq '') { $cols = 80; } my $rows = &Apache::lonxml::get_param('rows',$parstack,$safeeval); @@ -161,9 +166,13 @@ sub start_textfield { &Apache::lonxml::get_all_text("/textfield",$parser,$style); } } else { - #right or wrong don't show it - #$result='
'.$oldresponse.'
'; - $result=''; + #show past answer in the essayresponse case + if ($oldresponse =~ /\S/ + && &Apache::londefdef::is_inside_of($tagstack, + 'essayresponse') ) { + $result='
'. + $oldresponse.'
'; + } #get rid of any startup text &Apache::lonxml::get_all_text("/textfield",$parser,$style); } @@ -279,20 +288,27 @@ sub needs_exam_box { sub start_textline { my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_; my $result = ""; + my $input_id = &start_input($parstack,$safeeval); if ($target eq 'web') { $Apache::lonxml::evaluate--; my $partid=$Apache::inputtags::part; my $id=$Apache::inputtags::response[-1]; - if ($Apache::inputtags::status[-1] eq 'CAN_ANSWER' - || lc($Apache::lonhomework::problemstatus) eq 'no' - || ($Apache::inputtags::status[-1] eq 'CANNOT_ANSWER' - && $Apache::lonhomework::history{"resource.$partid.solved"} !~ /^correct/ )) { + if (!&Apache::response::show_answer()) { my $size = &Apache::lonxml::get_param('size',$parstack,$safeeval); my $maxlength; if ($size eq '') { $size=20; } else { - if ($size < 20) { $maxlength=$size; } + if ($size < 20) { + $maxlength = ' maxlength="'.$size.'"'; + } + } + my $oldresponse = $Apache::lonhomework::history{"resource.$partid.$id.submission"}; + &Apache::lonxml::debug("oldresponse $oldresponse is ".ref($oldresponse)); + + if (ref($oldresponse) eq 'ARRAY') { + $oldresponse = $oldresponse->[$#Apache::inputtags::inputlist]; } - my $oldresponse = &HTML::Entities::encode($Apache::lonhomework::history{"resource.$partid.$id.submission"},'<>&"'); + $oldresponse = &HTML::Entities::encode($oldresponse,'<>&"'); + if ($Apache::lonhomework::type ne 'exam') { my $addchars=&Apache::lonxml::get_param('addchars',$parstack,$safeeval); $result=''; @@ -311,8 +327,8 @@ sub start_textline { if ($Apache::inputtags::status[-1] eq 'CANNOT_ANSWER') { $name = "none"; } - $result.= ''; + $result.= ''; } if ($Apache::lonhomework::type eq 'exam' && &needs_exam_box($tagstack)) { @@ -320,7 +336,8 @@ sub start_textline { } } else { #right or wrong don't show what was last typed in. - $result=''.$Apache::inputtags::answertxt{$id}.''; + my $count = scalar(@Apache::inputtags::inputlist)-1; + $result=''.$Apache::inputtags::answertxt{$id}[$count].''; #$result=''; } } elsif ($target eq 'edit') { @@ -355,18 +372,25 @@ sub end_textline { my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_; if ($target eq 'web') { $Apache::lonxml::evaluate++; } elsif ($target eq 'edit') { return ('','no'); } + &end_input(); return ""; } sub start_hiddenline { my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_; my $result = ""; + my $input_id = &start_input($parstack,$safeeval); if ($target eq 'web') { $Apache::lonxml::evaluate--; if ($Apache::inputtags::status[-1] eq 'CAN_ANSWER') { my $partid=$Apache::inputtags::part; my $id=$Apache::inputtags::response[-1]; - my $oldresponse = &HTML::Entities::encode($Apache::lonhomework::history{"resource.$partid.$id.submission"},'<>&"'); + my $oldresponse = $Apache::lonhomework::history{"resource.$partid.$id.submission"}; + if (ref($oldresponse) eq 'ARRAY') { + $oldresponse = $oldresponse->[$#Apache::inputtags::inputlist]; + } + $oldresponse = &HTML::Entities::encode($oldresponse,'<>&"'); + if ($Apache::lonhomework::type ne 'exam') { $result= ''; @@ -389,6 +413,7 @@ sub end_hiddenline { my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_; if ($target eq 'web') { $Apache::lonxml::evaluate++; } elsif ($target eq 'edit') { return ('','no'); } + &end_input(); return ""; } @@ -418,19 +443,7 @@ sub file_selector { $result.=&mt('Submit a file: (only one file can be uploaded)'). '

'; - my $uploadedfile= &HTML::Entities::encode($Apache::lonhomework::history{"resource.$part.$id.uploadedfile"},'<>&"'); - - if ($uploadedfile) { - my $url=$Apache::lonhomework::history{"resource.$part.$id.uploadedurl"}; - &Apache::lonxml::extlink($url); - &Apache::lonnet::allowuploaded('/adm/essayresponse',$url); - my $icon=&Apache::loncommon::icon($url); - my $curfile=''.$uploadedfile.''; - $result.=&mt('Currently submitted: [_1]',$curfile); - } else { - #$result.=&mt('(Hand in a file you have prepared on your computer)'); - } + $result .= &show_past_file_submission($part,$id); } if ( $which eq 'both') { $result.='
'.''.&mt('OR:').'
'; @@ -440,44 +453,59 @@ sub file_selector { &mt('Select Portfolio Files').'
'. ''. '
'; - if ($Apache::lonhomework::history{"resource.$part.$id.portfiles"}=~/[^\s]/){ - my (@file_list,@bad_file_list); - foreach my $file (split(/\s*,\s*/,&unescape($Apache::lonhomework::history{"resource.$part.$id.portfiles"}))) { - my (undef,undef,$domain,$user)=&Apache::lonxml::whichuser(); - my $url="/uploaded/$domain/$user/portfolio$file"; - my $icon=&Apache::loncommon::icon($url); - push(@file_list,''.$file.''); - if (! &Apache::lonnet::stat_file($url)) { - &Apache::lonnet::logthis("bad file is $url"); - push(@bad_file_list,''.$file.''); - } - } - my $files = ''. - join(', ',@file_list). - ''; - $result.=&mt("Portfolio files previously selected: [_1]",$files); - if (@bad_file_list) { - my $bad_files = ''. - join(', ',@bad_file_list). - ''; - $result.='
'.&mt('These file(s) don\'t exist: [_1]',$bad_files); - } - } + $result .= &show_past_portfile_submission($part,$id); + } $result.=''; return $result; } -sub checkstatus { - my ($value,$awardref,$msgref)=@_; - for (my $i=0;$i<=$#$awardref;$i++) { - if ($$awardref[$i] eq $value) { - return ($$awardref[$i],$$msgref[$i]); - } +sub show_past_file_submission { + my ($part,$id) = @_; + my $uploadedfile= &HTML::Entities::encode($Apache::lonhomework::history{"resource.$part.$id.uploadedfile"},'<>&"'); + + return if (!$uploadedfile); + + my $url=$Apache::lonhomework::history{"resource.$part.$id.uploadedurl"}; + &Apache::lonxml::extlink($url); + &Apache::lonnet::allowuploaded('/adm/essayresponse',$url); + my $icon=&Apache::loncommon::icon($url); + my $curfile=''.$uploadedfile.''; + return &mt('Currently submitted: [_1]',$curfile); + +} + +sub show_past_portfile_submission { + my ($part,$id) = @_; + if ($Apache::lonhomework::history{"resource.$part.$id.portfiles"}!~/[^\s]/){ + return; + } + my (@file_list,@bad_file_list); + foreach my $file (split(/\s*,\s*/,&unescape($Apache::lonhomework::history{"resource.$part.$id.portfiles"}))) { + my (undef,undef,$domain,$user)=&Apache::lonnet::whichuser(); + my $url="/uploaded/$domain/$user/portfolio$file"; + my $icon=&Apache::loncommon::icon($url); + push(@file_list,''.$file.''); + if (! &Apache::lonnet::stat_file($url)) { + &Apache::lonnet::logthis("bad file is $url"); + push(@bad_file_list,''.$file.''); + } + } + my $files = ''. + join(', ',@file_list). + ''; + my $result = &mt("Portfolio files previously selected: [_1]",$files); + if (@bad_file_list) { + my $bad_files = ''. + join(', ',@bad_file_list). + ''; + $result.='
'.&mt('These file(s) don\'t exist: [_1]',$bad_files); } - return(undef,undef); + return $result; + } sub valid_award { @@ -497,15 +525,29 @@ sub valid_award { return 0; } +{ + my @awards = ('EXTRA_ANSWER', 'MISSING_ANSWER', 'ERROR', 'NO_RESPONSE', + 'TOO_LONG', + 'UNIT_INVALID_INSTRUCTOR', 'UNIT_INVALID_STUDENT', + 'UNIT_IRRECONCIBLE', 'UNIT_FAIL', 'NO_UNIT', + 'UNIT_NOTNEEDED', 'WANTED_NUMERIC', 'BAD_FORMULA', + 'COMMA_FAIL', 'SIG_FAIL', 'INCORRECT', 'MISORDERED_RANK', + 'INVALID_FILETYPE', 'DRAFT', 'SUBMITTED', 'ASSIGNED_SCORE', + 'APPROX_ANS', 'EXACT_ANS'); + my $i=0; + my %fwd_awards = map { ($_,$i++) } @awards; + my $max=scalar(@awards); + @awards=reverse(@awards); + $i=0; + my %rev_awards = map { ($_,$i++) } @awards; + sub finalizeawards { my ($awardref,$msgref,$nameref,$reverse)=@_; - my $result=undef; - my $award; - my $msg; + my $result; if ($#$awardref == -1) { $result = "NO_RESPONSE"; } if ($result eq '' ) { my $blankcount; - foreach $award (@$awardref) { + foreach my $award (@$awardref) { if ($award eq '') { $result='MISSING_ANSWER'; $blankcount++; @@ -513,25 +555,31 @@ sub finalizeawards { } if ($blankcount == ($#$awardref + 1)) { $result = 'NO_RESPONSE'; } } - if (defined($result)) { return ($result,$msg); } + if (defined($result)) { return ($result); } # these awards are ordered from most important error through best correct - - my @awards = ('EXTRA_ANSWER', 'MISSING_ANSWER', 'ERROR', 'NO_RESPONSE', - 'TOO_LONG', - 'UNIT_INVALID_INSTRUCTOR', 'UNIT_INVALID_STUDENT', - 'UNIT_IRRECONCIBLE', 'UNIT_FAIL', 'NO_UNIT', - 'UNIT_NOTNEEDED', 'WANTED_NUMERIC', 'BAD_FORMULA', - 'COMMA_FAIL', 'SIG_FAIL', 'INCORRECT', 'MISORDERED_RANK', - 'INVALID_FILETYPE', 'DRAFT', 'SUBMITTED', 'ASSIGNED_SCORE', - 'APPROX_ANS', 'EXACT_ANS'); - if ($reverse) { @awards=reverse(@awards); } - foreach my $possibleaward (@awards) { - ($result,$msg)=&checkstatus($possibleaward,$awardref,$msgref); - if (defined($result)) { return ($result,$msg); } + my $awards = (!$reverse) ? \%fwd_awards : \%rev_awards ; + + my $best = $max; + my $j=0; + my $which; + foreach my $award (@$awardref) { + if ($awards->{$award} < $best) { + $best = $awards->{$award}; + $which = $j; + } + $j++; + } + if (defined($which)) { + if (ref($nameref)) { + return ($$awardref[$which],$$msgref[$which],$$nameref[$which]); + } else { + return ($$awardref[$which],$$msgref[$which]); + } } return ('ERROR',undef); } +} sub decideoutput { my ($award,$awarded,$awardmsg,$solved,$previous,$target)=@_; @@ -580,9 +628,11 @@ sub decideoutput { $message.= $computer; } $added_computer_text=1; - unless ($env{'course.'. + my ($symb) = &Apache::lonnet::whichuser(); + if ((!$env{'course.'. $env{'request.course.id'}. - '.disable_receipt_display'} eq 'yes') { + '.disable_receipt_display'} eq 'yes')&& + $symb) { $message.=(($target eq 'web')?'
':' '). &mt('Your receipt is').' '.&Apache::lonnet::receipt($Apache::inputtags::part). (($target eq 'web')?&Apache::loncommon::help_open_topic('Receipt'):''); @@ -660,10 +710,8 @@ sub decideoutput { $button=1; } elsif ($award eq 'SIG_FAIL') { my ($used,$min,$max)=split(':',$awardmsg); - my $word; - if ($used < $min) { $word=&mt('more'); } - if ($used > $max) { $word=&mt('fewer'); } - $message = &mt("Submission not graded. Use [_2] digits.",$used,$word); + my $word = ($used < $min) ? 'more' : 'fewer'; + $message = &mt("Submission not graded. Use $word digits.",$used); $bgcolor=$possiblecolors{'not_charged_try'}; $button=1; } elsif ($award eq 'UNIT_INVALID_INSTRUCTOR') { @@ -726,7 +774,7 @@ sub decideoutput { $message = &mt("Unknown message").": $award"; $button=1; } - my (undef,undef,$domain,$user)=&Apache::lonxml::whichuser(); + my (undef,undef,$domain,$user)=&Apache::lonnet::whichuser(); foreach my $resid(@Apache::inputtags::response){ if ($Apache::lonhomework::history{"resource.$part.$resid.handback"}) { $message.='
'; @@ -951,10 +999,82 @@ sub grade { return ''; } +sub get_grade_messages { + my ($id,$prefix,$target,$status) = @_; + + my ($message,$latemessage,$trystr,$previousmsg); + my $showbutton = 1; + + my $award = $Apache::lonhomework::history{"$prefix.award"}; + my $awarded = $Apache::lonhomework::history{"$prefix.awarded"}; + my $solved = $Apache::lonhomework::history{"$prefix.solved"}; + my $previous = $Apache::lonhomework::history{"$prefix.previous"}; + my $awardmsg = $Apache::lonhomework::history{"$prefix.awardmsg"}; + &Apache::lonxml::debug("Found Award |$award|$solved|$awardmsg"); + if ( $award ne '' || $solved ne '' || $status eq 'SHOW_ANSWER') { + &Apache::lonxml::debug('Getting message'); + ($showbutton,my $bgcolor,$message,$previousmsg) = + &decideoutput($award,$awarded,$awardmsg,$solved,$previous, + $target); + if ($target eq 'tex') { + $message='\vskip 2 mm '.$message.' '; + } else { + $message="$message"; + if ($previousmsg) { + $previousmsg="$previousmsg"; + } + } + } + my $tries = $Apache::lonhomework::history{"$prefix.tries"}; + my $maxtries = &Apache::lonnet::EXT("resource.$id.maxtries"); + &Apache::lonxml::debug("got maxtries of :$maxtries:"); + #if tries are set to negative turn off the Tries/Button and messages + if (defined($maxtries) && $maxtries < 0) { return ''; } + if ( $tries eq '' ) { $tries = '0'; } + if ( $maxtries eq '' ) { $maxtries = '2'; } + if ( $maxtries eq 'con_lost' ) { $maxtries = '0'; } + my $tries_text=&mt('Tries'); + if ( $Apache::lonhomework::type eq 'survey' || + $Apache::lonhomework::parsing_a_task) { + $tries_text=&mt('Submissions'); + } + + if ($showbutton) { + if ($target eq 'tex') { + if ($env{'request.state'} ne "construct" + && $Apache::lonhomework::type ne 'exam' + && $env{'form.suppress_tries'} ne 'yes') { + $trystr = ' {\vskip 1 mm \small \textit{'.$tries_text.'} '. + $tries.'/'.$maxtries.'} \vskip 2 mm '; + } else { + $trystr = '\vskip 0 mm '; + } + } else { + $trystr = "".$tries_text." $tries"; + if ($Apache::lonhomework::parsing_a_task) { + } elsif($env{'request.state'} ne 'construct') { + $trystr.="/$maxtries"; + } else { + if (defined($Apache::inputtags::params{'maxtries'})) { + $trystr.="/".$Apache::inputtags::params{'maxtries'}; + } + } + $trystr.=""; + } + } + if ($Apache::lonhomework::history{"$prefix.afterduedate"}) { + #last submissions was after due date + $latemessage=&mt(' The last submission was after the Due Date ');; + if ($target eq 'web') { + $latemessage=''.$latemessage.''; + } + } + return ($previousmsg,$latemessage,$message,$trystr,$showbutton); +} + sub gradestatus { my ($id,$target) = @_; my $showbutton = 1; - my $bgcolor = ''; my $message = ''; my $latemessage = ''; my $trystr=''; @@ -968,72 +1088,22 @@ sub gradestatus { && $status ne 'INVALID_ACCESS' && $status ne 'NEEDS_CHECKIN' && $status ne 'NOT_IN_A_SLOT') { - my $award = $Apache::lonhomework::history{"resource.$id.award"}; - my $awarded = $Apache::lonhomework::history{"resource.$id.awarded"}; - my $solved = $Apache::lonhomework::history{"resource.$id.solved"}; - my $previous = $Apache::lonhomework::history{"resource.$id.previous"}; - my $awardmsg = $Apache::lonhomework::history{"resource.$id.awardmsg"}; - &Apache::lonxml::debug("Found Award |$award|$solved|$awardmsg"); - if ( $award ne '' || $solved ne '' || $status eq 'SHOW_ANSWER') { - &Apache::lonxml::debug('Getting message'); - ($showbutton,$bgcolor,$message,$previousmsg) = - &decideoutput($award,$awarded,$awardmsg,$solved,$previous, - $target); - if ($target eq 'tex') { - $message='\vskip 2 mm '.$message.' '; - } else { - $message="$message"; - if ($previousmsg) { - $previousmsg="$previousmsg"; - } - } + + ($previousmsg,$latemessage,$message,$trystr) = + &get_grade_messages($id,"resource.$id",$target,$status, + $showbutton); + if ( $status eq 'SHOW_ANSWER' || $status eq 'CANNOT_ANSWER') { + $showbutton = 0; } - my $tries = $Apache::lonhomework::history{"resource.$id.tries"}; - my $maxtries = &Apache::lonnet::EXT("resource.$id.maxtries"); - &Apache::lonxml::debug("got maxtries of :$maxtries:"); - #if tries are set to negative turn off the Tries/Button and messages - if (defined($maxtries) && $maxtries < 0) { return ''; } - if ( $tries eq '' ) { $tries = '0'; } - if ( $maxtries eq '' ) { $maxtries = '2'; } - if ( $maxtries eq 'con_lost' ) { $maxtries = '0'; } - my $tries_text=&mt('Tries'); - if ( $Apache::lonhomework::type eq 'survey' || - $Apache::lonhomework::parsing_a_task) { - $tries_text=&mt('Submissions'); + if ( $status eq 'SHOW_ANSWER') { + undef($previousmsg); } - if ( $showbutton ) { - if ($target eq 'tex') { - if ($env{'request.state'} ne "construct" && $Apache::lonhomework::type ne 'exam' && $env{'form.suppress_tries'} ne 'yes') { - $trystr = ' {\vskip 1 mm \small \textit{'.$tries_text.'} '.$tries.'/'.$maxtries.'} \vskip 2 mm '; - } else { - $trystr = '\vskip 0 mm '; - } - } else { - $trystr = "".$tries_text." $tries"; - if ($Apache::lonhomework::parsing_a_task) { - } elsif($env{'request.state'} ne 'construct') { - $trystr.="/$maxtries"; - } else { - if (defined($Apache::inputtags::params{'maxtries'})) { - $trystr.="/".$Apache::inputtags::params{'maxtries'}; - } - } - $trystr.=""; - } - } - if ( $status eq 'SHOW_ANSWER' || $status eq 'CANNOT_ANSWER') {$showbutton = 0;} if ( $showbutton ) { if ($target ne 'tex') { - $button = ''; - } - } - if ($Apache::lonhomework::history{"resource.$id.afterduedate"}) { - #last submissions was after due date - $latemessage=&mt(' The last submission was after the Due Date ');; - if ($target eq 'web') { - $latemessage=''.$latemessage.''; + $button = ''; } } + } my $output= $previousmsg.$latemessage.$message.$trystr; if ($output =~ /^\s*$/) { @@ -1042,10 +1112,76 @@ sub gradestatus { if ($target eq 'tex') { return $button.' \vskip 0 mm '.$output.' '; } else { - return ''.$output.'
'.$button.'
'; + return ''.$output.'
'.$button.''.&previous_tries($id,$target).'
'; + } + } +} + +sub previous_tries { + my ($id,$target) = @_; + my $output; + my $status = $Apache::inputtags::status['-1']; + + foreach my $i (1..$Apache::lonhomework::history{'version'}) { + my $prefix = $i.":resource.$id"; + + next if (!exists($Apache::lonhomework::history{"$prefix.award"})); + my ($previousmsg,$latemessage,$message,$trystr); + + ($previousmsg,$latemessage,$message,$trystr) = + &get_grade_messages($id,"$prefix",$target,$status); + if (!exists($Apache::lonhomework::history{"$prefix.tries"})) { + undef($trystr); + } + + if ($previousmsg eq '') { $previousmsg=''; } + if ($trystr eq '') { $trystr = ''; } + + $output.=''; + $output.=$message.$previousmsg.$trystr; + + foreach my $resid (@Apache::inputtags::response) { + my $prefix = $prefix.".$resid"; + if (exists($Apache::lonhomework::history{"$prefix.submission"})) { + my $submission = + $Apache::inputtags::submission_display{"$prefix.submission"}; + if (!defined($submission)) { + $submission = + $Apache::lonhomework::history{"$prefix.submission"}; + } + $output.=''.$submission.''; + } else { + $output.=''; + } } + $output.=''; } + return if ($output eq ''); + + $output =''.$output.'
'; + #return $output; + $output=~s/\\/\\\\/g; + $output=~s/\'/\\\'/g; + $output=~s/\s+/ /g; + my $windowopen=&Apache::lonhtmlcommon::javascript_docopen(); + my $start_page = + &Apache::loncommon::start_page('Previous Tries', undef, + {'only_body' => 1, + 'bgcolor' => '#FFFFFF', + 'js_ready' => 1,}); + my $end_page = + &Apache::loncommon::end_page({'js_ready' => 1,}); + + my $result ="".&mt("Previous Tries")."
"; + #use Data::Dumper; + #&Apache::lonnet::logthis(&Dumper(\%Apache::inputtags::submission_display)); + return $result; } + 1; __END__