'."\n";
return $result;
}
@@ -1598,7 +1612,6 @@ KEYWORDS
}
my %record = &Apache::lonnet::restore($symb,$env{'request.course.id'},$udom,$uname);
-
my ($partlist,$handgrade,$responseType) = &response_type($url,$symb);
# Display student info
@@ -2122,6 +2135,8 @@ sub saveHandGrade {
my @parts_graded;
my %newrecord = ();
my ($pts,$wgt) = ('','');
+ my %aggregate = ();
+ my $aggregateflag = 0;
foreach my $new_part (split(/:/,$env{'form.partlist'.$newflg})) {
#collaborator may vary for different parts
if ($submitter && $new_part ne $part) { next; }
@@ -2141,6 +2156,21 @@ sub saveHandGrade {
}
$newrecord{'resource.'.$new_part.'.regrader'}=
"$env{'user.name'}:$env{'user.domain'}";
+ my @partids = ("$new_part");
+ my %last_resets = ();
+ &get_last_resets($symb,$env{'request.course.id'},\%last_resets,\@partids);
+ my ($totaltries,$aggtries,$solvedstatus);
+ $totaltries = $record{'resource.'.$part.'.tries'};
+ if ($last_resets{$new_part}) {
+ $aggtries = &get_num_tries(\%record,$last_resets{$new_part},$new_part);
+ } else {
+ $aggtries = $totaltries;
+ }
+ $solvedstatus = $record{'resource.'.$new_part.'.solved'};
+ if ($aggtries > 0) {
+ &decrement($symb,$new_part,\%aggregate,$aggtries,$totaltries,$solvedstatus);
+ $aggregateflag = 1;
+ }
} elsif ($dropMenu eq '') {
$pts = ($env{'form.GD_BOX'.$newflg.'_'.$new_part} ne '' ?
$env{'form.GD_BOX'.$newflg.'_'.$new_part} :
@@ -2189,9 +2219,75 @@ sub saveHandGrade {
&Apache::lonnet::cstore(\%newrecord,$symb,
$env{'request.course.id'},$domain,$stuname);
}
+ if ($aggregateflag) {
+ &Apache::lonnet::cinc('nohist_resourcetracker',\%aggregate,
+ $env{'course.'.$env{'request.course.id'}.'.domain'},
+ $env{'course.'.$env{'request.course.id'}.'.num'});
+ }
return '',$pts,$wgt;
}
+# ----------- Provides number of tries since last reset.
+sub get_num_tries {
+ my ($record,$last_reset,$part) = @_;
+ my $timestamp = '';
+ my $num_tries = 0;
+ if ($$record{'version'}) {
+ for (my $version=$$record{'version'};$version>=1;$version--) {
+ if (exists($$record{$version.':resource.'.$part.'.solved'})) {
+ $timestamp = $$record{$version.':timestamp'};
+ if ($timestamp > $last_reset) {
+ $num_tries ++;
+ } else {
+ last;
+ }
+ }
+ }
+ }
+ return $num_tries;
+}
+
+# ----------- Determine decrements required in aggregate totals
+sub decrement_aggs {
+ my ($symb,$part,$aggregate,$aggtries,$totaltries,$solvedstatus) = @_;
+ my %decrement = (
+ attempts => 0,
+ users => 0,
+ correct => 0
+ );
+ $decrement{'attempts'} = $aggtries;
+ if ($solvedstatus =~ /^correct/) {
+ $decrement{'correct'} = 1;
+ }
+ if ($aggtries == $totaltries) {
+ $decrement{'users'} = 1;
+ }
+ foreach my $type (keys (%decrement)) {
+ $$aggregate{$symb."\0".$part."\0".$type} = -$decrement{$type};
+ }
+ return;
+}
+
+# ----------- Determine timestamps for last reset of aggregate totals for parts
+sub get_last_resets {
+ my ($symb,$courseid,$last_resets,$partids) =@_;
+ my $cdom = $env{'course.'.$courseid.'.domain'};
+ my $cname = $env{'course.'.$courseid.'.num'};
+ my %resethash = &Apache::lonnet::restore($symb,'nohist_resourcetracker',$cdom,$cname);
+ if ($resethash{'version'}) {
+ foreach my $part (@{$partids}) {
+ $$last_resets{$part} = '';
+ for (my $version=$resethash{'version'};$version>=1;$version--) {
+ if (exists($resethash{$version.':'.$part."\0".'prev_attempts'})) {
+ $$last_resets{$part} = $resethash{$version.':timestamp'};
+ last;
+ }
+ }
+ }
+ }
+ return;
+}
+
# ----------- Handles creating versions for portfolio files as answers
sub version_portfiles {
my ($record, $parts_graded, $courseid, $symb, $domain, $stuname, $v_flag) = @_;
@@ -2381,7 +2477,7 @@ sub viewgrades_js {
if (selval[2].selected) {
document.classgrade["GD_"+user+'_'+partid+"_tries"].value = "0";
}
- }
+ }
}
function resetEntry(numpart) {
@@ -2514,11 +2610,13 @@ sub viewgrades {
'
No.
'.
'
'.&nameUserString('header')."
\n";
my (@parts) = sort(&getpartlist($url,$symb));
+ my @partids = ();
foreach my $part (@parts) {
my $display=&Apache::lonnet::metadata($url,$part.'.display');
$display =~ s|^Number of Attempts|Tries |; # makes the column narrower
if (!$display) { $display = &Apache::lonnet::metadata($url,$part.'.name'); }
my ($partid) = &split_part_type($part);
+ push(@partids, $partid);
my $display_part=&get_display_part($partid,$url,$symb);
if ($display =~ /^Partial Credit Factor/) {
$result.='
';
+ # retrieve last reset information
+ my %last_resets = ();
+ &get_last_resets($symb,$env{'request.course.id'},\%last_resets,\@partids);
+
#get info for each student
#list all the students - with points and grade status
my (undef,undef,$fullname) = &getclasslist($env{'form.section'},'1');
@@ -2539,7 +2641,7 @@ sub viewgrades {
foreach (sort {lc($$fullname{$a}) cmp lc($$fullname{$b}) } keys %$fullname) {
$ctr++;
$result.=&viewstudentgrade($url,$symb,$env{'request.course.id'},
- $_,$$fullname{$_},\@parts,\%weight,$ctr);
+ $_,$$fullname{$_},\@parts,\%weight,$ctr,\%last_resets);
}
$result.='
';
$result.=''."\n";
@@ -2556,10 +2658,11 @@ sub viewgrades {
#--- call by previous routine to display each student
sub viewstudentgrade {
- my ($url,$symb,$courseid,$student,$fullname,$parts,$weight,$ctr) = @_;
+ my ($url,$symb,$courseid,$student,$fullname,$parts,$weight,$ctr,$last_resets) = @_;
my ($uname,$udom) = split(/:/,$student);
$student=~s/:/_/;
my %record=&Apache::lonnet::restore($symb,$courseid,$udom,$uname);
+ my %aggregates = ();
my $result='
'.
''.
"\n".$ctr.'
'.
@@ -2569,7 +2672,21 @@ sub viewstudentgrade {
foreach my $apart (@$parts) {
my ($part,$type) = &split_part_type($apart);
my $score=$record{"resource.$part.$type"};
- $result.='