--- loncom/homework/grades.pm 2009/12/27 01:00:44 1.574.2.4
+++ loncom/homework/grades.pm 2010/04/01 02:28:27 1.574.2.10
@@ -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.574.2.10 2010/04/01 02:28:27 raeburn 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 =
@@ -193,12 +205,17 @@ sub get_display_part {
#--- Show resource title
#--- and parts and response type
sub showResourceInfo {
- my ($symb,$probTitle,$checkboxes) = @_;
+ my ($symb,$probTitle,$checkboxes,$res_error) = @_;
my $col=3;
if ($checkboxes) { $col=4; }
my $result = '
'.&mt('Current Resource').': '.$probTitle.'
'."\n";
+ my ($partlist,$handgrade,$responseType) = &response_type($symb,$res_error);
+ if (ref($res_error)) {
+ if ($$res_error) {
+ return;
+ }
+ }
$result .='
';
- my ($partlist,$handgrade,$responseType) = &response_type($symb);
my %resptype = ();
my $hdgrade='no';
my %partsseen;
@@ -754,7 +771,7 @@ sub verifyreceipt {
my $title.=
'
'."\n";
@@ -766,7 +783,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 +831,11 @@ 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 [numerate,_1,student].',$matches).
'
'."\n";
@@ -1744,15 +1765,19 @@ 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);
+ my @part_response_id = &flatten_responseType($responseType);
foreach my $part_response_id (@part_response_id) {
my ($part,$resp) = @{ $part_response_id };
if ($part eq $partid) {
@@ -2045,7 +2070,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 ? '' : ' '));
@@ -2592,7 +2622,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 +2825,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 +3288,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 = ();
@@ -3309,7 +3352,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 +3515,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};
@@ -3801,7 +3852,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 +3959,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 +4200,12 @@ LISTJAVASCRIPT
&mt('Manual Grading by Page or Sequence').'';
$result.='
');
return '';
@@ -7778,7 +7938,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 +8127,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 +8145,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 +8227,14 @@ sub checkscantron_results {
if ($scandata{$pid} eq $record{$pid}) {
my $css_class = ($passed % 2)?'LC_odd_row':'LC_even_row';
$okstudents .= '
\n";
} else {
- $Str .='{'jscript'}.
' onClick="javascript:checkChoice(document.forms.gradingMenu,\'5\',\'verify\')" '.
' /> '.
@@ -8986,7 +9154,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 +9222,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 +9262,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 +9494,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 +9566,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