--- loncom/homework/grades.pm 2009/12/27 01:00:44 1.574.2.4 +++ loncom/homework/grades.pm 2009/12/15 18:26:18 1.584 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # The LON-CAPA Grading handler # -# $Id: grades.pm,v 1.574.2.4 2009/12/27 01:00:44 raeburn Exp $ +# $Id: grades.pm,v 1.584 2009/12/15 18:26:18 bisitz Exp $ # # Copyright Michigan State University Board of Trustees # @@ -97,9 +97,15 @@ sub ssi_print_error { # # --- Retrieve the parts from the metadata file.--- sub getpartlist { - my ($symb) = @_; + my ($symb,$errorref) = @_; my $navmap = Apache::lonnavmaps::navmap->new(); + unless (ref($navmap)) { + if (ref($errorref)) { + $$errorref = 'navmap'; + return; + } + } my $res = $navmap->getBySymb($symb); my $partlist = $res->parts(); my $url = $res->src(); @@ -144,9 +150,15 @@ sub nameUserString { #--- Get the partlist and the response type for a given problem. --- #--- Indicate if a response type is coded handgraded or not. --- sub response_type { - my ($symb) = shift; + my ($symb,$response_error) = @_; my $navmap = Apache::lonnavmaps::navmap->new(); + unless (ref($navmap)) { + if (ref($response_error)) { + $$response_error = 1; + } + return; + } my $res = $navmap->getBySymb($symb); my $partlist = $res->parts(); my %vPart = @@ -183,7 +195,8 @@ sub get_display_part { my ($partID,$symb)=@_; my $display=&Apache::lonnet::EXT('resource.'.$partID.'.display',$symb); if (defined($display) and $display ne '') { - $display.= " (id $partID)"; + $display.= ' (' + .&mt('Part ID: [_1]',$partID).')'; } else { $display=$partID; } @@ -193,37 +206,49 @@ sub get_display_part { #--- Show resource title #--- and parts and response type sub showResourceInfo { - my ($symb,$probTitle,$checkboxes) = @_; - my $col=3; - if ($checkboxes) { $col=4; } + my ($symb,$probTitle,$checkboxes,$res_error) = @_; my $result = '

'.&mt('Current Resource').': '.$probTitle.'

'."\n"; - $result .=''; - my ($partlist,$handgrade,$responseType) = &response_type($symb); + my ($partlist,$handgrade,$responseType) = &response_type($symb,$res_error); + if (ref($res_error)) { + if ($$res_error) { + return; + } + } + $result.=&Apache::loncommon::start_data_table() + .&Apache::loncommon::start_data_table_header_row(); + if ($checkboxes) { + $result.=''; + } + $result.='' + .'' + .'' + .&Apache::loncommon::end_data_table_header_row(); my %resptype = (); my $hdgrade='no'; my %partsseen; foreach my $partID (sort(keys(%$responseType))) { - foreach my $resID (sort(keys(%{ $responseType->{$partID} }))) { - my $handgrade=$$handgrade{$partID.'_'.$resID}; - my $responsetype = $responseType->{$partID}->{$resID}; - $hdgrade = $handgrade if ($handgrade eq 'yes'); - $result.=''; - if ($checkboxes) { - if (exists($partsseen{$partID})) { - $result.=""; - } else { - $result.=""; - } - $partsseen{$partID}=1; - } - my $display_part=&get_display_part($partID,$symb); - $result.=''. - ''; -# ''; - } + foreach my $resID (sort(keys(%{ $responseType->{$partID} }))) { + my $handgrade=$$handgrade{$partID.'_'.$resID}; + my $responsetype = $responseType->{$partID}->{$resID}; + $hdgrade = $handgrade if ($handgrade eq 'yes'); + $result.=&Apache::loncommon::start_data_table_row(); + if ($checkboxes) { + if (exists($partsseen{$partID})) { + $result.=""; + } else { + $result.=""; + } + $partsseen{$partID}=1; + } + my $display_part=&get_display_part($partID,$symb); + $result.='' + .'' + .'' +# .'' + .&Apache::loncommon::end_data_table_row(); + } } - $result.='
 '.&mt('Problem Part').''.&mt('Res. ID').''.&mt('Type').'
 '.&mt('Part').': '.$display_part. - ' '.$resID.''.&mt('Type').': '.$responsetype.'
