--- loncom/interface/lonquickgrades.pm 2002/11/14 21:36:23 1.1 +++ loncom/interface/lonquickgrades.pm 2002/11/22 20:07:11 1.5 @@ -31,9 +31,15 @@ package Apache::lonquickgrades; use strict; use Apache::Constants qw(:common :http); +use POSIX; sub handler { my $r = shift; + return real_handler($r); +} + +sub real_handler { + my $r = shift; &Apache::loncommon::get_unprocessed_cgi($ENV{QUERY_STRING}); @@ -60,7 +66,11 @@ sub handler { # Create the nav map my $navmap = Apache::lonnavmaps::navmap->new( $ENV{"request.course.fn"}.".db", - $ENV{"request.course.fn"}."_parms.db", 0, 0); + $ENV{"request.course.fn"}."_parms.db", 1, 0); + + # Keep this hash in sync with %statusIconMap in lonnavmaps; they + # should match color/icon + my $res = $navmap->firstResource(); # temp resource to access constants if (!defined($navmap)) { my $requrl = $r->uri; @@ -69,31 +79,150 @@ sub handler { } # Header - $r->print(&Apache::loncommon::bodytag('Navigate Course Map','', + $r->print(&Apache::loncommon::bodytag('Quick Score Display','', '')); + $navmap->init(); + # End navmap using boilerplate my $iterator = $navmap->getIterator(undef, undef, undef, 1); my $depth = 1; $iterator->next(); # ignore first BEGIN_MAP my $curRes = $iterator->next(); - + + # General overview of the following: Walk along the course resources. + # For every problem in the resource, tell its parent maps how many + # parts and how many parts correct it has. After that, each map will + # have a count of the total parts underneath it, correct and otherwise. + # After that, we will walk through the course again and read off + # maps in order, with their data. + # (If in the future people decide not to be cumulative, only add + # the counts to the parent map.) + + my $totalParts = 0; my $totalPossible = 0; my $totalRight = 0; + + # Pre-run: Count parts correct while ( $depth > 0 ) { if ($curRes == $iterator->BEGIN_MAP()) {$depth++;} if ($curRes == $iterator->END_MAP()) { $depth--; } - if (ref($curRes) && $curRes->is_problem()) { + if (ref($curRes) && $curRes->is_problem()) + { + # Get number of correct, incorrect parts + my $parts = $curRes->parts(); + if (scalar(@{$parts}) > 1) { shift @{$parts}; } # lose the first "0" + $totalParts += scalar(@{$parts}); + my $partsRight = 0; + my $stack = $iterator->getStack(); + + for my $part (@{$parts}) { + my $status = $curRes->getCompletionStatus($part); + if ($status == $curRes->CORRECT || $status == $curRes->CORRECT_BY_OVERRIDE + || $status == $curRes->EXCUSED) { + $partsRight++; + $totalRight++; + } + + my $dateStatus = $curRes->getDateStatus($part); + if ($status != $curRes->OPEN_LATER) { + $totalPossible++; + } + } + + # Crawl down stack and record parts correct and total + for my $res (@{$stack}) { + if (ref($res) && $res->is_map()) { + if (!defined($res->{DATA}->{CHILD_PARTS})) { + $res->{DATA}->{CHILD_PARTS} = 0; + $res->{DATA}->{CHILD_CORRECT} = 0; + } + + $res->{DATA}->{CHILD_PARTS} += scalar(@{$parts}); + $res->{DATA}->{CHILD_CORRECT} += $partsRight; + } + } + } + $curRes = $iterator->next(); + } + + $iterator = $navmap->getIterator(undef, undef, undef, 1); + my $depth = 1; + $iterator->next(); # ignore first BEGIN_MAP + my $curRes = $iterator->next(); + + my @start = (255, 255, 0); + my @end = (0, 192, 0); + + my $indentString = ' '; + + # Second pass: Print the maps. + $r->print('
Sequence | '); + $r->print('Correct / Total |
"); + + for (my $i = 1; $i < $depth; $i++) { $r->print($indentString); } + + $r->print("$title | "); + $r->print("$correct / $total |