--- loncom/homework/grades.pm 2004/09/14 13:30:09 1.209
+++ loncom/homework/grades.pm 2005/02/12 03:43:06 1.245
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# The LON-CAPA Grading handler
#
-# $Id: grades.pm,v 1.209 2004/09/14 13:30:09 ng Exp $
+# $Id: grades.pm,v 1.245 2005/02/12 03:43:06 albertel Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -25,16 +25,6 @@
#
# http://www.lon-capa.org/
#
-# 2/9,2/13 Guy Albertelli
-# 6/8 Gerd Kortemeyer
-# 7/26 H.K. Ng
-# 8/20 Gerd Kortemeyer
-# Year 2002
-# June-August H.K. Ng
-# Year 2003
-# February, March H.K. Ng
-# July, H. K. Ng
-#
package Apache::grades;
use strict;
@@ -101,25 +91,6 @@ sub get_symb_and_url {
return ($symb,$url);
}
-# --- Retrieve the fullname for a user. Return lastname, first middle ---
-# --- Generation is attached next to the lastname if it exists. ---
-sub get_fullname {
- my ($uname,$udom) = @_;
- my %name=&Apache::lonnet::get('environment', ['lastname','generation',
- 'firstname','middlename'],
- $udom,$uname);
- my $fullname;
- my ($tmp) = keys(%name);
- if ($tmp !~ /^(con_lost|error|no_such_host)/i) {
- $fullname = &Apache::loncoursedata::ProcessFullName
- (@name{qw/lastname generation firstname middlename/});
- } else {
- &Apache::lonnet::logthis('grades.pm: no name data for '.$uname.
- '@'.$udom.':'.$tmp);
- }
- return $fullname;
-}
-
#--- Format fullname, username:domain if different for display
#--- Use anywhere where the student names are listed
sub nameUserString {
@@ -1001,6 +972,8 @@ sub sub_page_kw_js {
my $request = shift;
my $iconpath = $request->dir_config('lonIconsURL');
&commonJSfunctions($request);
+ my $docopen=&Apache::lonhtmlcommon::javascript_docopen();
+ $docopen=~s/^document\.//;
$request->print(< You have forgetten to specify some information. Please go Back and try again. You have not selected a Sequence to grade You have not selected a file that contains the student\'s response data. You have not selected a the format of the student\'s response data. The ID on the form is ".
+ $$scan_record{'scantron.ID'}."Part: '.
$display_part.' ( ID '.$respid.
' ) ';
+ my @files;
+ if ($record{"resource.$partid.$respid.portfiles"}) {
+ my $file_url = '/uploaded/'.$udom.'/'.$uname.'/portfolio';
+ foreach my $file (split(',',$record{"resource.$partid.$respid.portfiles"})) {
+ push(@files,$file_url.$file);
+
+ &Apache::lonnet::logthis("found a portfolio file".$record{"resource.$partid.$respid.portfiles"});
+ &Apache::lonnet::logthis("uploaded URL file".$record{"resource.$partid.$respid.uploadedurl"});
+ }
+ }
if ($record{"resource.$partid.$respid.uploadedurl"}) {
- &Apache::lonnet::allowuploaded('/adm/grades',
- $record{"resource.$partid.$respid.uploadedurl"});
- $lastsubonly.=' File uploaded by student Like all files provided by users, this file may contain virusses
';
+ push(@files,$record{"resource.$partid.$respid.uploadedurl"});
+ }
+ if (@files) {
+ $lastsubonly.='
Like all files provided by users, this file may contain virusses
';
+ foreach my $file (@files) {
+ &Apache::lonnet::allowuploaded('/adm/grades',$file);
+ $lastsubonly.='
'.$file.'';
+ }
+ $lastsubonly.='
';
}
$lastsubonly.='Submitted Answer: '.
&cleanRecord($subval,$responsetype,$symb,$partid,
@@ -2414,9 +2404,6 @@ sub viewgrades {
my (undef,undef,$fullname) = &getclasslist($ENV{'form.section'},'1');
my $ctr = 0;
foreach (sort {lc($$fullname{$a}) cmp lc($$fullname{$b}) } keys %$fullname) {
- my $uname = $_;
- $uname=~s/:/_/;
- $result.=''."\n";
$ctr++;
$result.=&viewstudentgrade($url,$symb,$ENV{'request.course.id'},
$_,$$fullname{$_},\@parts,\%weight,$ctr);
@@ -2440,18 +2427,21 @@ sub viewstudentgrade {
my ($uname,$udom) = split(/:/,$student);
$student=~s/:/_/;
my %record=&Apache::lonnet::restore($symb,$courseid,$udom,$uname);
- my $result=''.$ctr.' '.
+ my $result=' '."\n";
$result.=''.
+ ''.
+ "\n".$ctr.' '.
''.$fullname.' '.
'('.$uname.($ENV{'user.domain'} eq $udom ? '' : ':'.$udom).') '."\n";
foreach my $apart (@$parts) {
my ($part,$type) = &split_part_type($apart);
my $score=$record{"resource.$part.$type"};
+ $result.='';
if ($type eq 'awarded') {
my $pts = $score eq '' ? '' : $score*$$weight{$part};
$result.=''."\n";
- $result.=' '."\n";
@@ -2460,7 +2450,7 @@ sub viewstudentgrade {
$status = 'nothing' if ($status eq '');
$result.=''."\n";
- $result.=' '."\n";
@@ -2857,6 +2859,7 @@ sub csvuploadmap {
&Apache::loncommon::load_tmp_file($request);
}
my @records=&Apache::loncommon::upfile_record_sep();
+ if ($ENV{'form.noFirstLine'}) { shift(@records); }
&csvuploadmap_header($request,$symb,$url,$datatoken,$#records+1);
my ($i,$keyfields);
if (@records) {
@@ -2888,6 +2891,7 @@ sub csvuploadassign {
if (!$symb) {return '';}
&Apache::loncommon::load_tmp_file($request);
my @gradedata = &Apache::loncommon::upfile_record_sep();
+ if ($ENV{'form.noFirstLine'}) { shift(@gradedata); }
my @keyfields = split(/\,/,$ENV{'form.keyfields'});
my %fields=();
for (my $i=0; $i<=$ENV{'form.nfields'}; $i++) {
@@ -2909,10 +2913,15 @@ sub csvuploadassign {
my $countdone=0;
foreach my $grade (@gradedata) {
my %entries=&Apache::loncommon::record_sep($grade);
- my $username=$entries{$fields{'username'}};
- $username=~s/\s//g;
my $domain=$entries{$fields{'domain'}};
$domain=~s/\s//g;
+ my $username=$entries{$fields{'username'}};
+ $username=~s/\s//g;
+ if (!$username) {
+ my $id=$entries{$fields{'ID'}};
+ my %ids=&Apache::lonnet::idget($domain,$id);
+ $username=$ids{$id};
+ }
if (!exists($$classlist{"$username:$domain"})) {
push(@skipped,"$username:$domain");
next;
@@ -2922,16 +2931,33 @@ sub csvuploadassign {
push(@notallowed,"$username:$domain");
next;
}
+ my %points;
my %grades;
foreach my $dest (keys(%fields)) {
- if ($dest eq 'username' || $dest eq 'domain') { next; }
- if ($entries{$fields{$dest}} eq '') { next; }
- my $store_key=$dest;
- $store_key=~s/^stores/resource/;
- $store_key=~s/_/\./g;
- $grades{$store_key}=$entries{$fields{$dest}};
+ if ($dest eq 'ID' || $dest eq 'username' ||
+ $dest eq 'domain') { next; }
+ if ($entries{$fields{$dest}} =~ /^\s*$/) { next; }
+ if ($dest=~/stores_(.*)_points/) {
+ my $part=$1;
+ my $wgt =&Apache::lonnet::EXT('resource.'.$part.'.weight',
+ $symb,$domain,$username);
+ my $pcr=$entries{$fields{$dest}} / $wgt;
+ my $award='correct_by_override';
+ $grades{"resource.$part.awarded"}=$pcr;
+ $grades{"resource.$part.solved"}=$award;
+ $points{$part}=1;
+ } else {
+ if ($dest=~/stores_(.*)_awarded/) { if ($points{$1}) {next;} }
+ if ($dest=~/stores_(.*)_solved/) { if ($points{$1}) {next;} }
+ my $store_key=$dest;
+ $store_key=~s/^stores/resource/;
+ $store_key=~s/_/\./g;
+ $grades{$store_key}=$entries{$fields{$dest}};
+ }
}
+ if (! %grades) { push(@skipped,"$username:$domain no data to store"); }
$grades{"resource.regrader"}="$ENV{'user.name'}:$ENV{'user.domain'}";
+# &Apache::lonnet::logthis(" storing ".(join('-',%grades)));
&Apache::lonnet::cstore(\%grades,$symb,$ENV{'request.course.id'},
$domain,$username);
$request->print('.');
@@ -3070,7 +3096,8 @@ sub getSymbMap {
my $minder = 0;
# Gather every sequence that has problems.
- my @sequences = $navmap->retrieveResources(undef, sub { shift->is_map(); }, 1);
+ my @sequences = $navmap->retrieveResources(undef, sub { shift->is_map(); },
+ 1,0,1);
for my $sequence ($navmap->getById('0.0'), @sequences) {
if ($navmap->hasResource($sequence, sub { shift->is_problem(); }, 0) ) {
my $title = $minder.'.'.$sequence->compTitle();
@@ -3079,8 +3106,6 @@ sub getSymbMap {
$minder++;
}
}
-
- $navmap->untieHashes();
return \@titles,\%symbx;
}
@@ -3151,7 +3176,7 @@ sub displayPage {
if($curRes == $iterator->BEGIN_MAP) { $depth++; }
if($curRes == $iterator->END_MAP) { $depth--; }
- if (ref($curRes) && $curRes->is_problem()) {
+ if (ref($curRes) && $curRes->is_problem() && !$curRes->randomout) {
my $parts = $curRes->parts();
my $title = $curRes->compTitle();
my $symbx = $curRes->symb();
@@ -3213,8 +3238,6 @@ sub displayPage {
$curRes = $iterator->next();
}
- $navmap->untieHashes();
-
$studentTable.=''."\n".
''.
@@ -3227,9 +3250,12 @@ sub displayPage {
sub displaySubByDates {
my ($symb,$record,$parts,$responseType,$checkIcon,$uname,$udom) = @_;
+ my $isCODE=0;
+ if (exists($record->{'resource.CODE'})) { $isCODE=1; }
my $studentTable=''."\n";
my $upfile_select=&Apache::loncommon::upfile_select_html();
+ my $ignore=&mt('Ignore First Line');
$result.=<
-
+
';
$studentTable.=&show_grading_menu_form($ENV{'form.symb'},$ENV{'form.url'});
my $grademsg=($changeflag == 0 ? 'No score was changed or updated.' :
@@ -3501,7 +3528,7 @@ sub scantron_CODElist {
my $cnum = $ENV{'course.'.$ENV{'request.course.id'}.'.num'};
my @names=&Apache::lonnet::getkeys('CODEs',$cdom,$cnum);
my $namechoice='';
- foreach my $name (sort(@names)) {
+ foreach my $name (sort {uc($a) cmp uc($b)} @names) {
if ($name =~ /^error: 2 /) { next; }
$namechoice.='';
}
@@ -3538,8 +3565,8 @@ sub scantron_selectphase {
$result.= <'.
' '.
' ';
my ($version);
@@ -3242,6 +3268,9 @@ sub displaySubByDates {
for ($version=1;$version<=$$record{'version'};$version++) {
my $timestamp = scalar(localtime($$record{$version.':timestamp'}));
$studentTable.='Date/Time '.
+ ($isCODE?'CODE ':'').
'Submission '.
'Status '.$timestamp.' ';
+ if ($isCODE) {
+ $studentTable.=''.$record->{$version.':resource.CODE'}.' ';
+ }
my @versionKeys = split(/\:/,$$record{$version.':keys'});
my @displaySub = ();
foreach my $partid (@{$parts}) {
@@ -3410,8 +3439,6 @@ sub updateGradeByPage {
$curRes = $iterator->next();
}
- $navmap->untieHashes();
-
$studentTable.='
+
SCANTRONFORM
@@ -3633,8 +3660,8 @@ SCANTRONFORM
}
$r->print(<
-
+
SCANTRONFORM
$r->print(<
+
-
-
@@ -3651,14 +3678,13 @@ SCANTRONFORM
".&show_grading_menu_form($symb,$url)."");
+ }
+ $r->print("
".&show_grading_menu_form($symb,$url)."");
return '';
}
@@ -4007,7 +4072,7 @@ sub scantron_form_start {
-
+
@@ -4297,6 +4362,12 @@ sub scantron_get_correction {
$r->print(" in scanline $i ".
$line."
\n");
}
+ my $message="
\n".
+ "The name on the paper is ".
+ $$scan_record{'scantron.LastName'}.",".
+ $$scan_record{'scantron.FirstName'}."
The ID on the form is ".
- $$scan_record{'scantron.ID'}."
\n");
- $r->print("The name on the paper is ".
- $$scan_record{'scantron.LastName'}.",".
- $$scan_record{'scantron.FirstName'}."
How should I handle this?
\n");
$r->print("\n
The encoded CODE has also been used by a previous paper ".join(', ',@{$arg}).", and CODEs are supposed to be unique
\n"); } - $r->print("The CODE on the form is ".
- $$scan_record{'scantron.CODE'}."
\n");
- $r->print("
The ID on the form is ".
- $$scan_record{'scantron.ID'}."
\n");
- $r->print("The name on the paper is ".
- $$scan_record{'scantron.LastName'}.",".
- $$scan_record{'scantron.FirstName'}."
The CODE on the form is '".
+ $$scan_record{'scantron.CODE'}."'
\n");
+ $r->print($message);
$r->print("
How should I handle this?
\n");
$r->print("\n
");
my $i=0;
@@ -4376,6 +4439,7 @@ ENDSCRIPT
$r->print("
There have been multiple bubbles scanned for a some question(s)
\n"); $r->print(''); + $r->print($message); $r->print("Please indicate which bubble should be used for grading
"); foreach my $question (@{$arg}) { my $selected=$$scan_record{"scantron.$question.answer"}; @@ -4383,6 +4447,7 @@ ENDSCRIPT } } elsif ($error eq 'missingbubble') { $r->print("There have been no bubbles scanned for some question(s)
\n"); + $r->print($message); $r->print("Please indicate which bubble should be used for grading
"); $r->print("Some questions have no scanned bubbles\n"); $r->print(' $result"); + &Apache::lonnet::logthis("scantron grading error info name $uname domain $udom course $ENV{'request.course.id'} url ".$resource->src()); + } + if (&Apache::loncommon::connection_aborted($r)) { last; } } $completedstudents{$uname}={'line'=>$line}; + if (&Apache::loncommon::connection_aborted($r)) { last; } } continue { &Apache::lonnet::delenv('form.counter'); &Apache::lonnet::delenv('scantron\.'); @@ -4658,7 +4738,6 @@ SCANTRONFORM # my $lasttime = &Time::HiRes::time()-$start; # $r->print("took $lasttime
"); - $navmap->untieHashes(); $r->print(""); $r->print(&show_grading_menu_form($symb,$url)); return ''; @@ -4719,7 +4798,8 @@ sub scantron_upload_scantron_data_save { } return ''; } -# $r->print("Doing upload to ".$ENV{'form.courseid'}."