--- loncom/homework/grades.pm 2012/12/18 18:05:48 1.596.2.12.2.12 +++ loncom/homework/grades.pm 2012/08/09 23:25:48 1.596.2.13 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # The LON-CAPA Grading handler # -# $Id: grades.pm,v 1.596.2.12.2.12 2012/12/18 18:05:48 raeburn Exp $ +# $Id: grades.pm,v 1.596.2.13 2012/08/09 23:25:48 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -125,16 +125,13 @@ sub getpartlist { # --- Get the symbolic name of a problem and the url sub get_symb { my ($request,$silent) = @_; - my $symb=$env{'form.symb'}; - unless ($symb) { - (my $url=$env{'form.url'}) =~ s-^http://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--; - $symb = &Apache::lonnet::symbread($url); - if ($symb eq '') { - if (!$silent) { - $request->print(&mt("Unable to handle ambiguous references: [_1].",$url)); - return (); - } - } + (my $url=$env{'form.url'}) =~ s-^http://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--; + my $symb=($env{'form.symb'} ne '' ? $env{'form.symb'} : (&Apache::lonnet::symbread($url))); + if ($symb eq '') { + if (!$silent) { + $request->print(&mt("Unable to handle ambiguous references: [_1].",$url)); + return (); + } } &Apache::lonenc::check_decrypt(\$symb); return ($symb); @@ -253,7 +250,7 @@ sub showResourceInfo { $result.=''.$display_part.'' .''.''.$resID.'' .''.&mt($responsetype).'' -# .''.&mt('Handgrade: [_1]',$handgrade).'' +# .''.&mt('Handgrade: [_1]',$handgrade).'' .&Apache::loncommon::end_data_table_row(); } } @@ -277,7 +274,7 @@ sub reset_caches { } sub get_analyze { - my ($symb,$uname,$udom,$no_increment,$add_to_hash,$type,$trial,$rndseed,$bubbles_per_row)=@_; + my ($symb,$uname,$udom,$no_increment,$add_to_hash,$type,$trial,$rndseed)=@_; my $key = "$symb\0$uname\0$udom"; if ($type eq 'randomizetry') { if ($trial ne '') { @@ -311,9 +308,6 @@ sub reset_caches { 'grade_courseid' => $env{'request.course.id'}, 'grade_username' => $uname, 'grade_noincrement' => $no_increment); - if ($bubbles_per_row ne '') { - $form{'bubbles_per_row'} = $bubbles_per_row; - } if ($type eq 'randomizetry') { $form{'grade_questiontype'} = $type; if ($rndseed ne '') { @@ -354,7 +348,7 @@ sub reset_caches { } sub scantron_partids_tograde { - my ($resource,$cid,$uname,$udom,$check_for_randomlist,$bubbles_per_row) = @_; + my ($resource,$cid,$uname,$udom,$check_for_randomlist) = @_; my (%analysis,@parts); if (ref($resource)) { my $symb = $resource->symb(); @@ -362,9 +356,7 @@ sub reset_caches { if ($check_for_randomlist) { $add_to_form = { 'check_parts_withrandomlist' => 1,}; } - my $analyze = - &get_analyze($symb,$uname,$udom,undef,$add_to_form, - undef,undef,undef,$bubbles_per_row); + my $analyze = &get_analyze($symb,$uname,$udom,undef,$add_to_form); if (ref($analyze) eq 'HASH') { %analysis = %{$analyze}; } @@ -1619,15 +1611,17 @@ INNERJS function savedMsgHeader(Nmsg,usrctr,fullname) { var height = 70*Nmsg+250; + var scrollbar = "no"; if (height > 600) { height = 600; + scrollbar = "yes"; } var xpos = (screen.width-600)/2; xpos = (xpos < 0) ? '0' : xpos; var ypos = (screen.height-height)/2-30; ypos = (ypos < 0) ? '0' : ypos; - pWin = window.open('', 'MessageCenter', 'resizable=yes,toolbar=no,location=no,scrollbars=yes,screenx='+xpos+',screeny='+ypos+',width=700,height='+height); + pWin = window.open('', 'MessageCenter', 'resizable=yes,toolbar=no,location=no,scrollbars='+scrollbar+',screenx='+xpos+',screeny='+ypos+',width=700,height='+height); pWin.focus(); pDoc = pWin.document; pDoc.$docopen; @@ -1837,6 +1831,7 @@ sub gradeBox { $line.=''."\n"; + #&mt('Part:[_1]Points:[_2]or[_3]',$display_part,$radio,$line); $result .= ''.$display_part.''.$radio.''.&mt('or').''.$line.''; $result.=&Apache::loncommon::end_data_table_row(); @@ -1923,27 +1918,14 @@ sub show_problem { $companswer=~s|||g; $companswer=~s|name="submit"|name="would_have_been_submit"|g; } - my $renderheading = &mt('View of the problem'); - my $answerheading = &mt('Correct answer'); - if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) { - my $stu_fullname = $env{'form.fullname'}; - if ($stu_fullname eq '') { - $stu_fullname = &Apache::loncommon::plainname($uname,$udom,'lastname'); - } - my $forwhom = &nameUserString(undef,$stu_fullname,$uname,$udom); - if ($forwhom ne '') { - $renderheading = &mt('View of the problem for[_1]',$forwhom); - $answerheading = &mt('Correct answer for[_1]',$forwhom); - } - } $rendered= '
' - .'

'.$renderheading.'

' + .'

'.&mt('View of the problem').'

' .$rendered .'
'; $companswer= '
' - .'

'.$answerheading.'

' + .'

'.&mt('Correct answer').'