'.&mt('Handgrade: [_1]',$handgrade).'
 '.$display_part.''.''.$resID.''.&mt($responsetype).''.&mt('Handgrade: [_1]',$handgrade).'
'."\n"; + $result.=&Apache::loncommon::end_data_table(); return $result,$responseType,$hdgrade,$partlist,$handgrade; } @@ -754,7 +779,7 @@ sub verifyreceipt { my $title.= '

'. - &mt('Verifying Receipt No. [_1]',$receipt). + &mt('Verifying Receipt No. [_1]',$receipt). '

'."\n". '

'.&mt('Resource: [_1]',$env{'form.probTitle'}). '

'."\n"; @@ -766,7 +791,13 @@ sub verifyreceipt { if ($env{"course.$courseid.receiptalg"} eq 'receipt2' || $env{"course.$courseid.receiptalg"} eq 'receipt3') { $receiptparts=1; } my $parts=['0']; - if ($receiptparts) { ($parts)=&response_type($symb); } + if ($receiptparts) { + my $res_error; + ($parts)=&response_type($symb,\$res_error); + if ($res_error) { + return &navmap_errormsg(); + } + } my $header = &Apache::loncommon::start_data_table(). @@ -808,11 +839,14 @@ sub verifyreceipt { } } if ($matches == 0) { - $string = $title.&mt('No match found for the above receipt.'); + $string = $title + .'

' + .&mt('No match found for the above receipt number.') + .'

'; } else { $string = &jscriptNform($symb).$title. '

'. - &mt('The above receipt matches the following [numerate,_1,student].',$matches). + &mt('The above receipt number matches the following [quant,_1,student].',$matches). '

'. $header. $contents. @@ -1734,7 +1768,7 @@ sub gradeBox { #&mt('Part:[_1]Points:[_2]or[_3]',$display_part,$radio,$line); $result .= - ''.&mt('Part').':'.$display_part.''.&mt('Points').':'.$radio.''.&mt('or').''.$line.''; + ''.&mt('Part:').''.$display_part.''.&mt('Points:').''.$radio.''.&mt('or').''.$line.''; $result.=''."\n"; $result.=''."\n". ''."\n". @@ -1744,13 +1778,17 @@ sub gradeBox { $$record{'resource.'.$partid.'.tries'}.'" />'."\n". ''."\n"; - $result.=&handback_box($symb,$uname,$udom,$counter,$partid,$record); + my $res_error; + $result.=&handback_box($symb,$uname,$udom,$counter,$partid,$record,\$res_error); + if ($res_error) { + return &navmap_errormsg(); + } return $result; } sub handback_box { - my ($symb,$uname,$udom,$counter,$partid,$record) = @_; - my ($partlist,$handgrade,$responseType) = &response_type($symb); + my ($symb,$uname,$udom,$counter,$partid,$record,$res_error) = @_; + my ($partlist,$handgrade,$responseType) = &response_type($symb,$res_error); my (@respids); my @part_response_id = &flatten_responseType($responseType); foreach my $part_response_id (@part_response_id) { @@ -2045,7 +2083,12 @@ KEYWORDS } my %record = &Apache::lonnet::restore($symb,$env{'request.course.id'},$udom,$uname); - my ($partlist,$handgrade,$responseType) = &response_type($symb); + my $res_error; + my ($partlist,$handgrade,$responseType) = &response_type($symb,\$res_error); + if ($res_error) { + $request->print(&navmap_errormsg()); + return; + } # Display student info $request->print(($counter == 0 ? '' : '
')); @@ -2112,9 +2155,11 @@ KEYWORDS } my $responsetype = $responseType->{$partid}->{$respid}; if (!exists($record{"resource.$partid.$respid.submission"})) { - $lastsubonly.="\n".'
Part: '. - $display_part.' ( ID '.$respid. - ' )   '. + $lastsubonly.="\n".'
'. + ''.&mt('Part: [_1]',$display_part).''. + ' '. + '('.&mt('Part ID: [_1]',$respid).')'. + '   '. ''.&mt('Nothing submitted - no attempts.').'

