[LON-CAPA-cvs] cvs: loncom /homework grades.pm /interface lonpickcode.pm

albertel lon-capa-cvs@mail.lon-capa.org
Tue, 04 May 2004 14:17:19 -0000


This is a MIME encoded message

--albertel1083680239
Content-Type: text/plain

albertel		Tue May  4 10:17:19 2004 EDT

  Modified files:              
    /loncom/interface	lonpickcode.pm 
    /loncom/homework	grades.pm 
  Log:
  - move more of pickcode in grades.pm where it probebly belongs
  - print which papers use the paticular code
  - add another set of options for handling the case of inccorect CODE,
    find the set of closest matches and present them as possible choices
  - make the validatepass passing actually work, so we don't redo all of
    the finished passes each time we handle an error.
  - in the case of duplicated CODEs when expecting announce the paper
    that previously use the CODE
  
  
  
--albertel1083680239
Content-Type: text/plain
Content-Disposition: attachment; filename="albertel-20040504101719.txt"

Index: loncom/interface/lonpickcode.pm
diff -u loncom/interface/lonpickcode.pm:1.3 loncom/interface/lonpickcode.pm:1.4
--- loncom/interface/lonpickcode.pm:1.3	Sat Apr 24 05:01:52 2004
+++ loncom/interface/lonpickcode.pm	Tue May  4 10:17:18 2004
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Pick a CODE from the list of possible CODEs
 #
-# $Id: lonpickcode.pm,v 1.3 2004/04/24 09:01:52 albertel Exp $
+# $Id: lonpickcode.pm,v 1.4 2004/05/04 14:17:18 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -48,33 +48,12 @@
 	    &Apache::grades::scantron_parse_scanline($line,$i,
 						     \%scantron_config,
 						     $scan_data,1);
-	$codes{$$scan_record{'scantron.CODE'}}++;
+	push(@{$codes{$$scan_record{'scantron.CODE'}}},$$scan_record{'scantron.PaperID'});
 
     }
     return %codes;
 }
 