' .$companswer .'
'; my $result; @@ -2014,7 +1996,7 @@ sub submission { $udom = ($udom eq '' ? $env{'user.domain'} : $udom); #has form.userdom changed for a student? my $usec = &Apache::lonnet::getsection($udom,$uname,$env{'request.course.id'}); $env{'form.fullname'} = &Apache::loncommon::plainname($uname,$udom,'lastname') if $env{'form.fullname'} eq ''; - my ($symb) = &get_symb($request); + my $symb = &get_symb($request); if ($symb eq '') { $request->print("Unable to handle ambiguous references:."); return ''; } if (!&canview($usec)) { @@ -2148,7 +2130,7 @@ KEYWORDS my ($adom,$aname,$apath)=($essayurl=~/^($LONCAPA::domain_re)\/($LONCAPA::username_re)\/(.*)$/); $apath=&escape($apath); $apath=~s/\W/\_/gs; - &init_old_essays($symb,$apath,$adom,$aname); + &init_old_essays($symb,$apath,$adom,$aname); } } @@ -2617,187 +2599,10 @@ sub keywords_highlight { return $string; } -# For Tasks provide a mechanism to display previous version for one specific student - -sub show_previous_task_version { - my ($request,$symb) = @_; - if ($symb eq '') { - $request->print("Unable to handle ambiguous references."); - - return ''; - } - my ($uname,$udom) = ($env{'form.student'},$env{'form.userdom'}); - my $usec = &Apache::lonnet::getsection($udom,$uname,$env{'request.course.id'}); - if (!&canview($usec)) { - $request->print('Unable to view previous version for requested student.('. - $uname.':'.$udom.' in section '.$usec.' in course id '. - $env{'request.course.id'}.')'); - return; - } - my $mode = 'both'; - my $isTask = ($symb =~/\.task$/); - if ($isTask) { - if ($env{'form.previousversion'} =~ /^\d+$/) { - if ($env{'form.fullname'} eq '') { - $env{'form.fullname'} = - &Apache::loncommon::plainname($uname,$udom,'lastname'); - } - my $probtitle=&Apache::lonnet::gettitle($symb); - $request->print("\n\n". - '
'. - '

'.&nameUserString(undef,$env{'form.fullname'},$uname,$udom). - '

'."\n"); - &Apache::lonxml::clear_problem_counter(); - $request->print(&show_problem($request,$symb,$uname,$udom,1,1,$mode, - {'previousversion' => $env{'form.previousversion'} })); - $request->print("\n
"); - } - } - return; -} - -sub choose_task_version_form { - my ($symb,$uname,$udom,$nomenu) = @_; - my $isTask = ($symb =~/\.task$/); - my ($current,$version,$result,$js,$displayed,$rowtitle); - if ($isTask) { - my %record = &Apache::lonnet::restore($symb,$env{'request.course.id'}, - $udom,$uname); - if (($record{'resource.0.version'} eq '') || - ($record{'resource.0.version'} < 2)) { - return ($record{'resource.0.version'}, - $record{'resource.0.version'},$result,$js); - } else { - $current = $record{'resource.0.version'}; - } - if ($env{'form.previousversion'}) { - $displayed = $env{'form.previousversion'}; - $rowtitle = &mt('Choose another version:') - } else { - $displayed = $current; - $rowtitle = &mt('Show earlier version:'); - } - $result = '
'; - my $list; - my $numversions = 0; - for (my $i=1; $i<=$record{'resource.0.version'}; $i++) { - if ($i == $current) { - if (!$env{'form.previousversion'} || $nomenu) { - next; - } else { - $list .= ''."\n"; - $numversions ++; - } - } elsif (defined($record{'resource.'.$i.'.0.status'})) { - unless ($i == $env{'form.previousversion'}) { - $numversions ++; - } - $list .= ''."\n"; - } - } - if ($numversions) { - $symb = &HTML::Entities::encode($symb,'<>"&'); - $result .= - '
'. - &Apache::loncommon::start_data_table(). - &Apache::loncommon::start_data_table_row(). - ''.$rowtitle.''. - ''. - &Apache::loncommon::end_data_table_row(); - unless ($nomenu) { - $result .= &Apache::loncommon::start_data_table_row(). - ''.&mt('Open in new window').''. - ''. - ''. - ''. - ''. - &Apache::loncommon::end_data_table_row(); - } - $result .= - &Apache::loncommon::start_data_table_row(). - ' '. - ''. - ''. - ''. - &Apache::loncommon::end_data_table_row(). - &Apache::loncommon::end_data_table(). - '
'; - $js = &previous_display_javascript($nomenu,$current); - } elsif ($displayed && $nomenu) { - $result .= ''.&mt('Close window').''; - } else { - $result .= &mt('No previous versions to show for this student'); - } - $result .= '
'; - } - return ($current,$displayed,$result,$js); -} - -sub previous_display_javascript { - my ($nomenu,$current) = @_; - my $js = <<"JSONE"; - -ENDJS - -} - #--- Called from submission routine sub processHandGrade { my ($request) = shift; - my ($symb) = &get_symb($request); + my $symb = &get_symb($request); my (undef,undef,$url) = &Apache::lonnet::decode_symb($symb); my $button = $env{'form.gradeOpt'}; my $ngrade = $env{'form.NCT'}; @@ -3202,10 +3007,8 @@ sub handback_files { &file_name_version_ext($answer_file); my ($portfolio_path) = ($directory =~ /^.+$stuname\/portfolio(.*)/); my $getpropath = 1; - my ($dir_list,$listerror) = - &Apache::lonnet::dirlist($portfolio_root.$portfolio_path, - $domain,$stuname,$getpropath); - my $version = &get_next_version($answer_name,$answer_ext,$dir_list); + my @dir_list = &Apache::lonnet::dirlist($portfolio_root.$portfolio_path,$domain,$stuname,$getpropath); + my $version = &get_next_version($answer_name, $answer_ext, \@dir_list); # fix file name my ($save_file_name) = (($directory.$answer_name.".$version.".$answer_ext) =~ /^.+\/${stuname}\/(.*)/); my $result=&Apache::lonnet::finishuserfileupload($stuname,$domain, @@ -3365,11 +3168,9 @@ sub version_portfiles { my ($directory,$answer_file) =($file =~ /^(.*?)([^\/]*)$/); my ($answer_name,$answer_ver,$answer_ext) = &file_name_version_ext($answer_file); - my $getpropath = 1; - my ($dir_list,$listerror) = - &Apache::lonnet::dirlist($portfolio_root.$directory,$domain, - $stu_name,$getpropath); - my $version = &get_next_version($answer_name,$answer_ext,$dir_list); + my $getpropath = 1; + my @dir_list = &Apache::lonnet::dirlist($portfolio_root.$directory,$domain,$stu_name,$getpropath); + my $version = &get_next_version($answer_name, $answer_ext, \@dir_list); my $new_answer = &version_selected_portfile($domain, $stu_name, $directory, $answer_file, $version); if ($new_answer ne 'problem getting file') { push(@versioned_portfiles, $directory.$new_answer); @@ -3388,24 +3189,21 @@ sub version_portfiles { sub get_next_version { my ($answer_name, $answer_ext, $dir_list) = @_; my $version; - if (ref($dir_list) eq 'ARRAY') { - foreach my $row (@{$dir_list}) { - my ($file) = split(/\&/,$row,2); - my ($file_name,$file_version,$file_ext) = - &file_name_version_ext($file); - if (($file_name eq $answer_name) && - ($file_ext eq $answer_ext)) { - # gets here if filename and extension match, - # regardless of version + foreach my $row (@$dir_list) { + my ($file) = split(/\&/,$row,2); + my ($file_name,$file_version,$file_ext) = + &file_name_version_ext($file); + if (($file_name eq $answer_name) && + ($file_ext eq $answer_ext)) { + # gets here if filename and extension match, regardless of version if ($file_version ne '') { - # a versioned file is found so save it for later - if ($file_version > $version) { - $version = $file_version; - } + # a versioned file is found so save it for later + if ($file_version > $version) { + $version = $file_version; } } } - } + } $version ++; return($version); } @@ -3865,7 +3663,7 @@ sub viewstudentgrade { sub editgrades { my ($request) = @_; - my ($symb)=&get_symb($request); + my $symb=&get_symb($request); my $section_display = join (", ",&Apache::loncommon::get_env_multiple('form.section')); my $title='