'; next; } @@ -2150,9 +2195,11 @@ KEYWORDS ($env{'form.lastSub'} eq 'hdgrade' && $$handgrade{$$part[0].'_'.$$part[1]} eq 'yes')) { my $display_part=&get_display_part($partid,$symb); - $lastsubonly.='
Part: '. - $display_part.' ( ID '.$respid. - ' )   '; + $lastsubonly.='
'. + ''.&mt('Part: [_1]',$display_part).''. + ' '. + '('.&mt('Part ID: [_1]',$respid).')'. + '   '; my $files=&get_submitted_files($udom,$uname,$partid,$respid,\%record); if (@$files) { $lastsubonly.='
'.&mt('Like all files provided by users, this file may contain viruses').'
'; @@ -2592,7 +2639,12 @@ sub processHandGrade { } $ctr = 0; @parsedlist = reverse @parsedlist if ($button eq 'Previous'); - my ($partlist) = &response_type($symb); + my $res_error; + my ($partlist) = &response_type($symb,\$res_error); + if ($res_error) { + $request->print(&navmap_errormsg()); + return; + } foreach my $student (@parsedlist) { my $submitonly=$env{'form.submitonly'}; my ($uname,$udom) = split(/:/,$student); @@ -2790,8 +2842,12 @@ sub check_and_remove_from_queue { sub handback_files { my ($request,$symb,$stuname,$domain,$newflg,$new_part,$newrecord) = @_; my $portfolio_root = '/userfiles/portfolio'; - my ($partlist,$handgrade,$responseType) = &response_type($symb); - + my $res_error; + my ($partlist,$handgrade,$responseType) = &response_type($symb,\$res_error); + if ($res_error) { + $request->print('
'.&navmap_errormsg().'
'); + return; + } my @part_response_id = &flatten_responseType($responseType); foreach my $part_response_id (@part_response_id) { my ($part_id,$resp_id) = @{ $part_response_id }; @@ -3249,7 +3305,11 @@ sub viewgrades { $result.= '

'.$common_header.'

