# The LearningOnline Network with CAPA
# Quick Student Grades Display
#
# $Id:
#
# Copyright Michigan State University Board of Trustees
#
# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
#
# LON-CAPA is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# LON-CAPA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LON-CAPA; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# /home/httpd/html/adm/gpl.txt
#
# http://www.lon-capa.org/
#
# Created Nov. 14, 2002 by Jeremy Bowers
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});
# Handle header-only request
if ($r->header_only) {
if ($ENV{'browser.mathml'}) {
$r->content_type('text/xml');
} else {
$r->content_type('text/html');
}
$r->send_http_header;
return OK;
}
# Send header, don't cache this page
if ($ENV{'browser.mathml'}) {
$r->content_type('text/xml');
} else {
$r->content_type('text/html');
}
&Apache::loncommon::no_cache($r);
$r->send_http_header;
my $showPoints = $ENV{'course.'.$ENV{'request.course.id'}.'.grading'} eq 'standard';
# Create the nav map
my $navmap = Apache::lonnavmaps::navmap->new(
$ENV{"request.course.fn"}.".db",
$ENV{"request.course.fn"}."_parms.db", 1, 0, 1);
if (!defined($navmap)) {
my $requrl = $r->uri;
$ENV{'user.error.msg'} = "$requrl:bre:0:0:Navamp initialization failed.";
return HTTP_NOT_ACCEPTABLE;
}
# Keep this hash in sync with %statusIconMap in lonnavmaps; they
# should match color/icon
my $res = $navmap->firstResource(); # temp resource to access constants
# Header
my $title = $showPoints ? "Quick Points Display" : "Quick Completed Problems Display";
$r->print(&Apache::loncommon::bodytag($title, '', ''));
if ($showPoints) {
$r->print(<
This may take a few moments to display.
"); $r->rflush(); $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.) # For convenience, "totalParts" is also "totalPoints" when we're looking # at points; I can't come up with a variable name that makes sense # equally for both cases. my $totalParts = 0; my $totalPossible = 0; my $totalRight = 0; my $now = time(); my $topLevelParts = 0; my $topLevelRight = 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() && !$curRes->randomout) { # Get number of correct, incorrect parts my $parts = $curRes->parts(); my $partsRight = 0; my $partsCount = 0; my $stack = $iterator->getStack(); for my $part (@{$parts}) { if ($showPoints) { my $score = $curRes->weight($part) * $curRes->awarded($part); $partsRight += $score; $totalRight += $score; $partsCount += $curRes->weight($part); if ($curRes->opendate($part) < $now) { $totalPossible += $curRes->weight(); } $totalParts += $curRes->weight($part); } else { my $status = $curRes->getCompletionStatus($part); my $thisright = 0; $partsCount++; if ($status == $curRes->CORRECT || $status == $curRes->CORRECT_BY_OVERRIDE || $status == $curRes->EXCUSED || $status == $curRes->ANSWER_SUBMITTED) { $partsRight++; $totalRight++; $thisright = 1; } my $dateStatus = $curRes->getDateStatus($part); $totalParts++; if ($curRes->opendate($part) < $now) { $totalPossible++; } } } if ($depth == 1) { # in top-level only $topLevelParts += $partsCount; $topLevelRight += $partsRight; $r->print($curRes->compTitle() . 'Sequence | '); $r->print('Done / Total |
"); my $thisIndent = ''; for (my $i = 1; $i < $depth; $i++) { $thisIndent .= $indentString; } $r->print("$thisIndent$title | "); $r->print("$thisIndent |
"); $r->print("Problems Not Contained In A Folder | "); $r->print("$topLevelRight / $topLevelParts |
Total $title: $totalRight "); $r->print("Max Possible To Date $maxHelpLink: $totalPossible "); $title = $showPoints ? "Points" : "Parts"; $r->print("Total $title In Course: $totalParts |