-sub get_codes {
-    my $old_name=$ENV{'form.scantron_CODElist'};
-    my $cdom =$ENV{'course.'.$ENV{'request.course.id'}.'.domain'};
-    my $cnum =$ENV{'course.'.$ENV{'request.course.id'}.'.num'};
-    my %result=&Apache::lonnet::get('CODEs',[$old_name],$cdom,$cnum);
-    my %allcodes=map {(&Apache::lonprintout::num_to_letters($_),1)} split(',',$result{$old_name});
-    return %allcodes;
-}
-
-sub num_matches {
-    my ($code) = @_;
-    my $orig=$ENV{'form.curCODE'};
-    my @code=split(//,$code);
-    my @orig=split(//,$orig);
-    my $same=0;
-    for (my $i=0;$i<scalar(@code);$i++) {
-	if ($code[$i] eq $orig[$i]) { $same++; }
-    }
-    return $same;
-}
-
 sub handler {
     my $r = shift;
     &Apache::loncommon::content_type($r,'text/html');
@@ -118,23 +97,28 @@
 
     $r->print("<p>The CODE on the paper is <tt><b>".$ENV{'form.curCODE'}.
 	      "</b></tt>. Please Select a new one.</p>\n".'<form>');
-    my %codes=&get_codes();
+    my %codes=&Apache::grades::get_codes();
     my %code_freq=&get_code_freq($r);
-    my $num_matches=&num_matches($ENV{'form.curCODE'});
+    my $num_matches=length($ENV{'form.curCODE'});
     for (my $i=$num_matches;$i>=0;$i--) {
 	my $to_print="<p> CODEs with $i matches</p>";
-	$to_print.='<table border="1"><tr><td></td><td>CODE</td><td># of exams using this CODE</td>';
+	$to_print.='<table border="1"><tr><td></td><td>CODE</td><td>exams using this CODE</td>';
 	my $print;
 	foreach my $code (sort(keys(%codes))) {
-	    if (&num_matches($code) != $i) { next; }
+	    if (&Apache::grades::num_matches($ENV{'form.curCODE'},$code) != $i) { next; }
 	    $print=1;
-	    my $count=$code_freq{$code};
-	    if (!$count) { $count=0; }
+	    my ($count,$list);
+	    if (!ref($code_freq{$code})) {
+		$count=0;
+	    } else {
+		$count=scalar(@{$code_freq{$code}});
+		$list=' - '.join(', ',@{$code_freq{$code}});
+	    }
 	    $to_print.='<tr><td>'.
 		      '<input type="button" value="'.&mt('Select').
 		      '" onClick="gochoose(\''.$code.'\')" /></td>'.
-		      '<td><tt>'.$code.'</tt></td><td> <tt>'.$count.
-		      '</tt></td></tr>';
+		      '<td><tt>'.$code.'</tt></td><td>'.$count.
+		      $list.'</td></tr>';
 	    delete($codes{$code});
 	}
 	$to_print.='</table>';
Index: loncom/homework/grades.pm
diff -u loncom/homework/grades.pm:1.193 loncom/homework/grades.pm:1.194
--- loncom/homework/grades.pm:1.193	Thu Apr 29 03:57:47 2004
+++ loncom/homework/grades.pm	Tue May  4 10:17:18 2004
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # The LON-CAPA Grading handler
 #
-# $Id: grades.pm,v 1.193 2004/04/29 07:57:47 albertel Exp $
+# $Id: grades.pm,v 1.194 2004/05/04 14:17:18 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -3729,7 +3729,7 @@
 }
 
 sub scantron_parse_scanline {
-    my ($line,$whichline,$scantron_config,$scan_data,$justCODE)=@_;
+    my ($line,$whichline,$scantron_config,$scan_data,$justHeader)=@_;
     my %record;
     my $questions=substr($line,$$scantron_config{'Qstart'}-1);
     my $data=substr($line,0,$$scantron_config{'Qstart'}-1);
@@ -3748,7 +3748,6 @@
 	    #FIXME interpret first N questions
 	}
     }
-    if ($justCODE) { return \%record; }
     $record{'scantron.ID'}=substr($data,$$scantron_config{'IDstart'}-1,
 				  $$scantron_config{'IDlength'});
     $record{'scantron.PaperID'}=
@@ -3760,6 +3759,8 @@
     $record{'scantron.LastName'}=
 	substr($data,$$scantron_config{'LastName'}-1,
 	       $$scantron_config{'LastNamelength'});
+    if ($justHeader) { return \%record; }
+
     my @alphabet=('A'..'Z');
     my $questnum=0;
     while ($questions) {
@@ -3850,6 +3851,8 @@
 	    $newCODE=$ENV{'form.scantron_CODE_selectedvalue'};
 	} elsif ($resolution eq 'use_typed') {
 	    $newCODE=$ENV{'form.scantron_CODE_newvalue'};
+	} elsif ($resolution =~ /^use_closest_(\d+)/) {
+	    $newCODE=$ENV{"form.scantron_CODE_closest_$1"};
 	}
 	if ($ENV{'form.scantron_corrections'} eq 'duplicateCODE') {
 	    $args{'CODE_ignore_dup'}=1;
@@ -3884,7 +3887,6 @@
     my $default_form_data=&defaultFormData($symb,$url);
     if ($ENV{'form.scantron_options_ignore'} eq 'ignore_corrections') {
 	my $result=&scantron_remove('corrected');
-	&Apache::lonnet::logthis("result was $result");
 	if ($result ne 'ok' && $result ne 'not_found' ) {
 	    $r->print("An error occured ($result) when trying to Remove the existing corrections.");
 	}
@@ -3916,14 +3918,10 @@
 			  'doublebubble',
 			  'missingbubbles');
     if (!$ENV{'form.validatepass'}) {
-	$ENV{'form.valiadatepass'} = 0;
+	$ENV{'form.validatepass'} = 0;
     }
-    my $currentphase=$ENV{'form.valiadatepass'};
+    my $currentphase=$ENV{'form.validatepass'};
 
-    if ($ENV{'form.scantron_selectfile'}=~m-^/-) {
-	#first pass copy file to classdir
-	
-    }
     my $stop=0;
     while (!$stop && $currentphase < scalar(@validate_phases)) {
 	$r->print("<p> Validating ".$validate_phases[$currentphase]."</p>");
@@ -3964,20 +3962,15 @@
 	return 'refused';
     }
     $file.=$ENV{'form.scantron_selectfile'};
-    &Apache::lonnet::logthis("removeing $file");
     my $result=&Apache::lonnet::removeuserfile($cname,$cdom,$file);
     my @keys=&Apache::lonnet::getkeys('nohist_scantrondata',$cdom,$cname);
-    &Apache::lonnet::logthis('got keys '.join(':',@keys));
-    &Apache::lonnet::logthis("cdom $cdom cname $cname");
     my @todelete;
     my $filename=$ENV{'form.scantron_selectfile'};
-    &Apache::lonnet::logthis('filename '.$filename);
     foreach my $key (@keys) {
 	if ($key=~/^\Q$filename\E_/) {
 	    push(@todelete,$key);
 	}
     }
-    &Apache::lonnet::logthis('todelete '.join(':',@todelete));
     if (@todelete) {
 	&Apache::lonnet::del('nohist_scantrondata',\@todelete,$cdom,$cname);
     }
@@ -4089,11 +4082,11 @@
 	    if ($found{'ids'}{$found}) {
 		&scantron_get_correction($r,$i,$scan_record,\%scantron_config,
 					 $line,'duplicateID',$found);
-		return(1);
+		return(1,$currentphase);
 	    } elsif ($found{'usernames'}{$username}) {
 		&scantron_get_correction($r,$i,$scan_record,\%scantron_config,
 					 $line,'duplicateID',$username);
-		return(1);
+		return(1,$currentphase);
 	    }
 	    #FIXME store away line we previously saw the ID on to use above
 	    $found{'ids'}{$found}++;
@@ -4105,18 +4098,18 @@
 		    &scantron_get_correction($r,$i,$scan_record,
 					     \%scantron_config,
 					     $line,'duplicateID',$username);
-		    return(1);
+		    return(1,$currentphase);
 		} elsif (!defined($username)) {
 		    &scantron_get_correction($r,$i,$scan_record,
 					     \%scantron_config,
 					     $line,'incorrectID');
-		    return(1);
+		    return(1,$currentphase);
 		}
 		$found{'usernames'}{$username}++;
 	    } else {
 		&scantron_get_correction($r,$i,$scan_record,\%scantron_config,
 					 $line,'incorrectID');
-		return(1);
+		return(1,$currentphase);
 	    }
 	}
     }