'.&Apache::loncommon::start_data_table(); #radio buttons/text box for assigning points for a section or class. #handles different parts of a problem - my ($partlist,$handgrade,$responseType) = &response_type($symb); + my $res_error; + my ($partlist,$handgrade,$responseType) = &response_type($symb,\$res_error); + if ($res_error) { + return &navmap_errormsg(); + } my %weight = (); my $ctsparts = 0; my %seen = (); @@ -3293,7 +3353,7 @@ sub viewgrades { $result.= &Apache::loncommon::start_data_table_row()."\n". - ''.&mt('Part').':'.$display_part.''.&mt('Points').':'.$radio.''.&mt('or').''.$line.''. + ''.&mt('Part:').''.$display_part.''.&mt('Points:').''.$radio.''.&mt('or').''.$line.''. &Apache::loncommon::end_data_table_row()."\n"; $ctsparts++; } @@ -3309,7 +3369,11 @@ sub viewgrades { &Apache::loncommon::start_data_table_header_row(). ''.&mt('No.').''. ''.&nameUserString('header')."\n"; - my (@parts) = sort(&getpartlist($symb)); + my $partserror; + my (@parts) = sort(&getpartlist($symb,\$partserror)); + if ($partserror) { + return &navmap_errormsg(); + } my (undef,undef,$url)=&Apache::lonnet::decode_symb($symb); my @partids = (); foreach my $part (@parts) { @@ -3468,7 +3532,11 @@ sub editgrades { my %columns = (); my ($i,$ctr,$count,$rec_update) = (0,0,0,0); - my (@parts) = sort(&getpartlist($symb)); + my $partserror; + my (@parts) = sort(&getpartlist($symb,\$partserror)); + if ($partserror) { + return &navmap_errormsg(); + } my $header; while ($ctr < $env{'form.totalparts'}) { my $partid = $env{'form.partid_'.$ctr}; @@ -3800,8 +3868,14 @@ ENDPICK } sub csvupload_fields { - my ($symb) = @_; - my (@parts) = &getpartlist($symb); + my ($symb,$errorref) = @_; + my (@parts) = &getpartlist($symb,$errorref); + if (ref($errorref)) { + if ($$errorref) { + return; + } + } + my @fields=(['ID','Student/Employee ID'], ['username','Student Username'], ['domain','Student Domain']); @@ -3901,8 +3975,12 @@ sub csvuploadmap { &csvuploadmap_header($request,$symb,$datatoken,$#records+1); my ($i,$keyfields); if (@records) { - my @fields=&csvupload_fields($symb); - + my $fieldserror; + my @fields=&csvupload_fields($symb,\$fieldserror); + if ($fieldserror) { + $request->print(&navmap_errormsg()); + return; + } if ($env{'form.upfile_associate'} eq 'reverse') { &Apache::loncommon::csv_print_samples($request,\@records); $i=&Apache::loncommon::csv_print_select_table($request,\@records, @@ -4138,7 +4216,12 @@ LISTJAVASCRIPT &mt('Manual Grading by Page or Sequence').''; $result.='
'."\n"; - my ($titles,$symbx) = &getSymbMap(); + my $map_error; + my ($titles,$symbx) = &getSymbMap($map_error); + if ($map_error) { + $request->print(&navmap_errormsg()); + return; + } my ($curpage) =&Apache::lonnet::decode_symb($symb); # my ($curpage,$mapId) =&Apache::lonnet::decode_symb($symb); # my $type=($curpage =~ /\.(page|sequence)/); @@ -4233,8 +4316,14 @@ LISTJAVASCRIPT } sub getSymbMap { + my ($map_error) = @_; my $navmap = Apache::lonnavmaps::navmap->new(); - + unless (ref($navmap)) { + if (ref($map_error)) { + $$map_error = 'navmap'; + } + return; + } my %symbx = (); my @titles = (); my $minder = 0; @@ -4293,6 +4382,11 @@ sub displayPage { $request->print($result); my $navmap = Apache::lonnavmaps::navmap->new(); + unless (ref($navmap)) { + $request->print(&navmap_errormsg()); + $request->print(&show_grading_menu_form($symb)); + return; + } my ($mapUrl, $id, $resUrl)=&Apache::lonnet::decode_symb($env{'form.page'}); my $map = $navmap->getResourceByUrl($resUrl); # add to navmaps if (!$map) { @@ -4465,13 +4559,16 @@ sub displaySubByDates { my ($responseId)= ($isTask ? ($matchKey=~ /^resource\.(.*?)\.\Q$partid\E\.award$/) : ($matchKey=~ /^resource\.\Q$partid\E\.(.*?)\.submission$/)); - $displaySub[0].=''.&mt('Part:').' '.$display_part.' '; - $displaySub[0].='('.&mt('ID').' '. - $responseId.') '; + $displaySub[0].='' + .' ' + .'('.&mt('Part ID: [_1]',$responseId).')' + .'' + .' '; if ($$record{"$where.$partid.tries"} eq '') { - $displaySub[0].=&mt('Trial not counted'); + $displaySub[0].=&mt('Trial not counted'); } else { - $displaySub[0].=&mt('Trial [_1]', + $displaySub[0].=&mt('Trial: [_1]', $$record{"$where.$partid.tries"}); } my $responseType=($isTask ? 'Task' @@ -4482,7 +4579,8 @@ sub displaySubByDates { &get_order($partid,$responseId,$symb,$uname,$udom, $no_increment); } - $displaySub[0].='  '. + $displaySub[0].=''; # /nobreak + $displaySub[0].='  '. &cleanRecord($$record{$version.':'.$matchKey},$responseType,$symb,$partid,$responseId,$record,$orders{$partid}->{$responseId},"$version:",$uname,$udom).'
'; } } @@ -4543,7 +4641,12 @@ sub updateGradeByPage { $request->print($result); + my $navmap = Apache::lonnavmaps::navmap->new(); + unless (ref($navmap)) { + $request->print(&navmap_errormsg()); + return; + } my ($mapUrl, $id, $resUrl) = &Apache::lonnet::decode_symb( $env{'form.page'}); my $map = $navmap->getResourceByUrl($resUrl); # add to navmaps if (!$map) { @@ -4688,7 +4791,7 @@ sub updateGradeByPage { # #------------------------------------------------------------------- -#--------------------Scantron Grading----------------------------------- +#-------------------- Bubblesheet (Scantron) Grading ------------------- # #------ start of section for handling grading by page/sequence --------- @@ -4766,14 +4869,19 @@ sub defaultFormData { Return html dropdown of possible sequences to grade Arguments: - $symb - $symb of the current resource + $symb - $symb of the current resource + $map_error - ref to scalar which will container error if + $navmap object is unavailable in &getSymbMap(). =cut sub getSequenceDropDown { - my ($symb)=@_; + my ($symb,$map_error)=@_; my $result=''."\n". - ''."\n". + ''."\n". ''."\n". &Apache::loncommon::end_data_table_row()."\n". &Apache::loncommon::end_data_table()."\n". @@ -6213,7 +6326,12 @@ sub scantron_validate_file { $r->print('

