--- loncom/homework/grades.pm 2009/12/27 01:00:44 1.574.2.4
+++ loncom/homework/grades.pm 2009/12/27 01:25:26 1.586
@@ -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.586 2009/12/27 01:25:26 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 =
@@ -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.='
'.&mt('Problem Part').'
'
+ .'
'.&mt('Res. ID').'
'
+ .'
'.&mt('Type').'
'
+ .&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.="
'.
- &mt('The above receipt matches the following [numerate,_1,student].',$matches).
+ &mt('The above receipt number matches the following [quant,_1,student].',$matches).
'
'
+ .&Apache::loncommon::end_data_table_header_row()
+ );
+}
+
+sub gradeBox_end {
+ return (
+ &Apache::loncommon::end_data_table()
+ );
+}
#--- displays the grading box, used in essay type problem and grading by page/sequence
sub gradeBox {
my ($request,$symb,$uname,$udom,$counter,$partid,$record) = @_;
@@ -1696,7 +1749,7 @@ sub gradeBox {
if ($last_resets{$partid}) {
$aggtries = &get_num_tries($record,$last_resets{$partid},$partid);
}
- $result.='
';
+ $result.=&Apache::loncommon::start_data_table_row();
my $ctr = 0;
my $thisweight = 0;
my $increment = &get_increment();
@@ -1719,8 +1772,8 @@ sub gradeBox {
$wgt.')" />'."\n";
$line.='
'.
+ ''.&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').' ';
@@ -2234,11 +2300,12 @@ KEYWORDS
my @partlist;
my @gradePartRespid;
my @part_response_id = &flatten_responseType($responseType);
- $request->print('
'.
-
- '
'.
- &mt('Assign Grades').'
'.
- '
');
+ $request->print(
+ '
'
+ .'
'
+ .&mt('Assign Grades').'
'
+ );
+ $request->print(&gradeBox_start()); #
foreach my $part_response_id (@part_response_id) {
my ($partid,$respid) = @{ $part_response_id };
my $part_resp = join('_',@{ $part_response_id });
@@ -2250,7 +2317,8 @@ KEYWORDS
push(@gradePartRespid,$partid.'.'.$respid);
$request->print(&gradeBox($request,$symb,$uname,$udom,$counter,$partid,\%record));
}
- $request->print('
');
+ $request->print(&gradeBox_end()); #
+ $request->print('
');
$request->print('
');
if ($perm{'vgr'}) {
@@ -2592,7 +2660,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 +2863,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 +3326,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 +3374,7 @@ sub viewgrades {
$result.=
&Apache::loncommon::start_data_table_row()."\n".
- '
\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 +3553,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 +3889,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 +3996,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 +4237,12 @@ LISTJAVASCRIPT
&mt('Manual Grading by Page or Sequence').'';
$result.='
');
return '';
@@ -7778,7 +7980,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 +8169,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 +8187,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 +8269,14 @@ sub checkscantron_results {
if ($scandata{$pid} eq $record{$pid}) {
my $css_class = ($passed % 2)?'LC_odd_row':'LC_even_row';
$okstudents .= '
'.
+ ($saveCmd eq 'pickStudentPage' ? 'checked="checked"' : '').' /> '.
&mt('The complete page/sequence/folder: For one student').'
-
-
+
+
-
-
-
';
$result .= &show_grading_menu_form($symb);
return $result;
@@ -8986,7 +9190,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 +9258,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 +9298,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 +9530,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 +9602,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