'.&mt('Current Grade Status').'

'; $title.='

'.&mt('Current Resource: [_1]',$env{'form.probTitle'}).'

'."\n"; @@ -4810,8 +4608,8 @@ sub displayPage { &Apache::loncommon::start_data_table_row(). ''.$prob. (scalar(@{$parts}) == 1 ? '' - : '
('.&mt('[_1]parts', - scalar(@{$parts}).' ').')' + : '
('.&mt('[_1]parts)', + scalar(@{$parts}).' ') ). ''; $studentTable.=''; @@ -4893,7 +4691,6 @@ sub displaySubByDates { &Apache::loncommon::start_data_table_header_row(). ''.&mt('Date/Time').''. ($isCODE?''.&mt('CODE').'':''). - ($isTask?''.&mt('Version').'':''). ''.&mt('Submission').''. ''.&mt('Status').''. &Apache::loncommon::end_data_table_header_row(); @@ -4914,9 +4711,7 @@ sub displaySubByDates { if (exists($$record{$version.':resource.0.version'})) { $interaction = $$record{$version.':resource.0.version'}; } - if ($isTask && $env{'form.previousversion'}) { - next unless ($interaction == $env{'form.previousversion'}); - } + my $where = ($isTask ? "$version:resource.$interaction" : "$version:resource"); $studentTable.=&Apache::loncommon::start_data_table_row(). @@ -4924,9 +4719,6 @@ sub displaySubByDates { if ($isCODE) { $studentTable.=''.$record->{$version.':resource.CODE'}.''; } - if ($isTask) { - $studentTable.=''.$interaction.''; - } my @versionKeys = split(/\:/,$$record{$version.':keys'}); my @displaySub = (); foreach my $partid (@{$parts}) { @@ -4946,7 +4738,7 @@ sub displaySubByDates { my ($responseId)= ($isTask ? ($matchKey=~ /^resource\.(.*?)\.\Q$partid\E\.award$/) : ($matchKey=~ /^resource\.\Q$partid\E\.(.*?)\.submission$/)); - $displaySub[0].=''; + $displaySub[0].='' .' ' .'('.&mt('Response ID: [_1]',$responseId).')' @@ -5370,16 +5162,14 @@ sub scantron_filenames { my $cdom=$env{'course.'.$env{'request.course.id'}.'.domain'}; my $cname=$env{'course.'.$env{'request.course.id'}.'.num'}; my $getpropath = 1; - my ($dirlist,$listerror) = &Apache::lonnet::dirlist('userfiles',$cdom, - $cname,$getpropath); + my @files=&Apache::lonnet::dirlist('userfiles',$cdom,$cname, + $getpropath); my @possiblenames; - if (ref($dirlist) eq 'ARRAY') { - foreach my $filename (sort(@{$dirlist})) { - ($filename)=split(/&/,$filename); - if ($filename!~/^scantron_orig_/) { next ; } - $filename=~s/^scantron_orig_//; - push(@possiblenames,$filename); - } + foreach my $filename (sort(@files)) { + ($filename)=split(/&/,$filename); + if ($filename!~/^scantron_orig_/) { next ; } + $filename=~s/^scantron_orig_//; + push(@possiblenames,$filename); } return @possiblenames; } @@ -5777,8 +5567,6 @@ sub scantron_selectphase { LastName - column that the last name starts in LastNameLength - number of columns that the last name spans - BubblesPerRow - number of bubbles available in each row used to - bubble an answer. (If not specified, 10 assumed). =cut @@ -5809,7 +5597,6 @@ sub get_scantron_config { $config{'FirstNamelength'}=$config[14]; $config{'LastName'}=$config[15]; $config{'LastNamelength'}=$config[16]; - $config{'BubblesPerRow'}=$config[17]; last; } return %config; @@ -6594,12 +6381,6 @@ sub scantron_warning_screen { ''.&mt('List of CODES to validate against:').''. $env{'form.scantron_CODElist'}.''; } - my $lastbubblepoints; - if ($env{'form.scantron_lastbubblepoints'} ne '') { - $lastbubblepoints = - ''.&mt('Hand-graded items: points from last bubble in row').''. - $env{'form.scantron_lastbubblepoints'}.''; - } return ('