'.&mt('Gathering necessary information.').'

');$r->rflush(); #get the student pick code ready $r->print(&Apache::loncommon::studentbrowser_javascript()); - my $max_bubble=&scantron_get_maxbubble(); + my $nav_error; + my $max_bubble=&scantron_get_maxbubble(\$nav_error); + if ($nav_error) { + $r->print(&navmap_errormsg()); + return ''; + } my $result=&scantron_form_start($max_bubble).$default_form_data; $r->print($result); @@ -6625,6 +6743,10 @@ sub scantron_validate_sequence { my ($r,$currentphase) = @_; my $navmap=Apache::lonnavmaps::navmap->new(); + unless (ref($navmap)) { + $r->print(&navmap_errormsg()); + return (1,$currentphase); + } my (undef,undef,$sequence)= &Apache::lonnet::decode_symb($env{'form.selectpage'}); @@ -6656,8 +6778,13 @@ sub scantron_validate_ID { #get scantron line setup my %scantron_config=&get_scantron_config($env{'form.scantron_format'}); my ($scanlines,$scan_data)=&scantron_getfile(); - - &scantron_get_maxbubble(); # parse needs the bubble_lines.. array. + + my $nav_error; + &scantron_get_maxbubble(\$nav_error); # parse needs the bubble_lines.. array. + if ($nav_error) { + $r->print(&navmap_errormsg()); + return(1,$currentphase); + } my %found=('ids'=>{},'usernames'=>{}); for (my $i=0;$i<=$scanlines->{'count'};$i++) { @@ -7210,7 +7337,12 @@ sub scantron_validate_CODE { my %allcodes=&get_codes(); - &scantron_get_maxbubble(); # parse needs the lines per response array. + my $nav_error; + &scantron_get_maxbubble(\$nav_error); # parse needs the lines per response array. + if ($nav_error) { + $r->print(&navmap_errormsg()); + return(1,$currentphase); + } my ($scanlines,$scan_data)=&scantron_getfile(); for (my $i=0;$i<=$scanlines->{'count'};$i++) { @@ -7264,7 +7396,12 @@ sub scantron_validate_doublebubble { #get scantron line setup my %scantron_config=&get_scantron_config($env{'form.scantron_format'}); my ($scanlines,$scan_data)=&scantron_getfile(); - &scantron_get_maxbubble(); # parse needs the bubble line array. + my $nav_error; + &scantron_get_maxbubble(\$nav_error); # parse needs the bubble line array. + if ($nav_error) { + $r->print(&navmap_errormsg()); + return(1,$currentphase); + } for (my $i=0;$i<=$scanlines->{'count'};$i++) { my $line=&scantron_get_line($scanlines,$scan_data,$i); @@ -7282,6 +7419,7 @@ sub scantron_validate_doublebubble { sub scantron_get_maxbubble { + my ($nav_error) = @_; if (defined($env{'form.scantron_maxbubble'}) && $env{'form.scantron_maxbubble'}) { &restore_bubble_lines(); @@ -7292,6 +7430,11 @@ sub scantron_get_maxbubble { &Apache::lonnet::decode_symb($env{'form.selectpage'}); my $navmap=Apache::lonnavmaps::navmap->new(); + unless (ref($navmap)) { + if (ref($nav_error)) { + $$nav_error = 1; + } + } my $map=$navmap->getResourceByUrl($sequence); my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0); @@ -7381,7 +7524,11 @@ sub scantron_validate_missingbubbles { #get scantron line setup my %scantron_config=&get_scantron_config($env{'form.scantron_format'}); my ($scanlines,$scan_data)=&scantron_getfile(); - my $max_bubble=&scantron_get_maxbubble(); + my $nav_error; + my $max_bubble=&scantron_get_maxbubble(\$nav_error); + if ($nav_error) { + return(1,$currentphase); + } if (!$max_bubble) { $max_bubble=2**31; } for (my $i=0;$i<=$scanlines->{'count'};$i++) { my $line=&scantron_get_line($scanlines,$scan_data,$i); @@ -7441,6 +7588,10 @@ sub scantron_process_students { my $classlist=&Apache::loncoursedata::get_classlist(); my %idmap=&username_to_idmap($classlist); my $navmap=Apache::lonnavmaps::navmap->new(); + unless (ref($navmap)) { + $r->print(&navmap_errormsg()); + return ''; + } my $map=$navmap->getResourceByUrl($sequence); my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0); my (%grader_partids_by_symb,%grader_randomlists_by_symb); @@ -7473,8 +7624,8 @@ SCANTRONFORM my $lock=&Apache::lonnet::set_lock(&mt('Grading bubblesheet exam')); my $count=&get_todo_count($scanlines,$scan_data); - my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Scantron Status', - 'Scantron Progress',$count, + my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Bubblesheet Status', + 'Bubblesheet Progress',$count, 'inline',undef,'scantronupload'); &Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state, 'Processing first student'); @@ -7483,7 +7634,12 @@ SCANTRONFORM my $i=-1; my $started; - &scantron_get_maxbubble(); # Need the bubble lines array to parse. + my $nav_error; + &scantron_get_maxbubble(\$nav_error); # Need the bubble lines array to parse. + if ($nav_error) { + $r->print(&navmap_errormsg()); + return ''; + } # If an ssi failed in scantron_get_maxbubble, put an error message out to # the user and return. @@ -7760,7 +7916,7 @@ sub scantron_upload_scantron_data { &Apache::lonhtmlcommon::end_pick_box().'
- +
'); return ''; @@ -7778,7 +7934,7 @@ sub scantron_upload_scantron_data_save { if (!&Apache::lonnet::allowed('usc',$env{'form.domainid'}) && !&Apache::lonnet::allowed('usc', $env{'form.domainid'}.'_'.$env{'form.courseid'})) { - $r->print(&mt("You are not allowed to upload Scantron data to the requested course.")."
"); + $r->print(&mt("You are not allowed to upload bubblesheet data to the requested course.")."
"); if ($symb) { $r->print(&show_grading_menu_form($symb)); } else { @@ -7967,6 +8123,10 @@ sub checkscantron_results { my $classlist=&Apache::loncoursedata::get_classlist(); my %idmap=&Apache::grades::username_to_idmap($classlist); my $navmap=Apache::lonnavmaps::navmap->new(); + unless (ref($navmap)) { + $r->print(&navmap_errormsg()); + return ''; + } my $map=$navmap->getResourceByUrl($sequence); my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0); my (%grader_partids_by_symb,%grader_randomlists_by_symb); @@ -7981,12 +8141,16 @@ sub checkscantron_results { my %completedstudents; my $count=&Apache::grades::get_todo_count($scanlines,$scan_data); - my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Scantron/Submissions Comparison Status', - 'Progress of Scantron Data/Submission Records Comparison',$count, + my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Bubblesheet/Submissions Comparison Status', + 'Progress of Bubblesheet Data/Submission Records Comparison',$count, 'inline',undef,'checkscantron'); my ($username,$domain,$started); - - &scantron_get_maxbubble(); # Need the bubble lines array to parse. + my $nav_error; + &scantron_get_maxbubble(\$nav_error); # Need the bubble lines array to parse. + if ($nav_error) { + $r->print(&navmap_errormsg()); + return ''; + } &Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state, 'Processing first student'); @@ -8059,14 +8223,14 @@ sub checkscantron_results { if ($scandata{$pid} eq $record{$pid}) { my $css_class = ($passed % 2)?'LC_odd_row':'LC_even_row'; $okstudents .= ''. -''.&mt('Scantron').''.$showscandata.''.$last.''.$pid.''."\n". +''.&mt('Bubblesheet').''.$showscandata.''.$last.''.$pid.''."\n". ''."\n". ''."\n". 'Submissions'.$showrecord.''."\n"; $passed ++; } else { my $css_class = ($failed % 2)?'LC_odd_row':'LC_even_row'; - $badstudents .= ''.&mt('Scantron').''.$scandata{$pid}.''.$last.''.$pid.''."\n". + $badstudents .= ''.&mt('Bubblesheet').''.$scandata{$pid}.''.$last.''.$pid.''."\n". ''."\n". ''."\n". 'Submissions'.$record{$pid}.''."\n". @@ -8279,36 +8443,50 @@ sub grading_menu { 'saveState'=>"", 'gradingMenu'=>1, 'showgrading'=>"yes"); - my $url = &Apache::lonhtmlcommon::build_url('grades/',\%fields); - my @menu = ({ url => $url, - name => &mt('Manual Grading/View Submissions'), - short_description => - &mt('Start the process of hand grading submissions.'), - }); + + my $url1 = &Apache::lonhtmlcommon::build_url('grades/',\%fields); + $fields{'command'} = 'csvform'; - $url = &Apache::lonhtmlcommon::build_url('grades/',\%fields); - push(@menu, { url => $url, - name => &mt('Upload Scores'), - short_description => - &mt('Specify a file containing the class scores for current resource.')}); + my $url2 = &Apache::lonhtmlcommon::build_url('grades/',\%fields); + $fields{'command'} = 'processclicker'; - $url = &Apache::lonhtmlcommon::build_url('grades/',\%fields); - push(@menu, { url => $url, - name => &mt('Process Clicker'), - short_description => - &mt('Specify a file containing the clicker information for this resource.')}); + my $url3 = &Apache::lonhtmlcommon::build_url('grades/',\%fields); + $fields{'command'} = 'scantron_selectphase'; - $url = &Apache::lonhtmlcommon::build_url('grades/',\%fields); - push(@menu, { url => $url, - name => &mt('Grade/Manage/Review Scantron Forms'), - short_description => - &mt('Grade scantron exams, upload/download scantron data files, and review previously graded scantron exams.')}); - $fields{'command'} = 'verify'; - $url = &Apache::lonhtmlcommon::build_url('grades/',\%fields); - push(@menu, { url => "", - name => &mt('Verify Receipt'), - short_description => - &mt('')}); + my $url4 = &Apache::lonhtmlcommon::build_url('grades/',\%fields); + + my @menu = ({ categorytitle=>'Course Grading', + items =>[ + { linktext => 'Manual Grading/View Submissions', + url => $url1, + permission => 'F', + icon => 'edit-find-replace.png', + linktitle => 'Start the process of hand grading submissions.' + }, + { linktext => 'Upload Scores', + url => $url2, + permission => 'F', + icon => 'uploadscores.png', + linktitle => 'Specify a file containing the class scores for current resource.' + }, + { linktext => 'Process Clicker', + url => $url3, + permission => 'F', + icon => 'addClickerInfoFile.png', + linktitle => 'Specify a file containing the clicker information for this resource.' + }, + { linktext => 'Grade/Manage/Review Bubblesheet Forms', + url => $url4, + permission => 'F', + icon => 'stat.png', + linktitle => 'Grade scantron exams, upload/download scantron data files, and review previously graded scantron exams.' + } + ] + }); + + #$fields{'command'} = 'verify'; + #$url = &Apache::lonhtmlcommon::build_url('grades/',\%fields); + # # Create the menu my $Str; # $Str .= '

