'."\n".
''.
- 'Fullname | Username | Domain | '."\n";
+ 'Fullname (Username) | '."\n";
my (@parts) = sort(&getpartlist($url));
foreach my $part (@parts) {
my $display=&Apache::lonnet::metadata($url,$part.'.display');
+ next if ($display =~ /Number of Attempts/);
if (!$display) { $display = &Apache::lonnet::metadata($url,$part.'.name'); }
if ($display =~ /^Partial Credit Factor/) {
my ($partid) = &split_part_type($part);
@@ -1835,7 +2001,8 @@ 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,$udom) = split(/:/);
+ my $uname = $_;
+ $uname=~s/:/_/;
$result.=''."\n";
$result.=&viewstudentgrade($url,$symb,$ENV{'request.course.id'},
$_,$$fullname{$_},\@parts,\%weight);
@@ -1845,6 +2012,11 @@ sub viewgrades {
$result.=''."\n";
$result.=''."\n";
+ if (scalar(%$fullname) eq 0) {
+ my $colspan=3+scalar(@parts);
+ $result='There are no students in section "'.$ENV{'form.section'}.
+ '" with enrollment status "'.$ENV{'form.Status'}.'" to modify or grade.';
+ }
$result.=&show_grading_menu_form($symb,$url);
return $result;
}
@@ -1853,42 +2025,43 @@ sub viewgrades {
sub viewstudentgrade {
my ($url,$symb,$courseid,$student,$fullname,$parts,$weight) = @_;
my ($uname,$udom) = split(/:/,$student);
+ $student=~s/:/_/;
my %record=&Apache::lonnet::restore($symb,$courseid,$udom,$uname);
my $result=' '.
''.$fullname.''.
- ' | '.$uname.' | '.$udom.' | '."\n";
+ '\')"; TARGET=_self>'.$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"};
if ($type eq 'awarded') {
my $pts = $score eq '' ? '' : $score*$$weight{$part};
$result.=''."\n";
+ 'GD_'.$student.'_'.$part.'_awarded_s" value="'.$pts.'" />'."\n";
$result.=' | '."\n";
} elsif ($type eq 'solved') {
my ($status,$foo)=split(/_/,$score,2);
$status = 'nothing' if ($status eq '');
- $result.=''."\n";
$result.=' | \n";
- } else {
- $result.=''.
- "\n";
- $result.=' | '."\n";
+# } else {
+# $result.=''.
+# "\n";
+# $result.=' | '."\n";
}
}
$result.=' ';
@@ -1907,7 +2080,7 @@ sub editgrades {
$title.='Section: '.$ENV{'form.section'}.''."\n";
my $result= ''."\n";
$result.= ''.
- 'Username | Fullname | '."\n";
+ 'Username | Domain | Fullname | '."\n";
my %scoreptr = (
'correct' =>'correct_by_override',
@@ -1955,16 +2128,24 @@ sub editgrades {
$result .= ' ';
$result .= $header;
$result .= ' '."\n";
-
+ my $noupdate;
for ($i=0; $i<$ENV{'form.total'}; $i++) {
+ my $line;
my $user = $ENV{'form.ctr'.$i};
+ my $usercolon = $user;
+ $usercolon =~s/_/:/;
+ my ($uname,$udom)=split(/_/,$user);
my %newrecord;
my $updateflag = 0;
- my @userdom = grep /^$user:/,keys %$classlist;
- my (undef,$udom) = split(/:/,$userdom[0]);
-
- $result .= ''.$user.' | '.
- $$fullname{$userdom[0]}.' | ';
+ $line .= ' '.$uname.' | '.
+ $udom.' | '.
+ $$fullname{$usercolon}.' | ';
+ my $usec=$classlist->{"$uname:$udom"}[5];
+ if (!&canmodify($usec)) {
+ my $numcols=scalar(@partid)*(scalar(@parts)-1)*2;
+ $noupdate.=$line."Not allowed to modify student | ";
+ next;
+ }
foreach (@partid) {
my $old_aw = $ENV{'form.GD_'.$user.'_'.$_.'_awarded_s'};
my $old_part_pcr = $old_aw/($weight{$_} ne '0' ? $weight{$_}:1);
@@ -1984,7 +2165,7 @@ sub editgrades {
}
$score = 'excused' if (($ENV{'form.GD_'.$user.'_'.$_.'_solved'} eq 'excused') &&
($score ne 'excused'));
- $result .= ''.$old_aw.' | '.
+ $line .= ''.$old_aw.' | '.
''.$awarded.
($score eq 'excused' ? $score : '').' | ';
@@ -2007,17 +2188,24 @@ sub editgrades {
$newrecord{'resource.'.$part.'regrader'}="$ENV{'user.name'}:$ENV{'user.domain'}";
$updateflag=1;
}
- $result .= ''.$old_aw.' | '.
+ $line .= ''.$old_aw.' | '.
''.$awarded.' | ';
}
}
- $result .= ''."\n";
+ $line.=''."\n";
if ($updateflag) {
$count++;
&Apache::lonnet::cstore(\%newrecord,$symb,$ENV{'request.course.id'},
- $udom,$user);
+ $udom,$uname);
+ $result.=$line;
+ } else {
+ $noupdate.=$line;
}
}
+ if ($noupdate) {
+ my $numcols=(scalar(@partid)*(scalar(@parts)-1)*2)+3;
+ $result .= 'No Changes Occured For the Students Below | '.$noupdate;
+ }
$result .= '
| '."\n".
&show_grading_menu_form ($symb,$url);
my $msg = 'Number of records updated = '.$rec_update.
@@ -2158,10 +2346,7 @@ to this page if the data selected is ins
value="$ENV{'form.upfile_associate'}" />
-
-
-
-
+
@@ -2199,6 +2384,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);
@@ -2258,7 +2485,8 @@ sub csvuploadassign {
}
$request->print('Assigning Grades');
my $courseid=$ENV{'request.course.id'};
- my ($classlist) = &getclasslist('all','1');
+ my ($classlist) = &getclasslist('all',0);
+ my @notallowed;
my @skipped;
my $countdone=0;
foreach my $grade (@gradedata) {
@@ -2269,6 +2497,11 @@ sub csvuploadassign {
push(@skipped,"$username:$domain");
next;
}
+ my $usec=$classlist->{"$username:$domain"}[5];
+ if (!&canmodify($usec)) {
+ push(@notallowed,"$username:$domain");
+ next;
+ }
my %grades;
foreach my $dest (keys(%fields)) {
if ($dest eq 'username' || $dest eq 'domain') { next; }
@@ -2287,10 +2520,14 @@ sub csvuploadassign {
}
$request->print(" Stored $countdone students\n");
if (@skipped) {
- $request->print(' Skipped Students ');
- foreach my $student (@skipped) { $request->print(" $student"); }
+ $request->print('Skipped Students ');
+ foreach my $student (@skipped) { $request->print("$student \n"); }
}
- $request->print(&view_edit_entire_class_form($symb,$url));
+ if (@notallowed) {
+ $request->print('Students Not Allowed to Modify ');
+ foreach my $student (@notallowed) { $request->print("$student \n"); }
+ }
+ $request->print(" \n");
$request->print(&show_grading_menu_form($symb,$url));
return '';
}
@@ -2355,7 +2592,7 @@ LISTJAVASCRIPT
my $result=' '.
'Manual Grading by Page or Sequence';
- $result.='
+$grading_menu_button
SCANTRONFORM
return $result;
}
-sub scantron_configphase {
- my ($r) = @_;
- my $sequence=$ENV{'form.selectpage'};
- my $result;
- $result.="got page $sequence";
- $Apache::lonxml::debug=1;
- &Apache::lonhomework::showhash(%ENV);
- $Apache::lonxml::debug=0;
- #FIXME Needs to present some lines from the file and allow the instructor to specify which columns represent what data, possibly have some nice defaults setup, probably should do a pass through all problems for a student to get an idea of how many questions there are, and homw many lines we'll have,
- return $result;
+sub get_scantron_config {
+ my ($which) = @_;
+ my $fh=Apache::File->new($Apache::lonnet::perlvar{'lonTabDir'}.'/scantronformat.tab');
+ my %config;
+ foreach my $line (<$fh>) {
+ my ($name,$descrip)=split(/:/,$line);
+ if ($name ne $which ) { next; }
+ chomp($line);
+ my @config=split(/:/,$line);
+ $config{'name'}=$config[0];
+ $config{'description'}=$config[1];
+ $config{'CODElocation'}=$config[2];
+ $config{'CODEstart'}=$config[3];
+ $config{'CODElength'}=$config[4];
+ $config{'IDstart'}=$config[5];
+ $config{'IDlength'}=$config[6];
+ $config{'Qstart'}=$config[7];
+ $config{'Qlength'}=$config[8];
+ $config{'Qoff'}=$config[9];
+ $config{'Qon'}=$config[10];
+ last;
+ }
+ return %config;
+}
+
+sub username_to_idmap {
+ my ($classlist)= @_;
+ my %idmap;
+ foreach my $student (keys(%$classlist)) {
+ $idmap{$classlist->{$student}->[&Apache::loncoursedata::CL_ID]}=
+ $student;
+ }
+ return %idmap;
+}
+
+sub scantron_parse_scanline {
+ my ($line,$scantron_config)=@_;
+ my %record;
+ my $questions=substr($line,$$scantron_config{'Qstart'}-1);
+ my $data=substr($line,0,$$scantron_config{'Qstart'}-1);
+ if ($$scantron_config{'CODElocation'} ne 0) {
+ if ($$scantron_config{'CODElocation'} < 0) {
+ $record{'scantron.CODE'}=substr($data,$$scantron_config{'CODEstart'}-1,
+ $$scantron_config{'CODElength'});
+ } else {
+ #FIXME interpret first N questions
+ }
+ }
+ $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).
+ '-'.$currentquest.'-'.$questnum.' ');
+ }
+ if (length($array[0]) eq $$scantron_config{'Qlength'}) {
+ $record{"scantron.$questnum.answer"}='';
+ } else {
+ $record{"scantron.$questnum.answer"}=$alphabet[length($array[0])];
+ }
+ }
+ $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 {
+ my ($r) = @_;
+ my (undef,undef,$sequence)=split(/___/,$ENV{'form.selectpage'});
+ my ($symb,$url)=&get_symb_and_url($r);
+ if (!$symb) {return '';}
+ my $default_form_data=&defaultFormData($symb,$url);
+
+ 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= <
+
+ $default_form_data
+SCANTRONFORM
+ $r->print($result);
+
+ my @delayqueue;
+ my $totalcorrect;
+ my $totalincorrect;
+
+ 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
+ # through grade target {
+ # 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
+ # to repair student provided info
+ #Expected errors include
+ # 1 bad/no stuid/username
+ # 2 invalid bubblings
+
+ }
#FIXME
- # loop through students, {
- # Check if studnet info valid, if not add line to delay queue
- # foreach question 'submit' the students answer to the server
- # through grade target {
- # generate data to pass back that includes grade recevied
- # }
- # }
- # loop through delay queue {
- # print out each delayed student with interface to select how
- # to repair student provided info
- # Expected errors include
- # 1 bad/no stuid/username
- # 2 invalid bubblings
- # }
# 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 -------
#
@@ -2878,16 +3333,24 @@ sub show_grading_menu_form {
my $result.=''."\n";
return $result;
}
+# -- Retrieve choices for grading form
+sub savedState {
+ my %savedState = ();
+ if ($ENV{'form.saveState'}) {
+ foreach (split(/:/,$ENV{'form.saveState'})) {
+ my ($key,$value) = split(/=/,$_,2);
+ $savedState{$key} = $value;
+ }
+ }
+ return \%savedState;
+}
#--- Displays the main menu page -------
sub gradingmenu {
@@ -2895,24 +3358,20 @@ sub gradingmenu {
my ($symb,$url)=&get_symb_and_url($request);
if (!$symb) {return '';}
my $probTitle = &Apache::lonnet::gettitle($symb);
- my $saveCmd = ($ENV{'form.saveCmd'} eq '' ? 'pickStudentPage' : $ENV{'form.saveCmd'});
- my $saveSec = ($ENV{'form.saveSec'} eq '' ? 'all' : $ENV{'form.saveSec'});
- my $saveSub = ($ENV{'form.saveSub'} eq '' ? 'yes' : $ENV{'form.saveSub'});
- my $saveStatus = ($ENV{'form.saveStatus'} eq '' ? 'Active' : $ENV{'form.saveStatus'});
$request->print(<
- function checkChoice(formname) {
- var cmd = formname.command;
- formname.saveCmd.value = radioSelection(cmd);
- formname.saveSec.value = pullDownSelection(formname.section);
- formname.saveSub.value = radioSelection(formname.submitonly);
- formname.saveStatus.value = 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[5].checked) {
+ function checkChoice(formname,val,cmdx) {
+ if (val <= 2) {
+ var cmd = radioSelection(formname.radioChoice);
+ } else {
+ cmd = cmdx;
+ }
+ formname.command.value = cmd;
+ formname.saveState.value = "saveCmd="+cmd+":saveSec="+pullDownSelection(formname.section)+
+ ":saveSub="+radioSelection(formname.submitonly)+":saveStatus="+pullDownSelection(formname.Status);
+ if (val < 5) formname.submit();
+ if (val == 5) {
if (!checkReceiptNo(formname,'notOK')) { return false;}
formname.submit();
}
@@ -2929,7 +3388,6 @@ sub gradingmenu {
formname.receipt.focus();
return false;
}
- formname.command[5].checked = true;
return true;
}
@@ -2960,57 +3418,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
@@ -3024,12 +3431,17 @@ GRADINGMENUJS
$resptype = $responsetype;
$hdgrade = $handgrade if ($handgrade eq 'yes');
$result.='Part '.(split(/_/))[0].' | '.
- 'Type: '.$responsetype.' | '.
- 'Handgrade: '.$handgrade.' | ';
+ 'Type: '.$responsetype.' | |
';
+# '