@@ -6608,11 +6389,11 @@ sub scantron_warning_screen { -'.$CODElist.$lastbubblepoints.' +'.$CODElist.'
'.&mt('Sequence to be Graded:').''.$title.'
'.&mt('Data File that will be used:').''.$env{'form.scantron_selectfile'}.'

-

'.&mt("If this information is correct, please click on '[_1]'.",&mt($button_text)).'

-

'.&mt("If something is incorrect, please click the 'Grading Menu' button to start over.").'

+

'.&mt('If this information is correct, please click on \'[_1]\'.',&mt($button_text)).'

+

'.&mt('If something is incorrect, please click the \'Grading Menu\' button to start over.').'


'); @@ -6648,9 +6429,8 @@ sub scantron_do_warning { } } else { my $warning=&scantron_warning_screen('Grading: Validate Records'); - my $bubbledbyhand=&hand_bubble_option(); $r->print(' -'.$warning.$bubbledbyhand.' +'.$warning.' '); @@ -6740,16 +6520,12 @@ sub scantron_validate_file { #get the student pick code ready $r->print(&Apache::loncommon::studentbrowser_javascript()); my $nav_error; - my %scantron_config=&get_scantron_config($env{'form.scantron_format'}); - my $max_bubble=&scantron_get_maxbubble(\$nav_error,\%scantron_config); + my $max_bubble=&scantron_get_maxbubble(\$nav_error); if ($nav_error) { $r->print(&navmap_errormsg()); return ''; } my $result=&scantron_form_start($max_bubble).$default_form_data; - if ($env{'form.scantron_lastbubblepoints'} ne '') { - $result .= ''; - } $r->print($result); my @validate_phases=( 'sequence', @@ -7175,12 +6951,7 @@ sub scantron_validate_sequence { my @resources= $navmap->retrieveResources($map,\&scantron_filter_not_exam,1,0); if (@resources) { - $r->print('

' - .&mt('Some resources in the sequence currently are not set to' - .' exam mode. Grading these resources currently may not' - .' work correctly.') - .'

' - ); + $r->print("

".&mt('Some resources in the sequence currently are not set to exam mode. Grading these resources currently may not work correctly.')."