@@ -4167,7 +4160,7 @@
 	if ($error eq 'incorrectCODE') {
 	    $r->print("</p><p>The encoded CODE is not in the list of possible CODEs</p>\n");
 	} elsif ($error eq 'duplicateCODE') {
-	    $r->print("</p><p>The encoded CODE has also been used by a previous paper $arg, and CODEs were supposed to be unique</p>\n");
+	    $r->print("</p><p>The encoded CODE has also been used by a previous paper ".join(', ',@{$arg}).", and CODEs are supposed to be unique</p>\n");
 	}
 	$r->print("<p>The CODE on the form is  <tt>".
 		  $$scan_record{'scantron.CODE'}."</tt><br />\n");
@@ -4178,8 +4171,21 @@
 		  $$scan_record{'scantron.FirstName'}."</p>");
 	$r->print("<p>How should I handle this? <br /> \n");
 	$r->print("\n<br /> ");
-	$r->print("<input type='radio' name='scantron_CODE_resolution' value='use_unfound' checked='on' /> Use the CODE <b><tt>".$$scan_record{'scantron.CODE'}."</tt></b> that is was on the paper, ignoring the error.");
+	my $i=0;
+	if ($error eq 'incorrectCODE') {
+	    my ($max,$closest)=&scantron_get_closely_matching_CODEs($arg,$$scan_record{'scantron.CODE'});
+	    foreach my $testcode (@{$closest}) {
+		my $checked='';
+		if (!$i) { $checked=' checked="on" '; }
+		$r->print("<input type='radio' name='scantron_CODE_resolution' value='use_closest_$i' $checked /> Use the similar CODE <b><tt>".$testcode."</tt></b> instead.<input type='hidden' name='scantron_CODE_closest_$i' value='$testcode' />");
+		$r->print("\n<br />");
+		$i++;
+	    }
+	}
+	my $checked; if (!$i) { $checked=' checked="on" '; }
+	$r->print("<input type='radio' name='scantron_CODE_resolution' value='use_unfound' $checked /> Use the CODE <b><tt>".$$scan_record{'scantron.CODE'}."</tt></b> that is was on the paper, ignoring the error.");
 	$r->print("\n<br />");
