--- loncom/homework/grades.pm 2007/08/29 13:41:32 1.436 +++ loncom/homework/grades.pm 2007/10/09 10:31:21 1.448 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # The LON-CAPA Grading handler # -# $Id: grades.pm,v 1.436 2007/08/29 13:41:32 albertel Exp $ +# $Id: grades.pm,v 1.448 2007/10/09 10:31:21 foxr Exp $ # # Copyright Michigan State University Board of Trustees # @@ -47,37 +47,103 @@ use POSIX qw(floor); my %perm=(); -my %bubble_lines_per_response; # no. bubble lines for each response. +my %bubble_lines_per_response = (); # no. bubble lines for each response. # index is "symb.part_id" +my %first_bubble_line = (); # First bubble line no. for each bubble. + +# Save and restore the bubble lines array to the form env. + + +sub save_bubble_lines { + &Apache::lonnet::logthis("Saving bubble_lines..."); + foreach my $line (keys(%bubble_lines_per_response)) { + &Apache::lonnet::logthis("Saving form.scantron.bubblelines.$line value: $bubble_lines_per_response{$line}"); + $env{"form.scantron.bubblelines.$line"} = $bubble_lines_per_response{$line}; + $env{"form.scantron.first_bubble_line.$line"} = + $first_bubble_line{$line}; + } +} + + +sub restore_bubble_lines { + my $line = 0; + %bubble_lines_per_response = (); + while ($env{"form.scantron.bubblelines.$line"}) { + my $value = $env{"form.scantron.bubblelines.$line"}; + &Apache::lonnet::logthis("Restoring form.scantron.bubblelines.$line value: $value"); + $bubble_lines_per_response{$line} = $value; + $first_bubble_line{$line} = + $env{"form.scantron.first_bubble_line.$line"}; + $line++; + } + +} + +# Given the parsed scanline, get the response for +# 'answer' number n: + +sub get_response_bubbles { + my ($parsed_line, $response) = @_; + + my $bubble_line = $first_bubble_line{$response}; + my $bubble_lines= $bubble_lines_per_response{$response}; + my $selected = ""; + + for (my $bline = 0; $bline < $bubble_lines; $bline++) { + $selected .= $$parsed_line{"scantron.$bubble_line.answer"}; + $bubble_line++; + } + return $selected; +} + # ----- These first few routines are general use routines.---- + +# Return the number of occurences of a pattern in a string. + +sub occurence_count { + my ($string, $pattern) = @_; + + my @matches = ($string =~ /$pattern/g); + + return scalar(@matches); +} + + +# Take a string known to have digits and convert all the +# digits into letters in the range J,A..I. + +sub digits_to_letters { + my ($input) = @_; + + my @alphabet = ('J', 'A'..'I'); + + my @input = split(//, $input); + my $output =''; + for (my $i = 0; $i < scalar(@input); $i++) { + if ($input[$i] =~ /\d/) { + $output .= $alphabet[$input[$i]]; + } else { + $output .= $input[$i]; + } + } + return $output; +} + # # --- Retrieve the parts from the metadata file.--- sub getpartlist { my ($symb) = @_; - my (undef,undef,$url) = &Apache::lonnet::decode_symb($symb); - my $partorder = &Apache::lonnet::metadata($url, 'partorder'); - my @parts; - if ($partorder) { - for my $part (split (/,/,$partorder)) { - if (!&Apache::loncommon::check_if_partid_hidden($part,$symb)) { - push(@parts, $part); - } - } - } else { - my $metadata = &Apache::lonnet::metadata($url, 'packages'); - foreach (split(/\,/,$metadata)) { - if ($_ =~ /^part_(.*)$/) { - if (!&Apache::loncommon::check_if_partid_hidden($1,$symb)) { - push(@parts, $1); - } - } - } - } + + my $navmap = Apache::lonnavmaps::navmap->new(); + my $res = $navmap->getBySymb($symb); + my $partlist = $res->parts(); + my $url = $res->src(); + my @metakeys = split(/,/,&Apache::lonnet::metadata($url,'keys')); + my @stores; - foreach my $part (@parts) { - my (@metakeys) = split(/,/,&Apache::lonnet::metadata($url,'keys')); + foreach my $part (@{ $partlist }) { foreach my $key (@metakeys) { if ($key =~ m/^stores_\Q$part\E_/) { push(@stores,$key); } } @@ -362,7 +428,10 @@ sub cleanRecord { $result.=''; return $result; } - + } elsif ( $response =~ m/(?:numerical|formula)/) { + $answer = + &Apache::loncommon::format_previous_attempt_value('submission', + $answer); } return $answer; } @@ -408,6 +477,7 @@ COMMONJSFUNCTIONS sub getclasslist { my ($getsec,$filterlist) = @_; my @getsec; + my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status')); if (!ref($getsec)) { if ($getsec ne '' && $getsec ne 'all') { @getsec=($getsec); @@ -437,8 +507,8 @@ sub getclasslist { my $status = $classlist->{$student}->[&Apache::loncoursedata::CL_STATUS()]; # filter students according to status selected - if ($filterlist && $env{'form.Status'} ne 'Any') { - if ($env{'form.Status'} ne $status) { + if ($filterlist && (!($stu_status =~ /Any/))) { + if (!($stu_status =~ $status)) { delete ($classlist->{$student}); next; } @@ -520,6 +590,7 @@ sub student_gradeStatus { # Shows a student's view of problem and submission sub jscriptNform { my ($symb) = @_; + my $stu_status = join(':',&Apache::loncommon::get_env_multiple('form.Status')); my $jscript=' +GRADINGMENUJS + &commonJSfunctions($request); + my $result='

 Manual Grading/View Submission