"); return (1,$currentphase); } } @@ -7202,7 +6973,7 @@ sub scantron_validate_ID { my ($scanlines,$scan_data)=&scantron_getfile(); my $nav_error; - &scantron_get_maxbubble(\$nav_error,\%scantron_config); # parse needs the bubble_lines.. array. + &scantron_get_maxbubble(\$nav_error); # parse needs the bubble_lines.. array. if ($nav_error) { $r->print(&navmap_errormsg()); return(1,$currentphase); @@ -7615,19 +7386,7 @@ sub scantron_bubble_selector { my $max=$$scan_config{'Qlength'}; my $scmode=$$scan_config{'Qon'}; - if ($scmode eq 'number' || $scmode eq 'letter') { - if (($$scan_config{'BubblesPerRow'} =~ /^\d+$/) && - ($$scan_config{'BubblesPerRow'} > 0)) { - $max=$$scan_config{'BubblesPerRow'}; - if (($scmode eq 'number') && ($max > 10)) { - $max = 10; - } elsif (($scmode eq 'letter') && $max > 26) { - $max = 26; - } - } else { - $max = 10; - } - } + if ($scmode eq 'number' || $scmode eq 'letter') { $max=10; } my @alphabet=('A'..'Z'); $r->print(&Apache::loncommon::start_data_table(). @@ -7782,7 +7541,7 @@ sub scantron_validate_CODE { my %allcodes=&get_codes(); my $nav_error; - &scantron_get_maxbubble(\$nav_error,\%scantron_config); # parse needs the lines per response array. + &scantron_get_maxbubble(\$nav_error); # parse needs the lines per response array. if ($nav_error) { $r->print(&navmap_errormsg()); return(1,$currentphase); @@ -7841,7 +7600,7 @@ sub scantron_validate_doublebubble { my %scantron_config=&get_scantron_config($env{'form.scantron_format'}); my ($scanlines,$scan_data)=&scantron_getfile(); my $nav_error; - &scantron_get_maxbubble(\$nav_error,\%scantron_config); # parse needs the bubble line array. + &scantron_get_maxbubble(\$nav_error); # parse needs the bubble line array. if ($nav_error) { $r->print(&navmap_errormsg()); return(1,$currentphase); @@ -7863,7 +7622,7 @@ sub scantron_validate_doublebubble { sub scantron_get_maxbubble { - my ($nav_error,$scantron_config) = @_; + my ($nav_error) = @_; if (defined($env{'form.scantron_maxbubble'}) && $env{'form.scantron_maxbubble'}) { &restore_bubble_lines(); @@ -7882,7 +7641,6 @@ sub scantron_get_maxbubble { } my $map=$navmap->getResourceByUrl($sequence); my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0); - my $bubbles_per_row = &bubblesheet_bubbles_per_row($scantron_config); &Apache::lonxml::clear_problem_counter(); @@ -7898,8 +7656,7 @@ sub scantron_get_maxbubble { my $response_number = 0; my $bubble_line = 0; foreach my $resource (@resources) { - my ($analysis,$parts) = &scantron_partids_tograde($resource,$cid,$uname, - $udom,$bubbles_per_row); + 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; @@ -7928,10 +7685,9 @@ sub scantron_get_maxbubble { if (ref($analysis->{$part_id.'.shown'}) eq 'ARRAY') { $numshown = scalar(@{$analysis->{$part_id.'.shown'}}); } - my $bubbles_per_row = - &bubblesheet_bubbles_per_row($scantron_config); - my $inner_bubble_lines = int($numbub/$bubbles_per_row); - if (($numbub % $bubbles_per_row) != 0) { + 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++) { @@ -7942,7 +7698,7 @@ sub scantron_get_maxbubble { $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; @@ -7963,18 +7719,6 @@ sub scantron_get_maxbubble { return $env{'form.scantron_maxbubble'}; } -sub bubblesheet_bubbles_per_row { - my ($scantron_config) = @_; - my $bubbles_per_row; - if (ref($scantron_config) eq 'HASH') { - $bubbles_per_row = $scantron_config->{'BubblesPerRow'}; - } - if ((!$bubbles_per_row) || ($bubbles_per_row < 1)) { - $bubbles_per_row = 10; - } - return $bubbles_per_row; -} - sub scantron_validate_missingbubbles { my ($r,$currentphase) = @_; #get student info @@ -7985,7 +7729,7 @@ sub scantron_validate_missingbubbles { my %scantron_config=&get_scantron_config($env{'form.scantron_format'}); my ($scanlines,$scan_data)=&scantron_getfile(); my $nav_error; - my $max_bubble=&scantron_get_maxbubble(\$nav_error,\%scantron_config); + my $max_bubble=&scantron_get_maxbubble(\$nav_error); if ($nav_error) { return(1,$currentphase); } @@ -8032,41 +7776,6 @@ sub scantron_validate_missingbubbles { return (0,$currentphase+1); } -sub hand_bubble_option { - my (undef, undef, $sequence) = - &Apache::lonnet::decode_symb($env{'form.selectpage'}); - return if ($sequence eq ''); - my $navmap = Apache::lonnavmaps::navmap->new(); - unless (ref($navmap)) { - return; - } - my $needs_hand_bubbles; - my $map=$navmap->getResourceByUrl($sequence); - my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0); - foreach my $res (@resources) { - if (ref($res)) { - if ($res->is_problem()) { - my $partlist = $res->parts(); - foreach my $part (@{ $partlist }) { - my @types = $res->responseType($part); - if (grep(/^(chem|essay|image|formula|math|string|functionplot)$/,@types)) { - $needs_hand_bubbles = 1; - last; - } - } - } - } - } - if ($needs_hand_bubbles) { - my %scantron_config=&get_scantron_config($env{'form.scantron_format'}); - my $bubbles_per_row = &bubblesheet_bubbles_per_row(\%scantron_config); - return &mt('The sequence to be graded contains response types which are handgraded.').'

'. - &mt('If you have already graded these by bubbling sheets to indicate points awarded, [_1]what point value is assigned to a filled last bubble in each row?','
'). - ' '.&mt('or').' '. - '

