');
}
-#
-# Go through the complete course and collect data
-#
sub getData {
- my ($showPoints,$uname,$udom,$usec)=@_;
+ my ($showPoints,$uname,$udom)=@_;
# Create the nav map
- my $navmap = Apache::lonnavmaps::navmap->new($uname,$udom,$usec);
-
- if (!defined($navmap)) {
- return ();
- }
+ my $navmap = Apache::lonnavmaps::navmap->new($uname,$udom);
my $res = $navmap->firstResource(); # temp resource to access constants
@@ -293,7 +182,7 @@ sub getData {
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
@@ -316,7 +205,7 @@ sub getData {
if ($curRes == $iterator->BEGIN_MAP()) {$depth++;}
if ($curRes == $iterator->END_MAP()) { $depth--; }
- if (ref($curRes) && $curRes->is_gradable() && !$curRes->randomout)
+ if (ref($curRes) && $curRes->is_problem() && !$curRes->randomout)
{
# Get number of correct, incorrect parts
my $parts = $curRes->parts();
@@ -326,36 +215,35 @@ sub getData {
my $stack = $iterator->getStack();
for my $part (@{$parts}) {
+ my $completionStatus = $curRes->getCompletionStatus($part);
my $dateStatus = $curRes->getDateStatus($part);
- my $weight = $curRes->weight($part);
- my $problemstatus = $curRes->problemstatus($part);
-
- if ($curRes->solved($part) eq 'excused') {
+
+ if ($completionStatus == $curRes->EXCUSED()) {
next;
}
if ($showPoints) {
my $score = 0;
# If we're not telling status and the answer date isn't passed yet,
# it's an "attempted" point
- if ((($problemstatus eq 'no') ||
- ($problemstatus eq 'no_feedback_ever')) &&
+ if ((($curRes->problemstatus($part) eq 'no') ||
+ ($curRes->problemstatus($part) eq 'no_feedback_ever')) &&
($dateStatus != $curRes->ANSWER_OPEN)) {
my $status = $curRes->simpleStatus($part);
if ($status == $curRes->ATTEMPTED) {
- $partsAttempted += $weight;
+ $partsAttempted += $curRes->weight($part);
$totalAttempted += $partsAttempted;
}
} else {
- $score = &Apache::grades::compute_points($weight, $curRes->awarded($part));
+ $score = &Apache::grades::compute_points($curRes->weight($part), $curRes->awarded($part));
}
$partsRight += $score;
$totalRight += $score;
- $partsCount += $weight;
+ $partsCount += $curRes->weight($part);
if ($curRes->opendate($part) < $now) {
- $totalPossible += $weight;
+ $totalPossible += $curRes->weight($part);
}
- $totalParts += $weight;
+ $totalParts += $curRes->weight($part);
} else {
my $status = $curRes->simpleStatus($part);
my $thisright = 0;
@@ -372,6 +260,7 @@ sub getData {
$totalAttempted++;
}
+ my $dateStatus = $curRes->getDateStatus($part);
$totalParts++;
if ($curRes->opendate($part) < $now) {
$totalPossible++;
@@ -402,8 +291,7 @@ sub getData {
}
$curRes = $iterator->next();
}
- return ($navmap,$totalParts,$totalPossible,$totalRight,$totalAttempted,
- $topLevelParts,$topLevelRight,$topLevelAttempted);
+ return ($navmap,$totalParts,$totalPossible,$totalRight,$totalAttempted,$topLevelParts,$topLevelRight,$topLevelAttempted);
}
#
@@ -412,8 +300,8 @@ sub getData {
sub outputTable {
- my ($r,$showPoints,$notshowTotals,$nostdtotals,$navmap,$totalParts,$totalPossible,
- $totalRight,$totalAttempted,$topLevelParts,$topLevelRight,$topLevelAttempted)=@_;
+ my ($r,$showPoints,$notshowTotals,
+ $navmap,$totalParts,$totalPossible,$totalRight,$totalAttempted,$topLevelParts,$topLevelRight,$topLevelAttempted)=@_;
my @start = (255, 255, 192);
my @end = (0, 192, 0);
@@ -498,103 +386,344 @@ sub outputTable {
# show totals (if applicable), close table
#
if ($showPoints) {
- unless ($nostdtotals) {
- my $maxHelpLink = &Apache::loncommon::help_open_topic("Quick_Grades_Possibly_Correct");
+ my $maxHelpLink = &Apache::loncommon::help_open_topic("Quick_Grades_Possibly_Correct");
+
+ $title = $showPoints ? "Points" : "Parts Done";
+ my $totaltitle = $showPoints ? &mt("Awarded Total Points") : &mt("Total Parts Done");
+ $r->print(&Apache::loncommon::start_data_table_row()
+ .'
'.$totaltitle.': '.$totalRight.' ');
+ $r->print(&mt('Max Possible To Date')." $maxHelpLink: $totalPossible ");
+ $title = $showPoints ? "Points" : "Parts";
+ $r->print(&mt("Total $title In Course").': '.$totalParts.'
');
+}
- if ($allowed_to_view) {
- my @notes;
- push(@notes,&mt('Students do not see total points.')) if ($notshowTotals);
- push(@notes,&mt('Students do not see link to spreadsheet.')) if ($notshowSPRSlink);
- push(@notes,&mt('Students will see points based on problem weights.')) if ($showPoints);
- if (($showPoints) && ($hidetotals ne '')) {
- if ($hidetotals eq 'all') {
- push(@notes,&mt('Students do not see course totals.'));
- } else {
- my @secs = split(/,/,$hidetotals);
- if (@secs == 1) {
- push(@notes,&mt('Students in section [_1] do not see course totals.',
- $hidetotals));
- } elsif (@secs > 1) {
- push(@notes,&mt('Students in sections [_1] do not see course totals.',
- join(', ',@secs)));
- }
+#
+# Make one new category
+#
+
+sub make_new_category {
+ my ($r,$cangrade,$ordernum,%categories)=@_;
+ unless ($cangrade) { return %categories; }
+# Generate new ID
+ my $id=time.'_'.$$.'_'.rand(10000);
+# Add new ID to list of all IDs ever created in this course
+ $categories{'all'}.=','.$id;
+ $categories{'all'}=~s/^\,//;
+# Add new ID to ordered list of displayed and evaluated categories
+ $categories{'order'}.=','.$id;
+ $categories{'order'}=~s/^\,//;
+# Move it into desired space
+ if (defined($ordernum)) {
+ %categories=&move_category($id,$cangrade,$ordernum,%categories);
+ }
+ $categories{$id.'_weighttype'}='default';
+ return %categories;
+}
+
+#
+# Delete category
+#
+
+sub del_category {
+ my ($id,$cangrade,%categories)=@_;
+ my @neworder=();
+ foreach my $currentid (split(/\,/,$categories{'order'})) {
+ unless ($currentid eq $id) {
+ push(@neworder,$currentid);
+ }
+ }
+ $categories{'order'}=join(',',@neworder);
+ return %categories;
+}
+
+#
+# Move a category to a desired position n the display order
+#
+
+sub move_category {
+ my ($id,$cangrade,$ordernum,%categories)=@_;
+ unless ($cangrade) { return %categories; }
+ my @order=split(/\,/,$categories{'order'});
+# Where is the index currently?
+ my $currentpos=¤t_pos_category($id,%categories);
+ if (defined($currentpos)) {
+ if ($currentpos<$ordernum) {
+# This is moving to a higher index
+# ....X1234....
+# ....1234X....
+ for (my $i=$currentpos;$i<$ordernum;$i++) {
+ $order[$i]=$order[$i+1];
}
+ $order[$ordernum]=$id;
}
- push(@notes,&mt('Students will see link to spreadsheet.')) if ($showSPRSlink);
- push(@notes,&Apache::lonhtmlcommon::coursepreflink(&mt('Grade display settings'),'grading'));
- $r->print(&Apache::loncommon::head_subbox(join(' ',@notes)));
- } elsif (!$allowed_to_edit) {
- if (!$showPoints && !$notshowSPRSlink ) {
- $r->print(&Apache::loncommon::head_subbox(
- &mt('This screen shows how many problems (or problem parts) you have completed'
- .', and how many you have not yet done.'
- .' You can also look at [_1]a detailed score sheet[_2].'
- ,'','')));
+ if ($currentpos>$ordernum) {
+# This is moving to a lower index
+# ....1234X....
+# ....X1234....
+ for (my $i=$currentpos;$i>$ordernum;$i--) {
+ $order[$i]=$order[$i-1];
+ }
+ $order[$ordernum]=$id;
}
}
- return;
+ $categories{'order'}=join(',',@order);
+ return %categories;
}
-sub endGradeScreen {
- my ($r)=@_;
- $r->print(&Apache::loncommon::end_page());
- return;
+#
+# Find current postion of a category in the order
+#
+
+sub current_pos_category {
+ my ($id,%categories)=@_;
+ my @order=split(/\,/,$categories{'order'});
+ for (my $i=0;$i<=$#order;$i++) {
+ if ($order[$i] eq $id) { return $i; }
+ }
+# not found
+ return undef;
+}
+
+#
+# Set name of a category
+#
+sub set_category_name {
+ my ($cangrade,$id,$name,%categories)=@_;
+ unless ($cangrade) { return %categories; }
+ $categories{$id.'_name'}=$name;
+ return %categories;
}
+#
+# Set weight of a category
+#
+sub set_category_weight {
+ my ($cangrade,$id,$weighttype,$weight,%categories)=@_;
+ unless ($cangrade) { return %categories; }
+ if (($categories{$id.'_weight'} eq '') && ($weight=~/\d/)) {
+ $weighttype='typein';
+ }
+ $categories{$id.'_weighttype'}=$weighttype;
+ if ($weighttype eq 'default') {
+ $categories{$id.'_weight'}='';
+ } else {
+ $weight=~s/\D//gs;
+ unless ($weight) { $weight=0; }
+ $categories{$id.'_weight'}=$weight;
+ }
+ return %categories;
+}
+
+
+#
+# === end category-related
+#
+#
# Pass this two refs to arrays for the start and end color, and a number
# from 0 to 1 for how much of the latter you want to mix in. It will
# return a string ready to show ("#FFC309");
+
sub mixColors {
my $start = shift;
my $end = shift;