');
hDoc.write("Text Color<\\/b><\\/td> Font Size<\\/b><\\/td> Font Style<\\/td><\\/tr>");
}
@@ -1680,7 +1704,7 @@ sub gradeBox {
my $radio.=''."\n"; # display radio buttons in a nice table 10 across
while ($thisweight<=$wgt) {
- $radio.= ' '.$thisweight." \n";
@@ -1696,7 +1720,7 @@ sub gradeBox {
$wgt.')" />'."\n";
$line.='/'.$wgt.' '.$wgtmsg.
($$record{'resource.'.$partid.'.solved'} eq 'correct_by_student' ? ' '.$checkIcon : '').
- ' '."\n";
+ ' '.&mt('Grade Status').': '."\n";
$line.=''."\n";
if ($$record{'resource.'.$partid.'.solved'} eq 'excused') {
@@ -1709,9 +1733,9 @@ sub gradeBox {
$line.=''.&mt('reset status').' '."\n";
+ #&mt('Part: [_1] Points: [_2] or [_3] ',$display_part,$radio,$line);
$result .=
- &mt('Part: [_1] Points: [_2] or [_3] ',$display_part,$radio,$line);
-
+ ''.&mt('Part:').' '.$display_part.' '.&mt('Points:').' '.$radio.' '.&mt('or').' '.$line.' '.
$result.='
'."\n";
$result.=' '."\n".
@@ -2090,10 +2114,12 @@ KEYWORDS
}
my $responsetype = $responseType->{$partid}->{$respid};
if (!exists($record{"resource.$partid.$respid.submission"})) {
- $lastsubonly.="\n".' Part: '.
- $display_part.' ( ID '.$respid.
- ' ) '.
- ''.&mt('Nothing submitted - no attempts').'
';
+ $lastsubonly.="\n".''.
+ ''.&mt('Part: [_1]',$display_part).' '.
+ ' '.
+ '('.&mt('Part ID: [_1]',$respid).')'.
+ ' '.
+ ''.&mt('Nothing submitted - no attempts.').'
';
next;
}
foreach my $submission (@$string) {
@@ -2112,10 +2138,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'}).
@@ -2129,23 +2154,25 @@ 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 virusses').' ';
+ $lastsubonly.='
'.&mt('Like all files provided by users, this file may contain viruses').' ';
my $file_counter = 0;
foreach my $file (@$files) {
$file_counter++;
&Apache::lonnet::allowuploaded('/adm/grades',$file);
- $lastsubonly.='
'.$file.'';
+ $lastsubonly.='
'.$file.'';
}
$lastsubonly.='
';
}
$lastsubonly.='
'.&mt('Submitted Answer:').' '.
&cleanRecord($subval,$responsetype,$symb,$partid,
- $respid,\%record,$order);
+ $respid,\%record,$order,undef,$uname,$udom);
if ($similar) {$lastsubonly.="
$similar\n";}
$lastsubonly.='
';
}
@@ -2225,8 +2252,8 @@ KEYWORDS
$seen{$partid}++;
next if ($$handgrade{$part_resp} ne 'yes'
&& $env{'form.lastSub'} eq 'hdgrade');
- push @partlist,$partid;
- push @gradePartRespid,$partid.'.'.$respid;
+ push(@partlist,$partid);
+ push(@gradePartRespid,$partid.'.'.$respid);
$request->print(&gradeBox($request,$symb,$uname,$udom,$counter,$partid,\%record));
}
$request->print('
');
@@ -2274,7 +2301,7 @@ KEYWORDS
'7 10 '."\n";
my $nsel = ($env{'form.NTSTU'} ne '' ? $env{'form.NTSTU'} : '1');
$ntstu =~ s/$nsel $nsel;
- $endform.=&mt('[_1]student(s)',$ntstu);
+ $endform.=&mt('[quant,_1,student]',$ntstu);
$endform.=' '."\n".
' Nothing submitted - no attempts. ';
+ ''.&mt('Nothing submitted - no attempts.').' ';
}
return (\@string,\$timestamp);
}
@@ -2440,7 +2467,7 @@ sub processHandGrade {
undef,$feedurl,undef,
undef,undef,$showsymb,
$restitle);
- $request->print(' '.&mt('Sending message to [_1]:[_2]',$uname,$udom).': '.
+ $request->print(' '.&mt('Sending message to [_1]',$uname.':'.$udom).': '.
$msgstatus);
}
if ($env{'form.collaborator'.$ctr}) {
@@ -2553,7 +2580,7 @@ sub processHandGrade {
my (@parsedlist,@nextlist);
my ($nextflg) = 0;
- foreach (sort
+ foreach my $item (sort
{
if (lc($$fullname{$a}) ne lc($$fullname{$b})) {
return (lc($$fullname{$a}) cmp lc($$fullname{$b}));
@@ -2561,12 +2588,12 @@ sub processHandGrade {
return $a cmp $b;
} (keys(%$fullname))) {
if ($nextflg == 1 && $button =~ /Next$/) {
- push @parsedlist,$_;
+ push(@parsedlist,$item);
}
- $nextflg = 1 if ($_ eq $laststu);
+ $nextflg = 1 if ($item eq $laststu);
if ($button eq 'Previous') {
- last if ($_ eq $firststu);
- push @parsedlist,$_;
+ last if ($item eq $firststu);
+ push(@parsedlist,$item);
}
}
$ctr = 0;
@@ -2589,11 +2616,11 @@ sub processHandGrade {
my $submitted = 0;
my $ungraded = 0;
my $incorrect = 0;
- foreach (keys(%status)) {
- $submitted = 1 if ($status{$_} ne 'nothing');
- $ungraded = 1 if ($status{$_} =~ /^ungraded/);
- $incorrect = 1 if ($status{$_} =~ /^incorrect/);
- my ($foo,$partid,$foo1) = split(/\./,$_);
+ foreach my $item (keys(%status)) {
+ $submitted = 1 if ($status{$item} ne 'nothing');
+ $ungraded = 1 if ($status{$item} =~ /^ungraded/);
+ $incorrect = 1 if ($status{$item} =~ /^incorrect/);
+ my ($foo,$partid,$foo1) = split(/\./,$item);
if ($status{'resource.'.$partid.'.submitted_by'} ne '') {
$submitted = 0;
}
@@ -2604,7 +2631,7 @@ sub processHandGrade {
next if (!$ungraded && ($submitonly eq 'graded'));
next if (!$incorrect && $submitonly eq 'incorrect');
}
- push @nextlist,$student if ($ctr < $ntstu);
+ push(@nextlist,$student) if ($ctr < $ntstu);
last if ($ctr == $ntstu);
$ctr++;
}
@@ -2612,7 +2639,7 @@ sub processHandGrade {
$ctr = 0;
my $total = scalar(@nextlist)-1;
- foreach (sort @nextlist) {
+ foreach (sort(@nextlist)) {
my ($uname,$udom,$submitter) = split(/:/);
$env{'form.student'} = $uname;
$env{'form.userdom'} = $udom;
@@ -2658,7 +2685,7 @@ sub saveHandGrade {
}
} elsif ($dropMenu eq 'reset status'
&& exists($record{'resource.'.$new_part.'.solved'})) { #don't bother if no old records -> no attempts
- foreach my $key (keys (%record)) {
+ foreach my $key (keys(%record)) {
if ($key=~/^resource\.\Q$new_part\E\./) { $newrecord{$key} = ''; }
}
$newrecord{'resource.'.$new_part.'.regrader'}=
@@ -2693,7 +2720,7 @@ sub saveHandGrade {
&handback_files($request,$symb,$stuname,$domain,$newflg,$new_part,\%newrecord);
next;
} else {
- push @parts_graded, $new_part;
+ push(@parts_graded,$new_part);
}
if ($record{'resource.'.$new_part.'.awarded'} ne $partial) {
$newrecord{'resource.'.$new_part.'.awarded'} = $partial;
@@ -2720,7 +2747,7 @@ sub saveHandGrade {
$record{'resource.'.$new_part.'.solved'} eq 'incorrect_by_override' ||
$dropMenu eq 'reset status')
{
- push (@version_parts,$new_part);
+ push(@version_parts,$new_part);
}
}
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
@@ -2795,8 +2822,10 @@ sub handback_files {
$newflg.'_'.$part_resp.'_returndoc'.$file_counter,
$save_file_name);
if ($result !~ m|^/uploaded/|) {
- $request->print('An error occurred ('.$result.
- ') while trying to upload '.$newflg.'_'.$part_resp.'_returndoc'.$file_counter.' ');
+ $request->print(''.
+ &mt('An error occurred ([_1]) while trying to upload [_2].',
+ $result,$newflg.'_'.$part_resp.'_returndoc'.$file_counter).
+ ' ');
} else {
# mark the file as read only
my @files = ($save_file_name);
@@ -2893,7 +2922,7 @@ sub decrement_aggs {
if ($aggtries == $totaltries) {
$decrement{'users'} = 1;
}
- foreach my $type (keys (%decrement)) {
+ foreach my $type (keys(%decrement)) {
$$aggregate{$symb."\0".$part."\0".$type} = -$decrement{$type};
}
return;
@@ -3015,6 +3044,7 @@ sub file_name_version_ext {
sub viewgrades_js {
my ($request) = shift;
+ my $alertmsg = &mt('A number equal or greater than 0 is expected. Entered value = ');
$request->print(<
function writePoint(partid,weight,point) {
@@ -3023,7 +3053,7 @@ sub viewgrades_js {
if (point == "textval") {
point = document.classgrade["TEXTVAL_"+partid].value;
if (isNaN(point) || parseFloat(point) < 0) {
- alert("A number equal or greater than 0 is expected. Entered value = "+parseFloat(point));
+ alert("$alertmsg"+parseFloat(point));
var resetbox = false;
for (var i=0; i '."\n".
' '."\n";
- my $sectionClass;
- my $section_display = join (", ",&Apache::loncommon::get_env_multiple('form.section'));
+ my ($common_header,$specific_header);
if ($env{'form.section'} eq 'all') {
- $sectionClass='Class';
+ $common_header = &mt('Assign Common Grade to Class');
+ $specific_header = &mt('Assign Grade to Specific Students in Class');
} elsif ($env{'form.section'} eq 'none') {
- $sectionClass='Students in no Section';
+ $common_header = &mt('Assign Common Grade to Students in no Section');
+ $specific_header = &mt('Assign Grade to Specific Students in no Section');
} else {
- $sectionClass='Students in Section(s) [_1]';
+ my $section_display = join (", ",&Apache::loncommon::get_env_multiple('form.section'));
+ $common_header = &mt('Assign Common Grade to Students in Section(s) [_1]',$section_display);
+ $specific_header = &mt('Assign Grade to Specific Students in Section(s) [_1]',$section_display);
}
- $result.=
- ''.
- &mt("Assign Common Grade To $sectionClass",$section_display).' ';
- $result.= &Apache::loncommon::start_data_table();
+ $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);
@@ -3253,8 +3283,8 @@ sub viewgrades {
my $line = ' /'.
- $weight{$partid}.' (problem weight) '."\n";
- $line.= ''."\n";
+ $line.= ''.&mt('Grade Status').': '.
' '.
@@ -3269,7 +3299,7 @@ sub viewgrades {
$result.=
&Apache::loncommon::start_data_table_row()."\n".
- &mt('Part: [_1] Points: [_2] or [_3] ',$display_part,$radio,$line).
+ ''.&mt('Part:').' '.$display_part.' '.&mt('Points:').' '.$radio.' '.&mt('or').' '.$line.' '.
&Apache::loncommon::end_data_table_row()."\n";
$ctsparts++;
}
@@ -3280,21 +3310,21 @@ sub viewgrades {
#table listing all the students in a section/class
#header of table
- $result.= ''.&mt('Assign Grade to Specific Students in '.$sectionClass,
- $section_display).' ';
- $result.= &Apache::loncommon::start_data_table().
- &Apache::loncommon::start_data_table_header_row().
- ''.&mt('No.').' '.
- ''.&nameUserString('header')." \n";
+ $result.= ''.$specific_header.' '.
+ &Apache::loncommon::start_data_table().
+ &Apache::loncommon::start_data_table_header_row().
+ ''.&mt('No.').' '.
+ ''.&nameUserString('header')." \n";
my (@parts) = sort(&getpartlist($symb));
my (undef,undef,$url)=&Apache::lonnet::decode_symb($symb);
my @partids = ();
foreach my $part (@parts) {
my $display=&Apache::lonnet::metadata($url,$part.'.display');
- $display =~ s|^Number of Attempts|Tries |; # makes the column narrower
+ my $narrowtext = &mt('Tries');
+ $display =~ s|^Number of Attempts|$narrowtext |; # makes the column narrower
if (!$display) { $display = &Apache::lonnet::metadata($url,$part.'.name'); }
my ($partid) = &split_part_type($part);
- push(@partids, $partid);
+ push(@partids,$partid);
my $display_part=&get_display_part($partid,$symb);
if ($display =~ /^Partial Credit Factor/) {
$result.=''.
@@ -3448,7 +3478,7 @@ sub editgrades {
my $header;
while ($ctr < $env{'form.totalparts'}) {
my $partid = $env{'form.partid_'.$ctr};
- push @partid,$partid;
+ push(@partid,$partid);
$weight{$partid} = $env{'form.weight_'.$partid};
$ctr++;
}
@@ -3462,10 +3492,11 @@ sub editgrades {
if ($part !~ m/^\Q$partid\E/) { next;}
if ($type eq 'awarded' || $type eq 'solved') { next; }
my $display=&Apache::lonnet::metadata($url,$stores.'.display');
- $display =~ s/\[Part: (\w)+\]//;
- $display =~ s/Number of Attempts/Tries/;
- $header .= ' '.&mt('Old '.$display).' '.
- ''.&mt('New '.$display).' ';
+ $display =~ s/\[Part: \Q$part\E\]//;
+ my $narrowtext = &mt('Tries');
+ $display =~ s/Number of Attempts/$narrowtext/;
+ $header .= ''.&mt('Old').' '.$display.' '.
+ ''.&mt('New').' '.$display.' ';
$columns{$partid}+=2;
}
}
@@ -3654,7 +3685,7 @@ sub split_part_type {
#
#--- Javascript to handle csv upload
sub csvupload_javascript_reverse_associate {
- my $error1=&mt('You need to specify the username or ID');
+ my $error1=&mt('You need to specify the username or the student/employee ID');
my $error2=&mt('You need to specify at least one grading field');
return(<
function checkUpload(formname) {
if (formname.upfile.value == "") {
- alert("Please use the browse button to select a file from your local directory.");
+ alert("$alertmsg");
return false;
}
formname.submit();
@@ -3831,8 +3863,8 @@ sub upcsvScores_form {
$result.=$table;
$result.=''."\n";
$result.=''."\n";
- $result.=' '.&mt('Specify a file containing the class scores for current resource').
- '. '."\n";
+ $result.=' '.&mt('Specify a file containing the class scores for current resource.').
+ ' '."\n";
$result.=''."\n";
my $upload=&mt("Upload Scores");
my $upfile_select=&Apache::loncommon::upfile_select_html();
@@ -4062,14 +4094,14 @@ sub csvuploadassign {
$countdone++;
}
}
- $request->print(''.&mt("Saved [_1] students",$countdone)." \n");
+ $request->print(' '.&Apache::lonhtmlcommon::confirm_success(&mt("Saved scores for [quant,_1,student]",$countdone),$countdone==0));
if (@skipped) {
- $request->print(''.&mt('Skipped Students').'
');
- foreach my $student (@skipped) { $request->print("$student \n"); }
+ $request->print(' '.&Apache::lonhtmlcommon::confirm_success(&mt('No scores stored for the following username(s):'),1).' ');
+ $request->print(join(', ',@skipped));
}
if (@notallowed) {
- $request->print(''.&mt('Students Not Allowed to Modify').'
');
- foreach my $student (@notallowed) { $request->print("$student \n"); }
+ $request->print(' '.&Apache::lonhtmlcommon::confirm_success(&mt('Modification of scores not allowed for the following username(s):'),1).' ');
+ $request->print(join(', ',@notallowed));
}
$request->print(" \n");
$request->print(&show_grading_menu_form($symb));
@@ -4085,12 +4117,13 @@ sub csvuploadassign {
sub pickStudentPage {
my ($request) = shift;
+ my $alertmsg = &mt('Please select the student you wish to grade.');
$request->print(<
function checkPickOne(formname) {
if (radioSelection(formname.student) == null) {
- alert("Please select the student you wish to grade.");
+ alert("$alertmsg");
return;
}
ptr = pullDownSelection(formname.selectpage);
@@ -4125,7 +4158,7 @@ LISTJAVASCRIPT
$ctr++;
}
$select.= '';
- $result.=&mt(' Problems from: [_1]',$select)." \n";
+ $result.=' '.&mt('Problems from').': '.$select." \n";
$ctr=0;
foreach (@$titles) {
@@ -4140,13 +4173,13 @@ LISTJAVASCRIPT
my $options =
' '.&mt('no').' '."\n".
' '.&mt('yes').' '." \n";
- $result.=' '.&mt('View Problems Text: [_1]',$options);
+ $result.=' '.&mt('View Problem Text').': '.$options;
$options =
' '.&mt('none').' '."\n".
' '.&mt('by dates and submissions').' '."\n".
' '.&mt('all details').' '."\n";
- $result.=' '.&mt('Submission Details: [_1]',$options);
+ $result.=' '.&mt('Submissions').': '.$options;
$result.=&build_section_inputs();
my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status'));
@@ -4155,12 +4188,10 @@ LISTJAVASCRIPT
' '."\n".
' '." \n";
- $result.=' '.&mt('Use CODE: [_1] ',
- ' ').
- ' '."\n";
+ $result.=' '.&mt('Use CODE').': '."\n";
$result.=' '."\n";
+ 'onClick="javascript:checkPickOne(this.form);" value="'.&mt('Next').' →" /> '."\n";
$request->print($result);
@@ -4199,7 +4230,7 @@ LISTJAVASCRIPT
}
$studentTable.=&Apache::loncommon::end_data_table()."\n";
$studentTable.=' '."\n";
+ 'onClick="javascript:checkPickOne(this.form);" value="'.&mt('Next').' →" />'."\n";
$studentTable.=&show_grading_menu_form($symb);
$request->print($studentTable);
@@ -4336,7 +4367,7 @@ sub displayPage {
# $request->print('match='.$1." \n");
# }
# $companswer =~ s|||g;
- $studentTable.=' '.$title.' '.&mt('Correct answer: [_1]',$companswer);
+ $studentTable.=' '.$title.' '.&mt('Correct answer').': '.$companswer;
}
my %record = &Apache::lonnet::restore($symbx,$env{'request.course.id'},$udom,$uname);
@@ -4406,10 +4437,11 @@ sub displaySubByDates {
my %orders;
$mark{'correct_by_student'} = $checkIcon;
if (!exists($$record{'1:timestamp'})) {
- return ' '.&mt('Nothing submitted - no attempts').' ';
+ return ' '.&mt('Nothing submitted - no attempts.').' ';
}
my $interaction;
+ my $no_increment = 1;
for ($version=1;$version<=$$record{'version'};$version++) {
my $timestamp =
&Apache::lonlocal::locallocaltime($$record{$version.':timestamp'});
@@ -4439,13 +4471,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: [_1]',$display_part).' '
+ .' '
+ .'('.&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'
@@ -4453,9 +4488,11 @@ sub displaySubByDates {
if (!exists($orders{$partid})) { $orders{$partid}={}; }
if (!exists($orders{$partid}->{$responseId})) {
$orders{$partid}->{$responseId}=
- &get_order($partid,$responseId,$symb,$uname,$udom);
+ &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).' ';
}
}
@@ -4506,12 +4543,12 @@ sub updateGradeByPage {
my ($uname,$udom) = split(/:/,$env{'form.student'});
my $usec=$classlist->{$env{'form.student'}}[5];
if (!&canmodify($usec)) {
- $request->print('Unable to modify requested student.('.$env{'form.student'}.' ');
+ $request->print(''.&mt('Unable to modify requested student ([_1])',$env{'form.student'}).' ');
$request->print(&show_grading_menu_form($env{'form.symb'}));
return;
}
my $result=' '.$env{'form.title'}.' ';
- $result.=' Student: '.&nameUserString(undef,$env{'form.fullname'},$uname,$udom).
+ $result.=' '.&mt('Student: ').&nameUserString(undef,$env{'form.fullname'},$uname,$udom).
' '."\n";
$request->print($result);
@@ -4520,7 +4557,7 @@ sub updateGradeByPage {
my ($mapUrl, $id, $resUrl) = &Apache::lonnet::decode_symb( $env{'form.page'});
my $map = $navmap->getResourceByUrl($resUrl); # add to navmaps
if (!$map) {
- $request->print('Unable to grade requested sequence. ('.$resUrl.') ');
+ $request->print(''.&mt('Unable to grade requested sequence ([_1]).',$resUrl).' ');
my ($symb)=&get_symb($request);
$request->print(&show_grading_menu_form($symb));
return;
@@ -4552,8 +4589,8 @@ sub updateGradeByPage {
&Apache::loncommon::start_data_table_row().
''.$prob.
(scalar(@{$parts}) == 1 ? ''
- : ' ('.&mt('[quant,_1, parts]',scalar(@{$parts}))
- ).') ';
+ : ' ('.&mt('[quant,_1, part]',scalar(@{$parts}))
+ .')').'';
$studentTable.=' '.$title.' ';
my %newrecord=();
@@ -4597,10 +4634,10 @@ sub updateGradeByPage {
}
my $display_part=&get_display_part($partid,$curRes->symb());
my $oldstatus = $env{'form.solved'.$question.'_'.$partid};
- $displayPts[0].=' Part: '.$display_part.' = '.
+ $displayPts[0].=' '.&mt('Part').': '.$display_part.' = '.
(($oldstatus eq 'excused') ? 'excused' : $oldpts).
' ';
- $displayPts[1].=' Part: '.$display_part.' = '.
+ $displayPts[1].=' '.&mt('Part').': '.$display_part.' = '.
(($score eq 'excused') ? 'excused' : $newpts).
' ';
$question++;
@@ -4649,9 +4686,9 @@ sub updateGradeByPage {
$studentTable.=&Apache::loncommon::end_data_table();
$studentTable.=&show_grading_menu_form($env{'form.symb'});
- my $grademsg=($changeflag == 0 ? 'No score was changed or updated.' :
- 'The scores were changed for '.
- $changeflag.' problem'.($changeflag == 1 ? '.' : 's.'));
+ my $grademsg=($changeflag == 0 ? &mt('No score was changed or updated.') :
+ &mt('The scores were changed for [quant,_1,problem].',
+ $changeflag));
$request->print($grademsg.$studentTable);
return '';
@@ -4688,10 +4725,10 @@ Next each scanline is checked for any er
bubbles' (it's an error because it may have been mis-scanned
because too light bubbling), 'double bubble' (each bubble line should
have no more that one letter picked), invalid or duplicated CODE,
-invalid student ID
+invalid student/employee ID
If the CODE option is used that determines the randomization of the
-homework problems, either way the student ID is looked up into a
+homework problems, either way the student/employee ID is looked up into a
username:domain.
During the validation phase the instructor can choose to skip scanlines.
@@ -4761,7 +4798,7 @@ sub getSequenceDropDown {
}
my %bubble_lines_per_response; # no. bubble lines for each response.
- # index is "symb.part_id"
+ # key is zero-based index - 0, 1, 2 ...
my %first_bubble_line; # First bubble line no. for each bubble.
@@ -4802,7 +4839,6 @@ sub restore_bubble_lines {
$env{"form.scantron.responsetype.$line"};
$line++;
}
-
}
# Given the parsed scanline, get the response for
@@ -4811,7 +4847,6 @@ sub restore_bubble_lines {
sub get_response_bubbles {
my ($parsed_line, $response) = @_;
-
my $bubble_line = $first_bubble_line{$response-1} +1;
my $bubble_lines= $bubble_lines_per_response{$response-1};
@@ -4982,11 +5017,11 @@ sub scantron_CODElist {
=cut
sub scantron_CODEunique {
- my $result='
+ my $result='
'.&mt('Yes').'
-
+
'.&mt('No').'
';
@@ -5042,10 +5077,10 @@ sub scantron_selectphase {
'.&mt('Sequence to grade:').' '.$sequence_selector.'
'.&Apache::loncommon::end_data_table_row().'
'.&Apache::loncommon::start_data_table_row().'
- '.&mt('Filename of scoring office file:').' '.$file_selector.'
+ '.&mt('Filename of bubblesheet data file:').' '.$file_selector.'
'.&Apache::loncommon::end_data_table_row().'
'.&Apache::loncommon::start_data_table_row().'
- '.&mt('Format of data file:').' '.$format_selector.'
+ '.&mt('Format of bubblesheet data file:').' '.$format_selector.'
'.&Apache::loncommon::end_data_table_row().'
'.&Apache::loncommon::start_data_table_row().'
'.&mt('Saved CODEs to validate against:').' '.$CODE_selector.'
@@ -5063,7 +5098,7 @@ sub scantron_selectphase {
'.&Apache::loncommon::end_data_table_row().'
'.&Apache::loncommon::start_data_table_row().'
-
+
'.&Apache::loncommon::end_data_table_row().'
'.&Apache::loncommon::end_data_table().'
@@ -5082,7 +5117,7 @@ sub scantron_selectphase {
'.&Apache::loncommon::start_data_table('LC_scantron_action').'
'.&Apache::loncommon::start_data_table_header_row().'
- '.&mt('Specify a Scantron data file to upload.').'
+ '.&mt('Specify a bubblesheet data file to upload.').'
'.&Apache::loncommon::end_data_table_header_row().'
'.&Apache::loncommon::start_data_table_row().'
@@ -5109,7 +5144,7 @@ sub scantron_selectphase {
'.&mt('File to upload: [_1]',' ').'
-
+
');
@@ -5146,12 +5181,12 @@ sub scantron_selectphase {
&Apache::lonpickcode::code_list($r,2);
- $r>print(' ");
- &ssi_print_error($r);
- $r->print(&show_grading_menu_form($symb));
- &Apache::lonnet::remove_lock($lock);
- return ''; # Why return ''? Beats me.
- }
+ my $scancode;
+ if ((exists($scan_record->{'scantron.CODE'})) &&
+ (&Apache::lonnet::validCODE($scan_record->{'scantron.CODE'}))) {
+ $scancode = $scan_record->{'scantron.CODE'};
+ } else {
+ $scancode = '';
+ }
+
+ if (&grade_student_bubbles($r,$uname,$udom,$scan_record,$scancode,
+ \@resources,\%partids_by_symb) eq 'ssi_error') {
+ $ssi_error = 0; # So end of handler error message does not trigger.
+ $r->print("");
+ &ssi_print_error($r);
+ $r->print(&show_grading_menu_form($symb));
+ &Apache::lonnet::remove_lock($lock);
+ return ''; # Why return ''? Beats me.
+ }
- if (&Apache::loncommon::connection_aborted($r)) { last; }
- }
$completedstudents{$uname}={'line'=>$line};
- if (&Apache::loncommon::connection_aborted($r)) { last; }
+ if ($env{'form.verifyrecord'}) {
+ my $lastpos = $env{'form.scantron_maxbubble'}*$scantron_config{'Qlength'};
+ my $studentdata = substr($line,$scantron_config{'Qstart'}-1,$lastpos);
+ chomp($studentdata);
+ $studentdata =~ s/\r$//;
+ my $studentrecord = '';
+ my $counter = -1;
+ foreach my $resource (@resources) {
+ my $ressymb = $resource->symb();
+ ($counter,my $recording) =
+ &verify_scantron_grading($resource,$udom,$uname,$env{'request.course.id'},
+ $counter,$studentdata,$partids_by_symb{$ressymb},
+ \%scantron_config,\%lettdig,$numletts);
+ $studentrecord .= $recording;
+ }
+ if ($studentrecord ne $studentdata) {
+ &Apache::lonxml::clear_problem_counter();
+ if (&grade_student_bubbles($r,$uname,$udom,$scan_record,$scancode,
+ \@resources,\%partids_by_symb) eq 'ssi_error') {
+ $ssi_error = 0; # So end of handler error message does not trigger.
+ $r->print("");
+ &ssi_print_error($r);
+ $r->print(&show_grading_menu_form($symb));
+ &Apache::lonnet::remove_lock($lock);
+ delete($completedstudents{$uname});
+ return '';
+ }
+ $counter = -1;
+ $studentrecord = '';
+ foreach my $resource (@resources) {
+ my $ressymb = $resource->symb();
+ ($counter,my $recording) =
+ &verify_scantron_grading($resource,$udom,$uname,$env{'request.course.id'},
+ $counter,$studentdata,$partids_by_symb{$ressymb},
+ \%scantron_config,\%lettdig,$numletts);
+ $studentrecord .= $recording;
+ }
+ if ($studentrecord ne $studentdata) {
+ $r->print('');
+ if ($scancode eq '') {
+ $r->print(&mt('Mismatch grading bubble sheet for user: [_1] with ID: [_2].',
+ $uname.':'.$udom,$scan_record->{'scantron.ID'}));
+ } else {
+ $r->print(&mt('Mismatch grading bubble sheet for user: [_1] with ID: [_2] and CODE: [_3].',
+ $uname.':'.$udom,$scan_record->{'scantron.ID'},$scancode));
+ }
+ $r->print(' '.&Apache::loncommon::start_data_table()."\n".
+ &Apache::loncommon::start_data_table_header_row()."\n".
+ '
'.&mt('Source').' '.&mt('Bubbled responses').' '.
+ &Apache::loncommon::end_data_table_header_row()."\n".
+ &Apache::loncommon::start_data_table_row().
+ ''.&mt('Bubble Sheet').' '.
+ ''.$studentdata.' '.
+ &Apache::loncommon::end_data_table_row().
+ &Apache::loncommon::start_data_table_row().
+ 'Stored submissions '.
+ ''.$studentrecord.' '."\n".
+ &Apache::loncommon::end_data_table_row().
+ &Apache::loncommon::end_data_table().'');
+ } else {
+ $r->print(''.
+ &mt('A second grading pass was needed for user: [_1] with ID: [_2], because a mismatch was seen on the first pass.',$uname.':'.$udom,$scan_record->{'scantron.ID'}).' '.
+ &mt("As a consequence, this user's submission history records two tries.").
+ ' ');
+ }
+ }
+ }
+ if (&Apache::loncommon::connection_aborted($r)) { last; }
} continue {
&Apache::lonxml::clear_problem_counter();
- &Apache::lonnet::delenv('scantron\.');
+ &Apache::lonnet::delenv('scantron.');
}
&Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state);
&Apache::lonnet::remove_lock($lock);
@@ -7657,62 +7655,125 @@ SCANTRONFORM
return '';
}
-=pod
-
-=item scantron_upload_scantron_data
-
- Creates the screen for adding a new bubble sheet data file to a course.
+sub graders_resources_pass {
+ my ($resources,$grader_partids_by_symb,$grader_randomlists_by_symb) = @_;
+ if ((ref($resources) eq 'ARRAY') && (ref($grader_partids_by_symb)) &&
+ (ref($grader_randomlists_by_symb) eq 'HASH')) {
+ foreach my $resource (@{$resources}) {
+ my $ressymb = $resource->symb();
+ my ($analysis,$parts) =
+ &scantron_partids_tograde($resource,$env{'request.course.id'},
+ $env{'user.name'},$env{'user.domain'},1);
+ $grader_partids_by_symb->{$ressymb} = $parts;
+ if (ref($analysis) eq 'HASH') {
+ if (ref($analysis->{'parts_withrandomlist'}) eq 'ARRAY') {
+ $grader_randomlists_by_symb->{$ressymb} =
+ $analysis->{'parts_withrandomlist'};
+ }
+ }
+ }
+ }
+ return;
+}
-=cut
+sub grade_student_bubbles {
+ my ($r,$uname,$udom,$scan_record,$scancode,$resources,$parts) = @_;
+ if (ref($resources) eq 'ARRAY') {
+ my $count = 0;
+ foreach my $resource (@{$resources}) {
+ my $ressymb = $resource->symb();
+ my %form = ('submitted' => 'scantron',
+ 'grade_target' => 'grade',
+ 'grade_username' => $uname,
+ 'grade_domain' => $udom,
+ 'grade_courseid' => $env{'request.course.id'},
+ 'grade_symb' => $ressymb,
+ 'CODE' => $scancode
+ );
+ if (ref($parts) eq 'HASH') {
+ if (ref($parts->{$ressymb}) eq 'ARRAY') {
+ foreach my $part (@{$parts->{$ressymb}}) {
+ $form{'scantron_questnum_start.'.$part} =
+ 1+$env{'form.scantron.first_bubble_line.'.$count};
+ $count++;
+ }
+ }
+ }
+ my $result=&ssi_with_retries($resource->src(),$ssi_retries,%form);
+ return 'ssi_error' if ($ssi_error);
+ last if (&Apache::loncommon::connection_aborted($r));
+ }
+ }
+ return;
+}
sub scantron_upload_scantron_data {
my ($r)=@_;
- $r->print(&Apache::loncommon::coursebrowser_javascript($env{'request.role.domain'}));
+ my $dom = $env{'request.role.domain'};
+ my $domdesc = &Apache::lonnet::domain($dom,'description');
+ $r->print(&Apache::loncommon::coursebrowser_javascript($dom));
my $select_link=&Apache::loncommon::selectcourse_link('rules','courseid',
'domainid',
- 'coursename');
- my $domsel=&Apache::loncommon::select_dom_form($env{'request.role.domain'},
- 'domainid');
+ 'coursename',$dom);
+ my $syllabuslink = ''.&mt('Syllabus').' '.
+ (' 'x2).&mt('(shows course personnel)');
my $default_form_data=&defaultFormData(&get_symb($r,1));
$r->print('
+'.&mt('Send scanned bubblesheet data to a course').'
+
');
return '';
}
-=pod
-
-=item scantron_upload_scantron_data_save
-
- Adds a provided bubble information data file to the course if user
- has the correct privileges to do so.
-
-=cut
sub scantron_upload_scantron_data_save {
my($r)=@_;
@@ -7725,7 +7786,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 {
@@ -7734,36 +7795,25 @@ sub scantron_upload_scantron_data_save {
return '';
}
my %coursedata=&Apache::lonnet::coursedescription($env{'form.domainid'}.'_'.$env{'form.courseid'});
- $r->print(&mt("Doing upload to [_1]",$coursedata{'description'})." ");
- my $fname=$env{'form.upfile.filename'};
- #FIXME
- #copied from lonnet::userfileupload()
- #make that function able to target a specified course
- # Replace Windows backslashes by forward slashes
- $fname=~s/\\/\//g;
- # Get rid of everything but the actual filename
- $fname=~s/^.*\/([^\/]+)$/$1/;
- # Replace spaces by underscores
- $fname=~s/\s+/\_/g;
- # Replace all other weird characters by nothing
- $fname=~s/[^\w\.\-]//g;
- # See if there is anything left
- unless ($fname) { return 'error: no uploaded file'; }
- my $uploadedfile=$fname;
- $fname='scantron_orig_'.$fname;
+ my $uploadedfile;
+ $r->print(''.&mt("Uploading file to [_1]",$coursedata{'description'}).' ');
if (length($env{'form.upfile'}) < 2) {
- $r->print(&mt("Error: The file you attempted to upload, [_1] contained no information. Please check that you entered the correct filename.",''.&HTML::Entities::encode($env{'form.upfile.filename'},'<>&"')." "));
+ $r->print(&mt('[_1]Error:[_2] The file you attempted to upload, [_3] contained no information. Please check that you entered the correct filename.','',' ',''.&HTML::Entities::encode($env{'form.upfile.filename'},'<>&"').' '));
} else {
- my $result=&Apache::lonnet::finishuserfileupload($env{'form.courseid'},$env{'form.domainid'},'upfile',$fname);
- if ($result =~ m|^/uploaded/|) {
- $r->print(&mt("Success: Successfully uploaded [_1] bytes of data into location [_2]",
- (length($env{'form.upfile'})-1),
- ''.$result." "));
+ my $result =
+ &Apache::lonnet::userfileupload('upfile','','scantron','','','',
+ $env{'form.courseid'},$env{'form.domainid'});
+ if ($result =~ m{^/uploaded/}) {
+ $r->print(&mt('[_1]Success:[_2] Successfully uploaded [_3] bytes of data into location: [_4]',
+ '',' ',(length($env{'form.upfile'})-1),
+ ''.$result.' '));
+ ($uploadedfile) = ($result =~ m{/([^/]+)$});
+ $r->print(&validate_uploaded_scantron_file($env{'form.domainid'},
+ $env{'form.courseid'},$uploadedfile));
} else {
- $r->print(&mt("Error: An error ([_1]) occurred when attempting to upload the file, [_2]",
- $result,
- ''.&HTML::Entities::encode($env{'form.upfile.filename'},'<>&"')." "));
-
+ $r->print(&mt('[_1]Error:[_2] An error ([_3]) occurred when attempting to upload the file, [_4]',
+ '',' ',$result,
+ ''.&HTML::Entities::encode($env{'form.upfile.filename'},'<>&"').' '));
}
}
if ($symb) {
@@ -7774,13 +7824,91 @@ sub scantron_upload_scantron_data_save {
return '';
}
-=pod
-
-=item valid_file
-
- Validates that the requested bubble data file exists in the course.
-
-=cut
+sub validate_uploaded_scantron_file {
+ my ($cdom,$cname,$fname) = @_;
+ my $scanlines=&Apache::lonnet::getfile('/uploaded/'.$cdom.'/'.$cname.'/'.$fname);
+ my @lines;
+ if ($scanlines ne '-1') {
+ @lines=split("\n",$scanlines,-1);
+ }
+ my $output;
+ if (@lines) {
+ my (%counts,$max_match_format);
+ my ($max_match_count,$max_match_pct) = (0,0);
+ my $classlist = &Apache::loncoursedata::get_classlist($cdom,$cname);
+ my %idmap = &username_to_idmap($classlist);
+ foreach my $key (keys(%idmap)) {
+ my $lckey = lc($key);
+ $idmap{$lckey} = $idmap{$key};
+ }
+ my %unique_formats;
+ my @formatlines = &get_scantronformat_file();
+ foreach my $line (@formatlines) {
+ chomp($line);
+ my @config = split(/:/,$line);
+ my $idstart = $config[5];
+ my $idlength = $config[6];
+ if (($idstart ne '') && ($idlength > 0)) {
+ if (ref($unique_formats{$idstart.':'.$idlength}) eq 'ARRAY') {
+ push(@{$unique_formats{$idstart.':'.$idlength}},$config[0].':'.$config[1]);
+ } else {
+ $unique_formats{$idstart.':'.$idlength} = [$config[0].':'.$config[1]];
+ }
+ }
+ }
+ foreach my $key (keys(%unique_formats)) {
+ my ($idstart,$idlength) = split(':',$key);
+ %{$counts{$key}} = (
+ 'found' => 0,
+ 'total' => 0,
+ );
+ foreach my $line (@lines) {
+ next if ($line =~ /^#/);
+ next if ($line =~ /^[\s\cz]*$/);
+ my $id = substr($line,$idstart-1,$idlength);
+ $id = lc($id);
+ if (exists($idmap{$id})) {
+ $counts{$key}{'found'} ++;
+ }
+ $counts{$key}{'total'} ++;
+ }
+ if ($counts{$key}{'total'}) {
+ my $percent_match = (100*$counts{$key}{'found'})/($counts{$key}{'total'});
+ if (($max_match_format eq '') || ($percent_match > $max_match_pct)) {
+ $max_match_pct = $percent_match;
+ $max_match_format = $key;
+ $max_match_count = $counts{$key}{'total'};
+ }
+ }
+ }
+ if (ref($unique_formats{$max_match_format}) eq 'ARRAY') {
+ my $format_descs;
+ my $numwithformat = @{$unique_formats{$max_match_format}};
+ for (my $i=0; $i<$numwithformat; $i++) {
+ my ($name,$desc) = split(':',$unique_formats{$max_match_format}[$i]);
+ if ($i<$numwithformat-2) {
+ $format_descs .= '"'.$desc.' ", ';
+ } elsif ($i==$numwithformat-2) {
+ $format_descs .= '"'.$desc.' " '.&mt('and').' ';
+ } elsif ($i==$numwithformat-1) {
+ $format_descs .= '"'.$desc.' "';
+ }
+ }
+ my $showpct = sprintf("%.0f",$max_match_pct).'%';
+ $output .= ' '.&mt('Comparison of student IDs in the uploaded file with the course roster found matches for [_1] of the [_2] entries in the file (for the format defined for [_3]).',''.$showpct.' ',''.$max_match_count.' ',$format_descs).
+ ' '.&mt('A low percentage of matches results from one of the following:').''.
+ ''.&mt('The file was uploaded to the wrong course').' '.
+ ''.&mt('The data are not in the format expected for the domain: [_1]',
+ ''.$cdom.' ').' '.
+ ''.&mt('Students did not bubble their IDs, or mis-bubbled them').' '.
+ ''.&mt('The course roster is not up to date').' '.
+ ' ';
+ }
+ } else {
+ $output = ''.&mt('Uploaded file contained no data').' ';
+ }
+ return $output;
+}
sub valid_file {
my ($requested_file)=@_;
@@ -7790,16 +7918,6 @@ sub valid_file {
return 0;
}
-=pod
-
-=item scantron_download_scantron_data
-
- Shows a list of the three internal files (original, corrected,
- skipped) for a specific bubble sheet data file that exists in the
- course.
-
-=cut
-
sub scantron_download_scantron_data {
my ($r)=@_;
my $default_form_data=&defaultFormData(&get_symb($r,1));
@@ -7845,18 +7963,7 @@ sub checkscantron_results {
if (!$symb) {return '';}
my $grading_menu_button=&show_grading_menu_form($symb);
my $cid = $env{'request.course.id'};
- my %lettdig = (
- A => 1,
- B => 2,
- C => 3,
- D => 4,
- E => 5,
- F => 6,
- G => 7,
- H => 8,
- I => 9,
- J => 0,
- );
+ my %lettdig = &letter_to_digits();
my $numletts = scalar(keys(%lettdig));
my $cnum = $env{'course.'.$cid.'.num'};
my $cdom = $env{'course.'.$cid.'.domain'};
@@ -7869,7 +7976,11 @@ sub checkscantron_results {
my %idmap=&Apache::grades::username_to_idmap($classlist);
my $navmap=Apache::lonnavmaps::navmap->new();
my $map=$navmap->getResourceByUrl($sequence);
- my @resources=$navmap->retrieveResources($map,undef,1,0);
+ 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 ($uname,$udom);
my (%scandata,%lastname,%bylast);
$r->print('
'.$grading_menu_button);
return;
}
-=pod
+sub verify_scantron_grading {
+ my ($resource,$domain,$username,$cid,$counter,$scandata,$partids,
+ $scantron_config,$lettdig,$numletts) = @_;
+ my ($record,%expected,%startpos);
+ return ($counter,$record) if (!ref($resource));
+ return ($counter,$record) if (!$resource->is_problem());
+ my $symb = $resource->symb();
+ return ($counter,$record) if (ref($partids) ne 'ARRAY');
+ foreach my $part_id (@{$partids}) {
+ $counter ++;
+ $expected{$part_id} = 0;
+ if ($env{"form.scantron.sub_bubblelines.$counter"}) {
+ my @sub_lines = split(/,/,$env{"form.scantron.sub_bubblelines.$counter"});
+ foreach my $item (@sub_lines) {
+ $expected{$part_id} += $item;
+ }
+ } else {
+ $expected{$part_id} = $env{"form.scantron.bubblelines.$counter"};
+ }
+ $startpos{$part_id} = $env{"form.scantron.first_bubble_line.$counter"};
+ }
+ if ($symb) {
+ my %recorded;
+ my (%returnhash) = &Apache::lonnet::restore($symb,$cid,$domain,$username);
+ if ($returnhash{'version'}) {
+ my %lasthash=();
+ my $version;
+ for ($version=1;$version<=$returnhash{'version'};$version++) {
+ foreach my $key (sort(split(/\:/,$returnhash{$version.':keys'}))) {
+ $lasthash{$key}=$returnhash{$version.':'.$key};
+ }
+ }
+ foreach my $key (keys(%lasthash)) {
+ if ($key =~ /\.scantron$/) {
+ my $value = &unescape($lasthash{$key});
+ my ($part_id) = ($key =~ /^resource\.(.+)\.scantron$/);
+ if ($value eq '') {
+ for (my $i=0; $i<$expected{$part_id}; $i++) {
+ for (my $j=0; $j<$scantron_config->{'length'}; $j++) {
+ $recorded{$part_id} .= $scantron_config->{'Qoff'};
+ }
+ }
+ } else {
+ my @tocheck;
+ my @items = split(//,$value);
+ if (($scantron_config->{'Qon'} eq 'letter') ||
+ ($scantron_config->{'Qon'} eq 'number')) {
+ if (@items < $expected{$part_id}) {
+ my $fragment = substr($scandata,$startpos{$part_id},$expected{$part_id});
+ my @singles = split(//,$fragment);
+ foreach my $pos (@singles) {
+ if ($pos eq ' ') {
+ push(@tocheck,$pos);
+ } else {
+ my $next = shift(@items);
+ push(@tocheck,$next);
+ }
+ }
+ } else {
+ @tocheck = @items;
+ }
+ foreach my $letter (@tocheck) {
+ if ($scantron_config->{'Qon'} eq 'letter') {
+ if ($letter !~ /^[A-J]$/) {
+ $letter = $scantron_config->{'Qoff'};
+ }
+ $recorded{$part_id} .= $letter;
+ } elsif ($scantron_config->{'Qon'} eq 'number') {
+ my $digit;
+ if ($letter !~ /^[A-J]$/) {
+ $digit = $scantron_config->{'Qoff'};
+ } else {
+ $digit = $lettdig->{$letter};
+ }
+ $recorded{$part_id} .= $digit;
+ }
+ }
+ } else {
+ @tocheck = @items;
+ for (my $i=0; $i<$expected{$part_id}; $i++) {
+ my $curr_sub = shift(@tocheck);
+ my $digit;
+ if ($curr_sub =~ /^[A-J]$/) {
+ $digit = $lettdig->{$curr_sub}-1;
+ }
+ if ($curr_sub eq 'J') {
+ $digit += scalar($numletts);
+ }
+ for (my $j=0; $j<$scantron_config->{'Qlength'}; $j++) {
+ if ($j == $digit) {
+ $recorded{$part_id} .= $scantron_config->{'Qon'};
+ } else {
+ $recorded{$part_id} .= $scantron_config->{'Qoff'};
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ foreach my $part_id (@{$partids}) {
+ if ($recorded{$part_id} eq '') {
+ for (my $i=0; $i<$expected{$part_id}; $i++) {
+ for (my $j=0; $j<$scantron_config->{'Qlength'}; $j++) {
+ $recorded{$part_id} .= $scantron_config->{'Qoff'};
+ }
+ }
+ }
+ $record .= $recorded{$part_id};
+ }
+ }
+ return ($counter,$record);
+}
-=back
+sub letter_to_digits {
+ my %lettdig = (
+ A => 1,
+ B => 2,
+ C => 3,
+ D => 4,
+ E => 5,
+ F => 6,
+ G => 7,
+ H => 8,
+ I => 9,
+ J => 0,
+ );
+ return %lettdig;
+}
-=cut
#-------- end of section for handling grading scantron forms -------
#
@@ -8155,36 +8287,49 @@ 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 Scantron 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;
@@ -8198,25 +8343,16 @@ sub grading_menu {
' '."\n".
' '."\n";
- foreach my $menudata (@menu) {
- if ($menudata->{'name'} ne &mt('Verify Receipt')) {
- $Str .=' \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(<
function checkChoice(formname,val,cmdx) {
@@ -8244,7 +8380,7 @@ sub grading_menu {
if (nospace == "OK" && isNaN(receiptNo)) {checkOpt = true;}
if (nospace == "notOK" && (isNaN(receiptNo) || receiptNo == "")) {checkOpt = true;}
if (checkOpt) {
- alert("Please enter a receipt number given by a student in the receipt box.");
+ alert("$receiptalert");
formname.receipt.value = "";
formname.receipt.focus();
return false;
@@ -8265,6 +8401,7 @@ sub submit_options {
if (!$symb) {return '';}
my $probTitle = &Apache::lonnet::gettitle($symb);
+ my $receiptalert = &mt("Please enter a receipt number given by a student in the receipt box.");
$request->print(<
function checkChoice(formname,val,cmdx) {
@@ -8292,7 +8429,7 @@ sub submit_options {
if (nospace == "OK" && isNaN(receiptNo)) {checkOpt = true;}
if (nospace == "notOK" && (isNaN(receiptNo) || receiptNo == "")) {checkOpt = true;}
if (checkOpt) {
- alert("Please enter a receipt number given by a student in the receipt box.");
+ alert("$receiptalert");
formname.receipt.value = "";
formname.receipt.focus();
return false;
@@ -8311,6 +8448,15 @@ GRADINGMENUJS
my $saveSub = ($$savedState{'saveSub'} eq '' ? 'all' : $$savedState{'saveSub'});
my $saveStatus = ($$savedState{'saveStatus'} eq '' ? 'Active' : $$savedState{'saveStatus'});
+ # Preselect sections
+ my $selsec="";
+ if (ref($sections)) {
+ foreach my $section (sort(@$sections)) {
+ $selsec.=''.$section.' '."\n";
+ }
+ }
+
$result.='