'; - } - return; -} sub scantron_process_students { my ($r) = @_; @@ -8079,8 +7788,6 @@ sub scantron_process_students { my $default_form_data=&defaultFormData($symb); my %scantron_config=&get_scantron_config($env{'form.scantron_format'}); - my $bubbles_per_row = - &bubblesheet_bubbles_per_row(\%scantron_config); my ($scanlines,$scan_data)=&scantron_getfile(); my $classlist=&Apache::loncoursedata::get_classlist(); my %idmap=&username_to_idmap($classlist); @@ -8090,29 +7797,22 @@ sub scantron_process_students { return ''; } my $map=$navmap->getResourceByUrl($sequence); - my $randomorder; - if (ref($map)) { - $randomorder = $map->randomorder(); - } my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0); - my (%grader_partids_by_symb,%grader_randomlists_by_symb,%ordered); + my (%grader_partids_by_symb,%grader_randomlists_by_symb); &graders_resources_pass(\@resources,\%grader_partids_by_symb, - \%grader_randomlists_by_symb,$bubbles_per_row); - my ($resource_error,%symb_to_resource,@master_seq); + \%grader_randomlists_by_symb); + my $resource_error; foreach my $resource (@resources) { my $ressymb; if (ref($resource)) { $ressymb = $resource->symb(); - push(@master_seq,$ressymb); - $symb_to_resource{$ressymb} = $resource; } else { $resource_error = 1; last; } my ($analysis,$parts) = &scantron_partids_tograde($resource,$env{'request.course.id'}, - $env{'user.name'},$env{'user.domain'}, - 1,$bubbles_per_row); + $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') { @@ -8139,7 +7839,9 @@ SCANTRONFORM my $lock=&Apache::lonnet::set_lock(&mt('Grading bubblesheet exam')); my $count=&get_todo_count($scanlines,$scan_data); - my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,$count); + my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Bubblesheet Status', + 'Bubblesheet Progress',$count, + 'inline',undef,'scantronupload'); &Apache::lonhtmlcommon::Update_PrgWin($r,\%prog_state, 'Processing first student'); $r->print('
'); @@ -8148,7 +7850,7 @@ SCANTRONFORM my $started; my $nav_error; - &scantron_get_maxbubble(\$nav_error,\%scantron_config); # Need the bubble lines array to parse. + &scantron_get_maxbubble(\$nav_error); # Need the bubble lines array to parse. if ($nav_error) { $r->print(&navmap_errormsg()); return ''; @@ -8191,26 +7893,10 @@ SCANTRONFORM 'Student '.$uname.' has multiple sheets',2); next; } - my $usec = $classlist->{$uname}->[&Apache::loncoursedata::CL_SECTION]; - my $user = $uname.':'.$usec; ($uname,$udom)=split(/:/,$uname); - my $scancode; - if ((exists($scan_record->{'scantron.CODE'})) && - (&Apache::lonnet::validCODE($scan_record->{'scantron.CODE'}))) { - $scancode = $scan_record->{'scantron.CODE'}; - } else { - $scancode = ''; - } - - my @mapresources = @resources; - if ($randomorder) { - @mapresources = - &users_order($user,$scancode,$sequence,\@master_seq,\%ordered, - \%symb_to_resource); - } my (%partids_by_symb,$res_error); - foreach my $resource (@mapresources) { + foreach my $resource (@resources) { my $ressymb; if (ref($resource)) { $ressymb = $resource->symb(); @@ -8221,8 +7907,7 @@ SCANTRONFORM if ((exists($grader_randomlists_by_symb{$ressymb})) || (ref($grader_partids_by_symb{$ressymb}) ne 'ARRAY')) { my ($analysis,$parts) = - &scantron_partids_tograde($resource,$env{'request.course.id'}, - $uname,$udom,undef,$bubbles_per_row); + &scantron_partids_tograde($resource,$env{'request.course.id'},$uname,$udom); $partids_by_symb{$ressymb} = $parts; } else { $partids_by_symb{$ressymb} = $grader_partids_by_symb{$ressymb}; @@ -8242,9 +7927,16 @@ SCANTRONFORM &scantron_putfile($scanlines,$scan_data); } + 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, - \@mapresources,\%partids_by_symb, - $bubbles_per_row) eq 'ssi_error') { + \@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); @@ -8261,7 +7953,7 @@ SCANTRONFORM $studentdata =~ s/\r$//; my $studentrecord = ''; my $counter = -1; - foreach my $resource (@mapresources) { + foreach my $resource (@resources) { my $ressymb = $resource->symb(); ($counter,my $recording) = &verify_scantron_grading($resource,$udom,$uname,$env{'request.course.id'}, @@ -8272,8 +7964,7 @@ SCANTRONFORM if ($studentrecord ne $studentdata) { &Apache::lonxml::clear_problem_counter(); if (&grade_student_bubbles($r,$uname,$udom,$scan_record,$scancode, - \@mapresources,\%partids_by_symb, - $bubbles_per_row) eq 'ssi_error') { + \@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); @@ -8284,7 +7975,7 @@ SCANTRONFORM } $counter = -1; $studentrecord = ''; - foreach my $resource (@mapresources) { + foreach my $resource (@resources) { my $ressymb = $resource->symb(); ($counter,my $recording) = &verify_scantron_grading($resource,$udom,$uname,$env{'request.course.id'}, @@ -8338,16 +8029,14 @@ SCANTRONFORM } sub graders_resources_pass { - my ($resources,$grader_partids_by_symb,$grader_randomlists_by_symb, - $bubbles_per_row) = @_; + 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,$bubbles_per_row); + $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') { @@ -8360,55 +8049,8 @@ sub graders_resources_pass { return; } -=pod - -=item users_order - - Returns array of resources in current map, ordered based on either CODE, - if this is a CODEd exam, or based on student's identity if this is a - "NAMEd" exam. - - Should be used when randomorder applied when the corresponding exam was - printed, prior to students completing bubblesheets for the version of the - exam the student received. - -=cut - -sub users_order { - my ($user,$scancode,$mapurl,$master_seq,$ordered,$symb_to_resource) = @_; - my @mapresources; - unless ((ref($ordered) eq 'HASH') && (ref($symb_to_resource) eq 'HASH')) { - return @mapresources; - } - if (($scancode) && (ref($ordered->{$scancode}) eq 'ARRAY')) { - @mapresources = @{$ordered->{$scancode}}; - } elsif ($scancode) { - $env{'form.CODE'} = $scancode; - my $actual_seq = - &Apache::lonprintout::master_seq_to_person_seq($mapurl, - $master_seq, - $user,$scancode); - if (ref($actual_seq) eq 'ARRAY') { - @{$ordered->{$scancode}} = - map { $symb_to_resource->{$_}; } @{$actual_seq}; - @mapresources = @{$ordered->{$scancode}}; - } - delete($env{'form.CODE'}); - } else { - my $actual_seq = - &Apache::lonprintout::master_seq_to_person_seq($mapurl, - $master_seq, - $user); - if (ref($actual_seq) eq 'ARRAY') { - @mapresources = - map { $symb_to_resource->{$_}; } @{$actual_seq}; - } - } - return @mapresources; -} - sub grade_student_bubbles { - my ($r,$uname,$udom,$scan_record,$scancode,$resources,$parts,$bubbles_per_row) = @_; + my ($r,$uname,$udom,$scan_record,$scancode,$resources,$parts) = @_; if (ref($resources) eq 'ARRAY') { my $count = 0; foreach my $resource (@{$resources}) { @@ -8421,12 +8063,6 @@ sub grade_student_bubbles { 'grade_symb' => $ressymb, 'CODE' => $scancode ); - if ($bubbles_per_row ne '') { - $form{'bubbles_per_row'} = $bubbles_per_row; - } - if ($env{'form.scantron_lastbubblepoints'} ne '') { - $form{'scantron_lastbubblepoints'} = $env{'form.scantron_lastbubblepoints'}; - } if (ref($parts) eq 'HASH') { if (ref($parts->{$ressymb}) eq 'ARRAY') { foreach my $part (@{$parts->{$ressymb}}) { @@ -8453,9 +8089,8 @@ sub scantron_upload_scantron_data { 'domainid', 'coursename',$dom); my $syllabuslink = ''.&mt('Syllabus').''. - (' 'x2).&mt('(shows course personnel)'); - my ($symb) = &get_symb($r,1); - my $default_form_data=&defaultFormData($symb); + (' 'x2).&mt('(shows course personnel)'); + my $default_form_data=&defaultFormData(&get_symb($r,1)); my $nofile_alert = &mt('Please use the browse button to select a file from your local directory.'); my $nocourseid_alert = &mt("Please use the 'Select Course' link to open a separate window where you can search for a course to which a file can be uploaded."); $r->print(' @@ -8660,8 +8295,7 @@ sub valid_file { sub scantron_download_scantron_data { my ($r)=@_; - my ($symb) = &get_symb($r,1); - my $default_form_data=&defaultFormData($symb); + my $default_form_data=&defaultFormData(&get_symb($r,1)); my $cname=$env{'course.'.$env{'request.course.id'}.'.num'}; my $cdom=$env{'course.'.$env{'request.course.id'}.'.domain'}; my $file=$env{'form.scantron_selectfile'}; @@ -8671,7 +8305,7 @@ sub scantron_download_scantron_data { '.&mt('The requested file name was invalid.').'

'); - $r->print(&show_grading_menu_form($symb)); + $r->print(&show_grading_menu_form(&get_symb($r,1))); return; } my $orig='/uploaded/'.$cdom.'/'.$cname.'/scantron_orig_'.$file; @@ -8694,7 +8328,7 @@ sub scantron_download_scantron_data { '','').'

'); - $r->print(&show_grading_menu_form($symb)); + $r->print(&show_grading_menu_form(&get_symb($r,1))); return ''; } @@ -8712,7 +8346,6 @@ sub checkscantron_results { my %record; my %scantron_config = &Apache::grades::get_scantron_config($env{'form.scantron_format'}); - my $bubbles_per_row = &bubblesheet_bubbles_per_row(\%scantron_config); my ($scanlines,$scan_data)=&Apache::grades::scantron_getfile(); my $classlist=&Apache::loncoursedata::get_classlist(); my %idmap=&Apache::grades::username_to_idmap($classlist); @@ -8722,21 +8355,10 @@ sub checkscantron_results { return ''; } my $map=$navmap->getResourceByUrl($sequence); - my ($randomorder,@master_seq,%symb_to_resource); - if (ref($map)) { - $randomorder=$map->randomorder(); - } my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0); - foreach my $resource (@resources) { - if (ref($resource)) { - my $ressymb = $resource->symb(); - push(@master_seq,$ressymb); - $symb_to_resource{$ressymb} = $resource; - } - } my (%grader_partids_by_symb,%grader_randomlists_by_symb); - &graders_resources_pass(\@resources,\%grader_partids_by_symb, - \%grader_randomlists_by_symb,$bubbles_per_row); + &graders_resources_pass(\@resources,\%grader_partids_by_symb, \%grader_randomlists_by_symb); + my ($uname,$udom); my (%scandata,%lastname,%bylast); $r->print(' @@ -8746,10 +8368,12 @@ sub checkscantron_results { my %completedstudents; my $count=&Apache::grades::get_todo_count($scanlines,$scan_data); - my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,$count); - my ($username,$domain,$started,%ordered); + my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,'Bubblesheet/Submissions Comparison Status', + 'Progress of Bubblesheet Data/Submission Records Comparison',$count, + 'inline',undef,'checkscantron'); + my ($username,$domain,$started); my $nav_error; - &scantron_get_maxbubble(\$nav_error,\%scantron_config); # Need the bubble lines array to parse. + &scantron_get_maxbubble(\$nav_error); # Need the bubble lines array to parse. if ($nav_error) { $r->print(&navmap_errormsg()); return ''; @@ -8791,34 +8415,15 @@ sub checkscantron_results { $scandata{$pid} = substr($line,$scantron_config{'Qstart'}-1,$lastpos); chomp($scandata{$pid}); $scandata{$pid} =~ s/\r$//; - my $usec = $classlist->{$uname}->[&Apache::loncoursedata::CL_SECTION]; - my $user = $uname.':'.$usec; ($username,$domain)=split(/:/,$uname); - - my $scancode; - if ((exists($scan_record->{'scantron.CODE'})) && - (&Apache::lonnet::validCODE($scan_record->{'scantron.CODE'}))) { - $scancode = $scan_record->{'scantron.CODE'}; - } else { - $scancode = ''; - } - - my @mapresources = @resources; - if ($randomorder) { - @mapresources = - &users_order($user,$scancode,$sequence,\@master_seq,\%ordered, - \%symb_to_resource); - } my $counter = -1; - foreach my $resource (@mapresources) { + foreach my $resource (@resources) { my $parts; my $ressymb = $resource->symb(); if ((exists($grader_randomlists_by_symb{$ressymb})) || (ref($grader_partids_by_symb{$ressymb}) ne 'ARRAY')) { (my $analysis,$parts) = - &scantron_partids_tograde($resource,$env{'request.course.id'}, - $username,$domain,undef, - $bubbles_per_row); + &scantron_partids_tograde($resource,$env{'request.course.id'},$username,$domain); } else { $parts = $grader_partids_by_symb{$ressymb}; } @@ -8871,11 +8476,7 @@ sub checkscantron_results { $env{'form.scantron_maxbubble'}). '

' ); - $r->print('

' - .&mt('Exact matches for [_1][quant,_2,student][_3].','',$passed,'') - .'
' - .&mt('Discrepancies detected for [_1][quant,_2,student][_3].','',$failed,'') - .'

'); + $r->print('

'.&mt('Exact matches for [quant,_1,student].',$passed).'
'.&mt('Discrepancies detected for [quant,_1,student].',$failed).'

'); if ($passed) { $r->print(&mt('Students with exact correspondence between bubblesheet data and submissions are as follows:').'

'); $r->print(&Apache::loncommon::start_data_table()."\n". @@ -9061,13 +8662,6 @@ sub savedState { return \%savedState; } -#--- Href with symb and command --- - -sub href_symb_cmd { - my ($symb,$cmd)=@_; - return '/adm/grades?symb='.&HTML::Entities::encode(&Apache::lonenc::check_encrypt($symb),'<>&"').'&command='.$cmd; -} - sub grading_menu { my ($request) = @_; my ($symb)=&get_symb($request); @@ -9491,8 +9085,7 @@ sub process_clicker { my $pincorrect=&mt("Percentage points for incorrect solution"); my $selectform=&Apache::loncommon::select_form($env{'form.upfiletype'},'upfiletype', {'iclicker' => 'i>clicker', - 'interwrite' => 'interwrite PRS', - 'turning' => 'Turning Technologies'}); + 'interwrite' => 'interwrite PRS'}); $symb = &Apache::lonenc::check_encrypt($symb); $result.=< @@ -9665,9 +9258,6 @@ ENDHEADER if ($env{'form.upfiletype'} eq 'interwrite') { ($errormsg,$number)=&interwrite_eval(\@questiontitles,\%responses); } - if ($env{'form.upfiletype'} eq 'turning') { - ($errormsg,$number)=&turning_eval(\@questiontitles,\%responses); - } $result.='
'.&mt('Found [_1] question(s)',$number).'
'. ''. &mt('Awarding [_1] percent for correct and [_2] percent for incorrect responses', @@ -9799,31 +9389,6 @@ sub interwrite_eval { return ($errormsg,$number); } -sub turning_eval { - my ($questiontitles,$responses)=@_; - my $number=0; - my $errormsg=''; - foreach my $line (split(/[\n\r]/,$env{'form.upfile'})) { - my %components=&Apache::loncommon::record_sep($line); - my @entries=map {$components{$_}} (sort(keys(%components))); - if ($#entries>$number) { $number=$#entries; } - my $id=$entries[0]; - my @idresponses; - $id=~s/^[\#0]+//; - unless ($id) { next; } - for (my $idx=1;$idx<=$#entries;$idx++) { - $entries[$idx]=~s/\,/\;/g; - $entries[$idx]=~s/[^a-zA-Z0-9\.\*\-\+\;]+//g; - push(@idresponses,$entries[$idx]); - } - $$responses{$id}=join(',',@idresponses); - } - for (my $i=1; $i<=$number; $i++) { - $$questiontitles[$i]=&mt('Question [_1]',$i); - } - return ($errormsg,$number); -} - sub assign_clicker_grades { my ($r)=@_; my ($symb)=&get_symb($r); @@ -9965,19 +9530,6 @@ sub navmap_errormsg { ''; } -sub startpage { - my ($r,$symb,$crumbs,$onlyfolderflag,$nodisplayflag,$stuvcurrent,$stuvdisp,$nomenu,$js) = @_; - if ($nomenu) { - $r->print(&Apache::loncommon::start_page("Student's Version",$js,{'only_body' => '1'})); - } else { - $r->print(&Apache::loncommon::start_page('Grading',$js, - {'bread_crumbs' => $crumbs})); - } - unless ($nodisplayflag) { - $r->print(&Apache::lonhtmlcommon::resource_info_box($symb,$onlyfolderflag,$stuvcurrent,$stuvdisp)); - } -} - sub handler { my $request=$_[0]; &reset_caches(); @@ -9999,7 +9551,7 @@ sub handler { $ssi_error = 0; my $brcrum = [{href=>"/adm/grades",text=>"Grading"}]; my $start_page = &Apache::loncommon::start_page('Grading',undef, - {'bread_crumbs' => $brcrum}); + {'bread_crumbs' => $brcrum}); if ($symb eq '' && $command eq '') { if ($env{'user.adv'}) { &Apache::loncommon::content_type($request,'text/html'); @@ -10052,33 +9604,9 @@ sub handler { } &Apache::loncommon::content_type($request,'text/html'); $request->send_http_header; - unless ((($command eq 'submission' || $command eq 'versionsub')) && ($perm{'vgr'})) { - $request->print($start_page); - } + $request->print($start_page); if ($command eq 'submission' && $perm{'vgr'}) { - my ($stuvcurrent,$stuvdisp,$versionform,$js); - if (($env{'form.student'} ne '') && ($env{'form.userdom'} ne '')) { - ($stuvcurrent,$stuvdisp,$versionform,$js) = - &choose_task_version_form($symb,$env{'form.student'}, - $env{'form.userdom'}); - } - &startpage($request,$symb,[{href=>"", text=>"Student Submissions"}],undef,undef,$stuvcurrent,$stuvdisp,undef,$js); - if ($versionform) { - $request->print($versionform); - } - $request->print('
'); ($env{'form.student'} eq '' ? &listStudents($request) : &submission($request,0,0)); - } elsif ($command eq 'versionsub' && $perm{'vgr'}) { - my ($stuvcurrent,$stuvdisp,$versionform,$js) = - &choose_task_version_form($symb,$env{'form.student'}, - $env{'form.userdom'}, - $env{'form.inhibitmenu'}); - &startpage($request,$symb,[{href=>"", text=>"Previous Student Version"}],undef,undef,$stuvcurrent,$stuvdisp,$env{'form.inhibitmenu'},$js); - if ($versionform) { - $request->print($versionform); - } - $request->print('
'); - $request->print(&show_previous_task_version($request,$symb)); } elsif ($command eq 'pickStudentPage' && $perm{'vgr'}) { &pickStudentPage($request); } elsif ($command eq 'displayPage' && $perm{'vgr'}) { @@ -10258,8 +9786,6 @@ ssi_with_retries() calling routine should trap the error condition and display the warning found in &navmap_errormsg(). - $scantron_config - Reference to bubblesheet format configuration hash. - Returns the maximum number of bubble lines that are expected to occur. Does this by walking the selected sequence rendering the resource and then checking &Apache::lonxml::get_problem_counter()