version 1.541, 2008/12/22 14:55:28
|
version 1.548, 2009/01/16 10:59:52
|
Line 779 sub listStudents {
|
Line 779 sub listStudents {
|
my $getsec = $env{'form.section'} eq '' ? 'all' : $env{'form.section'}; |
my $getsec = $env{'form.section'} eq '' ? 'all' : $env{'form.section'}; |
my $getgroup = $env{'form.group'} eq '' ? 'all' : $env{'form.group'}; |
my $getgroup = $env{'form.group'} eq '' ? 'all' : $env{'form.group'}; |
my $submitonly= $env{'form.submitonly'} eq '' ? 'all' : $env{'form.submitonly'}; |
my $submitonly= $env{'form.submitonly'} eq '' ? 'all' : $env{'form.submitonly'}; |
my $viewgrade = $env{'form.showgrading'} eq 'yes' ? &mt('View/Grade/Regrade') : &mt('View'); |
my $viewgrade = $env{'form.showgrading'} eq 'yes' ? 'View/Grade/Regrade' : 'View'; |
$env{'form.probTitle'} = $env{'form.probTitle'} eq '' ? |
$env{'form.probTitle'} = $env{'form.probTitle'} eq '' ? |
&Apache::lonnet::gettitle($symb) : $env{'form.probTitle'}; |
&Apache::lonnet::gettitle($symb) : $env{'form.probTitle'}; |
|
|
my $result='<h3><span class="LC_info"> '.$viewgrade. |
my $result='<h3><span class="LC_info"> ' |
&mt(' Submissions for a Student or a Group of Students') |
.&mt("$viewgrade Submissions for a Student or a Group of Students") |
.'</span></h3>'; |
.'</span></h3>'; |
|
|
my ($table,undef,$hdgrade,$partlist,$handgrade) = &showResourceInfo($symb,$env{'form.probTitle'},($env{'form.showgrading'} eq 'yes')); |
my ($table,undef,$hdgrade,$partlist,$handgrade) = &showResourceInfo($symb,$env{'form.probTitle'},($env{'form.showgrading'} eq 'yes')); |
Line 889 LISTJAVASCRIPT
|
Line 889 LISTJAVASCRIPT
|
&Apache::lonhtmlcommon::StatusOptions($saveStatus,undef,1,'javascript:reLoadList(this.form);')).'<br />'; |
&Apache::lonhtmlcommon::StatusOptions($saveStatus,undef,1,'javascript:reLoadList(this.form);')).'<br />'; |
} |
} |
|
|
$gradeTable.=&mt('To [_1] a submission or a group of submissions, click on the check box(es) next to the student\'s name(s). Then click on the Next button.',lc($viewgrade)).'<br />'."\n". |
$gradeTable.=&mt('To '.lc($viewgrade)." a submission or a group of submissions, click on the check box(es) next to the student's name(s). Then click on the Next button.").'<br />'."\n". |
'<input type="hidden" name="command" value="processGroup" />'."\n"; |
'<input type="hidden" name="command" value="processGroup" />'."\n"; |
|
|
# checkall buttons |
# checkall buttons |
Line 2094 KEYWORDS
|
Line 2094 KEYWORDS
|
' )</span> '; |
' )</span> '; |
my $files=&get_submitted_files($udom,$uname,$partid,$respid,\%record); |
my $files=&get_submitted_files($udom,$uname,$partid,$respid,\%record); |
if (@$files) { |
if (@$files) { |
$lastsubonly.='<br /><span class="LC_warning">'.&mt('Like all files provided by users, this file may contain virusses').'</span><br />'; |
$lastsubonly.='<br /><span class="LC_warning">'.&mt('Like all files provided by users, this file may contain viruses').'</span><br />'; |
my $file_counter = 0; |
my $file_counter = 0; |
foreach my $file (@$files) { |
foreach my $file (@$files) { |
$file_counter++; |
$file_counter++; |
Line 2317 sub get_last_submission {
|
Line 2317 sub get_last_submission {
|
$$returnhash{$version.':keys'}))) { |
$$returnhash{$version.':keys'}))) { |
$lasthash{$key}=$$returnhash{$version.':'.$key}; |
$lasthash{$key}=$$returnhash{$version.':'.$key}; |
$timestamp = |
$timestamp = |
scalar(localtime($$returnhash{$version.':timestamp'})); |
&Apache::lonlocal::locallocaltime($$returnhash{$version.':timestamp'}); |
} |
} |
} |
} |
foreach my $key (keys(%lasthash)) { |
foreach my $key (keys(%lasthash)) { |
Line 6177 sub scantron_validate_file {
|
Line 6177 sub scantron_validate_file {
|
} |
} |
if (!$stop) { |
if (!$stop) { |
my $warning=&scantron_warning_screen('Start Grading'); |
my $warning=&scantron_warning_screen('Start Grading'); |
$r->print(&mt('Validation process complete.').'<br /> |
$r->print(&mt('Validation process complete.').'<br />'. |
'.$warning.' |
$warning. |
<input type="submit" name="submit" value="'.&mt('Start Grading').'" /> |
&mt('Perform verification for each student after storage of submissions?'). |
<input type="hidden" name="command" value="scantron_process" /> |
' <span class="LC_nobreak"><label>'. |
'); |
'<input type="radio" name="verifyrecord" value="1" />'.&mt('Yes').'</label>'. |
|
(' 'x3).'<label>'. |
|
'<input type="radio" name="verifyrecord" value="0" checked="checked" />'.&mt('No'). |
|
'</label></span><br />'. |
|
&mt('Grading will take longer if you use verification.').'<br />'. |
|
&mt("Alternatively, the 'Review scantron data' utility (see grading menu) can be used for all students after grading is complete.").'<br /><br />'. |
|
'<input type="submit" name="submit" value="'.&mt('Start Grading').'" />'. |
|
'<input type="hidden" name="command" value="scantron_process" />'."\n"); |
} else { |
} else { |
$r->print('<input type="hidden" name="command" value="scantron_validate" />'); |
$r->print('<input type="hidden" name="command" value="scantron_validate" />'); |
$r->print("<input type='hidden' name='validatepass' value='".$currentphase."' />"); |
$r->print("<input type='hidden' name='validatepass' value='".$currentphase."' />"); |
Line 7240 sub scantron_get_maxbubble {
|
Line 7246 sub scantron_get_maxbubble {
|
my $response_number = 0; |
my $response_number = 0; |
my $bubble_line = 0; |
my $bubble_line = 0; |
foreach my $resource (@resources) { |
foreach my $resource (@resources) { |
my $symb = $resource->symb(); |
my ($analysis,$parts) = &scantron_partids_tograde($resource,$cid,$uname,$udom); |
|
if ((ref($analysis) eq 'HASH') && (ref($parts) eq 'ARRAY')) { |
|
foreach my $part_id (@{$parts}) { |
|
my $lines; |
|
|
|
# TODO - make this a persistent hash not an array. |
|
|
|
# optionresponse, matchresponse and rankresponse type items |
|
# render as separate sub-questions in exam mode. |
|
if (($analysis->{$part_id.'.type'} eq 'optionresponse') || |
|
($analysis->{$part_id.'.type'} eq 'matchresponse') || |
|
($analysis->{$part_id.'.type'} eq 'rankresponse')) { |
|
my ($numbub,$numshown); |
|
if ($analysis->{$part_id.'.type'} eq 'optionresponse') { |
|
if (ref($analysis->{$part_id.'.options'}) eq 'ARRAY') { |
|
$numbub = scalar(@{$analysis->{$part_id.'.options'}}); |
|
} |
|
} elsif ($analysis->{$part_id.'.type'} eq 'matchresponse') { |
|
if (ref($analysis->{$part_id.'.items'}) eq 'ARRAY') { |
|
$numbub = scalar(@{$analysis->{$part_id.'.items'}}); |
|
} |
|
} elsif ($analysis->{$part_id.'.type'} eq 'rankresponse') { |
|
if (ref($analysis->{$part_id.'.foils'}) eq 'ARRAY') { |
|
$numbub = scalar(@{$analysis->{$part_id.'.foils'}}); |
|
} |
|
} |
|
if (ref($analysis->{$part_id.'.shown'}) eq 'ARRAY') { |
|
$numshown = scalar(@{$analysis->{$part_id.'.shown'}}); |
|
} |
|
my $bubbles_per_line = 10; |
|
my $inner_bubble_lines = int($numbub/$bubbles_per_line); |
|
if (($numbub % $bubbles_per_line) != 0) { |
|
$inner_bubble_lines++; |
|
} |
|
for (my $i=0; $i<$numshown; $i++) { |
|
$subdivided_bubble_lines{$response_number} .= |
|
$inner_bubble_lines.','; |
|
} |
|
$subdivided_bubble_lines{$response_number} =~ s/,$//; |
|
$lines = $numshown * $inner_bubble_lines; |
|
} else { |
|
$lines = $analysis->{"$part_id.bubble_lines"}; |
|
} |
|
|
|
$first_bubble_line{$response_number} = $bubble_line; |
|
$bubble_lines_per_response{$response_number} = $lines; |
|
$responsetype_per_response{$response_number} = |
|
$analysis->{$part_id.'.type'}; |
|
$response_number++; |
|
|
|
$bubble_line += $lines; |
|
$total_lines += $lines; |
|
} |
|
} |
|
} |
|
&Apache::lonnet::delenv('scantron\.'); |
|
|
|
&save_bubble_lines(); |
|
$env{'form.scantron_maxbubble'} = |
|
$total_lines; |
|
return $env{'form.scantron_maxbubble'}; |
|
} |
|
|
my @parts; |
sub scantron_partids_tograde { |
|
my ($resource,$cid,$uname,$udom) = @_; |
|
my (%analysis,@parts); |
|
|
|
if (ref($resource)) { |
|
my $symb = $resource->symb(); |
my $result=&ssi_with_retries($resource->src(), $ssi_retries, |
my $result=&ssi_with_retries($resource->src(), $ssi_retries, |
('symb' => $symb, |
('symb' => $symb, |
'grade_target' => 'analyze', |
'grade_target' => 'analyze', |
'grade_courseid' => $cid, |
'grade_courseid' => $cid, |
'grade_domain' => $udom, |
'grade_domain' => $udom, |
'grade_username' => $uname)); |
'grade_username' => $uname)); |
my (undef, $an) = |
my (undef, $an) = split(/_HASH_REF__/,$result, 2); |
split(/_HASH_REF__/,$result, 2); |
%analysis = &Apache::lonnet::str2hash($an); |
|
|
my %analysis = &Apache::lonnet::str2hash($an); |
|
|
|
if (ref($analysis{'parts'}) eq 'ARRAY') { |
if (ref($analysis{'parts'}) eq 'ARRAY') { |
foreach my $part (@{$analysis{'parts'}}) { |
foreach my $part (@{$analysis{'parts'}}) { |
Line 7263 sub scantron_get_maxbubble {
|
Line 7332 sub scantron_get_maxbubble {
|
} |
} |
} |
} |
} |
} |
|
|
foreach my $part_id (@parts) { |
|
my $lines; |
|
|
|
# TODO - make this a persistent hash not an array. |
|
|
|
# optionresponse, matchresponse and rankresponse type items |
|
# render as separate sub-questions in exam mode. |
|
if (($analysis{$part_id.'.type'} eq 'optionresponse') || |
|
($analysis{$part_id.'.type'} eq 'matchresponse') || |
|
($analysis{$part_id.'.type'} eq 'rankresponse')) { |
|
my ($numbub,$numshown); |
|
if ($analysis{$part_id.'.type'} eq 'optionresponse') { |
|
if (ref($analysis{$part_id.'.options'}) eq 'ARRAY') { |
|
$numbub = scalar(@{$analysis{$part_id.'.options'}}); |
|
} |
|
} elsif ($analysis{$part_id.'.type'} eq 'matchresponse') { |
|
if (ref($analysis{$part_id.'.items'}) eq 'ARRAY') { |
|
$numbub = scalar(@{$analysis{$part_id.'.items'}}); |
|
} |
|
} elsif ($analysis{$part_id.'.type'} eq 'rankresponse') { |
|
if (ref($analysis{$part_id.'.foils'}) eq 'ARRAY') { |
|
$numbub = scalar(@{$analysis{$part_id.'.foils'}}); |
|
} |
|
} |
|
if (ref($analysis{$part_id.'.shown'}) eq 'ARRAY') { |
|
$numshown = scalar(@{$analysis{$part_id.'.shown'}}); |
|
} |
|
my $bubbles_per_line = 10; |
|
my $inner_bubble_lines = int($numbub/$bubbles_per_line); |
|
if (($numbub % $bubbles_per_line) != 0) { |
|
$inner_bubble_lines++; |
|
} |
|
for (my $i=0; $i<$numshown; $i++) { |
|
$subdivided_bubble_lines{$response_number} .= |
|
$inner_bubble_lines.','; |
|
} |
|
$subdivided_bubble_lines{$response_number} =~ s/,$//; |
|
$lines = $numshown * $inner_bubble_lines; |
|
} else { |
|
$lines = $analysis{"$part_id.bubble_lines"}; |
|
} |
|
|
|
$first_bubble_line{$response_number} = $bubble_line; |
|
$bubble_lines_per_response{$response_number} = $lines; |
|
$responsetype_per_response{$response_number} = |
|
$analysis{$part_id.'.type'}; |
|
$response_number++; |
|
|
|
$bubble_line += $lines; |
|
$total_lines += $lines; |
|
} |
|
|
|
} |
} |
&Apache::lonnet::delenv('scantron\.'); |
return (\%analysis,\@parts); |
|
|
&save_bubble_lines(); |
|
$env{'form.scantron_maxbubble'} = |
|
$total_lines; |
|
return $env{'form.scantron_maxbubble'}; |
|
} |
} |
|
|
|
|
sub scantron_validate_missingbubbles { |
sub scantron_validate_missingbubbles { |
my ($r,$currentphase) = @_; |
my ($r,$currentphase) = @_; |
#get student info |
#get student info |
Line 7397 sub scantron_process_students {
|
Line 7407 sub scantron_process_students {
|
my $navmap=Apache::lonnavmaps::navmap->new(); |
my $navmap=Apache::lonnavmaps::navmap->new(); |
my $map=$navmap->getResourceByUrl($sequence); |
my $map=$navmap->getResourceByUrl($sequence); |
my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0); |
my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0); |
|
|
|
my ($uname,$udom,%partids_by_symb); |
|
foreach my $resource (@resources) { |
|
my $ressymb = $resource->symb(); |
|
my ($analysis,$parts) = |
|
&scantron_partids_tograde($resource,$env{'request.course.id'},$uname,$udom); |
|
$partids_by_symb{$ressymb} = $parts; |
|
} |
# $r->print("geto ".scalar(@resources)."<br />"); |
# $r->print("geto ".scalar(@resources)."<br />"); |
my $result= <<SCANTRONFORM; |
my $result= <<SCANTRONFORM; |
<form method="post" enctype="multipart/form-data" action="/adm/grades" name="scantronupload"> |
<form method="post" enctype="multipart/form-data" action="/adm/grades" name="scantronupload"> |
Line 7406 SCANTRONFORM
|
Line 7424 SCANTRONFORM
|
$r->print($result); |
$r->print($result); |
|
|
my @delayqueue; |
my @delayqueue; |
my %completedstudents; |
my (%completedstudents,%scandata); |
|
|
my $lock=&Apache::lonnet::set_lock(&mt('Grading bubblesheet exam')); |
my $lock=&Apache::lonnet::set_lock(&mt('Grading bubblesheet exam')); |
my $count=&get_todo_count($scanlines,$scan_data); |
my $count=&get_todo_count($scanlines,$scan_data); |
Line 7415 SCANTRONFORM
|
Line 7433 SCANTRONFORM
|
'inline',undef,'scantronupload'); |
'inline',undef,'scantronupload'); |
&Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state, |
&Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state, |
'Processing first student'); |
'Processing first student'); |
|
$r->print('<br />'); |
my $start=&Time::HiRes::time(); |
my $start=&Time::HiRes::time(); |
my $i=-1; |
my $i=-1; |
my ($uname,$udom,$started); |
my $started; |
|
|
&scantron_get_maxbubble(); # Need the bubble lines array to parse. |
&scantron_get_maxbubble(); # Need the bubble lines array to parse. |
|
|
Line 7433 SCANTRONFORM
|
Line 7452 SCANTRONFORM
|
return ''; # Dunno why the other returns return '' rather than just returning. |
return ''; # Dunno why the other returns return '' rather than just returning. |
} |
} |
|
|
|
my %lettdig = &letter_to_digits(); |
|
my $numletts = scalar(keys(%lettdig)); |
|
|
while ($i<$scanlines->{'count'}) { |
while ($i<$scanlines->{'count'}) { |
($uname,$udom)=('',''); |
($uname,$udom)=('',''); |
$i++; |
$i++; |
Line 7465 SCANTRONFORM
|
Line 7487 SCANTRONFORM
|
&scantron_putfile($scanlines,$scan_data); |
&scantron_putfile($scanlines,$scan_data); |
} |
} |
|
|
my $i=0; |
my $scancode; |
foreach my $resource (@resources) { |
if ((exists($scan_record->{'scantron.CODE'})) && |
$i++; |
(&Apache::lonnet::validCODE($scan_record->{'scantron.CODE'}))) { |
my %form=('submitted' =>'scantron', |
$scancode = $scan_record->{'scantron.CODE'}; |
'grade_target' =>'grade', |
} else { |
'grade_username'=>$uname, |
$scancode = ''; |
'grade_domain' =>$udom, |
} |
'grade_courseid'=>$env{'request.course.id'}, |
|
'grade_symb' =>$resource->symb()); |
if (&grade_student_bubbles($r,$uname,$udom,$scan_record,$scancode, |
if (exists($scan_record->{'scantron.CODE'}) |
@resources) eq 'ssi_error') { |
&& |
$ssi_error = 0; # So end of handler error message does not trigger. |
&Apache::lonnet::validCODE($scan_record->{'scantron.CODE'})) { |
$r->print("</form>"); |
$form{'CODE'}=$scan_record->{'scantron.CODE'}; |
&ssi_print_error($r); |
} else { |
$r->print(&show_grading_menu_form($symb)); |
$form{'CODE'}=''; |
&Apache::lonnet::remove_lock($lock); |
} |
return ''; # Why return ''? Beats me. |
my $result=&ssi_with_retries($resource->src(), $ssi_retries, %form); |
} |
if ($ssi_error) { |
|
$ssi_error = 0; # So end of handler error message does not trigger. |
|
$r->print("</form>"); |
|
&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}; |
$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) { |
|
($counter,my $recording) = |
|
&verify_scantron_grading($resource,$udom,$uname,$env{'request.course.id'}, |
|
$counter,$studentdata,\%partids_by_symb, |
|
\%scantron_config,\%lettdig,$numletts); |
|
$studentrecord .= $recording; |
|
} |
|
if ($studentrecord ne $studentdata) { |
|
$counter = -1; |
|
$studentrecord = ''; |
|
foreach my $resource (@resources) { |
|
($counter,my $recording) = |
|
&verify_scantron_grading($resource,$udom,$uname,$env{'request.course.id'}, |
|
$counter,$studentdata,\%partids_by_symb, |
|
\%scantron_config,\%lettdig,$numletts); |
|
$studentrecord .= $recording; |
|
} |
|
if ($studentrecord ne $studentdata) { |
|
$r->print('<p><span class="LC_error">'); |
|
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('</span><br />'.&Apache::loncommon::start_data_table()."\n". |
|
&Apache::loncommon::start_data_table_header_row()."\n". |
|
'<th>'.&mt('Source').'</th><th>'.&mt('Bubbled responses').'</th>'. |
|
&Apache::loncommon::end_data_table_header_row()."\n". |
|
&Apache::loncommon::start_data_table_row(). |
|
'<td>'.&mt('Bubble Sheet').'</td>'. |
|
'<td><span class="LC_nobreak">'.$studentdata.'</span></td>'. |
|
&Apache::loncommon::end_data_table_row(). |
|
&Apache::loncommon::start_data_table_row(). |
|
'<td>Stored submissions</td>'. |
|
'<td><span class="LC_nobreak">'.$studentrecord.'</span></td>'."\n". |
|
&Apache::loncommon::end_data_table_row(). |
|
&Apache::loncommon::end_data_table().'</p>'); |
|
} else { |
|
$r->print('<br /><span class="LC_warning">'. |
|
&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'}).'<br />'. |
|
&mt("As a consequence, this user's submission history records two tries."). |
|
'</span><br />'); |
|
} |
|
} |
|
} |
|
if (&Apache::loncommon::connection_aborted($r)) { last; } |
} continue { |
} continue { |
&Apache::lonxml::clear_problem_counter(); |
&Apache::lonxml::clear_problem_counter(); |
&Apache::lonnet::delenv('scantron\.'); |
&Apache::lonnet::delenv('scantron\.'); |
Line 7509 SCANTRONFORM
|
Line 7575 SCANTRONFORM
|
return ''; |
return ''; |
} |
} |
|
|
|
sub grade_student_bubbles { |
|
my ($r,$uname,$udom,$scan_record,$scancode,@resources) = @_; |
|
foreach my $resource (@resources) { |
|
my %form = ('submitted' => 'scantron', |
|
'grade_target' => 'grade', |
|
'grade_username'=> $uname, |
|
'grade_domain' => $udom, |
|
'grade_courseid'=> $env{'request.course.id'}, |
|
'grade_symb' => $resource->symb(), |
|
'CODE' => $scancode); |
|
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 { |
sub scantron_upload_scantron_data { |
my ($r)=@_; |
my ($r)=@_; |
$r->print(&Apache::loncommon::coursebrowser_javascript($env{'request.role.domain'})); |
$r->print(&Apache::loncommon::coursebrowser_javascript($env{'request.role.domain'})); |
Line 7663 sub checkscantron_results {
|
Line 7746 sub checkscantron_results {
|
if (!$symb) {return '';} |
if (!$symb) {return '';} |
my $grading_menu_button=&show_grading_menu_form($symb); |
my $grading_menu_button=&show_grading_menu_form($symb); |
my $cid = $env{'request.course.id'}; |
my $cid = $env{'request.course.id'}; |
my %lettdig = ( |
my %lettdig = &letter_to_digits(); |
A => 1, |
|
B => 2, |
|
C => 3, |
|
D => 4, |
|
E => 5, |
|
F => 6, |
|
G => 7, |
|
H => 8, |
|
I => 9, |
|
J => 0, |
|
); |
|
my $numletts = scalar(keys(%lettdig)); |
my $numletts = scalar(keys(%lettdig)); |
my $cnum = $env{'course.'.$cid.'.num'}; |
my $cnum = $env{'course.'.$cid.'.num'}; |
my $cdom = $env{'course.'.$cid.'.domain'}; |
my $cdom = $env{'course.'.$cid.'.domain'}; |
Line 7688 sub checkscantron_results {
|
Line 7760 sub checkscantron_results {
|
my $navmap=Apache::lonnavmaps::navmap->new(); |
my $navmap=Apache::lonnavmaps::navmap->new(); |
my $map=$navmap->getResourceByUrl($sequence); |
my $map=$navmap->getResourceByUrl($sequence); |
my @resources=$navmap->retrieveResources($map,undef,1,0); |
my @resources=$navmap->retrieveResources($map,undef,1,0); |
|
my ($uname,$udom,%partids_by_symb); |
|
foreach my $resource (@resources) { |
|
my $ressymb = $resource->symb(); |
|
my ($analysis,$parts) = |
|
&scantron_partids_tograde($resource,$env{'request.course.id'},$uname,$udom); |
|
$partids_by_symb{$ressymb} = $parts; |
|
} |
my (%scandata,%lastname,%bylast); |
my (%scandata,%lastname,%bylast); |
$r->print(' |
$r->print(' |
<form method="post" enctype="multipart/form-data" action="/adm/grades" name="checkscantron">'."\n"); |
<form method="post" enctype="multipart/form-data" action="/adm/grades" name="checkscantron">'."\n"); |
Line 7699 sub checkscantron_results {
|
Line 7778 sub checkscantron_results {
|
my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Scantron/Submissions Comparison Status', |
my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Scantron/Submissions Comparison Status', |
'Progress of Scantron Data/Submission Records Comparison',$count, |
'Progress of Scantron Data/Submission Records Comparison',$count, |
'inline',undef,'checkscantron'); |
'inline',undef,'checkscantron'); |
my ($username,$domain,$uname,$started); |
my ($username,$domain,$started); |
|
|
&Apache::grades::scantron_get_maxbubble(); # Need the bubble lines array to parse. |
&Apache::grades::scantron_get_maxbubble(); # Need the bubble lines array to parse. |
|
|
Line 7741 sub checkscantron_results {
|
Line 7820 sub checkscantron_results {
|
$scandata{$pid} =~ s/\r$//; |
$scandata{$pid} =~ s/\r$//; |
($username,$domain)=split(/:/,$uname); |
($username,$domain)=split(/:/,$uname); |
my $counter = -1; |
my $counter = -1; |
my (%expected,%startpos); |
|
foreach my $resource (@resources) { |
foreach my $resource (@resources) { |
next if (!$resource->is_problem()); |
($counter,my $recording) = |
my $symb = $resource->symb(); |
&verify_scantron_grading($resource,$domain,$username,$cid,$counter, |
my $partsref = $resource->parts(); |
$scandata{$pid},\%partids_by_symb, |
my @parts; |
\%scantron_config,\%lettdig,$numletts); |
my @part_ids = (); |
$record{$pid} .= $recording; |
if (ref($partsref) eq 'ARRAY') { |
|
@parts = @{$partsref}; |
|
foreach my $part (@parts) { |
|
my @resp_ids = $resource->responseIds($part); |
|
foreach my $resp (@resp_ids) { |
|
$counter ++; |
|
my $part_id = $part.'.'.$resp; |
|
$expected{$part_id} = 0; |
|
push(@part_ids,$part_id); |
|
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} .= $; |
|
} |
|
} |
|
} 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{$pid},$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 (@part_ids) { |
|
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{$pid} .= $recorded{$part_id}; |
|
} |
|
} |
|
} |
} |
} |
} |
&Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state); |
&Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state); |
Line 7922 sub checkscantron_results {
|
Line 7887 sub checkscantron_results {
|
return; |
return; |
} |
} |
|
|
|
sub verify_scantron_grading { |
|
my ($resource,$domain,$username,$cid,$counter,$scandata,$partids_by_symb, |
|
$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_by_symb) ne 'HASH'); |
|
return ($counter,$record) if (ref($partids_by_symb->{$symb}) ne 'ARRAY'); |
|
foreach my $part_id (@{$partids_by_symb->{$symb}}) { |
|
$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_by_symb->{$symb}}) { |
|
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); |
|
} |
|
|
|
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; |
|
} |
|
|
|
|
#-------- end of section for handling grading scantron forms ------- |
#-------- end of section for handling grading scantron forms ------- |
# |
# |