--- loncom/homework/grades.pm 2009/05/05 00:42:28 1.568
+++ loncom/homework/grades.pm 2010/04/14 16:34:54 1.574.2.11
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# The LON-CAPA Grading handler
#
-# $Id: grades.pm,v 1.568 2009/05/05 00:42:28 raeburn Exp $
+# $Id: grades.pm,v 1.574.2.11 2010/04/14 16:34:54 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";
$result.=''."\n".
''."\n".
@@ -1745,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) {
@@ -2046,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 ? '' : ' '));
@@ -2135,10 +2164,9 @@ KEYWORDS
{'one_time' => 1});
$similar="
".
- &mt('Essay is [_1]% similar to an essay by [_2] ([_3]:[_4]) in course [_5] (course id [_6]:[_7])',
+ &mt('Essay is [_1]% similar to an essay by [_2] in course [_3] (course id [_4]:[_5])',
$osim,
- &Apache::loncommon::plainname($oname,$odom),
- $oname,$odom,
+ &Apache::loncommon::plainname($oname,$odom).' ('.$oname.':'.$odom.')',
$old_course_desc{'description'},
$old_course_desc{'num'},
$old_course_desc{'domain'}).
@@ -2297,7 +2325,7 @@ KEYWORDS
''."\n";
my $nsel = ($env{'form.NTSTU'} ne '' ? $env{'form.NTSTU'} : '1');
$ntstu =~ s/
- '.&mt('Review scantron data and submissions for a previously graded folder/sequence')."\n".
+ '.&mt('Review bubblesheet data and submissions for a previously graded folder/sequence')."\n".
'
'."\n".
&Apache::loncommon::end_data_table_row()."\n".
&Apache::loncommon::end_data_table()."\n".
@@ -5241,7 +5331,7 @@ sub scantron_selectphase {
CODEstart - (only matter if a CODE exists) column in the line where
the CODE starts
CODElength - length of the CODE
- IDstart - column where the student/employee ID number starts
+ IDstart - column where the student/employee ID starts
IDlength - length of the student/employee ID info
Qstart - column where the information from the bubbled
'questions' start
@@ -5341,7 +5431,7 @@ sub username_to_idmap {
$whichline - line number of the passed in scanline
$field - type of change to process
(either
- 'ID' -> correct the student/employee ID number
+ 'ID' -> correct the student/employee ID
'CODE' -> correct the CODE
'answer' -> fixup the submitted answers)
@@ -6215,7 +6305,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);
@@ -6251,7 +6346,7 @@ sub scantron_validate_file {
''.&mt('No').
' '.
&mt('Grading will take longer if you use verification.').' '.
- &mt("Alternatively, the 'Review scantron data' utility (see grading menu) can be used for all students after grading is complete.").'
'.
+ &mt("Alternatively, the 'Review bubblesheet data' utility (see grading menu) can be used for all students after grading is complete.").'
'.
''.
''."\n");
} else {
@@ -6627,6 +6722,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'});
@@ -6659,7 +6758,12 @@ sub scantron_validate_ID {
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++) {
@@ -6777,10 +6881,10 @@ sub scantron_get_correction {
if ($closest > 0) {
foreach my $testcode (@{$closest}) {
my $checked='';
- if (!$i) { $checked=' checked="checked" '; }
+ if (!$i) { $checked=' checked="checked"'; }
$r->print("
@@ -6791,10 +6895,10 @@ sub scantron_get_correction {
}
}
if ($$scan_record{'scantron.CODE'}=~/\S/ ) {
- my $checked; if (!$i) { $checked=' checked="checked" '; }
+ my $checked; if (!$i) { $checked=' checked="checked"'; }
$r->print("
");
@@ -7018,7 +7122,7 @@ sub prompt_for_corrections {
($responsetype_per_response{$question-1} eq 'imageresponse') ||
($responsetype_per_response{$question-1} eq 'reactionresponse') ||
($responsetype_per_response{$question-1} eq 'organicresponse')) {
- $r->print(&mt("Although this particular question type requires handgrading, the instructions for this question in the exam directed students to leave [quant,_1,line] blank on their scantron sheets.",$lines).'
'.&mt('A non-zero score can be assigned to the student during scantron grading by selecting a bubble in at least one line.').' '.&mt('The score for this question will be a sum of the numeric values for the selected bubbles from each line, where A=1 point, B=2 points etc.').' '.&mt("To assign a score of zero for this question, mark all lines as 'No bubble'.").'
');
+ $r->print(&mt("Although this particular question type requires handgrading, the instructions for this question in the exam directed students to leave [quant,_1,line] blank on their bubblesheets.",$lines).'
'.&mt('A non-zero score can be assigned to the student during bubblesheet grading by selecting a bubble in at least one line.').' '.&mt('The score for this question will be a sum of the numeric values for the selected bubbles from each line, where A=1 point, B=2 points etc.').' '.&mt("To assign a score of zero for this question, mark all lines as 'No bubble'.").'
');
} else {
$r->print(&mt("Select at most one bubble in a single line and select 'No Bubble' in all the other lines. ")." ");
}
@@ -7212,7 +7316,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++) {
@@ -7266,7 +7375,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);
@@ -7284,6 +7398,8 @@ sub scantron_validate_doublebubble {
sub scantron_get_maxbubble {
+ my ($nav_error) = @_;
+
if (defined($env{'form.scantron_maxbubble'}) &&
$env{'form.scantron_maxbubble'}) {
&restore_bubble_lines();
@@ -7294,6 +7410,12 @@ 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;
+ }
+ return;
+ }
my $map=$navmap->getResourceByUrl($sequence);
my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0);
@@ -7383,7 +7505,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);
@@ -7443,13 +7569,24 @@ 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);
&graders_resources_pass(\@resources,\%grader_partids_by_symb,
\%grader_randomlists_by_symb);
+ my $resource_error;
foreach my $resource (@resources) {
- my $ressymb = $resource->symb();
+ my $ressymb;
+ if (ref($resource)) {
+ $ressymb = $resource->symb();
+ } else {
+ $resource_error = 1;
+ last;
+ }
my ($analysis,$parts) =
&scantron_partids_tograde($resource,$env{'request.course.id'},
$env{'user.name'},$env{'user.domain'},1);
@@ -7461,6 +7598,10 @@ sub scantron_process_students {
}
}
}
+ if ($resource_error) {
+ $r->print(&navmap_errormsg());
+ return '';
+ }
my ($uname,$udom);
my $result= <print(&navmap_errormsg());
+ return '';
+ }
# If an ssi failed in scantron_get_maxbubble, put an error message out to
# the user and return.
@@ -7526,9 +7672,15 @@ SCANTRONFORM
}
($uname,$udom)=split(/:/,$uname);
- my %partids_by_symb;
+ my (%partids_by_symb,$res_error);
foreach my $resource (@resources) {
- my $ressymb = $resource->symb();
+ my $ressymb;
+ if (ref($resource)) {
+ $ressymb = $resource->symb();
+ } else {
+ $res_error = 1;
+ last;
+ }
if ((exists($grader_randomlists_by_symb{$ressymb})) ||
(ref($grader_partids_by_symb{$ressymb}) ne 'ARRAY')) {
my ($analysis,$parts) =
@@ -7539,6 +7691,12 @@ SCANTRONFORM
}
}
+ if ($res_error) {
+ &scantron_add_delay(\@delayqueue,$line,
+ 'An error occurred while grading student '.$uname,2);
+ next;
+ }
+
&Apache::lonxml::clear_problem_counter();
&Apache::lonnet::appenv($scan_record);
@@ -7710,15 +7868,17 @@ sub scantron_upload_scantron_data {
my $syllabuslink = ''.&mt('Syllabus').''.
(' 'x2).&mt('(shows course personnel)');
my $default_form_data=&defaultFormData(&get_symb($r,1));
+ my $nofile_alert = &mt('Please use the browse button to select a file from your local directory.');
+ my $nocourseid_alert = &mt("Please use the 'Select Course' link to open a separate window where you can search for a course to which a file can be uploaded.");
$r->print('