'.
''.
' Fullname (username) '.
@@ -2388,7 +2420,7 @@ LISTJAVASCRIPT
' Fullname (username) '.
' Fullname (username) ';
- my (undef,undef,$fullname) = &getclasslist($getsec,'0');
+ my (undef,undef,$fullname) = &getclasslist($getsec,'1');
my $ptr = 1;
foreach my $student (sort {lc($$fullname{$a}) cmp lc($$fullname{$b}) } keys %$fullname) {
my ($uname,$udom) = split(/:/,$student);
@@ -2412,8 +2444,8 @@ LISTJAVASCRIPT
}
sub getSymbMap {
- my $navmap = Apache::lonnavmaps::navmap-> new(
- $ENV{'request.course.fn'}.'.db',
+ my ($request) = @_;
+ my $navmap = Apache::lonnavmaps::navmap-> new($ENV{'request.course.fn'}.'.db',
$ENV{'request.course.fn'}.'_parms.db',1, 1);
my $res = $navmap->firstResource(); # temp resource to access constants
@@ -2434,10 +2466,32 @@ sub getSymbMap {
if ($curRes == $iterator->END_MAP()) { $depth--; }
if (ref($curRes) && $curRes->is_map()) {
- my $title = $curRes->compTitle();
- push @titles,$minder.'.'.$title; # minder, just in case two titles are identical
- $symbx{$minder.'.'.$title} = $curRes->symb();
- $minder++;
+ my ($mapUrl, $id, $resUrl) = split(/___/, $curRes->symb()); # check map contains at least one problem
+ my $map = $navmap->getResourceByUrl($resUrl); # add to navmaps
+
+ my $mapiterator = $navmap->getIterator($map->map_start(),
+ $map->map_finish());
+
+ my $mapdepth = 1;
+ my $countProblems = 0;
+ $mapiterator->next(); # skip the first BEGIN_MAP
+ my $mapcurRes = $mapiterator->next(); # for "current resource"
+ my $ctr=0;
+ while ($mapdepth > 0 && $ctr < 100) {
+ if($mapcurRes == $mapiterator->BEGIN_MAP) { $mapdepth++; }
+ if($mapcurRes == $mapiterator->END_MAP) { $mapdepth++; }
+
+ if (ref($mapcurRes) && $mapcurRes->is_problem() && !$mapcurRes->randomout) {
+ $countProblems++;
+ }
+ $ctr++;
+ }
+ if ($countProblems > 0) {
+ my $title = $curRes->compTitle();
+ push @titles,$minder.'.'.$title; # minder, just in case two titles are identical
+ $symbx{$minder.'.'.$title} = $curRes->symb();
+ $minder++;
+ }
}
$curRes = $iterator->next();
}
@@ -2446,23 +2500,27 @@ sub getSymbMap {
return \@titles,\%symbx;
}
+#
+#--- Displays a page/sequence w/wo problems, w/wo submissions
sub displayPage {
my ($request) = shift;
+ my ($symb,$url) = &get_symb_and_url($request);
my $cdom = $ENV{"course.$ENV{'request.course.id'}.domain"};
my $cnum = $ENV{"course.$ENV{'request.course.id'}.num"};
my $getsec = $ENV{'form.section'} eq '' ? 'all' : $ENV{'form.section'};
my $pageTitle = $ENV{'form.page'};
- my (undef,undef,$fullname) = &getclasslist($getsec,'0');
+ my (undef,undef,$fullname) = &getclasslist($getsec,'1');
my ($uname,$udom) = split(/:/,$ENV{'form.student'});
- my ($idx,$showtitle) = ($pageTitle =~ /(\d+)\.(.*)/);
my $result=' '.$ENV{'form.title'}.' ';
$result.=' Student: '.$$fullname{$ENV{'form.student'}}.
' ('.$uname.($udom eq $cdom ? '':':'.$udom).') '."\n";
- my $navmap = Apache::lonnavmaps::navmap-> new(
- $ENV{'request.course.fn'}.'.db',
+ &sub_page_js($request);
+ $request->print($result);
+
+ my $navmap = Apache::lonnavmaps::navmap-> new($ENV{'request.course.fn'}.'.db',
$ENV{'request.course.fn'}.'_parms.db',1, 1);
my ($mapUrl, $id, $resUrl) = split(/___/, $ENV{'form.page'});
my $map = $navmap->getResourceByUrl($resUrl); # add to navmaps
@@ -2470,163 +2528,749 @@ sub displayPage {
my $iterator = $navmap->getIterator($map->map_start(),
$map->map_finish());
- my $depth = 1;
+ my $studentTable='
+$grading_menu_button
+SCANTRONFORM
- my $hostver=unpack("%32C*",$Apache::lonnet::perlvar{'lonHostID'});
+ return $result;
+}
- $result.=''."\n";
- $result.=''."\n";
- $result.=' Verify a Submission Receipt Issued by this Server '."\n";
- $result.=''."\n";
- $result.=''."\n";
- $result.=' '.$hostver.'- '."\n";
- $result.=' '."\n";
- $result.=' '."\n";
- if ($ENV{'form.url'}) {
- $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{'CODE'}=substr($data,$$scantron_config{'CODEstart'}-1,
+ $$scantron_config{'CODElength'});
+ } else {
+ #FIXME interpret first N questions
+ }
}
- if ($ENV{'form.symb'}) {
- $result.=' ';
+ $record{'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'})='';
+ 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).'-'.
+ ' ');
+ }
+ if (length($array[0]) eq $$scantron_config{'Qlength'}) {
+ $record{"$questnum.answer"}='';
+ } else {
+ $record{"$questnum.answer"}=$alphabet[length($array[0])];
+ }
}
- $result.=' ';
- $result.='
'."\n";
- $result.='
'."\n";
+ $record{'maxquest'}=$questnum;
+ $Apache::lonxml::debug=1;
+ &Apache::lonhomework::showhash(%record);
+ $Apache::lonxml::debug=0;
+ return %record;
+}
+
+sub scantron_add_delay {
+}
+
+sub scantron_find_student {
+}
+
+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 $classlist=&Apache::loncoursedata::get_classlist();
+ my %idmap=&username_to_idmap($classlist);
+ my $result= <
+
+ $default_form_data
+SCANTRONFORM
+ $r->print($result);
+
+ my @delayqueue;
+
+ foreach my $line (<$scanlines>) {
+ 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');
+ }
+ ($uname,$udom)=split(/:/,$uname);
+ #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
+ #}
+ }
+ 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
+ # if delay queue exists 2 submits one to process delayed students one
+ # to ignore delayed students, possibly saving the delay queue for later
+
+}
+#-------- end of section for handling grading scantron forms -------
+#
+#-------------------------------------------------------------------
+
+
+#-------------------------- Menu interface -------------------------
+#
+#--- Show a Grading Menu button - Calls the next routine ---
+sub show_grading_menu_form {
+ my ($symb,$url)=@_;
+ my $result.=''."\n".
+ ' '."\n".
+ ' '."\n".
+ ' '."\n".
+ ' '."\n".
+ ' '."\n".
+ ' '."\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 {
+ my ($request) = @_;
+ my ($symb,$url)=&get_symb_and_url($request);
+ if (!$symb) {return '';}
+ my $probTitle = &Apache::lonnet::gettitle($symb);
+
+ $request->print(<
+ function checkChoice(formname) {
+ 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[5].checked) {
+ if (!checkReceiptNo(formname,'notOK')) { return false;}
+ formname.submit();
+ }
+ }
+
+ function checkReceiptNo(formname,nospace) {
+ var receiptNo = formname.receipt.value;
+ var checkOpt = false;
+ if (nospace == "OK" && isNaN(receiptNo)) {checkOpt = true;}
+ if (nospace == "notOK" && (isNaN(receiptNo) || receiptNo == "")) {checkOpt = true;}
+ if (checkOpt) {
+ alert("Please enter a receipt number given by a student in the receipt box.");
+ formname.receipt.value = "";
+ formname.receipt.focus();
+ return false;
+ }
+ formname.command[5].checked = true;
+ return true;
+ }
+
+ function radioSelection(radioButton) {
+ var selection=null;
+ if (radioButton.length > 1) {
+ for (var i=0; i 1) {
+ for (var i=0; i");
+ lDoc.write("Browse And Upload ");
+
+ lDoc.write("
+GRADINGMENUJS
+
+ my $result=' Manual Grading/View Submission '.
+ ''.
+ 'Problem: '.$probTitle.' '."\n";
+ 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.='
'."\n";
+
+ my (undef,$sections) = &getclasslist('all','0');
+ my $savedState = &savedState();
+ my $saveCmd = ($$savedState{'saveCmd'} eq '' ? 'pickStudentPage' : $$savedState{'saveCmd'});
+ my $saveSec = ($$savedState{'saveSec'} eq '' ? 'all' : $$savedState{'saveSec'});
+ my $saveSub = ($$savedState{'saveSub'} eq '' ? 'yes' : $$savedState{'saveSub'});
+ my $saveStatus = ($$savedState{'saveStatus'} eq '' ? 'Active' : $$savedState{'saveStatus'});
+
+ $result.=''."\n".
+ ' '."\n".
+ ' '."\n".
+ ' '."\n".
+ ' '."\n".
+ ' '."\n".
+ ' '."\n".
+ ' '."\n";
+
+ $result.=''."\n".
+ ''."\n".
+ ' Select a Grading/Viewing Option '."\n".
+ ''."\n";
+
+ $result.=''."\n".
+ '
'."\n".
+ '
'."\n";
return $result;
}
@@ -2681,13 +3325,12 @@ sub handler {
$Apache::grades::viewgrades=&Apache::lonnet::allowed('vgr',$ENV{'request.course.id'});
if ($command eq 'submission') {
($ENV{'form.student'} eq '' ? &listStudents($request) : &submission($request,0,0));
-# if ($command eq 'submission') {
-# &listStudents($request) if ($ENV{'form.student'} eq '');
-# &submission($request,0,0) if ($ENV{'form.student'} ne '');
} elsif ($command eq 'pickStudentPage') {
&pickStudentPage($request);
} elsif ($command eq 'displayPage') {
&displayPage($request);
+ } elsif ($command eq 'gradeByPage') {
+ &updateGradeByPage($request);
} elsif ($command eq 'processGroup') {
&processGroup($request);
} elsif ($command eq 'gradingmenu') {
@@ -2700,6 +3343,8 @@ sub handler {
$request->print(&editgrades($request));
} elsif ($command eq 'verify') {
$request->print(&verifyreceipt($request));
+ } elsif ($command eq 'csvform') {
+ $request->print(&upcsvScores_form($request));
} elsif ($command eq 'csvupload') {
$request->print(&csvupload($request));
} elsif ($command eq 'viewclasslist') {
@@ -2717,6 +3362,10 @@ sub handler {
}
$request->print(&csvuploadmap($request));
}
+ } elsif ($command eq 'scantron_selectphase') {
+ $request->print(&scantron_selectphase($request));
+ } elsif ($command eq 'scantron_process') {
+ $request->print(&scantron_process_students($request));
} else {
$request->print("Unknown action: $command:");
}