@@ -638,97 +659,212 @@ ENDMOVE
$r->print('
'.&mt('Delete').' ');
$r->print('
');
- } else {
+ } elsif ($output) {
$r->print('
'.$categories{$id.'_name'}.' ');
}
-# Content
- $r->print('
');
+# Content display and summing up of points
+ my $totalpossible=0;
+ my $totalcorrect=0;
+ my @individual=();
+ if ($output) { $r->print(''); }
foreach my $contentid (split(/\,/,$categories{$id.'_content'})) {
- $r->print('');
- $r->print(&Apache::lonnet::gettitle($contentid));
- if ($cangrade) {
- $r->print(' '.&mt('Delete').' ');
- }
- $r->print(' ');
- }
- $r->print(' ');
- if ($cangrade) {
- $r->print(' '.&Apache::loncommon::selectresource_link('quickform','addcont_'.$id.'_res',&mt('Add Problem or Folder')).' '.
- ' ");
+ my ($type,$possible,$attempted,$correct)=split(/\:/,$$performance{$contentid});
+ $totalpossible+=$possible;
+ $totalcorrect+=$correct;
+ if ($possible>0) { push(@individual,"$possible:$correct"); }
+ if ($output) {
+ $r->print('');
+ $r->print(&Apache::lonnet::gettitle($contentid).' ('.&numberout($correct).'/'.&numberout($possible).')');
+ if ($cangrade) {
+ $r->print(' '.&mt('Delete').' ');
+ }
+ $r->print(' ');
+ }
+ }
+ if ($output) {
+ $r->print('');
+ if ($cangrade) {
+ $r->print(' '.&Apache::loncommon::selectresource_link('quickform','addcont_'.$id,&mt('Add Problem or Folder')).' ');
+ }
+ $r->print(''.&mt('Total raw points: [_1]/[_2]',&numberout($totalcorrect),&numberout($totalpossible)).'
');
+ $r->print(' ');
}
- $r->print(' ');
-
# Total
+ if ($output) { $r->print('
'); }
if ($cangrade) {
- $r->print(' '.
+ if ($output) {
+ $r->print(
''.
''.&mt('default').' '.
''.&mt('Type-in value').' '.
' '.
' ');
+ '" value="'.&Apache::lonhtmlcommon::entity_encode($categories{$id.'_total'}).'" />');
+ }
} else {
- $r->print('
'.($categories{$id.'_totaltype'} eq 'default'?&mt('default'):$categories{$id.'_total'}).' ');
+ if ($output) {
+ $r->print('
'.($categories{$id.'_totaltype'} eq 'default'?&mt('default'):$categories{$id.'_total'}));
+ }
+ }
+# Adjust total points
+ if ($categories{$id.'_totaltype'} eq 'typein') {
+ $totalpossible=1.*$categories{$id.'_total'};
+ }
+ if ($output) {
+ $r->print(''.&mt('Adjusted raw points: [_1]/[_2]',&numberout($totalcorrect),&numberout($totalpossible)).'
');
}
# Calculation
- $r->print(' ');
+ if ($output) { $r->print(''); }
foreach my $calcrule (split(/\,/,$categories{$id.'_calculations'})) {
- $r->print('');
+ if ($output) { $r->print(' '); }
my ($code,$value)=split(/\:/,$calcrule);
- $r->print(&pretty_prt_rule($cangrade,$id,$code,$value));
+ if ($output) { $r->print(&pretty_prt_rule($cangrade,$id,$code,$value)); }
if ($cangrade) {
- $r->print(' '.&mt('Delete').' ');
+ if ($output) { $r->print(' '.&mt('Delete').' '); }
}
- $r->print(' ');
- }
- $r->print(' ');
- if ($cangrade) {
- $r->print(' '.&new_calc_rule_form($id));
+ if ($code eq 'capabove') {
+ if ($totalpossible>0) {
+ if ($totalcorrect/$totalpossible>$value/100.) {
+ $totalcorrect=$totalpossible*$value/100.;
+ }
+ }
+ } elsif ($code eq 'capbelow') {
+ if ($totalpossible>0) {
+ if ($totalcorrect/$totalpossible<$value/100.) {
+ $totalcorrect=$totalpossible*$value/100.;
+ }
+ }
+ } elsif ($code eq 'droplow') {
+ ($totalpossible,$totalcorrect,@individual)=&drop(0,0,$value,@individual);
+ } elsif ($code eq 'drophigh') {
+ ($totalpossible,$totalcorrect,@individual)=&drop(1,0,$value,@individual);
+ } elsif ($code eq 'droplowperc') {
+ ($totalpossible,$totalcorrect,@individual)=&drop(0,1,$value,@individual);
+ } elsif ($code eq 'drophighperc') {
+ ($totalpossible,$totalcorrect,@individual)=&drop(1,1,$value,@individual);
+ }
+ if ($output) { $r->print(''); }
+ }
+# Re-adjust total points if force total
+ if ($categories{$id.'_totaltype'} eq 'typein') {
+ $totalpossible=1.*$categories{$id.'_total'};
+ }
+
+ if ($output) {
+ $r->print('');
+ if ($cangrade) { $r->print(' '.&new_calc_rule_form($id)); }
+ $r->print(''.&mt('Calculated points: [_1]/[_2]',&numberout($totalcorrect),&numberout($totalpossible)).'
');
+ $r->print(' ');
}
- $r->print(' ');
-
+#
+# Prepare for export
+#
# Weight
+ my $weight=$categories{$id.'_weight'};
+ unless (1.*$weight>0) { $weight=0; }
if ($cangrade) {
- $r->print('
'.
+ if ($output) {
+ $r->print(' '.
' ');
+ '" value="'.&Apache::lonhtmlcommon::entity_encode($weight).'" />');
+ }
} else {
- $r->print('
'.$categories{$id.'_weight'}.' ');
+ if ($output) {
+ $r->print('
'.$weight.' ');
+ }
}
# Achieved
- $r->print('
');
- if ($cangrade) {
- $r->print(''.
- ''.&mt('percent').' '.
- ''.&mt('points').' '.
+ my $type=$categories{$id.'_displayachieved'};
+ unless (($type eq 'percent') || ($type eq 'points')) { $type='points'; }
+ if ($output) { $r->print(''); }
+ if ($cangrade) {
+ if ($output) {
+ $r->print(''.
+ ''.&mt('percent').' '.
+ ''.&mt('points').' '.
' ');
- } else {
- if ($categories{$id.'_displayachieved'} eq 'percent') {
- $r->print(&mt('percent'));
+ }
+ }
+ if ($output) {
+ $r->print('');
+ if ($type eq 'percent') {
+ my $perc='---';
+ if ($totalpossible) {
+ $perc=100.*$totalcorrect/$totalpossible;
+ }
+ $r->print(&mt('[_1] percent',&numberout($perc)));
} else {
- $r->print(&mt('points'));
+ $r->print(&mt('[_1]/[_2] points',&numberout($totalcorrect),&numberout($totalpossible)));
}
+ $r->print('
');
}
- $r->print(' ');
+ if ($output) { $r->print(' '); }
- return ($value,$weight);
+ return ($totalcorrect,$totalpossible,$type,$weight);
}
#
+# Drop folders and problems
+#
+
+sub drop {
+ my ($high,$percent,$n,@individual)=@_;
+# Sort assignments by points or percent
+ my @newindividual=sort {
+ my ($pa,$ca)=split(/\:/,$a);
+ my ($pb,$cb)=split(/\:/,$b);
+ if ($percent) {
+ my $perca=0;
+ if ($pa>0) { $perca=$ca/$pa; }
+ my $percb=0;
+ if ($pb>0) { $percb=$cb/$pb; }
+ $perca<=>$percb;
+ } else {
+ $ca<=>$cb;
+ }
+ } @individual;
+# Drop the ones we don't want
+ if ($#newindividual>=$n) {
+ if ($high) {
+ splice(@newindividual,$#newindividual+1-$n,$n);
+ } else {
+ splice(@newindividual,0,$n);
+ }
+ } else {
+ @newindividual=();
+ }
+# Re-calculate how many points possible and achieved
+ my $newpossible=0;
+ my $newcorrect=0;
+ for my $score (@newindividual) {
+ my ($thispossible,$thiscorrect)=(split(/\:/,$score));
+ $newpossible+=$thispossible;
+ $newcorrect+=$thiscorrect;
+ }
+ return ($newpossible,$newcorrect,@newindividual);
+}
+#
# Bottom line with grades
#
sub bottom_line_category {
- my ($r,$cangrade,$sum,$total)=@_;
+ my ($r,$cangrade,$perc)=@_;
$r->print(&Apache::loncommon::start_data_table_row());
if ($cangrade) {
$r->print('
'.&mt('Create New Category').' ');
}
- $r->print('
'.&mt('Current:').$sum.' '.&mt('Total:').$total.' ');
+ $r->print('
'.&mt('Total: [_1] percent',&numberout($perc)).' ');
}
+sub numberout {
+ my ($number)=@_;
+ my $printout=sprintf("%.3f", $number);
+ $printout=~s/0+$//;
+ $printout=~s/\.$//;
+ return $printout;
+}
#
# Make one new category
#
@@ -759,8 +895,10 @@ sub make_new_category {
sub category_rule_codes {
return &Apache::lonlocal::texthash(
- 'droplow' => 'Drop N lowest grade assignments',
- 'drophigh' => 'Drop N highest grade assignments',
+ 'droplowperc' => 'Drop N lowest grade percentage problems/folders',
+ 'drophighperc' => 'Drop N highest grade percentage problems/folderss',
+ 'droplow' => 'Drop N lowest point problems/folders',
+ 'drophigh' => 'Drop N highest point problems/folders',
'capabove' => 'Cap percentage above N percent',
'capbelow' => 'Cap percentage below N percent');
}
@@ -844,6 +982,7 @@ sub set_category_rules {
sub add_category_content {
my ($id,$cangrade,$newcontent,%categories)=@_;
unless ($cangrade) { return %categories; }
+ &Apache::lonnet::logthis("In here $newcontent");
my %newcontent=($newcontent => 1);
foreach my $current (split(/\,/,$categories{$id.'_content'})) {
$newcontent{$current}=1;