'.
'';
@@ -692,7 +717,14 @@ LISTJAVASCRIPT
$gradeTable.=' '."\n";
my $ctr = 0;
- foreach my $student (sort {lc($$fullname{$a}) cmp lc($$fullname{$b}) } keys %$fullname) {
+ foreach my $student (sort
+ {
+ if (lc($$fullname{$a}) ne lc($$fullname{$b})) {
+ return (lc($$fullname{$a}) cmp lc($$fullname{$b}));
+ }
+ return $a cmp $b;
+ }
+ (keys(%$fullname))) {
my ($uname,$udom) = split(/:/,$student);
my %status = ();
if ($env{'form.showgrading'} eq 'yes' && $submitonly ne 'all') {
@@ -737,7 +769,7 @@ LISTJAVASCRIPT
if ($env{'form.showgrading'} eq 'yes' && $submitonly ne 'all') {
foreach (sort keys(%status)) {
next if (/^resource.*?submitted_by$/);
- $gradeTable.=' '.$status{$_}.' | '."\n";
+ $gradeTable.=' '.$status{$_}.' | '."\n";
}
}
# $gradeTable.=' | ' if ($ctr%2 ==1);
@@ -1346,16 +1378,24 @@ sub gradeBox {
my $result=''."\n";
my $display_part=&get_display_part($partid,undef,$symb);
+
+ my %last_resets = &get_last_resets($symb,$env{'request.course.id'},
+ [$partid]);
+ my $aggtries = $$record{'resource.'.$partid.'.tries'};
+ if ($last_resets{$partid}) {
+ $aggtries = &get_num_tries($record,$last_resets{$partid},$partid);
+ }
+
$result.=''.
'Part: '.$display_part.' Points: | '."\n";
my $ctr = 0;
$result.=''."\n";
return $result;
}
@@ -1593,7 +1637,6 @@ KEYWORDS
}
my %record = &Apache::lonnet::restore($symb,$env{'request.course.id'},$udom,$uname);
-
my ($partlist,$handgrade,$responseType) = &response_type($url,$symb);
# Display student info
@@ -1836,7 +1879,16 @@ KEYWORDS
# print end of form
if ($counter == $total) {
- my $endform=''."\n";
+ my $endform='';
+ if (&Apache::lonnet::allowed('vgr',$env{'request.course.id'})) {
+ $endform.=' '.
+ &Apache::loncommon::track_student_link(&mt('View recent activity'),$uname,$udom,'check');
+ }
+ if (&Apache::lonnet::allowed('opa',$env{'request.course.id'})) {
+ $endform.=' '.
+ &Apache::loncommon::pprmlink(&mt('Set/Change parameters'),$uname,$udom,$symb,'check');
+ }
+ $endform.=''."\n";
$endform.=' '."\n";
@@ -1924,6 +1976,7 @@ sub processHandGrade {
my ($subject,$message,$msgstatus) = ('','','');
if ($includemsg =~ /savemsg|newmsg\Q$ctr\E/) {
$subject = $env{'form.msgsub'} if ($includemsg =~ /^msgsub/);
+ unless ($subject=~/\w/) { $subject=&mt('Grading Feedback'); }
my (@msgnum) = split(/,/,$includemsg);
foreach (@msgnum) {
$message.=$env{'form.'.$_} if ($_ =~ /savemsg|newmsg/ && $_ ne '');
@@ -1934,7 +1987,10 @@ sub processHandGrade {
&Apache::lonnet::clutter($url).
"?symb=$symb\">$env{'form.probTitle'}";
$msgstatus = &Apache::lonmsg::user_normal_msg ($uname,$udom,
- $env{'form.msgsub'},$message);
+ $env{'form.msgsub'}.' ['.
+ &Apache::lonnet::declutter($url).']',$message);
+ $request->print(' '.&mt('Sending message to [_1]@[_2]',$uname,$udom).': '.
+ $msgstatus);
}
if ($env{'form.collaborator'.$ctr}) {
my @collabstrs=&Apache::loncommon::get_env_multiple("form.collaborator$ctr");
@@ -2043,7 +2099,13 @@ sub processHandGrade {
my (@parsedlist,@nextlist);
my ($nextflg) = 0;
- foreach (sort {lc($$fullname{$a}) cmp lc($$fullname{$b}) } keys %$fullname) {
+ foreach (sort
+ {
+ if (lc($$fullname{$a}) ne lc($$fullname{$b})) {
+ return (lc($$fullname{$a}) cmp lc($$fullname{$b}));
+ }
+ return $a cmp $b;
+ } (keys(%$fullname))) {
if ($nextflg == 1 && $button =~ /Next$/) {
push @parsedlist,$_;
}
@@ -2117,6 +2179,8 @@ sub saveHandGrade {
my @parts_graded;
my %newrecord = ();
my ($pts,$wgt) = ('','');
+ my %aggregate = ();
+ my $aggregateflag = 0;
foreach my $new_part (split(/:/,$env{'form.partlist'.$newflg})) {
#collaborator may vary for different parts
if ($submitter && $new_part ne $part) { next; }
@@ -2136,6 +2200,21 @@ sub saveHandGrade {
}
$newrecord{'resource.'.$new_part.'.regrader'}=
"$env{'user.name'}:$env{'user.domain'}";
+ my $totaltries = $record{'resource.'.$part.'.tries'};
+
+ my %last_resets = &get_last_resets($symb,$env{'request.course.id'},
+ [$new_part]);
+ my $aggtries =$totaltries;
+ if ($last_resets{$new_part}) {
+ $aggtries = &get_num_tries(\%record,$last_resets{$new_part},
+ $new_part);
+ }
+
+ my $solvedstatus = $record{'resource.'.$new_part.'.solved'};
+ if ($aggtries > 0) {
+ &decrement($symb,$new_part,\%aggregate,$aggtries,$totaltries,$solvedstatus);
+ $aggregateflag = 1;
+ }
} elsif ($dropMenu eq '') {
$pts = ($env{'form.GD_BOX'.$newflg.'_'.$new_part} ne '' ?
$env{'form.GD_BOX'.$newflg.'_'.$new_part} :
@@ -2184,9 +2263,73 @@ sub saveHandGrade {
&Apache::lonnet::cstore(\%newrecord,$symb,
$env{'request.course.id'},$domain,$stuname);
}
+ if ($aggregateflag) {
+ &Apache::lonnet::cinc('nohist_resourcetracker',\%aggregate,
+ $env{'course.'.$env{'request.course.id'}.'.domain'},
+ $env{'course.'.$env{'request.course.id'}.'.num'});
+ }
return '',$pts,$wgt;
}
+# ----------- Provides number of tries since last reset.
+sub get_num_tries {
+ my ($record,$last_reset,$part) = @_;
+ my $timestamp = '';
+ my $num_tries = 0;
+ if ($$record{'version'}) {
+ for (my $version=$$record{'version'};$version>=1;$version--) {
+ if (exists($$record{$version.':resource.'.$part.'.solved'})) {
+ $timestamp = $$record{$version.':timestamp'};
+ if ($timestamp > $last_reset) {
+ $num_tries ++;
+ } else {
+ last;
+ }
+ }
+ }
+ }
+ return $num_tries;
+}
+
+# ----------- Determine decrements required in aggregate totals
+sub decrement_aggs {
+ my ($symb,$part,$aggregate,$aggtries,$totaltries,$solvedstatus) = @_;
+ my %decrement = (
+ attempts => 0,
+ users => 0,
+ correct => 0
+ );
+ $decrement{'attempts'} = $aggtries;
+ if ($solvedstatus =~ /^correct/) {
+ $decrement{'correct'} = 1;
+ }
+ if ($aggtries == $totaltries) {
+ $decrement{'users'} = 1;
+ }
+ foreach my $type (keys (%decrement)) {
+ $$aggregate{$symb."\0".$part."\0".$type} = -$decrement{$type};
+ }
+ return;
+}
+
+# ----------- Determine timestamps for last reset of aggregate totals for parts
+sub get_last_resets {
+ my ($symb,$courseid,$partids) =@_;
+ my %last_resets;
+ my $cdom = $env{'course.'.$courseid.'.domain'};
+ my $cname = $env{'course.'.$courseid.'.num'};
+ my @keys;
+ foreach my $part (@{$partids}) {
+ push(@keys,"$symb\0$part\0resettime");
+ }
+ my %results=&Apache::lonnet::get('nohist_resourcetracker',\@keys,
+ $cdom,$cname);
+ foreach my $part (@{$partids}) {
+ $last_resets{$part}=$results{"$symb\0$part\0resettime"};
+ }
+ return %last_resets;
+}
+
# ----------- Handles creating versions for portfolio files as answers
sub version_portfiles {
my ($record, $parts_graded, $courseid, $symb, $domain, $stuname, $v_flag) = @_;
@@ -2195,12 +2338,13 @@ sub version_portfiles {
my $portfolio_root = &Apache::loncommon::propath($domain,
$stuname).
'/userfiles/portfolio';
- foreach my $key(keys %$record) {
+ foreach my $key (keys(%$record)) {
my $new_portfiles;
+
if ($key =~ /^resource\.($version_parts)\./ && $key =~ /\.portfiles$/ ) {
my @v_portfiles;
my @portfiles = split(/,/,$$record{$key});
- # &Apache::lonnet::logthis("should be unmarking and remarking");
+ &Apache::lonnet::logthis("should be unmarking and remarking $key",@portfiles);
foreach my $file (@portfiles) {
&Apache::lonnet::unmark_as_readonly($domain,$stuname,[$symb,$env{'request.course.id'}],$file);
my ($directory,$answer_file) =($file =~ /^(.*?)([^\/]*$)/);
@@ -2223,14 +2367,13 @@ sub version_portfiles {
}
}
$version++;
- my $home_server = &Apache::lonnet::homeserver($stuname,$domain,undef);
$env{'form.copy'} = &Apache::lonnet::getfile("/uploaded/$domain/$stuname/portfolio$directory$answer_file");
if($env{'form.copy'} eq '-1') {
&Apache::lonnet::logthis('problem getting file '.$directory.$answer_file);
} else {
- my $copy_result = &Apache::lonnet::finishuserfileupload($stuname,$domain,$home_server,'copy',
+ my $copy_result = &Apache::lonnet::finishuserfileupload($stuname,$domain,'copy',
'/portfolio'.$directory.$answer_file_parts[0].'.'.$version.'.'.$answer_file_parts[-1]);
- push(@v_portfiles, $answer_file_parts[0].'.'.$version.'.'.$answer_file_parts[-1]);
+ push(@v_portfiles, $directory.$answer_file_parts[0].'.'.$version.'.'.$answer_file_parts[-1]);
&Apache::lonnet::mark_as_readonly($domain,$stuname,
['/portfolio'.$directory.$answer_file_parts[0].'.'.$version.'.'.$answer_file_parts[-1]],
[$symb,$env{'request.course.id'},'graded']);
@@ -2292,6 +2435,7 @@ sub viewgrades_js {
}
for (i=0;i';
my $ctr = 0;
while ($ctr<=$weight{$partid}) { # display radio buttons in a nice table 10 across
- $result.= ' | \n";
+ ','.$ctr.')" />'.$ctr."\n";
$result.=(($ctr+1)%10 == 0 ? ' ' : '');
$ctr++;
}
@@ -2509,11 +2656,13 @@ sub viewgrades {
' No. | '.
''.&nameUserString('header')." | \n";
my (@parts) = sort(&getpartlist($url,$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
if (!$display) { $display = &Apache::lonnet::metadata($url,$part.'.name'); }
my ($partid) = &split_part_type($part);
+ push(@partids, $partid);
my $display_part=&get_display_part($partid,$url,$symb);
if ($display =~ /^Partial Credit Factor/) {
$result.='Score Part: '.$display_part.
@@ -2527,14 +2676,23 @@ sub viewgrades {
}
$result.=' | ';
+ my %last_resets =
+ &get_last_resets($symb,$env{'request.course.id'},\@partids);
+
#get info for each student
#list all the students - with points and grade status
my (undef,undef,$fullname) = &getclasslist($env{'form.section'},'1');
my $ctr = 0;
- foreach (sort {lc($$fullname{$a}) cmp lc($$fullname{$b}) } keys %$fullname) {
+ foreach (sort
+ {
+ if (lc($$fullname{$a}) ne lc($$fullname{$b})) {
+ return (lc($$fullname{$a}) cmp lc($$fullname{$b}));
+ }
+ return $a cmp $b;
+ } (keys(%$fullname))) {
$ctr++;
$result.=&viewstudentgrade($url,$symb,$env{'request.course.id'},
- $_,$$fullname{$_},\@parts,\%weight,$ctr);
+ $_,$$fullname{$_},\@parts,\%weight,$ctr,\%last_resets);
}
$result.='
| ';
$result.=''."\n";
@@ -2551,20 +2709,36 @@ sub viewgrades {
#--- call by previous routine to display each student
sub viewstudentgrade {
- my ($url,$symb,$courseid,$student,$fullname,$parts,$weight,$ctr) = @_;
+ my ($url,$symb,$courseid,$student,$fullname,$parts,$weight,$ctr,$last_resets) = @_;
my ($uname,$udom) = split(/:/,$student);
- $student=~s/:/_/;
my %record=&Apache::lonnet::restore($symb,$courseid,$udom,$uname);
+ my %aggregates = ();
my $result=' | '.
''.
"\n".$ctr.' | '.
''.$fullname.' '.
'('.$uname.($env{'user.domain'} eq $udom ? '' : ':'.$udom).') | '."\n";
+ $student=~s/:/_/; # colon doen't work in javascript for names
foreach my $apart (@$parts) {
my ($part,$type) = &split_part_type($apart);
my $score=$record{"resource.$part.$type"};
- $result.='';
+ $result.=' | ';
+ my ($aggtries,$totaltries);
+ unless (exists($aggregates{$part})) {
+ $totaltries = $record{'resource.'.$part.'.tries'};
+
+ $aggtries = $totaltries;
+ if ($$last_resets{$part}) {
+ $aggtries = &get_num_tries(\%record,$$last_resets{$part},
+ $part);
+ }
+ $result.=''."\n";
+ $result.=''."\n";
+ $aggregates{$part} = 1;
+ }
if ($type eq 'awarded') {
my $pts = $score eq '' ? '' : $score*$$weight{$part};
$result.='Not allowed to modify student | ";
next;
}
+ my %aggregate = ();
+ my $aggregateflag = 0;
+ $user=~s/:/_/; # colon doen't work in javascript for names
foreach (@partid) {
my $old_aw = $env{'form.GD_'.$user.'_'.$_.'_awarded_s'};
my $old_part_pcr = $old_aw/($weight{$_} ne '0' ? $weight{$_}:1);
my $old_part = $old_aw eq '' ? '' : $old_part_pcr;
my $old_score = $scoreptr{$env{'form.GD_'.$user.'_'.$_.'_solved_s'}};
-
my $awarded = $env{'form.GD_'.$user.'_'.$_.'_awarded'};
my $pcr = $awarded/($weight{$_} ne '0' ? $weight{$_} : 1);
my $partial = $awarded eq '' ? '' : $pcr;
@@ -2699,14 +2873,22 @@ sub editgrades {
my $dropMenu = $env{'form.GD_'.$user.'_'.$_.'_solved'};
$score = 'excused' if (($dropMenu eq 'excused') && ($score ne 'excused'));
+ $newrecord{'resource.'.$_.'.regrader'}=
+ "$env{'user.name'}:$env{'user.domain'}";
if ($dropMenu eq 'reset status' &&
$old_score ne '') { # ignore if no previous attempts => nothing to reset
$newrecord{'resource.'.$_.'.tries'} = 0;
$newrecord{'resource.'.$_.'.solved'} = '';
$newrecord{'resource.'.$_.'.award'} = '';
$newrecord{'resource.'.$_.'.awarded'} = 0;
- $newrecord{'resource.'.$_.'.regrader'}="$env{'user.name'}:$env{'user.domain'}";
$updateflag = 1;
+ if ($env{'form.GD_'.$user.'_'.$_.'_aggtries'} > 0) {
+ my $aggtries = $env{'form.GD_'.$user.'_'.$_.'_aggtries'};
+ my $totaltries = $env{'form.GD_'.$user.'_'.$_.'_totaltries'};
+ my $solvedstatus = $env{'form.GD_'.$user.'_'.$_.'_solved_s'};
+ &decrement_aggs($symb,$_,\%aggregate,$aggtries,$totaltries,$solvedstatus);
+ $aggregateflag = 1;
+ }
} elsif (!($old_part eq $partial && $old_score eq $score)) {
$updateflag = 1;
$newrecord{'resource.'.$_.'.awarded'} = $partial if $partial ne '';
@@ -2746,6 +2928,11 @@ sub editgrades {
$noupdate.=' '.$noupdateCtr.' | '.$line;
$noupdateCtr++;
}
+ if ($aggregateflag) {
+ &Apache::lonnet::cinc('nohist_resourcetracker',\%aggregate,
+ $env{'course.'.$env{'request.course.id'}.'.domain'},
+ $env{'course.'.$env{'request.course.id'}.'.num'});
+ }
}
if ($noupdate) {
# my $numcols=(scalar(@partid)*(scalar(@parts)-1)*2)+3;
@@ -2930,10 +3117,7 @@ sub csvuploadmap_footer {
ENDPICK
}
-sub upcsvScores_form {
- my ($request) = shift;
- my ($symb,$url)=&get_symb_and_url($request);
- if (!$symb) {return '';}
+sub checkforfile_js {
my $result =<
function checkUpload(formname) {
@@ -2945,6 +3129,14 @@ sub upcsvScores_form {
}
CSVFORMJS
+ return $result;
+}
+
+sub upcsvScores_form {
+ my ($request) = shift;
+ my ($symb,$url)=&get_symb_and_url($request);
+ if (!$symb) {return '';}
+ my $result=&checkforfile_js();
$env{'form.probTitle'} = &Apache::lonnet::gettitle($symb);
my ($table) = &showResourceInfo($url,$env{'form.probTitle'});
$result.=$table;
@@ -2964,7 +3156,7 @@ CSVFORMJS
$upfile_select
- '."\n";
@@ -3022,7 +3214,6 @@ sub csvuploadoptions {
\n");
+ $request->print('
+ '."\n");
$request->print(&show_grading_menu_form($symb,$url));
return '';
}
@@ -3225,13 +3417,13 @@ LISTJAVASCRIPT
$result.=''."\n".
''."\n";
- $result.=' View Problems Text: no '."\n".
- ' yes '." \n";
+ $result.=' View Problems Text: no '."\n".
+ ' yes '." \n";
$result.=' Submission Details: '.
- ' none'."\n".
- ' by dates and submissions'."\n".
- ' all details'."\n";
+ ' none'."\n".
+ ' by dates and submissions'."\n".
+ ' all details'."\n";
$result.=''."\n".
''."\n".
@@ -3255,12 +3447,18 @@ LISTJAVASCRIPT
my (undef,undef,$fullname) = &getclasslist($getsec,'1');
my $ptr = 1;
- foreach my $student (sort {lc($$fullname{$a}) cmp lc($$fullname{$b}) } keys %$fullname) {
+ foreach my $student (sort
+ {
+ if (lc($$fullname{$a}) ne lc($$fullname{$b})) {
+ return (lc($$fullname{$a}) cmp lc($$fullname{$b}));
+ }
+ return $a cmp $b;
+ } (keys(%$fullname))) {
my ($uname,$udom) = split(/:/,$student);
$studentTable.=($ptr%2 == 1 ? ' | ' : '');
$studentTable.=''.$ptr.' | ';
- $studentTable.=' '
- .&nameUserString(undef,$$fullname{$student},$uname,$udom)."\n";
+ $studentTable.=' | '
+ .&nameUserString(undef,$$fullname{$student},$uname,$udom)."\n";
$studentTable.=($ptr%2 == 0 ? ' | ' : '');
$ptr++;
}
@@ -3332,7 +3530,11 @@ sub displayPage {
my $navmap = Apache::lonnavmaps::navmap->new();
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 view requested sequence. ('.$resUrl.')');
+ $request->print(&show_grading_menu_form($symb,$url));
+ return;
+ }
my $iterator = $navmap->getIterator($map->map_start(),
$map->map_finish());
@@ -3538,7 +3740,12 @@ sub updateGradeByPage {
my $navmap = Apache::lonnavmaps::navmap->new();
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.')');
+ my ($symb,$url)=&get_symb_and_url($request);
+ $request->print(&show_grading_menu_form($symb,$url));
+ return;
+ }
my $iterator = $navmap->getIterator($map->map_start(),
$map->map_finish());
@@ -3566,6 +3773,8 @@ sub updateGradeByPage {
my %newrecord=();
my @displayPts=();
+ my %aggregate = ();
+ my $aggregateflag = 0;
foreach my $partid (@{$parts}) {
my $newpts = $env{'form.GD_BOX'.$question.'_'.$partid};
my $oldpts = $env{'form.oldpts'.$question.'_'.$partid};
@@ -3592,6 +3801,14 @@ sub updateGradeByPage {
$newrecord{'resource.'.$partid.'.regrader'} = "$env{'user.name'}:$env{'user.domain'}";
$changeflag++;
$newpts = '';
+
+ my $aggtries = $env{'form.aggtries'.$question.'_'.$partid};
+ my $totaltries = $env{'form.totaltries'.$question.'_'.$partid};
+ my $solvedstatus = $env{'form.solved'.$question.'_'.$partid};
+ if ($aggtries > 0) {
+ &decrement_aggs($symbx,$partid,\%aggregate,$aggtries,$totaltries,$solvedstatus);
+ $aggregateflag = 1;
+ }
}
my $display_part=&get_display_part($partid,undef,
$curRes->symb());
@@ -3617,6 +3834,11 @@ sub updateGradeByPage {
&Apache::lonnet::cstore(\%newrecord,$symbx,$env{'request.course.id'},
$udom,$uname);
}
+ if ($aggregateflag) {
+ &Apache::lonnet::cinc('nohist_resourcetracker',\%aggregate,
+ $env{'course.'.$env{'request.course.id'}.'.domain'},
+ $env{'course.'.$env{'request.course.id'}.'.num'});
+ }
$studentTable.=''.$displayPts[0].' | '.
''.$displayPts[1].' | '.
@@ -3718,6 +3940,7 @@ sub scantron_CODElist {
my $namechoice='';
foreach my $name (sort {uc($a) cmp uc($b)} @names) {
if ($name =~ /^error: 2 /) { next; }
+ if ($name =~ /^type\0/) { next; }
$namechoice.='';
}
$namechoice='';
@@ -3726,12 +3949,12 @@ sub scantron_CODElist {
sub scantron_CODEunique {
my $result='
- Yes
+ Yes
- No
+ No
';
return $result;
}
@@ -3781,8 +4004,8 @@ sub scantron_selectphase {
Options: |
- Do only previously skipped records
- Remove all exisiting corrections
+ Do only previously skipped records
+ Remove all exisiting corrections
|
@@ -3862,7 +4085,7 @@ SCANTRONFORM
-
+
|
@@ -3961,7 +4184,14 @@ sub scantron_fixup_scanline {
&scan_data($scan_data,
"$whichline.no_bubble.".$args->{'question'},'1');
} else {
- substr($answer,$args->{'response'},1)=$on;
+ if ($on eq 'letter') {
+ my @alphabet=('A'..'Z');
+ $answer=$alphabet[$args->{'response'}];
+ } elsif ($on eq 'number') {
+ $answer=$args->{'response'}+1;
+ } else {
+ substr($answer,$args->{'response'},1)=$on;
+ }
&scan_data($scan_data,
"$whichline.no_bubble.".$args->{'question'},undef,'1');
}
@@ -3986,8 +4216,11 @@ sub scantron_parse_scanline {
my %record;
my $questions=substr($line,$$scantron_config{'Qstart'}-1);
my $data=substr($line,0,$$scantron_config{'Qstart'}-1);
- if ($$scantron_config{'CODElocation'} ne 0) {
- if ($$scantron_config{'CODElocation'} < 0) {
+ if (!($$scantron_config{'CODElocation'} eq 0 ||
+ $$scantron_config{'CODElocation'} eq 'none')) {
+ if ($$scantron_config{'CODElocation'} < 0 ||
+ $$scantron_config{'CODElocation'} eq 'letter' ||
+ $$scantron_config{'CODElocation'} eq 'number') {
$record{'scantron.CODE'}=substr($data,
$$scantron_config{'CODEstart'}-1,
$$scantron_config{'CODElength'});
@@ -4022,8 +4255,12 @@ sub scantron_parse_scanline {
substr($questions,0,$$scantron_config{'Qlength'})='';
if (length($currentquest) < $$scantron_config{'Qlength'}) { next; }
if ($$scantron_config{'Qon'} eq 'letter') {
- if (!$currentquest || $currentquest eq $$scantron_config{'Qoff'} ||
- $currentquest !~ /^[A-Z]$/) {
+ if ($currentquest eq '?') {
+ push(@{$record{'scantron.doubleerror'}},$questnum);
+ $record{"scantron.$questnum.answer"}='';
+ } elsif (!$currentquest
+ || $currentquest eq $$scantron_config{'Qoff'}
+ || $currentquest !~ /^[A-Z]$/) {
$record{"scantron.$questnum.answer"}='';
if (!&scan_data($scan_data,"$whichline.no_bubble.$questnum")) {
push(@{$record{"scantron.missingerror"}},$questnum);
@@ -4032,8 +4269,12 @@ sub scantron_parse_scanline {
$record{"scantron.$questnum.answer"}=$currentquest;
}
} elsif ($$scantron_config{'Qon'} eq 'number') {
- if (!$currentquest || $currentquest eq $$scantron_config{'Qoff'} ||
- $currentquest !~ /^\d$/) {
+ if ($currentquest eq '?') {
+ push(@{$record{'scantron.doubleerror'}},$questnum);
+ $record{"scantron.$questnum.answer"}='';
+ } elsif (!$currentquest
+ || $currentquest eq $$scantron_config{'Qoff'}
+ || $currentquest !~ /^\d$/) {
$record{"scantron.$questnum.answer"}='';
if (!&scan_data($scan_data,"$whichline.no_bubble.$questnum")) {
push(@{$record{"scantron.missingerror"}},$questnum);
@@ -4150,7 +4391,7 @@ sub scantron_process_corrections {
}
}
if ($err) {
- $r->print("Unable to accept last correction, an error occurred :$errmsg:");
+ $r->print("Unable to accept last correction, an error occurred :$errmsg:");
} else {
&scantron_put_line($scanlines,$scan_data,$which,$line,$skip);
&scantron_putfile($scanlines,$scan_data);
@@ -4204,14 +4445,26 @@ sub check_for_error {
sub scantron_warning_screen {
my ($button_text)=@_;
my $title=&Apache::lonnet::gettitle($env{'form.selectpage'});
+ my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
+ my $CODElist="a";
+ if ($scantron_config{'CODElocation'} &&
+ $scantron_config{'CODEstart'} &&
+ $scantron_config{'CODElength'}) {
+ $CODElist=$env{'form.scantron_CODElist'};
+ if ($CODElist eq '') { $CODElist='None'; }
+ $CODElist=
+ 'List of CODES to validate against: | '.
+ $CODElist.' | ';
+ }
return (<
Please double check the information
below before clicking on '$button_text'
-Sequence To be Graded: | $title |
+Sequence to be Graded: | $title |
Data File that will be used: | $env{'form.scantron_selectfile'} |
+$CODElist
@@ -4418,9 +4671,8 @@ sub lonnet_putfile {
my ($contents,$filename)=@_;
my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'};
my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'};
- my $docuhome=$env{'course.'.$env{'request.course.id'}.'.home'};
$env{'form.sillywaytopassafilearound'}=$contents;
- &Apache::lonnet::finishuserfileupload($docuname,$docudom,$docuhome,'sillywaytopassafilearound',$filename);
+ &Apache::lonnet::finishuserfileupload($docuname,$docudom,'sillywaytopassafilearound',$filename);
}
@@ -4588,19 +4840,24 @@ sub scantron_get_correction {
$r->print("How should I handle this? \n");
$r->print("\n ");
my $i=0;
- if ($error eq 'incorrectCODE') {
+ if ($error eq 'incorrectCODE'
+ && $$scan_record{'scantron.CODE'}=~/\S/ ) {
my ($max,$closest)=&scantron_get_closely_matching_CODEs($arg,$$scan_record{'scantron.CODE'});
- foreach my $testcode (@{$closest}) {
- my $checked='';
- if (!$i) { $checked=' checked="on" '; }
- $r->print(" Use the similar CODE ".$testcode." instead.");
- $r->print("\n ");
- $i++;
+ if ($closest > 0) {
+ foreach my $testcode (@{$closest}) {
+ my $checked='';
+ if (!$i) { $checked=' checked="on" '; }
+ $r->print(" Use the similar CODE ".$testcode." instead.");
+ $r->print("\n ");
+ $i++;
+ }
}
}
- my $checked; if (!$i) { $checked=' checked="on" '; }
- $r->print(" Use the CODE ".$$scan_record{'scantron.CODE'}." that is was on the paper, ignoring the error.");
- $r->print("\n ");
+ if ($$scan_record{'scantron.CODE'}=~/\S/ ) {
+ my $checked; if (!$i) { $checked=' checked="on" '; }
+ $r->print(" Use the CODE ".$$scan_record{'scantron.CODE'}." that is was on the paper, ignoring the error.");
+ $r->print("\n ");
+ }
$r->print(<
@@ -4619,9 +4876,9 @@ ENDSCRIPT
"&scantron_CODElist=".&Apache::lonnet::escape($env{'form.scantron_CODElist'}).
"&curCODE=".&Apache::lonnet::escape($$scan_record{'scantron.CODE'}).
"&scantron_selectfile=".&Apache::lonnet::escape($env{'form.scantron_selectfile'});
- $r->print(" Select a CODE from the list of all CODEs and use it. Selected CODE is ");
+ $r->print(" Select a CODE from the list of all CODEs and use it. Selected CODE is ");
$r->print("\n ");
- $r->print(" Use as the CODE.");
+ $r->print(" Use as the CODE.");
$r->print("\n
");
} elsif ($error eq 'doublebubble') {
$r->print("There have been multiple bubbles scanned for a some question(s) \n");
@@ -4654,21 +4911,26 @@ ENDSCRIPT
sub scantron_bubble_selector {
my ($r,$scan_config,$quest,@selected)=@_;
my $max=$$scan_config{'Qlength'};
+
+ my $scmode=$$scan_config{'Qon'};
+ if ($scmode eq 'number' || $scmode eq 'letter') { $max=10; }
+
my @alphabet=('A'..'Z');
$r->print("');
}
@@ -4694,11 +4956,24 @@ sub scantron_get_closely_matching_CODEs
}
sub get_codes {
- my $old_name=$env{'form.scantron_CODElist'};
- my $cdom =$env{'course.'.$env{'request.course.id'}.'.domain'};
- my $cnum =$env{'course.'.$env{'request.course.id'}.'.num'};
- my %result=&Apache::lonnet::get('CODEs',[$old_name],$cdom,$cnum);
- my %allcodes=map {(&Apache::lonprintout::num_to_letters($_),1)} split(',',$result{$old_name});
+ my ($old_name, $cdom, $cnum) = @_;
+ if (!$old_name) {
+ $old_name=$env{'form.scantron_CODElist'};
+ }
+ if (!$cdom) {
+ $cdom =$env{'course.'.$env{'request.course.id'}.'.domain'};
+ }
+ if (!$cnum) {
+ $cnum =$env{'course.'.$env{'request.course.id'}.'.num'};
+ }
+ my %result=&Apache::lonnet::get('CODEs',[$old_name,"type\0$old_name"],
+ $cdom,$cnum);
+ my %allcodes;
+ if ($result{"type\0$old_name"} eq 'number') {
+ %allcodes=map {($_,1)} split(',',$result{$old_name});
+ } else {
+ %allcodes=map {(&Apache::lonprintout::num_to_letters($_),1)} split(',',$result{$old_name});
+ }
return %allcodes;
}
@@ -4988,8 +5263,6 @@ sub scantron_upload_scantron_data_save {
}
my %coursedata=&Apache::lonnet::coursedescription($env{'form.domainid'}.'_'.$env{'form.courseid'});
$r->print("Doing upload to ".$coursedata{'description'}." ");
- my $home=&Apache::lonnet::homeserver($env{'form.courseid'},
- $env{'form.domainid'});
my $fname=$env{'form.upfile.filename'};
#FIXME
#copied from lonnet::userfileupload()
@@ -5009,7 +5282,7 @@ sub scantron_upload_scantron_data_save {
if (length($env{'form.upfile'}) < 2) {
$r->print("Error: The file you attempted to upload, ".&HTML::Entities::encode($env{'form.upfile.filename'},'<>&"').", contained no information. Please check that you entered the correct filename.");
} else {
- my $result=&Apache::lonnet::finishuserfileupload($env{'form.courseid'},$env{'form.domainid'},$home,'upfile',$fname);
+ my $result=&Apache::lonnet::finishuserfileupload($env{'form.courseid'},$env{'form.domainid'},'upfile',$fname);
if ($result =~ m|^/uploaded/|) {
$r->print("Success: Successfully uploaded ".(length($env{'form.upfile'})-1)." bytes of data into location ".$result."");
} else {
@@ -5184,10 +5457,10 @@ GRADINGMENUJS
$result.='';
- $result.=''.
+ $result.=' | '.
' '.''.&mt('Current Resource').': '.&mt('For one or more students').
- ' | '."\n";
$result.=''.
- ' '.
- 'Current Resource: For all students in selected section or course | '."\n";
+ 'Current Resource: For all students in selected section or course'."\n";
$result.=''.
- ' '.
- 'The complete set/page/sequence: For one student | '."\n";
+ 'The complete set/page/sequence: For one student'."\n";
$result.=' '.
''.
@@ -5233,6 +5506,9 @@ GRADINGMENUJS
$result.=' | '.
' access times. | '."\n";
+ $result.=''.
+ ' saved CODEs. | '."\n";
$result.=' '."\n".
' |