--- loncom/homework/grades.pm 2012/05/02 14:01:32 1.596.2.12.2.1
+++ 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.1 2012/05/02 14:01:32 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
#
@@ -52,6 +52,7 @@ use POSIX qw(floor);
my %perm=();
+my %old_essays=();
# These variables are used to recover from ssi errors
@@ -260,6 +261,7 @@ sub showResourceInfo {
sub reset_caches {
&reset_analyze_cache();
&reset_perm();
+ &reset_old_essays();
}
{
@@ -272,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 '') {
@@ -306,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 '') {
@@ -349,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();
@@ -357,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};
}
@@ -743,7 +740,11 @@ sub compute_points {
#
sub most_similar {
- my ($uname,$udom,$uessay,$old_essays)=@_;
+ my ($uname,$udom,$symb,$uessay)=@_;
+
+ unless ($symb) { return ''; }
+
+ unless (ref($old_essays{$symb}) eq 'HASH') { return ''; }
# ignore spaces and punctuation
@@ -760,11 +761,11 @@ sub most_similar {
my $scrsid='';
my $sessay='';
# go through all essays ...
- foreach my $tkey (keys(%$old_essays)) {
+ foreach my $tkey (keys(%{$old_essays{$symb}})) {
my ($tname,$tdom,$tcrsid)=map {&unescape($_)} (split(/\./,$tkey));
# ... except the same student
next if (($tname eq $uname) && ($tdom eq $udom));
- my $tessay=$old_essays->{$tkey};
+ my $tessay=$old_essays{$symb}{$tkey};
$tessay=~s/\W+/ /gs;
# String similarity gives up if not even limit
my $tsimilar=&String::Similarity::similarity($uessay,$tessay,$limit);
@@ -774,7 +775,7 @@ sub most_similar {
$sname=$tname;
$sdom=$tdom;
$scrsid=$tcrsid;
- $sessay=$old_essays->{$tkey};
+ $sessay=$old_essays{$symb}{$tkey};
}
}
if ($limit>0.6) {
@@ -1830,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();
@@ -2013,7 +2015,6 @@ sub submission {
'" src="'.$request->dir_config('lonIconsURL').
'/check.gif" height="16" border="0" />';
- my %old_essays;
# header info
if ($counter == 0) {
&sub_page_js($request);
@@ -2129,7 +2130,7 @@ KEYWORDS
my ($adom,$aname,$apath)=($essayurl=~/^($LONCAPA::domain_re)\/($LONCAPA::username_re)\/(.*)$/);
$apath=&escape($apath);
$apath=~s/\W/\_/gs;
- %old_essays=&Apache::lonnet::dump('nohist_essay_'.$apath,$adom,$aname);
+ &init_old_essays($symb,$apath,$adom,$aname);
}
}
@@ -2266,7 +2267,7 @@ KEYWORDS
}
if($env{'form.checkPlag'}){
my ($oname,$odom,$ocrsid,$oessay,$osim)=
- &most_similar($uname,$udom,$subval,\%old_essays);
+ &most_similar($uname,$udom,$symb,$subval);
if ($osim) {
$osim=int($osim*100.0);
my %old_course_desc =
@@ -5566,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
@@ -5598,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;
@@ -6522,8 +6520,7 @@ 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 '';
@@ -6976,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);
@@ -7389,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().
@@ -7556,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);
@@ -7615,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);
@@ -7637,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();
@@ -7656,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();
@@ -7672,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;
@@ -7702,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++) {
@@ -7716,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;
@@ -7737,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
@@ -7759,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);
}
@@ -7842,8 +7812,7 @@ sub scantron_process_students {
}
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') {
@@ -7881,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 '';
@@ -7938,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};
@@ -7968,8 +7936,7 @@ SCANTRONFORM
}
if (&grade_student_bubbles($r,$uname,$udom,$scan_record,$scancode,
- \@resources,\%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);
@@ -7997,8 +7964,7 @@ SCANTRONFORM
if ($studentrecord ne $studentdata) {
&Apache::lonxml::clear_problem_counter();
if (&grade_student_bubbles($r,$uname,$udom,$scan_record,$scancode,
- \@resources,\%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);
@@ -8070,8 +8036,7 @@ sub graders_resources_pass {
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') {
@@ -8085,7 +8050,7 @@ sub graders_resources_pass {
}
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}) {
@@ -8098,9 +8063,6 @@ sub grade_student_bubbles {
'grade_symb' => $ressymb,
'CODE' => $scancode
);
- if ($bubbles_per_row ne '') {
- $form{'bubbles_per_row'} = $bubbles_per_row;
- }
if (ref($parts) eq 'HASH') {
if (ref($parts->{$ressymb}) eq 'ARRAY') {
foreach my $part (@{$parts->{$ressymb}}) {
@@ -8411,7 +8373,7 @@ sub checkscantron_results {
'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 '';
@@ -8461,9 +8423,7 @@ sub checkscantron_results {
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};
}
@@ -9009,6 +8969,21 @@ sub init_perm {
}
}
+sub init_old_essays {
+ my ($symb,$apath,$adom,$aname) = @_;
+ if ($symb ne '') {
+ my %essays = &Apache::lonnet::dump('nohist_essay_'.$apath,$adom,$aname);
+ if (keys(%essays) > 0) {
+ $old_essays{$symb} = \%essays;
+ }
+ }
+ return;
+}
+
+sub reset_old_essays {
+ undef(%old_essays);
+}
+
sub gather_clicker_ids {
my %clicker_ids;
@@ -9811,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()