--- loncom/homework/grades.pm 2011/10/10 16:35:59 1.659
+++ loncom/homework/grades.pm 2011/12/23 20:04:46 1.668
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# The LON-CAPA Grading handler
#
-# $Id: grades.pm,v 1.659 2011/10/10 16:35:59 raeburn Exp $
+# $Id: grades.pm,v 1.668 2011/12/23 20:04:46 www Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -341,7 +341,7 @@ sub cleanRecord {
return '
'.
'
'.&mt('Answer').'
'.$toprow.'
'.
'
'.$grayFont.&mt('Option ID').'
'.
- $grayFont.$bottomrow.'
'.'
';
+ $bottomrow.'';
} elsif ($response eq 'match') {
my %answer=&Apache::lonnet::str2hash($answer);
my %grading=&Apache::lonnet::str2hash($record->{$version."resource.$partid.$respid.submissiongrading"});
@@ -363,7 +363,7 @@ sub cleanRecord {
'
'.$grayFont.&mt('Item ID').'
'.
$middlerow.'
'.
'
'.$grayFont.&mt('Option ID').'
'.
- $bottomrow.'
'.'';
+ $bottomrow.'';
} elsif ($response eq 'radiobutton') {
my %answer=&Apache::lonnet::str2hash($answer);
my ($toprow,$bottomrow);
@@ -384,7 +384,7 @@ sub cleanRecord {
return '
'.
'
'.&mt('Answer').'
'.$toprow.'
'.
'
'.$grayFont.&mt('Option ID').'
'.
- $bottomrow.'
'.'
';
+ $bottomrow.'';
} elsif ($response eq 'essay') {
if (! exists ($env{'form.'.$symb})) {
my (%keyhash) = &Apache::lonnet::dump('nohist_handgrade',
@@ -1524,17 +1524,15 @@ INNERJS
function savedMsgHeader(Nmsg,usrctr,fullname) {
var height = 70*Nmsg+250;
- var scrollbar = "no";
if (height > 600) {
height = 600;
- scrollbar = "yes";
}
var xpos = (screen.width-600)/2;
xpos = (xpos < 0) ? '0' : xpos;
var ypos = (screen.height-height)/2-30;
ypos = (ypos < 0) ? '0' : ypos;
- pWin = window.open('', 'MessageCenter', 'resizable=yes,toolbar=no,location=no,scrollbars='+scrollbar+',screenx='+xpos+',screeny='+ypos+',width=700,height='+height);
+ pWin = window.open('', 'MessageCenter', 'resizable=yes,toolbar=no,location=no,scrollbars=yes,screenx='+xpos+',screeny='+ypos+',width=700,height='+height);
pWin.focus();
pDoc = pWin.document;
pDoc.$docopen;
@@ -2027,7 +2025,7 @@ sub submission {
keyw => 'Keyword Options',
list => 'List',
past => 'Paste Selection to List',
- high => 'Hightlight Attribute',
+ high => 'Highlight Attribute',
);
#
# Print out the keyword options line
@@ -2905,8 +2903,10 @@ sub handback_files {
&file_name_version_ext($answer_file);
my ($portfolio_path) = ($directory =~ /^.+$stuname\/portfolio(.*)/);
my $getpropath = 1;
- my @dir_list = &Apache::lonnet::dirlist($portfolio_root.$portfolio_path,$domain,$stuname,$getpropath);
- my $version = &get_next_version($answer_name, $answer_ext, \@dir_list);
+ my ($dir_list,$listerror) =
+ &Apache::lonnet::dirlist($portfolio_root.$portfolio_path,
+ $domain,$stuname,$getpropath);
+ my $version = &get_next_version($answer_name,$answer_ext,$dir_list);
# fix file name
my ($save_file_name) = (($directory.$answer_name.".$version.".$answer_ext) =~ /^.+\/${stuname}\/(.*)/);
my $result=&Apache::lonnet::finishuserfileupload($stuname,$domain,
@@ -3067,8 +3067,10 @@ sub version_portfiles {
my ($answer_name,$answer_ver,$answer_ext) =
&file_name_version_ext($answer_file);
my $getpropath = 1;
- my @dir_list = &Apache::lonnet::dirlist($portfolio_root.$directory,$domain,$stu_name,$getpropath);
- my $version = &get_next_version($answer_name, $answer_ext, \@dir_list);
+ my ($dir_list,$listerror) =
+ &Apache::lonnet::dirlist($portfolio_root.$directory,$domain,
+ $stu_name,$getpropath);
+ my $version = &get_next_version($answer_name,$answer_ext,$dir_list);
my $new_answer = &version_selected_portfile($domain, $stu_name, $directory, $answer_file, $version);
if ($new_answer ne 'problem getting file') {
push(@versioned_portfiles, $directory.$new_answer);
@@ -3087,21 +3089,24 @@ sub version_portfiles {
sub get_next_version {
my ($answer_name, $answer_ext, $dir_list) = @_;
my $version;
- foreach my $row (@$dir_list) {
- my ($file) = split(/\&/,$row,2);
- my ($file_name,$file_version,$file_ext) =
- &file_name_version_ext($file);
- if (($file_name eq $answer_name) &&
- ($file_ext eq $answer_ext)) {
- # gets here if filename and extension match, regardless of version
+ if (ref($dir_list) eq 'ARRAY') {
+ foreach my $row (@{$dir_list}) {
+ my ($file) = split(/\&/,$row,2);
+ my ($file_name,$file_version,$file_ext) =
+ &file_name_version_ext($file);
+ if (($file_name eq $answer_name) &&
+ ($file_ext eq $answer_ext)) {
+ # gets here if filename and extension match,
+ # regardless of version
if ($file_version ne '') {
- # a versioned file is found so save it for later
- if ($file_version > $version) {
- $version = $file_version;
- }
+ # a versioned file is found so save it for later
+ if ($file_version > $version) {
+ $version = $file_version;
+ }
+ }
}
}
- }
+ }
$version ++;
return($version);
}
@@ -4999,14 +5004,16 @@ sub scantron_filenames {
my $cdom=$env{'course.'.$env{'request.course.id'}.'.domain'};
my $cname=$env{'course.'.$env{'request.course.id'}.'.num'};
my $getpropath = 1;
- my @files=&Apache::lonnet::dirlist('userfiles',$cdom,$cname,
- $getpropath);
+ my ($dirlist,$listerror) = &Apache::lonnet::dirlist('userfiles',$cdom,
+ $cname,$getpropath);
my @possiblenames;
- foreach my $filename (sort(@files)) {
- ($filename)=split(/&/,$filename);
- if ($filename!~/^scantron_orig_/) { next ; }
- $filename=~s/^scantron_orig_//;
- push(@possiblenames,$filename);
+ if (ref($dirlist) eq 'ARRAY') {
+ foreach my $filename (sort(@{$dirlist})) {
+ ($filename)=split(/&/,$filename);
+ if ($filename!~/^scantron_orig_/) { next ; }
+ $filename=~s/^scantron_orig_//;
+ push(@possiblenames,$filename);
+ }
}
return @possiblenames;
}
@@ -6217,6 +6224,12 @@ sub scantron_warning_screen {
'
'.&mt('List of CODES to validate against:').'
'.
$env{'form.scantron_CODElist'}.'
';
}
+ my $lastbubblepoints;
+ if ($env{'form.scantron_lastbubblepoints'} ne '') {
+ $lastbubblepoints =
+ '
'.&mt('Hand-graded items: points from last bubble in row').'
'.
+ $env{'form.scantron_lastbubblepoints'}.'
';
+ }
return ('
@@ -6225,7 +6238,7 @@ sub scantron_warning_screen {
'.&mt('Sequence to be Graded:').'
'.$title.'
'.&mt('Data File that will be used:').'
'.$env{'form.scantron_selectfile'}.'
-'.$CODElist.'
+'.$CODElist.$lastbubblepoints.'
'.&mt('If this information is correct, please click on \'[_1]\'.',&mt($button_text)).'
'.&mt('If something is incorrect, please return to [_1]Grade/Manage/Review Bubblesheets[_2] to start over.','','').'
@@ -6263,8 +6276,9 @@ sub scantron_do_warning {
}
} else {
my $warning=&scantron_warning_screen('Grading: Validate Records',$symb);
+ my $bubbledbyhand=&hand_bubble_option();
$r->print('
-'.$warning.'
+'.$warning.$bubbledbyhand.'
');
@@ -6360,6 +6374,9 @@ sub scantron_validate_file {
return '';
}
my $result=&scantron_form_start($max_bubble).$default_form_data;
+ if ($env{'form.scantron_lastbubblepoints'} ne '') {
+ $result .= '';
+ }
$r->print($result);
my @validate_phases=( 'sequence',
@@ -6890,7 +6907,7 @@ sub scantron_get_correction {
.&mt('The ID on the form is [_1]',
"$$scan_record{'scantron.ID'}")
.' '
- .&mt('The name on the paper is [_2], [_3]',
+ .&mt('The name on the paper is [_1], [_2]',
$$scan_record{'scantron.LastName'},
$$scan_record{'scantron.FirstName'})
.'
';
@@ -7632,6 +7649,41 @@ sub scantron_validate_missingbubbles {
return (0,$currentphase+1);
}
+sub hand_bubble_option {
+ my (undef, undef, $sequence) =
+ &Apache::lonnet::decode_symb($env{'form.selectpage'});
+ return if ($sequence eq '');
+ my $navmap = Apache::lonnavmaps::navmap->new();
+ unless (ref($navmap)) {
+ return;
+ }
+ my $needs_hand_bubbles;
+ my $map=$navmap->getResourceByUrl($sequence);
+ my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0);
+ foreach my $res (@resources) {
+ if (ref($res)) {
+ if ($res->is_problem()) {
+ my $partlist = $res->parts();
+ foreach my $part (@{ $partlist }) {
+ my @types = $res->responseType($part);
+ if (grep(/^(chem|essay|image|formula|math|string|functionplot)$/,@types)) {
+ $needs_hand_bubbles = 1;
+ last;
+ }
+ }
+ }
+ }
+ }
+ if ($needs_hand_bubbles) {
+ my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
+ my $bubbles_per_row = &bubblesheet_bubbles_per_row(\%scantron_config);
+ return &mt('The sequence to be graded contains response types which are handgraded.').'
'.
+ &mt('If you have already graded these by bubbling sheets to indicate points awarded, [_1]what point value is assigned to a filled last bubble in each row?',' ').
+ ' '.&mt('or').' '.
+ '
';
+ }
+ return;
+}
sub scantron_process_students {
my ($r,$symb) = @_;
@@ -7696,11 +7748,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,'Bubblesheet Status',
- 'Bubblesheet Progress',$count,
- 'inline',undef,'scantronupload');
- &Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state,
- 'Processing first student');
+ my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,$count);
+ &Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state,'Processing first student');
$r->print(' ');
my $start=&Time::HiRes::time();
my $i=-1;
@@ -7732,8 +7781,7 @@ SCANTRONFORM
my $line=&scantron_get_line($scanlines,$scan_data,$i);
if ($line=~/^[\s\cz]*$/) { next; }
if ($started) {
- &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,
- 'last student');
+ &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,'last student');
}
$started=1;
my $scan_record=&scantron_parse_scanline($line,$i,\%scantron_config,
@@ -7923,6 +7971,9 @@ sub grade_student_bubbles {
if ($bubbles_per_row ne '') {
$form{'bubbles_per_row'} = $bubbles_per_row;
}
+ if ($env{'form.scantron_lastbubblepoints'} ne '') {
+ $form{'scantron_lastbubblepoints'} = $env{'form.scantron_lastbubblepoints'};
+ }
if (ref($parts) eq 'HASH') {
if (ref($parts->{$ressymb}) eq 'ARRAY') {
foreach my $part (@{$parts->{$ressymb}}) {
@@ -8221,9 +8272,7 @@ sub checkscantron_results {
my %completedstudents;
my $count=&Apache::grades::get_todo_count($scanlines,$scan_data);
- my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Bubblesheet/Submissions Comparison Status',
- 'Progress of Bubblesheet Data/Submission Records Comparison',$count,
- 'inline',undef,'checkscantron');
+ my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,$count);
my ($username,$domain,$started);
my $nav_error;
&scantron_get_maxbubble(\$nav_error,\%scantron_config); # Need the bubble lines array to parse.
@@ -8232,8 +8281,7 @@ sub checkscantron_results {
return '';
}
- &Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state,
- 'Processing first student');
+ &Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state,'Processing first student');
my $start=&Time::HiRes::time();
my $i=-1;
@@ -8243,8 +8291,7 @@ sub checkscantron_results {
my $line=&Apache::grades::scantron_get_line($scanlines,$scan_data,$i);
if ($line=~/^[\s\cz]*$/) { next; }
if ($started) {
- &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,
- 'last student');
+ &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,'last student');
}
$started=1;
my $scan_record=
@@ -8856,7 +8903,8 @@ sub process_clicker {
my $pincorrect=&mt("Percentage points for incorrect solution");
my $selectform=&Apache::loncommon::select_form($env{'form.upfiletype'},'upfiletype',
{'iclicker' => 'i>clicker',
- 'interwrite' => 'interwrite PRS'});
+ 'interwrite' => 'interwrite PRS',
+ 'turning' => 'Turning Technologies'});
$symb = &Apache::lonenc::check_encrypt($symb);
$result.= &Apache::lonhtmlcommon::scripttag(<'.&mt('Found [_1] question(s)',$number).' '.
''.
&mt('Awarding [_1] percent for correct and [_2] percent for incorrect responses',
@@ -9166,6 +9217,32 @@ sub interwrite_eval {
return ($errormsg,$number);
}
+sub turning_eval {
+ my ($questiontitles,$responses)=@_;
+ my $number=0;
+ my $errormsg='';
+ foreach my $line (split(/[\n\r]/,$env{'form.upfile'})) {
+ my %components=&Apache::loncommon::record_sep($line);
+ my @entries=map {$components{$_}} (sort(keys(%components)));
+ if ($#entries>$number) { $number=$#entries; }
+ my $id=$entries[0];
+ my @idresponses;
+ $id=~s/^[\#0]+//;
+ unless ($id) { next; }
+ for (my $idx=1;$idx<=$#entries;$idx++) {
+ $entries[$idx]=~s/\,/\;/g;
+ $entries[$idx]=~s/[^a-zA-Z0-9\.\*\-\+\;]+//g;
+ push(@idresponses,$entries[$idx]);
+ }
+ $$responses{$id}=join(',',@idresponses);
+ }
+ for (my $i=1; $i<=$number; $i++) {
+ $$questiontitles[$i]=&mt('Question [_1]',$i);
+ }
+ return ($errormsg,$number);
+}
+
+
sub assign_clicker_grades {
my ($r,$symb)=@_;
if (!$symb) {return '';}
@@ -9331,23 +9408,25 @@ sub handler {
}
&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'});
+# see what command we need to execute
+
+ my @commands=&Apache::loncommon::get_env_multiple('form.command');
+ my $command=$commands[0];
+
&init_perm();
if (!$env{'request.course.id'}) {
- # Not in a course.
- $env{'user.error.msg'}="/adm/grades::vgr:0:0:Cannot display grades page outside course context";
- return HTTP_NOT_ACCEPTABLE;
+ unless ((&Apache::lonnet::allowed('usc',$env{'request.role.domain'})) &&
+ ($command =~ /^scantronupload/)) {
+ # Not in a course.
+ $env{'user.error.msg'}="/adm/grades::vgr:0:0:Cannot display grades page outside course context";
+ return HTTP_NOT_ACCEPTABLE;
+ }
} elsif (!%perm) {
$request->internal_redirect('/adm/quickgrades');
}
&Apache::loncommon::content_type($request,'text/html');
$request->send_http_header;
-
-# see what command we need to execute
-
- my @commands=&Apache::loncommon::get_env_multiple('form.command');
- my $command=$commands[0];
-
if ($#commands > 0) {
&Apache::lonnet::logthis("grades got multiple commands ".join(':',@commands));
}