'; + $result.=$table; + my (undef,$sections) = &getclasslist('all','0'); + my $savedState = &savedState(); + my $saveCmd = ($$savedState{'saveCmd'} eq '' ? 'submission' : $$savedState{'saveCmd'}); + my $saveSec = ($$savedState{'saveSec'} eq '' ? 'all' : $$savedState{'saveSec'}); + my $saveSub = ($$savedState{'saveSub'} eq '' ? 'all' : $$savedState{'saveSub'}); + my $saveStatus = ($$savedState{'saveStatus'} eq '' ? 'Active' : $$savedState{'saveStatus'}); + + $result.='
'."\n". + ''."\n". + ''."\n". + ''."\n". + ''."\n". + ''."\n". + ''."\n"; + + $result.='
'."\n". + ''."\n". + '
'."\n". + ' Select a Grading/Viewing Option
'."\n"; + + $result.=''; + $result.=''."\n"; + $result.=''; +# $result.=''; + $result.=''."\n"; + $result.=''; + $result.='
'.&mt('Sections').'Groups'.&mt('Access Status').'
'."\n". + '    '; + return $Str; +} + + +#--- Displays the submissions first page ------- +sub submit_options { my ($request) = @_; my ($symb)=&get_symb($request); if (!$symb) {return '';} @@ -7003,14 +7406,19 @@ GRADINGMENUJS ''."\n". ''."\n"; - $result.='
'."\n". - '
'."\n". + $result.=''; + $result.= '
'."\n". + ''."\n". '
'."\n". ' Select a Grading/Viewing Option
'."\n"; $result.=''; + $result.=''."\n"; + $result.=''; + $result.=''; + $result.=''."\n"; + $result.=''; $result.=''; - $result.=''."\n"; - $result.=''."\n"; - $result.=''."\n"; - $result.='
'.&mt('Sections').''.&mt('Groups').''.&mt('Access Status').'
'."\n". - ' '.&mt('Select Section').': '."\n"; if (ref($sections)) { foreach (sort (@$sections)) { $result.='   '; - - $result.=&mt('Student Status').':'.&Apache::lonhtmlcommon::StatusOptions($saveStatus,undef,1,undef); + $result.= ''."\n"; + $result.= &Apache::lonstatistics::GroupSelect('group','multiple',3); + $result.=''."\n"; + $result.=&Apache::lonhtmlcommon::StatusOptions($saveStatus,undef,3,undef,'mult'); $result.='
'. + $result.='
'. '
'. + $result.='
'. '

'. + $result.='