'.&mt('Please select a grading task').'

'; @@ -8320,24 +8498,15 @@ sub grading_menu { ''."\n". ''."\n". ''."\n"; - foreach my $menudata (@menu) { - if ($menudata->{'name'} ne &mt('Verify Receipt')) { - $Str .='

{'jscript'}. - ' href="'. - $menudata->{'url'}.'" >'. - $menudata->{'name'}."

\n"; - } else { - $Str .='
{'jscript'}. - ' onClick="javascript:checkChoice(document.forms.gradingMenu,\'5\',\'verify\')" '. - ' /> '. - &Apache::lonnet::recprefix($env{'request.course.id'}). - '-'; - } - $Str .= ' '.(' 'x8).$menudata->{'short_description'}. - "\n"; - } + + $Str .= Apache::lonhtmlcommon::generate_menu(@menu); + #$menudata->{'jscript'} + $Str .='
'. + &Apache::lonnet::recprefix($env{'request.course.id'}). + '-'; + $Str .="\n"; my $receiptalert = &mt("Please enter a receipt number given by a student in the receipt box."); $request->print(<'."\n"; $result.=' -
-
-

- '.&mt('Grade Current Resource').' -

-
-
- '.$table.' -
-
-
- '.&mt('Sections').' -
-
- '."\n"; + $result.= $selsec; $result.= '   '; $result.=' -
-
-
-
- '.&mt('Groups').' -
-
- '.&Apache::lonstatistics::GroupSelect('group','multiple',5).' -
-
-
-
- '.&mt('Access Status').' -
-
- '.&Apache::lonhtmlcommon::StatusOptions($saveStatus,undef,5,undef,'mult').' -
-
-
-
- '.&mt('Submission Status').' -
-
- + + + + - -
-
-
-
+ + + +
+ +
+
+
+
-
-
-
-
+ +

