--- loncom/homework/grades.pm 2004/07/27 15:14:52 1.206
+++ loncom/homework/grades.pm 2005/02/12 02:37:00 1.243
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# The LON-CAPA Grading handler
#
-# $Id: grades.pm,v 1.206 2004/07/27 15:14:52 albertel Exp $
+# $Id: grades.pm,v 1.243 2005/02/12 02:37:00 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 {
@@ -167,6 +138,20 @@ sub response_type {
return \@partlist,\%handgrade,\%responseType;
}
+sub get_display_part {
+ my ($partID,$url,$symb)=@_;
+ if (!defined($symb) || $symb eq '') {
+ $symb=$ENV{'form.symb'};
+ if ($symb eq '') { $symb=&Apache::lonnet::symbread($url) }
+ }
+ my $display=&Apache::lonnet::EXT('resource.'.$partID.'.display',$symb);
+ if (defined($display) and $display ne '') {
+ $display.= " (id $partID)";
+ } else {
+ $display=$partID;
+ }
+ return $display;
+}
#--- Show resource title
#--- and parts and response type
sub showResourceInfo {
@@ -194,7 +179,8 @@ sub showResourceInfo {
}
$partsseen{$partID}=1;
}
- $result.='
Part '.$partID.' '.
+ my $display_part=&get_display_part($partID,$url);
+ $result.='
Part: '.$display_part.' '.
$resID.'
'.
'
Type: '.$responsetype.'
';
# '
Handgrade: '.$handgrade.'
';
@@ -691,7 +677,9 @@ LISTJAVASCRIPT
'
'.&nameUserString('header').'
';
if ($ENV{'form.showgrading'} eq 'yes' && $submitonly ne 'all') {
foreach (sort(@$partlist)) {
- $gradeTable.='
Part '.(split(/_/))[0].' Status
';
+ my $display_part=&get_display_part((split(/_/))[0],$url,$symb);
+ $gradeTable.='
Part: '.$display_part.
+ ' Status
';
}
}
$loop++;
@@ -984,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(<
@@ -1096,7 +1086,7 @@ sub sub_page_kw_js {
pWin = window.open('', 'MessageCenter', 'resizable=yes,toolbar=no,location=no,scrollbars='+scrollbar+',screenx='+xpos+',screeny='+ypos+',width=600,height='+height);
pWin.focus();
pDoc = pWin.document;
- pDoc.open('text/html','replace');
+ pDoc.$docopen;
pDoc.write("");
pDoc.write("Message Central");
@@ -1227,7 +1217,7 @@ sub sub_page_kw_js {
hwdWin = window.open('', 'KeywordHighlightCentral', 'resizeable=yes,toolbar=no,location=no,scrollbars=no,width=400,height=300,screenx='+xpos+',screeny='+ypos);
hwdWin.focus();
var hDoc = hwdWin.document;
- hDoc.open('text/html','replace');
+ hDoc.$docopen;
hDoc.write("");
hDoc.write("Highlight Central");
@@ -1298,8 +1288,9 @@ sub gradeBox {
'' : $$record{'resource.'.$partid.'.awarded'}*$wgt);
my $result=''."\n";
+ my $display_part=&get_display_part($partid,undef,$symb);
$result.='
'.
- 'Part '.$partid.' Points:
'."\n";
+ 'Part: '.$display_part.' Points:
'."\n";
my $ctr = 0;
$result.='
'."\n"; # display radio buttons in a nice table 10 across
@@ -1395,14 +1386,15 @@ sub submission {
my ($uname,$udom) = ($ENV{'form.student'},$ENV{'form.userdom'});
$udom = ($udom eq '' ? $ENV{'user.domain'} : $udom); #has form.userdom changed for a student?
my $usec = &Apache::lonnet::getsection($udom,$uname,$ENV{'request.course.id'});
- $ENV{'form.fullname'} = &get_fullname ($uname,$udom) if $ENV{'form.fullname'} eq '';
+ $ENV{'form.fullname'} = &Apache::loncommon::plainname($uname,$udom,'lastname') if $ENV{'form.fullname'} eq '';
my $symb=($ENV{'form.symb'} ne '' ? $ENV{'form.symb'} : (&Apache::lonnet::symbread($url)));
if ($symb eq '') { $request->print("Unable to handle ambiguous references:$url:."); return ''; }
if (!&canview($usec)) {
$request->print('Unable to view requested student.('.
- $uname.$udom.$usec.$ENV{'request.course.id'}.')');
+ $uname.'@'.$udom.' in section '.$usec.' in course id '.
+ $ENV{'request.course.id'}.')');
$request->print(&show_grading_menu_form($symb,$url));
return;
}
@@ -1631,11 +1623,12 @@ KEYWORDS
my %seenparts;
for my $part (sort keys(%$handgrade)) {
my ($partid,$respid) = split(/_/,$part);
+ my $display_part=&get_display_part($partid,$url,$symb);
if ($ENV{"form.$uname:$udom:$partid:submitted_by"}) {
if (exists($seenparts{$partid})) { next; }
$seenparts{$partid}=1;
- my $submitby='Part '.$partid.
- ' Collaborative submission by: '.
+ my $submitby='Part: '.$display_part.
+ ' Collaborative submission by: '.
''.
@@ -1645,8 +1638,8 @@ KEYWORDS
}
my $responsetype = $responseType->{$partid}->{$respid};
if (!exists($record{"resource.$partid.$respid.submission"})) {
- $lastsubonly.='
';
+ my $display_part=&get_display_part($partid,$url,$symb);
+ $result.='
Part: '.$display_part.' Point:
';
$result.='
';
my $ctr = 0;
while ($ctr<=$weight{$partid}) { # display radio buttons in a nice table 10 across
@@ -2374,14 +2385,17 @@ sub viewgrades {
my $display=&Apache::lonnet::metadata($url,$part.'.display');
$display =~ s|^Number of Attempts|Tries |; # makes the column narrower
if (!$display) { $display = &Apache::lonnet::metadata($url,$part.'.name'); }
+ my ($partid) = &split_part_type($part);
+ my $display_part=&get_display_part($partid,$url,$symb);
if ($display =~ /^Partial Credit Factor/) {
- my ($partid) = &split_part_type($part);
- $result.='
Score Part '.$partid.' (weight = '.
- $weight{$partid}.')
'."\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";
@@ -2436,7 +2450,7 @@ sub viewstudentgrade {
$status = 'nothing' if ($status eq '');
$result.=''."\n";
- $result.='
';
}
$result .= '
';
@@ -2640,15 +2655,17 @@ sub csvupload_javascript_reverse_associa
function verify(vf) {
var foundsomething=0;
var founduname=0;
+ var foundID=0;
var founddomain=0;
for (i=0;i<=vf.nfields.value;i++) {
tw=eval('vf.f'+i+'.selectedIndex');
- if (i==0 && tw!=0) { founduname=1; }
- if (i==1 && tw!=0) { founddomain=1; }
- if (i!=0 && i!=1 && tw!=0) { foundsomething=1; }
+ if (i==0 && tw!=0) { foundID=1; }
+ if (i==1 && tw!=0) { founduname=1; }
+ if (i==2 && tw!=0) { founddomain=1; }
+ if (i!=0 && i!=1 && i!=2 && tw!=0) { foundsomething=1; }
}
- if (founduname==0 || founddomain==0) {
- alert('You need to specify at both the username and domain');
+ if ((founduname==0 && foundID==0) || founddomain==0) {
+ alert('You need to specify the domain and either the username or ID');
return;
}
if (foundsomething==0) {
@@ -2678,15 +2695,17 @@ sub csvupload_javascript_forward_associa
function verify(vf) {
var foundsomething=0;
var founduname=0;
+ var foundID=0;
var founddomain=0;
for (i=0;i<=vf.nfields.value;i++) {
tw=eval('vf.f'+i+'.selectedIndex');
- if (tw==1) { founduname=1; }
- if (tw==2) { founddomain=1; }
- if (tw>2) { foundsomething=1; }
+ if (tw==1) { foundID=1; }
+ if (tw==2) { founduname=1; }
+ if (tw==3) { founddomain=1; }
+ if (tw>3) { foundsomething=1; }
}
- if (founduname==0 || founddomain==0) {
- alert('You need to specify at both the username and domain');
+ if ((founduname==0 && foundID==0) || founddomain==0) {
+ alert('You need to specify the domain and either the username or ID');
return;
}
if (foundsomething==0) {
@@ -2753,7 +2772,9 @@ ENDPICK
sub csvupload_fields {
my ($url,$symb) = @_;
my (@parts) = &getpartlist($url,$symb);
- my @fields=(['username','Student Username'],['domain','Student Domain']);
+ my @fields=(['ID','Student ID'],
+ ['username','Student Username'],
+ ['domain','Student Domain']);
foreach my $part (sort(@parts)) {
my @datum;
my $display=&Apache::lonnet::metadata($url,$part.'.display');
@@ -2884,10 +2905,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;
@@ -3045,7 +3071,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();
@@ -3054,8 +3081,6 @@ sub getSymbMap {
$minder++;
}
}
-
- $navmap->untieHashes();
return \@titles,\%symbx;
}
@@ -3126,7 +3151,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();
@@ -3188,8 +3213,6 @@ sub displayPage {
$curRes = $iterator->next();
}
- $navmap->untieHashes();
-
$studentTable.='
'."\n".
''.
@@ -3202,9 +3225,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='
'.
'
'.
'
Date/Time
'.
+ ($isCODE?'
CODE
':'').
'
Submission
'.
'
Status
';
my ($version);
@@ -3217,18 +3243,22 @@ sub displaySubByDates {
for ($version=1;$version<=$$record{'version'};$version++) {
my $timestamp = scalar(localtime($$record{$version.':timestamp'}));
$studentTable.='
'.$timestamp.'
';
+ if ($isCODE) {
+ $studentTable.='
'.$record->{$version.':resource.CODE'}.'
';
+ }
my @versionKeys = split(/\:/,$$record{$version.':keys'});
my @displaySub = ();
foreach my $partid (@{$parts}) {
my @matchKey = sort(grep /^resource\.\Q$partid\E\..*?\.submission$/,@versionKeys);
# next if ($$record{"$version:resource.$partid.solved"} eq '');
+ my $display_part=&get_display_part($partid,undef,$symb);
foreach my $matchKey (@matchKey) {
if (exists($$record{$version.':'.$matchKey}) &&
$$record{$version.':'.$matchKey} ne '') {
my ($responseId)=($matchKey=~ /^resource\.\Q$partid\E\.(.*?)\.submission$/);
- $displaySub[0].='Part '.$partid.' ';
+ $displaySub[0].='Part: '.$display_part.' ';
$displaySub[0].='(ID '.
- $responseId.') ';
+ $responseId.') ';
if ($$record{"$version:resource.$partid.tries"} eq '') {
$displaySub[0].='Trial not counted';
} else {
@@ -3246,14 +3276,14 @@ sub displaySubByDates {
}
}
if (exists $$record{"$version:resource.$partid.award"}) {
- $displaySub[1].='Part '.$partid.' '.
+ $displaySub[1].='Part: '.$display_part.' '.
lc($$record{"$version:resource.$partid.award"}).' '.
$mark{$$record{"$version:resource.$partid.solved"}}.
' ';
}
if (exists $$record{"$version:resource.$partid.regrader"}) {
$displaySub[2].=$$record{"$version:resource.$partid.regrader"}.
- ' ('.&mt('Part').': '.$partid.')';
+ ' ('.&mt('Part').': '.$display_part.')';
}
}
# needed because old essay regrader has not parts info
@@ -3350,12 +3380,13 @@ sub updateGradeByPage {
$changeflag++;
$newpts = '';
}
-
+ my $display_part=&get_display_part($partid,undef,
+ $curRes->symb());
my $oldstatus = $ENV{'form.solved'.$question.'_'.$partid};
- $displayPts[0].=' Part '.$partid.' = '.
+ $displayPts[0].=' Part: '.$display_part.' = '.
(($oldstatus eq 'excused') ? 'excused' : $oldpts).
' ';
- $displayPts[1].=' Part '.$partid.' = '.
+ $displayPts[1].=' Part: '.$display_part.' = '.
(($score eq 'excused') ? 'excused' : $newpts).
' ';
@@ -3383,8 +3414,6 @@ sub updateGradeByPage {
$curRes = $iterator->next();
}
- $navmap->untieHashes();
-
$studentTable.='
';
$studentTable.=&show_grading_menu_form($ENV{'form.symb'},$ENV{'form.url'});
my $grademsg=($changeflag == 0 ? 'No score was changed or updated.' :
@@ -3445,10 +3474,11 @@ sub scantron_filenames {
}
sub scantron_uploads {
+ my ($file2grade) = @_;
my $result= '";
return $result;
@@ -3473,7 +3503,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.='';
}
@@ -3494,13 +3524,13 @@ sub scantron_CODEunique {
}
sub scantron_selectphase {
- my ($r) = @_;
+ my ($r,$file2grade) = @_;
my ($symb,$url)=&get_symb_and_url($r);
if (!$symb) {return '';}
my $sequence_selector=&getSequenceDropDown($r,$symb);
my $default_form_data=&defaultFormData($symb,$url);
my $grading_menu_button=&show_grading_menu_form($symb,$url);
- my $file_selector=&scantron_uploads();
+ my $file_selector=&scantron_uploads($file2grade);
my $format_selector=&scantron_scantab();
my $CODE_selector=&scantron_CODElist();
my $CODE_unique=&scantron_CODEunique();
@@ -3510,8 +3540,8 @@ sub scantron_selectphase {
$result.= <
The ID on the form is ".
+ $$scan_record{'scantron.ID'}." \n".
+ "The name on the paper is ".
+ $$scan_record{'scantron.LastName'}.",".
+ $$scan_record{'scantron.FirstName'}."
";
+
$r->print(''."\n");
$r->print(''."\n");
if ($error =~ /ID$/) {
@@ -4277,11 +4351,7 @@ sub scantron_get_correction {
} elsif ($error eq 'duplicateID') {
$r->print("The encoded ID has also been used by a previous paper $arg\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'}."
");
+ $r->print($message);
$r->print("
How should I handle this? \n");
$r->print("\n
");
#FIXME it would be nice if this sent back the user ID and
@@ -4299,13 +4369,9 @@ sub scantron_get_correction {
} elsif ($error eq 'duplicateCODE') {
$r->print("
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'}."
");
+ $r->print("
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;
@@ -4348,6 +4414,7 @@ ENDSCRIPT
$r->print("
There have been multiple bubbles scanned for a some question(s)