'. ''. '
'."\n"; - $result.='
'; - - $result.=''; - $result.=''."\n"; - - $result.=''."\n"; - - $result.=''."\n"; + $result.=''; #'."\n"; - } - $result.=''."\n"; - $result.=''."\n"; - - $result.='
'. - ''. - ' '.&mt('scores from file').'
'. - ''. - ' '.&mt('clicker file').'
'. - ' scantron forms
'; - if ((&Apache::lonnet::allowed('mgr',$env{'request.course.id'})) && ($symb)) { - $result.='
'. - ''. - ' '.&mt('receipt').': '. - &Apache::lonnet::recprefix($env{'request.course.id'}). - '-'. - '
'. - ' access times.
'. - ' saved CODEs.
'."\n". - '
'."\n". +# $result.=''; +# $result.=''."\n"; +# +# $result.=''."\n"; +# +# $result.=''."\n"; +# +# if ((&Apache::lonnet::allowed('mgr',$env{'request.course.id'})) && ($symb)) { +# $result.=''."\n"; +# } +# $result.=''."\n"; +# $result.=''."\n"; +# +# $result.='
'. +# ''. +# ' '.&mt('scores from file').'
'. +# ''. +# ' '.&mt('clicker file').'
'. +# ' scantron forms
'. +# ''. +# ' '.&mt('receipt').': '. +# &Apache::lonnet::recprefix($env{'request.course.id'}). +# '-'. +# '
'. +# ' access times.
'. +# ' saved CODEs.
'."\n".'
'."\n". '
'."\n"; return $result; } @@ -7118,9 +7528,10 @@ sub gather_clicker_ids { # Set up a couple variables. my $username_idx = &Apache::loncoursedata::CL_SNAME(); my $domain_idx = &Apache::loncoursedata::CL_SDOM(); + my $status_idx = &Apache::loncoursedata::CL_STATUS(); foreach my $student (keys(%$classlist)) { - + if ($classlist->{$student}->[$status_idx] ne 'Active') { next; } my $username = $classlist->{$student}->[$username_idx]; my $domain = $classlist->{$student}->[$domain_idx]; my $clickers = @@ -7362,6 +7773,8 @@ ENDHEADER } $result.='
'.&mt('Found [_1] question(s)',$number).'
'. ''. + &mt('Awarding [_1] percent for corrion(s)',$number).'
'. + ''. &mt('Awarding [_1] percent for correct and [_2] percent for incorrect responses', $env{'form.pcorrect'},$env{'form.pincorrect'}). '
'; @@ -7381,8 +7794,21 @@ ENDHEADER $result.="\n".''; $correct_count++; } elsif ($clicker_ids{$id}) { - $result.="\n".''; - $student_count++; + if ($clicker_ids{$id}=~/\,/) { +# More than one user with the same clicker! + $result.="\n
".&mt('Clicker registered more than once').": ".$id."
"; + $result.="\n".''. + "'; + $unknown_count++; + } else { +# Good: found one and only one user with the right clicker + $result.="\n".''; + $student_count++; + } } else { $result.="\n
".&mt('Unregistered Clicker')." ".$id."
"; $result.="\n".''. @@ -7533,6 +7959,8 @@ ENDHEADER my $id=$1; if (($env{'form.uname'.$id}) && ($env{'form.udom'.$id})) { $user=$env{'form.uname'.$id}.':'.$env{'form.udom'.$id}; + } elsif ($env{'form.multi'.$id}) { + $user=$env{'form.multi'.$id}; } } if ($user) { @@ -7590,9 +8018,12 @@ sub handler { my $symb=&get_symb($request,1); my @commands=&Apache::loncommon::get_env_multiple('form.command'); my $command=$commands[0]; + if ($#commands > 0) { &Apache::lonnet::logthis("grades got multiple commands ".join(':',@commands)); } + + $request->print(&Apache::loncommon::start_page('Grading')); if ($symb eq '' && $command eq '') { if ($env{'user.adv'}) { @@ -7633,7 +8064,9 @@ sub handler { } elsif ($command eq 'processGroup' && $perm{'vgr'}) { &processGroup($request); } elsif ($command eq 'gradingmenu' && $perm{'vgr'}) { - $request->print(&gradingmenu($request)); + $request->print(&grading_menu($request)); + } elsif ($command eq 'submit_options' && $perm{'vgr'}) { + $request->print(&submit_options($request)); } elsif ($command eq 'viewgrades' && $perm{'vgr'}) { $request->print(&viewgrades($request)); } elsif ($command eq 'handgrade' && $perm{'mgr'}) { @@ -7668,6 +8101,7 @@ sub handler { } elsif ($command eq 'csvuploadassign' && $perm{'mgr'} ) { $request->print(&csvuploadassign($request)); } elsif ($command eq 'scantron_selectphase' && $perm{'mgr'}) { + &Apache::lonnet::logthis("Selecting pyhase"); $request->print(&scantron_selectphase($request)); } elsif ($command eq 'scantron_warning' && $perm{'mgr'}) { $request->print(&scantron_do_warning($request));