--- loncom/homework/grades.pm 2023/09/07 17:38:56 1.596.2.12.2.60.2.5 +++ loncom/homework/grades.pm 2018/10/08 19:11:01 1.752 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # The LON-CAPA Grading handler # -# $Id: grades.pm,v 1.596.2.12.2.60.2.5 2023/09/07 17:38:56 raeburn Exp $ +# $Id: grades.pm,v 1.752 2018/10/08 19:11:01 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -44,11 +44,10 @@ use Apache::Constants qw(:common :http); use Apache::lonlocal; use Apache::lonenc; use Apache::lonstathelpers; +use Apache::lonquickgrades; use Apache::bridgetask(); use Apache::lontexconvert(); use String::Similarity; -use HTML::Parser(); -use File::MMagic; use LONCAPA; use POSIX qw(floor); @@ -147,7 +146,6 @@ sub nameUserString { #--- Get the partlist and the response type for a given problem. --- #--- Indicate if a response type is coded handgraded or not. --- -#--- Count responseIDs, essayresponse items, and dropbox items --- #--- Sets response_error pointer to "1" if navmaps object broken --- sub response_type { my ($symb,$response_error) = @_; @@ -165,7 +163,6 @@ sub response_type { return; } my $partlist = $res->parts(); - my ($numresp,$numessay,$numdropbox) = (0,0,0); my %vPart = map { $_ => 1 } (&Apache::loncommon::get_env_multiple('form.vPart')); my (%response_types,%handgrade); @@ -175,20 +172,13 @@ sub response_type { my @types = $res->responseType($part); my @ids = $res->responseIds($part); for (my $i=0; $i < scalar(@ids); $i++) { - $numresp ++; $response_types{$part}{$ids[$i]} = $types[$i]; - if ($types[$i] eq 'essay') { - $numessay ++; - if (&Apache::lonnet::EXT("resource.$part".'_'.$ids[$i].".uploadedfiletypes",$symb)) { - $numdropbox ++; - } - } $handgrade{$part.'_'.$ids[$i]} = &Apache::lonnet::EXT('resource.'.$part.'_'.$ids[$i]. '.handgrade',$symb); } } - return ($partlist,\%handgrade,\%response_types,$numresp,$numessay,$numdropbox); + return ($partlist,\%handgrade,\%response_types); } sub flatten_responseType { @@ -215,129 +205,6 @@ sub get_display_part { return $display; } -#--- Show parts and response type -sub showResourceInfo { - my ($symb,$partlist,$responseType,$formname,$checkboxes,$uploads) = @_; - unless ((ref($partlist) eq 'ARRAY') && (ref($responseType) eq 'HASH')) { - return ''; - } - my $coltitle = &mt('Problem Part Shown'); - if ($checkboxes) { - $coltitle = &mt('Problem Part'); - } else { - my $checkedparts = 0; - foreach my $partid (&Apache::loncommon::get_env_multiple('form.vPart')) { - if (grep(/^\Q$partid\E$/,@{$partlist})) { - $checkedparts ++; - } - } - if ($checkedparts == scalar(@{$partlist})) { - return ''; - } - if ($uploads) { - $coltitle = &mt('Problem Part Selected'); - } - } - my $result = '
'. - &mt('No dropbox items or essayresponse items with uploadedfiletypes set.'). - '
'.&keywords_highlight($answer).'
' .&mt('Part(s) graded correct by the computer is marked with a [_1] symbol.',$checkIcon) ."
'. + &keywords_highlight($oessay). + '
'.&mt('No grading privileges').'
'. - &keywords_highlight($oessay). - '
'.&mt('[_1]Message:[_2] No more students for this section or class.','','').'
".&mt('Users are in domain: [_1]',$domform)."
'. + &mt('Score not saved for clicker: [_1] (matched multiple usernames: [_2])', + $clicker,join(', ',@inclass)).'
". &mt("Failed to save data for student [_1]. Message when trying to save was: [_2]", "$username:$domain",$result)."
' .&mt('Unable to accept last correction, an error occurred: [_1]', $errmsg) @@ -7331,7 +7058,7 @@ sub check_for_error { sub scantron_warning_screen { my ($button_text,$symb)=@_; my $title=&Apache::lonnet::gettitle($env{'form.selectpage'}); - my %scantron_config=&Apache::lonnet::get_scantron_config($env{'form.scantron_format'}); + my %scantron_config=&get_scantron_config($env{'form.scantron_format'}); my $CODElist; if ($scantron_config{'CODElocation'} && $scantron_config{'CODEstart'} && @@ -7487,7 +7214,7 @@ sub scantron_validate_file { #get the student pick code ready $r->print(&Apache::loncommon::studentbrowser_javascript()); my $nav_error; - my %scantron_config=&Apache::lonnet::get_scantron_config($env{'form.scantron_format'}); + my %scantron_config=&get_scantron_config($env{'form.scantron_format'}); my $max_bubble=&scantron_get_maxbubble(\$nav_error,\%scantron_config); if ($nav_error) { $r->print(&navmap_errormsg()); @@ -7514,7 +7241,7 @@ sub scantron_validate_file { while (!$stop && $currentphase < scalar(@validate_phases)) { $r->print(&mt('Validating '.$validate_phases[$currentphase]).''); $r->rflush(); - + my $which="scantron_validate_".$validate_phases[$currentphase]; { no strict 'refs'; @@ -7544,7 +7271,7 @@ sub scantron_validate_file { $r->print(''); $r->print(' '.&mt('this error').' '); - $r->print('
'.&mt('Or return to [_1]Grade/Manage/Review Bubblesheets[_2] to start over.','','').'
' + $r->print( + '
' .&mt('Some resources in the sequence currently are not set to' - .' exam mode. Grading these resources currently may not' + .' bubblesheet exam mode. Grading these resources currently may not' .' work correctly.') .'
'.&mt("The encoded ID is not in the classlist"). + $r->print('
'.&mt("The encoded ID is not in the classlist"). "
'.&mt("The encoded ID has also been used by a previous paper [_1]",$arg)."
".&mt("How should I handle this?")." \n"); @@ -8070,8 +7798,8 @@ sub scantron_get_correction { } elsif ($error eq 'duplicateCODE') { $r->print('
'.&mt("The encoded CODE has also been used by a previous paper [_1], and CODEs are supposed to be unique.",join(', ',@{$arg}))."
".&mt('The CODE on the form is [_1]', - "'$$scan_record{'scantron.CODE'}'") + $r->print("
".&mt('The CODE on the form is [_1]', + "'$$scan_record{'scantron.CODE'}'") ."
".&mt("How should I handle this?")."
'. &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?',''). @@ -8996,8 +8712,8 @@ sub scantron_process_students { } my $default_form_data=&defaultFormData($symb); - my %scantron_config=&Apache::lonnet::get_scantron_config($env{'form.scantron_format'}); - my $bubbles_per_row = &bubblesheet_bubbles_per_row(\%scantron_config); + 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); @@ -9008,21 +8724,10 @@ sub scantron_process_students { } my $map=$navmap->getResourceByUrl($sequence); my ($randomorder,$randompick,@master_seq,%symb_to_resource,%grader_partids_by_symb, - %grader_randomlists_by_symb,%symb_for_examcode); + %grader_randomlists_by_symb); if (ref($map)) { $randomorder = $map->randomorder(); $randompick = $map->randompick(); - unless ($randomorder || $randompick) { - foreach my $res ($navmap->retrieveResources($map,sub { $_[0]->is_map() },1,0,1)) { - if ($res->randomorder()) { - $randomorder = 1; - } - if ($res->randompick()) { - $randompick = 1; - } - last if ($randomorder || $randompick); - } - } } else { $r->print(&navmap_errormsg()); return ''; @@ -9030,7 +8735,7 @@ sub scantron_process_students { my $nav_error; my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0); if ($randomorder || $randompick) { - $nav_error = &get_master_seq(\@resources,\@master_seq,\%symb_to_resource,1,\%symb_for_examcode); + $nav_error = &get_master_seq(\@resources,\@master_seq,\%symb_to_resource); if ($nav_error) { $r->print(&navmap_errormsg()); return ''; @@ -9075,7 +8780,7 @@ SCANTRONFORM return ''; # Dunno why the other returns return '' rather than just returning. } - my %lettdig = &Apache::lonnet::letter_to_digits(); + my %lettdig = &letter_to_digits(); my $numletts = scalar(keys(%lettdig)); my %orderedforcode; @@ -9092,7 +8797,7 @@ SCANTRONFORM my %startline = (); my $total; my $scan_record=&scantron_parse_scanline($line,$i,\%scantron_config, - $scan_data,undef,\%idmap,$randomorder, + $scan_data,undef,\%idmap,$randomorder, $randompick,$sequence,\@master_seq, \%symb_to_resource,\%grader_partids_by_symb, \%orderedforcode,\%respnumlookup,\%startline, @@ -9122,7 +8827,7 @@ SCANTRONFORM my @mapresources = @resources; if ($randomorder || $randompick) { - @mapresources = + @mapresources = &users_order($user,$scancode,$sequence,\@master_seq,\%symb_to_resource, \%orderedforcode); } @@ -9177,16 +8882,11 @@ SCANTRONFORM } if (($scancode) && ($randomorder || $randompick)) { - foreach my $key (keys(%symb_for_examcode)) { - my $symb_in_map = $symb_for_examcode{$key}; - if ($symb_in_map ne '') { - my $parmresult = - &Apache::lonparmset::storeparm_by_symb($symb_in_map, - '0_examcode',2,$scancode, - 'string_examcode',$uname, - $udom); - } - } + my $parmresult = + &Apache::lonparmset::storeparm_by_symb($symb, + '0_examcode',2,$scancode, + 'string_examcode',$uname, + $udom); } $completedstudents{$uname}={'line'=>$line}; if ($env{'form.verifyrecord'}) { @@ -9216,7 +8916,7 @@ SCANTRONFORM if (&grade_student_bubbles($r,$uname,$udom,$scan_record,$scancode, \@mapresources,\%partids_by_symb, $bubbles_per_row,$randomorder,$randompick, - \%respnumlookup,\%startline) + \%respnumlookup,\%startline) eq 'ssi_error') { $ssi_error = 0; # So end of handler error message does not trigger. $r->print(""); @@ -9309,7 +9009,7 @@ sub graders_resources_pass { =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 + if this is a CODEd exam, or based on student's identity if this is a "NAMEd" exam. Should be used when randomorder and/or randompick applied when the @@ -9336,7 +9036,7 @@ sub users_order { if (ref($actual_seq) eq 'ARRAY') { @mapresources = map { $symb_to_resource->{$_}; } @{$actual_seq}; if (ref($orderedforcode) eq 'HASH') { - if (@mapresources > 0) { + if (@mapresources > 0) { $orderedforcode->{$scancode} = \@mapresources; } } @@ -9349,7 +9049,7 @@ sub users_order { $master_seq, $user,undef,1); if (ref($actual_seq) eq 'ARRAY') { - @mapresources = + @mapresources = map { $symb_to_resource->{$_}; } @{$actual_seq}; } } @@ -9405,16 +9105,15 @@ sub grade_student_bubbles { } sub scantron_upload_scantron_data { - my ($r,$symb) = @_; + my ($r,$symb)=@_; my $dom = $env{'request.role.domain'}; - my ($formatoptions,$formattitle,$formatjs) = &scantron_upload_dataformat($dom); my $domdesc = &Apache::lonnet::domain($dom,'description'); $r->print(&Apache::loncommon::coursebrowser_javascript($dom)); my $select_link=&Apache::loncommon::selectcourse_link('rules','courseid', 'domainid', 'coursename',$dom); my $syllabuslink = ''.&mt('Syllabus').''. - (' 'x2).&mt('(shows course personnel)'); + (' 'x2).&mt('(shows course personnel)'); my $default_form_data=&defaultFormData($symb); my $nofile_alert = &mt('Please use the browse button to select a file from your local directory.'); &js_escape(\$nofile_alert); @@ -9447,7 +9146,6 @@ sub scantron_upload_scantron_data { return; } - '.$formatjs.' ')); $r->print('
'.&mt("Uploading file to [_1]",$coursedata{'description'}).'
'.&mt('Uploading file to [_1]','"'.$coursedata{'description'}.'"').'
'. - &mt('Comparison of bubblesheet data (including corrections) with corresponding submission records (most recent submission) for [_1][quant,_2,student][_3] ([quant,_4,bubblesheet line] per student).', - '', - $numstudents, - '', - $env{'form.scantron_maxbubble'}). - '
' + .&mt('Comparison of bubblesheet data (including corrections) with corresponding submission records (most recent submission) for [_1][quant,_2,student][_3] ([quant,_4,bubblesheet line] per student).', + '', + $numstudents, + '', + $env{'form.scantron_maxbubble'}) + .'
' .&mt('Exact matches for [_1][quant,_2,student][_3].','',$passed,'') .'' .&mt('Discrepancies detected for [_1][quant,_2,student][_3].','',$failed,'') - .'
'. - &Apache::lonhtmlcommon::confirm_success( - &mt('File format is neither csv (iclicker 6) nor xml (iclicker 7)'),1).'
'. - &Apache::lonhtmlcommon::confirm_success( - &mt('Invalid clicker type: choose one of: i>clicker, Interwrite PRS, or Turning Technologies.'),1).'
'. - &mt('Part(s) graded correct by the computer is marked with a [_1] symbol.',$checkIcon). - "
'.&mt('Access Denied ([_1])',$command).'