+
 	$r->print(<<ENDSCRIPT);
 <script type="text/javascript">
 function change_radio(field) {
@@ -4202,7 +4208,6 @@
 	$r->print("<input type='radio' name='scantron_CODE_resolution' value='use_typed' /> Use <input type='text' size='8' name='scantron_CODE_newvalue' onfocus=\"javascript:change_radio('use_typed')\" onkeypress=\"javascript:change_radio('use_typed')\" /> as the CODE.");
 	$r->print("\n<br /><br />");
     } elsif ($error eq 'doublebubble') {
-#FIXME Need to print out who this is along with the paper info
 	$r->print("<p>There have been multiple bubbles scanned for a some question(s)</p>\n");
 	$r->print('<input type="hidden" name="scantron_questions" value="'.
 		  join(',',@{$arg}).'" />');
@@ -4249,9 +4254,38 @@
     $r->print('</tr></table>');
 }
 
+sub num_matches {
+    my ($orig,$code) = @_;
+    my @code=split(//,$code);
+    my @orig=split(//,$orig);
+    my $same=0;
+    for (my $i=0;$i<scalar(@code);$i++) {
+	if ($code[$i] eq $orig[$i]) { $same++; }
+    }
+    return $same;
+}
+
+sub scantron_get_closely_matching_CODEs {
+    my ($allcodes,$CODE)=@_;
+    my @CODEs;
+    foreach my $testcode (sort(keys(%{$allcodes}))) {
+	push(@{$CODEs[&num_matches($CODE,$testcode)]},$testcode);
+    }
+
+    return ($#CODEs,$CODEs[-1]);
+}
+
+sub get_codes {
+    my $old_name=$ENV{'form.scantron_CODElist'};
+    my $cdom =$ENV{'course.'.$ENV{'request.course.id'}.'.domain'};
+    my $cnum =$ENV{'course.'.$ENV{'request.course.id'}.'.num'};
+    my %result=&Apache::lonnet::get('CODEs',[$old_name],$cdom,$cnum);
+    my %allcodes=map {(&Apache::lonprintout::num_to_letters($_),1)} split(',',$result{$old_name});
+    return %allcodes;
+}
+
 sub scantron_validate_CODE {
     my ($r,$currentphase) = @_;
-    #FIXME doesn't do anything yet
     my %scantron_config=&get_scantron_config($ENV{'form.scantron_format'});
     if ($scantron_config{'CODElocation'} &&
 	$scantron_config{'CODEstart'} &&
@@ -4265,11 +4299,7 @@
     
     my %usedCODEs;
 
-    my $old_name=$ENV{'form.scantron_CODElist'};
-    my $cdom =$ENV{'course.'.$ENV{'request.course.id'}.'.domain'};
-    my $cnum =$ENV{'course.'.$ENV{'request.course.id'}.'.num'};
-    my %result=&Apache::lonnet::get('CODEs',[$old_name],$cdom,$cnum);
-    my %allcodes=map {(&Apache::lonprintout::num_to_letters($_),1)} split(',',$result{$old_name});
+    my %allcodes=&get_codes();
 
     my ($scanlines,$scan_data)=&scantron_getfile();
     for (my $i=0;$i<=$scanlines->{'count'};$i++) {
@@ -4282,17 +4312,17 @@
 	if (!exists($allcodes{$CODE}) && !$$scan_record{'scantron.useCODE'}) {
 	    &scantron_get_correction($r,$i,$scan_record,
 				     \%scantron_config,
-				     $line,'incorrectCODE',$CODE);
-	    return(1);
+				     $line,'incorrectCODE',\%allcodes);
+	    return(1,$currentphase);
 	}
 	if (exists($usedCODEs{$CODE}) && $ENV{'form.scantron_CODEunique'}
 	    && !$$scan_record{'scantron.CODE_ignore_dup'}) {
 	    &scantron_get_correction($r,$i,$scan_record,
 				     \%scantron_config,
-				     $line,'duplicateCODE',$CODE);
-	    return(1);
+				     $line,'duplicateCODE',$usedCODEs{$CODE});
+	    return(1,$currentphase);
 	}
-	$usedCODEs{$CODE}++;
+	push (@{$usedCODEs{$CODE}},$$scan_record{'scantron.PaperID'});
     }
     return (0,$currentphase+1);
 }

--albertel1083680239--