--- loncom/homework/grades.pm 2003/04/01 05:21:48 1.82
+++ loncom/homework/grades.pm 2003/04/30 15:52:28 1.87
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# The LON-CAPA Grading handler
#
-# $Id: grades.pm,v 1.82 2003/04/01 05:21:48 albertel Exp $
+# $Id: grades.pm,v 1.87 2003/04/30 15:52:28 www Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -46,6 +46,9 @@ use Apache::lonhomework;
use Apache::loncoursedata;
use Apache::lonmsg qw(:user_normal_msg);
use Apache::Constants qw(:common);
+use String::Similarity;
+
+my %oldessays=();
# ----- These first few routines are general use routines.----
#
@@ -221,6 +224,50 @@ sub jscriptNform {
}
#------------------ End of general use routines --------------------
+
+#
+# Find most similar essay
+#
+
+sub most_similar {
+ my ($uname,$udom,$uessay)=@_;
+
+# ignore spaces and punctuation
+
+ $uessay=~s/\W+/ /gs;
+
+# these will be returned. Do not care if not at least 50 percent similar
+ my $limit=0.5;
+ my $sname='';
+ my $sdom='';
+ my $scrsid='';
+ my $sessay='';
+# go through all essays ...
+ foreach my $tkey (keys %oldessays) {
+ my ($tname,$tdom,$tcrsid)=split(/\./,$tkey);
+# ... except the same student
+ if (($tname ne $uname) && ($tdom ne $udom)) {
+ my $tessay=$oldessays{$tkey};
+ $tessay=~s/\W+/ /gs;
+# String similarity gives up if not even limit
+ my $tsimilar=&String::Similarity::similar($uessay,$tessay,$limit);
+# Found one
+ if ($tsimilar>$limit) {
+ $limit=$tsimilar;
+ $sname=$tname;
+ $sdom=$sdom;
+ $scrsid=$tcrsid;
+ $sessay=$oldessays{$tkey};
+ }
+ }
+ }
+ if ($limit>0.5) {
+ return ($sname,$sdom,$scrsid,$sessay,$limit);
+ } else {
+ return ('','','','',0);
+ }
+}
+
#-------------------------------------------------------------------
#------------------------------------ Receipt Verification Routines
@@ -717,7 +764,7 @@ sub sub_page_kw_js {
height = 600;
scrollbar = "yes";
}
-// if (window.pWin) window.pWin.close();
+// if (window.pWin) {window.pWin.close(); window.pWin=null}
pWin = window.open('', 'MessageCenter', 'toolbar=no,location=no,scrollbars='+scrollbar+',screenx=70,screeny=75,width=600,height='+height);
pWin.focus();
pDoc = pWin.document;
@@ -752,11 +799,7 @@ sub sub_page_kw_js {
pDoc.write(" includemsg = 1;");
pDoc.write(" }");
pDoc.write(" imgformname = eval(\\"opener.document.SCORE.mailicon\\"+usrctr);");
- pDoc.write(" if (includemsg) {");
- pDoc.write(" imgformname.src = \\"$iconpath/mailto.gif\\";");
- pDoc.write(" } else {");
- pDoc.write(" imgformname.src = \\"$iconpath/mailbkgrd.gif\\";");
- pDoc.write(" }");
+ pDoc.write(" imgformname.src = \\"$iconpath/\\"+((includemsg) ? \\"mailto.gif\\" : \\"mailbkgrd.gif\\");");
pDoc.write(" var includemsg = eval(\\"opener.document.SCORE.includemsg\\"+usrctr);");
pDoc.write(" includemsg.value = msgchk;");
@@ -1112,7 +1155,6 @@ KEYWORDS
my @col_fullnames;
my ($classlist,$fullname);
if ($ENV{'form.handgrade'} eq 'yes') {
- my @col_list;
($classlist,undef,$fullname) = &getclasslist('all','0');
for (keys (%$handgrade)) {
my $ncol = &Apache::lonnet::EXT('resource.'.$_.
@@ -1121,56 +1163,46 @@ KEYWORDS
next if ($ncol <= 0);
s/\_/\./g;
next if ($record{'resource.'.$_.'.collaborators'} eq '');
- my (@colList) = split(/,?\s+/,
- $record{'resource.'.$_.'.collaborators'});
- my @collaborators = ();
- foreach (@colList) { #pre-filter list - throw out submitter
+ my @goodcollaborators = ();
+ my @badcollaborators = ();
+ foreach (split(/,?\s+/,$record{'resource.'.$_.'.collaborators'})) {
+ $_ =~ s/[\$\^\(\)]//g;
+ next if ($_ eq '');
my ($co_name,$co_dom) = split /\@|:/,$_;
- $co_dom = $udom if (! defined($co_dom));
+ $co_dom = $udom if (! defined($co_dom) || $co_dom =~ /^domain$/i);
next if ($co_name eq $uname && $co_dom eq $udom);
- push @collaborators, $_;
+ # Doing this grep allows 'fuzzy' specification
+ my @Matches = grep /^$co_name:$co_dom$/i,keys %$classlist;
+ if (! scalar(@Matches)) {
+ push @badcollaborators,$_;
+ } else {
+ push @goodcollaborators, @Matches;
+ }
}
- my (@badcollaborators);
- if (scalar(@collaborators) != 0) {
+ if (scalar(@goodcollaborators) != 0) {
$result.='Collaborators: ';
- foreach my $collaborator (@collaborators) {
- my ($co_name,$co_dom) = split /\@|:/,$collaborator;
- $co_dom = $udom if (! defined($co_dom));
- # Doing this grep allows 'fuzzy' specification
- my @Matches = grep /^$co_name:$co_dom$/i,
- keys %$classlist;
- if (! scalar(@Matches)) {
- push @badcollaborators,':'.$collaborator.':';
- next;
- }
- push @col_list, @Matches;
- foreach (@Matches) {
- my ($lastname,$givenn) = split(/,/,$$fullname{$_});
- push @col_fullnames, $givenn.' '.$lastname;
- $result.=$$fullname{$_}.' ';
- }
- }
+ foreach (@goodcollaborators) {
+ my ($lastname,$givenn) = split(/,/,$$fullname{$_});
+ push @col_fullnames, $givenn.' '.$lastname;
+ $result.=$$fullname{$_}.' ';
+ }
$result.='
'."\n";
- if (scalar(@badcollaborators) > 0) {
- $result.='
';
- $result.='This student has submitted ';
- if (scalar(@badcollaborators) == 1) {
- $result .= 'an invalid collaborator';
- } else {
- $result .= 'invalid collaborators';
- }
- $result .= ': '.join(', ',@badcollaborators);
- $result .= ' |
';
- }
- if (scalar(@collaborators > $ncol)) {
- $result .= '';
- $result .= 'This student has submitted too many '.
- 'collaborators. Maximum is '.$ncol;
- $result .= ' |
';
- }
- $result.=''."\n";
- }
+ $result.=''."\n";
+ }
+ if (scalar(@badcollaborators) > 0) {
+ $result.='';
+ $result.='This student has submitted ';
+ $result.=(scalar(@badcollaborators) == 1) ? 'an invalid collaborator' : 'invalid collaborators';
+ $result .= ': '.join(', ',@badcollaborators);
+ $result .= ' |
';
+ }
+ if (scalar(@badcollaborators > $ncol)) {
+ $result .= '';
+ $result .= 'This student has submitted too many '.
+ 'collaborators. Maximum is '.$ncol.'.';
+ $result .= ' |
';
+ }
}
}
$request->print($result."\n");
@@ -1250,6 +1282,7 @@ KEYWORDS
my $lastone = pop @col_fullnames;
$msgfor .= ', '.(join ', ',@col_fullnames).' and '.$lastone.'.';
}
+ $msgfor =~ s/\'/\\'/g; #\'
$result.=''."\n".
' '.
@@ -1447,12 +1480,20 @@ sub processHandGrade {
$ENV{'course.'.$ENV{'request.course.id'}.'.num'});
# Called by Save & Refresh from Highlight Attribute Window
+ my (undef,undef,$fullname) = &getclasslist($ENV{'form.section'},'0');
if ($ENV{'form.refresh'} eq 'on') {
- my $ctr = 0;
- $ENV{'form.NTSTU'}=$ngrade;
+ my ($ctr,$total) = (0,0);
while ($ctr < $ngrade) {
- ($ENV{'form.student'},$ENV{'form.userdom'}) = split(/:/,$ENV{'form.unamedom'.$ctr});
- &submission($request,$ctr,$ngrade-1);
+ $total++ if $ENV{'form.unamedom'.$ctr} ne '';
+ $ctr++;
+ }
+ $ENV{'form.NTSTU'}=$ngrade;
+ $ctr = 0;
+ while ($ctr < $total) {
+ my $processUser = $ENV{'form.unamedom'.$ctr};
+ ($ENV{'form.student'},$ENV{'form.userdom'}) = split(/:/,$processUser);
+ $ENV{'form.fullname'} = $$fullname{$processUser};
+ &submission($request,$ctr,$total-1);
$ctr++;
}
return '';
@@ -1468,7 +1509,6 @@ sub processHandGrade {
$laststu = $firststu if ($ctr > $ngrade);
}
- my (undef,undef,$fullname) = &getclasslist($ENV{'form.section'},'0');
my (@parsedlist,@nextlist);
my ($nextflg) = 0;
foreach (sort {lc($$fullname{$a}) cmp lc($$fullname{$b}) } keys %$fullname) {
@@ -2214,6 +2254,48 @@ sub csvuploadmap_footer {
ENDPICK
}
+sub upcsvScores_form {
+ my ($request) = shift;
+ my ($symb,$url)=&get_symb_and_url($request);
+ if (!$symb) {return '';}
+ my $result =<
+ function checkUpload(formname) {
+ if (formname.upfile.value == "") {
+ alert("Please use the browse button to select a file from your local directory.");
+ return false;
+ }
+ formname.submit();
+ }
+
+CSVFORMJS
+ $ENV{'form.probTitle'} = &Apache::lonnet::gettitle($symb);
+ $result.='
'."\n";
+ $result.=''."\n";
+ $result.=' |
'."\n";
+ $result.=&show_grading_menu_form($symb,$url);
+
+ return $result;
+}
+
+
sub csvuploadmap {
my ($request)= @_;
my ($symb,$url)=&get_symb_and_url($request);
@@ -2924,47 +3006,56 @@ sub scantron_parse_scanline {
my $data=substr($line,0,$$scantron_config{'Qstart'}-1);
if ($$scantron_config{'CODElocation'} ne 0) {
if ($$scantron_config{'CODElocation'} < 0) {
- $record{'CODE'}=substr($data,$$scantron_config{'CODEstart'}-1,
- $$scantron_config{'CODElength'});
+ $record{'scantron.CODE'}=substr($data,$$scantron_config{'CODEstart'}-1,
+ $$scantron_config{'CODElength'});
} else {
#FIXME interpret first N questions
}
}
- $record{'ID'}=substr($data,$$scantron_config{'IDstart'}-1,
- $$scantron_config{'IDlength'});
+ $record{'scantron.ID'}=substr($data,$$scantron_config{'IDstart'}-1,
+ $$scantron_config{'IDlength'});
my @alphabet=('A'..'Z');
my $questnum=0;
while ($questions) {
$questnum++;
my $currentquest=substr($questions,0,$$scantron_config{'Qlength'});
substr($questions,0,$$scantron_config{'Qlength'})='';
+ if (length($currentquest) < $$scantron_config{'Qlength'}) { next; }
my (@array)=split(/$$scantron_config{'Qon'}/,$currentquest);
if (scalar(@array) gt 2) {
#FIXME do something intelligent with double bubbles
- Apache->request->print(" Wha!!! ".scalar(@array).
- '-'.$questions.'-'.$currentquest.'-'.$questnum.
- '-'.length($questions).
- '-'.$line.'-'.length($line).'-'.
- '-'.$data.'-'.length($data).'-'.
- ' ');
+ Apache->request->print(" Wha!!! ".scalar(@array).
+ '-'.$currentquest.'-'.$questnum.' ');
}
if (length($array[0]) eq $$scantron_config{'Qlength'}) {
- $record{"$questnum.answer"}='';
+ $record{"scantron.$questnum.answer"}='';
} else {
- $record{"$questnum.answer"}=$alphabet[length($array[0])];
+ $record{"scantron.$questnum.answer"}=$alphabet[length($array[0])];
}
}
- $record{'maxquest'}=$questnum;
- $Apache::lonxml::debug=1;
- &Apache::lonhomework::showhash(%record);
- $Apache::lonxml::debug=0;
- return %record;
+ $record{'scantron.maxquest'}=$questnum;
+ return \%record;
}
sub scantron_add_delay {
}
sub scantron_find_student {
+ my ($scantron_record,$idmap)=@_;
+ my $scanID=$$scantron_record{'scantron.ID'};
+ foreach my $id (keys(%$idmap)) {
+ Apache->request->print('checking studnet -'.$id.'- againt -'.$scanID.'- ');
+ if (lc($id) eq lc($scanID)) { Apache->request->print('success');return $$idmap{$id}; }
+ }
+ return undef;
+}
+
+sub scantron_filter {
+ my ($curres)=@_;
+ if (ref($curres) && $curres->is_problem() && !$curres->randomout) {
+ return 1;
+ }
+ return 0;
}
sub scantron_process_students {
@@ -2976,8 +3067,13 @@ sub scantron_process_students {
my %scantron_config=&get_scantron_config($ENV{'form.scantron_format'});
my $scanlines=Apache::File->new($Apache::lonnet::perlvar{'lonScansDir'}."/$ENV{'form.scantron_selectfile'}");
+ my @scanlines=<$scanlines>;
my $classlist=&Apache::loncoursedata::get_classlist();
my %idmap=&username_to_idmap($classlist);
+ my $navmap=Apache::lonnavmaps::navmap->new($ENV{'request.course.fn'}.'.db',$ENV{'request.course.fn'}.'_parms.db',1, 1);
+ my $map=$navmap->getResourceByUrl($sequence);
+ my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0);
+ $r->print("geto ".scalar(@resources)." ");
my $result= <
@@ -2986,15 +3082,65 @@ SCANTRONFORM
$r->print($result);
my @delayqueue;
+ my $totalcorrect;
+ my $totalincorrect;
- foreach my $line (<$scanlines>) {
+ my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin($r,
+ 'Scantron Status','Scantron Progress',scalar(@scanlines));
+ foreach my $line (@scanlines) {
+ my $studentcorrect;
+ my $studentincorrect;
+
+ chomp($line);
my $scan_record=&scantron_parse_scanline($line,\%scantron_config);
my ($uname,$udom);
if ($uname=&scantron_find_student($scan_record,\%idmap)) {
&scantron_add_delay(\@delayqueue,$line,
'Unable to find a student that matches');
}
+ $r->print('doing studnet'.$uname.' ');
($uname,$udom)=split(/:/,$uname);
+ &Apache::lonnet::delenv('form.counter');
+ &Apache::lonnet::appenv(%$scan_record);
+# &Apache::lonhomework::showhash(%ENV);
+ $Apache::lonxml::debug=1;
+ &Apache::lonxml::debug("line is $line");
+
+ my $i=0;
+ foreach my $resource (@resources) {
+ $i++;
+ my $result=&Apache::lonnet::ssi($resource->src(),
+ ('submitted' =>'scantron',
+ 'grade_target' =>'grade',
+ 'grade_username'=>$uname,
+ 'grade_domain' =>$udom,
+ 'grade_courseid'=>$ENV{'request.course.id'},
+ 'grade_symb' =>$resource->symb()));
+ my %score=&Apache::lonnet::restore($resource->symb(),
+ $ENV{'request.course.id'},
+ $udom,$uname);
+ foreach my $part ($resource->{PARTS}) {
+ if ($score{'resource.'.$part.'.solved'} =~ /^correct/) {
+ $studentcorrect++;
+ $totalcorrect++;
+ } else {
+ $studentincorrect++;
+ $totalincorrect++;
+ }
+ }
+ $r->print(''.
+ $resource->symb().'-'.
+ $resource->src().'-'.' result is'.$result);
+ &Apache::lonhomework::showhash(%score);
+ # if ($i eq 3) {last;}
+ }
+ &Apache::lonnet::delenv('form.counter');
+ &Apache::lonnet::delenv('scantron\.');
+ &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,
+ 'last student Who got a '.$studentcorrect.' correct and '.
+ $studentincorrect.' incorrect. The class has gotten '.
+ $totalcorrect.' correct and '.$totalincorrect.' incorrect');
+ last;
#FIXME
#get iterator for $sequence
#foreach question 'submit' the students answer to the server
@@ -3002,6 +3148,7 @@ SCANTRONFORM
# generate data to pass back that includes grade recevied
#}
}
+ $Apache::lonxml::debug=0;
foreach my $delay (@delayqueue) {
#FIXME
#print out each delayed student with interface to select how
@@ -3014,7 +3161,8 @@ SCANTRONFORM
#FIXME
# if delay queue exists 2 submits one to process delayed students one
# to ignore delayed students, possibly saving the delay queue for later
-
+
+ $navmap->untieHashes();
}
#-------- end of section for handling grading scantron forms -------
#
@@ -3061,10 +3209,7 @@ sub gradingmenu {
var cmd = formname.command;
formname.saveState.value = "saveCmd="+radioSelection(cmd)+":saveSec="+pullDownSelection(formname.section)+
":saveSub="+radioSelection(formname.submitonly)+":saveStatus="+pullDownSelection(formname.status);
- if (cmd[0].checked || cmd[1].checked || cmd[2].checked || cmd[4].checked) formname.submit();
-
- if (cmd[3].checked) browseAndUpload();
-
+ if (cmd[0].checked || cmd[1].checked || cmd[2].checked || cmd[3].checked || cmd[4].checked) formname.submit();
if (cmd[5].checked) {
if (!checkReceiptNo(formname,'notOK')) { return false;}
formname.submit();
@@ -3113,57 +3258,6 @@ sub gradingmenu {
}
}
- function browseAndUpload() {
- bNLoad = window.open('', 'BrowseAndUpload', 'toolbar=no,location=no,scrollbars=no,width=550,height=200,screenx=100,screeny=75');
- bNLoad.focus();
- var lDoc = bNLoad.document;
- lDoc.write("");
- lDoc.write("Browse And Upload");
-
- lDoc.write("
GRADINGMENUJS
@@ -3225,8 +3319,8 @@ GRADINGMENUJS
($saveSub eq 'all' ? 'checked' : '').' /> everybody |
'."\n".
''.
- ' '.
+ ' '.
'Upload scores from file |
'."\n";
$result.=''.
|