--- loncom/homework/grades.pm 2002/06/20 21:21:16 1.28
+++ loncom/homework/grades.pm 2002/08/05 20:49:54 1.45
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# The LON-CAPA Grading handler
#
-# $Id: grades.pm,v 1.28 2002/06/20 21:21:16 ng Exp $
+# $Id: grades.pm,v 1.45 2002/08/05 20:49:54 ng Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -29,6 +29,9 @@
# 6/8 Gerd Kortemeyer
# 7/26 H.K. Ng
# 8/20 Gerd Kortemeyer
+# Year 2002
+# June-August H.K. Ng
+#
package Apache::grades;
use strict;
@@ -37,436 +40,1789 @@ use Apache::lonxml;
use Apache::lonnet;
use Apache::loncommon;
use Apache::lonhomework;
+use Apache::lonmsg qw(:user_normal_msg);
use Apache::Constants qw(:common);
-sub moreinfo {
- my ($request,$reason) = @_;
- $request->print("Unable to process request: $reason");
- if ( $Apache::grades::viewgrades eq 'F' ) {
- $request->print('
');
- }
- return '';
-}
+# ----- These first few routines are general use routines.-----
+#
-sub verifyreceipt {
- my $request=shift;
- my $courseid=$ENV{'request.course.id'};
- my $cdom=$ENV{"course.$courseid.domain"};
- my $cnum=$ENV{"course.$courseid.num"};
- my $receipt=unpack("%32C*",$Apache::lonnet::perlvar{'lonHostID'}).'-'.
- $ENV{'form.receipt'};
- $receipt=~s/[^\-\d]//g;
- my $symb=$ENV{'form.symb'};
- unless ($symb) {
- $symb=&Apache::lonnet::symbread($ENV{'form.url'});
- }
- if ((&Apache::lonnet::allowed('mgr',$courseid)) && ($symb)) {
- $request->print('
Verifying Submission Receipt '.$receipt.'
');
- my $matches=0;
- my (%classlist) = &getclasslist($cdom,$cnum,'0');
- foreach my $student ( sort(@{ $classlist{'allids'} }) ) {
- my ($uname,$udom)=split(/\:/,$student);
- if ($receipt eq
- &Apache::lonnet::ireceipt($uname,$udom,$courseid,$symb)) {
- $request->print('Matching '.$student.' ');
- $matches++;
- }
- }
- $request->print('
');
+ for (sort keys (%$hash)) {
+ $request->print('
'.$_.'
'.$$hash{$_}.'
');
}
+ $request->print('
');
return '';
}
-sub listStudents {
- my ($request) = shift;
- my $cdom=$ENV{"course.$ENV{'request.course.id'}.domain"};
- my $cnum=$ENV{"course.$ENV{'request.course.id'}.num"};
- my $hostver=unpack("%32C*",$Apache::lonnet::perlvar{'lonHostID'});
- $request->print(<Verify a Submission Receipt Issued by this Server
-'."\n";
+ $result.=&show_grading_menu_form($symb,$url);
+ return $result;
}
+#--- call by previous routine to display each student
+sub viewstudentgrade {
+ my ($url,$symb,$courseid,$student,$fullname,$parts,$weight) = @_;
+ my ($uname,$udom) = split(/:/,$student);
+ my %record=&Apache::lonnet::restore($symb,$courseid,$udom,$uname);
+ my $result='
';
+ return $result;
+}
+
+#--- change scores for all the students in a section/class
+# record does not get update if unchanged
sub editgrades {
- my ($request) = @_;
- my $result='';
+ my ($request) = @_;
- my $symb=$ENV{'form.symb'};
- if ($symb eq '') { $request->print("Unable to handle ambiguous references:$symb:$ENV{'form.url'}"); return ''; }
- my $url=$ENV{'form.url'};
- #get classlist
- my ($cdom,$cnum) = split(/_/,$ENV{'request.course.id'});
- #print "Found $cdom:$cnum ";
- my (%classlist) = &getclasslist($cdom,$cnum,'0');
-
- #get list of parts for this problem
- my (@parts) = &getpartlist($url);
-
- $result.='
'."\n";
+ my $msg = 'Number of records updated = '.$rec_update.
+ ' for '.$count.' student'.($count <= 1 ? '' : 's').'. '.
+ 'Total number of students = '.$ENV{'form.total'}.' ';
+ return $title.$msg.$result;
}
+#------------- end of section for handling grading by section/class ---------
+#
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+#
+#-------------------------- Next few routines handles grading by csv upload
+#
+#--- Javascript to handle csv upload
sub csvupload_javascript_reverse_associate {
return(<print(<';
+ $result.='
Resource: '.$url.'
';
+ my ($partlist,$handgrade) = &response_type($url);
+ my ($resptype,$hdgrade)=('','no');
+ for (sort keys(%$handgrade)) {
+ my ($responsetype,$handgrade)=split(/:/,$$handgrade{$_});
+ $resptype = $responsetype;
+ $hdgrade = $handgrade if ($handgrade eq 'yes');
+ $result.='
Part '.(split(/_/))[0].'
'.
+ '
Type: '.$responsetype.'
'.
+ '
Handgrade: '.$handgrade.'
';
+ }
+ $result.='';
+ $request->print(<
-
Uploading Class Grades for resource $url
+
Uploading Class Grades
+$result
Identify fields
Total number of records found in file: $distotal
@@ -573,28 +1943,28 @@ to this page if the data selected is ins
$javascript
ENDPICK
- return '';
+return '';
}
sub csvupload_fields {
- my ($url) = @_;
- my (@parts) = &getpartlist($url);
- my @fields=(['username','Student Username'],['domain','Student Domain']);
- foreach my $part (sort(@parts)) {
- my @datum;
- my $display=&Apache::lonnet::metadata($url,$part.'.display');
- my $name=$part;
- if (!$display) { $display = $name; }
- @datum=($name,$display);
- push(@fields,\@datum);
- }
- return (@fields);
+ my ($url) = @_;
+ my (@parts) = &getpartlist($url);
+ my @fields=(['username','Student Username'],['domain','Student Domain']);
+ foreach my $part (sort(@parts)) {
+ my @datum;
+ my $display=&Apache::lonnet::metadata($url,$part.'.display');
+ my $name=$part;
+ if (!$display) { $display = $name; }
+ @datum=($name,$display);
+ push(@fields,\@datum);
+ }
+ return (@fields);
}
sub csvuploadmap_footer {
- my ($request,$i,$keyfields) =@_;
- $request->print(<print(<
@@ -604,178 +1974,357 @@ ENDPICK
}
sub csvuploadmap {
- my ($request)= @_;
- my ($symb,$url)=&get_symb_and_url($request);
- if (!$symb) {return '';}
- my $datatoken;
- if (!$ENV{'form.datatoken'}) {
- $datatoken=&Apache::loncommon::upfile_store($request);
- } else {
- $datatoken=$ENV{'form.datatoken'};
- &Apache::loncommon::load_tmp_file($request);
- }
- my @records=&Apache::loncommon::upfile_record_sep();
- &csvuploadmap_header($request,$symb,$url,$datatoken,$#records+1);
- my $i;
- my $keyfields;
- if (@records) {
- my @fields=&csvupload_fields($url);
- if ($ENV{'form.upfile_associate'} eq 'reverse') {
- &Apache::loncommon::csv_print_samples($request,\@records);
- $i=&Apache::loncommon::csv_print_select_table($request,\@records,
- \@fields);
- foreach (@fields) { $keyfields.=$_->[0].','; }
- chop($keyfields);
+ my ($request)= @_;
+ my ($symb,$url)=&get_symb_and_url($request);
+ if (!$symb) {return '';}
+ my $datatoken;
+ if (!$ENV{'form.datatoken'}) {
+ $datatoken=&Apache::loncommon::upfile_store($request);
} else {
- unshift(@fields,['none','']);
- $i=&Apache::loncommon::csv_samples_select_table($request,\@records,
- \@fields);
- my %sone=&Apache::loncommon::record_sep($records[0]);
- $keyfields=join(',',sort(keys(%sone)));
+ $datatoken=$ENV{'form.datatoken'};
+ &Apache::loncommon::load_tmp_file($request);
}
- }
- &csvuploadmap_footer($request,$i,$keyfields);
- return '';
+ my @records=&Apache::loncommon::upfile_record_sep();
+ &csvuploadmap_header($request,$symb,$url,$datatoken,$#records+1);
+ my ($i,$keyfields);
+ if (@records) {
+ my @fields=&csvupload_fields($url);
+
+ if ($ENV{'form.upfile_associate'} eq 'reverse') {
+ &Apache::loncommon::csv_print_samples($request,\@records);
+ $i=&Apache::loncommon::csv_print_select_table($request,\@records,
+ \@fields);
+ foreach (@fields) { $keyfields.=$_->[0].','; }
+ chop($keyfields);
+ } else {
+ unshift(@fields,['none','']);
+ $i=&Apache::loncommon::csv_samples_select_table($request,\@records,
+ \@fields);
+ my %sone=&Apache::loncommon::record_sep($records[0]);
+ $keyfields=join(',',sort(keys(%sone)));
+ }
+ }
+ &csvuploadmap_footer($request,$i,$keyfields);
+ return '';
}
sub csvuploadassign {
- my ($request)= @_;
- my ($symb,$url)=&get_symb_and_url($request);
- if (!$symb) {return '';}
- &Apache::loncommon::load_tmp_file($request);
- my @gradedata=&Apache::loncommon::upfile_record_sep();
- my @keyfields = split(/\,/,$ENV{'form.keyfields'});
- my %fields=();
- for (my $i=0; $i<=$ENV{'form.nfields'}; $i++) {
- if ($ENV{'form.upfile_associate'} eq 'reverse') {
- if ($ENV{'form.f'.$i} ne 'none') {
- $fields{$keyfields[$i]}=$ENV{'form.f'.$i};
- }
- } else {
- if ($ENV{'form.f'.$i} ne 'none') {
- $fields{$ENV{'form.f'.$i}}=$keyfields[$i];
- }
+ my ($request)= @_;
+ my ($symb,$url)=&get_symb_and_url($request);
+ if (!$symb) {return '';}
+ &Apache::loncommon::load_tmp_file($request);
+ my @gradedata = &Apache::loncommon::upfile_record_sep();
+ my @keyfields = split(/\,/,$ENV{'form.keyfields'});
+ my %fields=();
+ for (my $i=0; $i<=$ENV{'form.nfields'}; $i++) {
+ if ($ENV{'form.upfile_associate'} eq 'reverse') {
+ if ($ENV{'form.f'.$i} ne 'none') {
+ $fields{$keyfields[$i]}=$ENV{'form.f'.$i};
+ }
+ } else {
+ if ($ENV{'form.f'.$i} ne 'none') {
+ $fields{$ENV{'form.f'.$i}}=$keyfields[$i];
+ }
+ }
}
- }
- $request->print('
Assigning Grades
');
- &Apache::lonhomework::showhash(('1'=>\@keyfields));
- &Apache::lonhomework::showhash(%fields);
- my $courseid=$ENV{'request.course.id'};
- my $cdom=$ENV{"course.$courseid.domain"};
- my $cnum=$ENV{"course.$courseid.num"};
- my (%classlist) = &getclasslist($cdom,$cnum,'1');
- foreach my $student ( sort(@{ $classlist{'allids'} }) ) {
- my %newhash;
+ $request->print('
Assigning Grades
');
+ my $courseid=$ENV{'request.course.id'};
+# my $cdom=$ENV{"course.$courseid.domain"};
+# my $cnum=$ENV{"course.$courseid.num"};
+ my ($classlist) = &getclasslist('all','1');
+ my @skipped;
+ my $countdone=0;
foreach my $grade (@gradedata) {
- my %entries=&Apache::loncommon::record_sep($grade);
- foreach my $dest (keys(%fields)) {
-
- }
+ my %entries=&Apache::loncommon::record_sep($grade);
+ my $username=$entries{$fields{'username'}};
+ my $domain=$entries{$fields{'domain'}};
+ if (!exists($$classlist{"$username:$domain"})) {
+ push(@skipped,"$username:$domain");
+ next;
+ }
+ 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}};
+ }
+ $grades{"resource.regrader"}="$ENV{'user.name'}:$ENV{'user.domain'}";
+ &Apache::lonnet::cstore(\%grades,$symb,$ENV{'request.course.id'},
+ $domain,$username);
+ $request->print('.');
+ $request->rflush();
+ $countdone++;
+ }
+ $request->print(" Stored $countdone students\n");
+ if (@skipped) {
+ $request->print(' Skipped Students ');
+ foreach my $student (@skipped) { $request->print(" $student"); }
}
- }
+ $request->print(&view_edit_entire_class_form($symb,$url));
+ $request->print(&show_grading_menu_form($symb,$url));
+ return '';
}
+#------------- end of section for handling csv file upload ---------
+#
+#-------------------------------------------------------------------
-sub send_header {
- my ($request)= @_;
- $request->print(&Apache::lontexconvert::header());
-# $request->print("
-#");
- $request->print('');
+#-------------------------- Menu interface -------------------------
+#
+#--- Show a Grading Menu button - Calls the next routine ---
+sub show_grading_menu_form {
+ my ($symb,$url)=@_;
+ my $result.='
'."\n";
+ return $result;
}
-sub send_footer {
- my ($request)= @_;
- $request->print('');
- $request->print(&Apache::lontexconvert::footer());
+#--- Displays the main menu page -------
+sub gradingmenu {
+ my ($request) = @_;
+ my ($symb,$url)=&get_symb_and_url($request);
+ if (!$symb) {return '';}
+ my $result='
Select a Grading Method
';
+ $result.='
';
+ $result.='
Resource: '.$url.'
';
+ my ($partlist,$handgrade) = &response_type($url);
+ my ($resptype,$hdgrade)=('','no');
+ for (sort keys(%$handgrade)) {
+ my ($responsetype,$handgrade)=split(/:/,$$handgrade{$_});
+ $resptype = $responsetype;
+ $hdgrade = $handgrade if ($handgrade eq 'yes');
+ $result.='
Part '.(split(/_/))[0].'
'.
+ '
Type: '.$responsetype.'
'.
+ '
Handgrade: '.$handgrade.'
';
+ }
+ $result.='
';
+ $result.=&view_edit_entire_class_form($symb,$url).' ';
+ $result.=&upcsvScores_form($symb,$url).' ';
+ $result.=&viewGradeaStu_form($symb,$url,$resptype,$hdgrade).' ';
+ $result.=&verifyReceipt_form($symb,$url)
+ if ((&Apache::lonnet::allowed('mgr',$ENV{'request.course.id'})) && ($symb));
+
+ return $result;
+}
+
+#--- Menu for grading a section or the whole class ---
+sub view_edit_entire_class_form {
+ my ($symb,$url)=@_;
+ my ($classlist,$sections) = &getclasslist('all','0');
+ my $result.='
'."\n";
+ return $result;
+}
+
+#--- Menu to upload a csv scores ---
+sub upcsvScores_form {
+ my ($symb,$url) = @_;
+ if (!$symb) {return '';}
+ my $result.='
'."\n";
+ $result.='
'."\n";
+ $result.=' Specify a file containing the class scores for above resource
'."\n";
+ return $result;
+}
+
+#--- Handgrading problems ---
+sub viewGradeaStu_form {
+ my ($symb,$url,$response,$handgrade) = @_;
+ my ($classlist,$sections) = &getclasslist('all','0');
+ my $result.='
'."\n";
+ $result.='
'."\n";
+ $result.=' View/Grade an Individual Student\'s Submission
'."\n";
+ $result.='
'."\n";
+ $result.='
'."\n".
+ ''."\n".
+ ''."\n".
+ ''."\n".
+ ''."\n".
+ ''."\n".
+ ''."\n";
+
+ $result.=' Select section: '."\n";
+ $result.=' Display students who has: '.
+ ' submitted'.
+ ' everybody ';
+ $result.=' (Section "no" implies the students were not assigned a section.) '
+ if (grep /no/,@$sections);
+
+ $result.=' '."\n".
+ '
'."\n";
+ $result.='
'."\n";
+ $result.='
'."\n";
+ return $result;
+}
+
+#--- Form to input a receipt number ---
+sub verifyReceipt_form {
+ my ($symb,$url) = @_;
+ my $cdom=$ENV{"course.$ENV{'request.course.id'}.domain"};
+ my $cnum=$ENV{"course.$ENV{'request.course.id'}.num"};
+ my $hostver=unpack("%32C*",$Apache::lonnet::perlvar{'lonHostID'});
+
+ my $result.='
'."\n";
+ $result.='
'."\n";
+ $result.=' Verify a Submission Receipt Issued by this Server