'.&mt('Grade Complete Folder for One Student').'

-
-
-
+
+
-
- +
+
-
-
-
'; $result .= &show_grading_menu_form($symb); return $result; @@ -8986,7 +9144,11 @@ sub assign_clicker_grades { my ($symb)=&get_symb($r); if (!$symb) {return '';} # See which part we are saving to - my ($partlist,$handgrade,$responseType) = &response_type($symb); + my $res_error; + my ($partlist,$handgrade,$responseType) = &response_type($symb,\$res_error); + if ($res_error) { + return &navmap_errormsg(); + } # FIXME: This should probably look for the first handgradeable part my $part=$$partlist[0]; # Start screen output @@ -9050,13 +9212,13 @@ ENDHEADER my $sum=0; my $realnumber=$number; for (my $i=0;$i<$number;$i++) { - if ($answer[$i]) { + if ($correct[$i] eq '-') { + $realnumber--; + } elsif ($answer[$i]) { if ($gradingmechanism eq 'attendance') { $sum+=$pcorrect; - } elsif ($answer[$i] eq '*') { + } elsif ($correct[$i] eq '*') { $sum+=$pcorrect; - } elsif ($answer[$i] eq '-') { - $realnumber--; } else { if ($answer[$i] eq $correct[$i]) { $sum+=$pcorrect; @@ -9090,6 +9252,13 @@ ENDHEADER return $result.&show_grading_menu_form($symb); } +sub navmap_errormsg { + return '
'. + &mt('An error occurred retrieving information about resources in the course.').'
'. + &mt('It is recommended that you [_1]re-initialize the course[_2] and then return to this grading page..','',''). + '
'; +} + sub handler { my $request=$_[0]; &reset_caches(); @@ -9315,6 +9484,13 @@ ssi_with_retries() =item scantron_get_maxbubble() : + Arguments: + $nav_error - Reference to scalar which is a flag to indicate a + failure to retrieve a navmap object. + if $nav_error is set to 1 by scantron_get_maxbubble(), the + calling routine should trap the error condition and display the warning + found in &navmap_errormsg(). + Returns the maximum number of bubble lines that are expected to occur. Does this by walking the selected sequence rendering the resource and then checking &Apache::lonxml::get_problem_counter() @@ -9380,6 +9556,11 @@ ssi_with_retries() Validates all scanlines in the selected file to not have any invalid or underspecified student/employee IDs +=item navmap_errormsg() : + + Returns HTML mark-up inside a
with a link to re-initialize the course. + Should be called whenever the request to instantiate a navmap object fails. + =back =cut