'.
'';
@@ -1346,6 +1352,14 @@ sub gradeBox {
my $result=''."\n";
my $display_part=&get_display_part($partid,undef,$symb);
+
+ my %last_resets = &get_last_resets($symb,$env{'request.course.id'},
+ [$partid]);
+ my $aggtries = $$record{'resource.'.$partid.'.tries'};
+ if ($last_resets{$partid}) {
+ $aggtries = &get_num_tries($record,$last_resets{$partid},$partid);
+ }
+
$result.=''.
'Part: '.$display_part.' Points: | '."\n";
@@ -1384,7 +1398,11 @@ sub gradeBox {
$result.=''."\n".
''."\n".
''."\n";
+ $$record{'resource.'.$partid.'.solved'}.'" />'."\n".
+ ''."\n".
+ ''."\n";
$result.=' | '."\n";
return $result;
}
@@ -1593,7 +1611,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
@@ -2117,6 +2134,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; }
@@ -2136,6 +2155,21 @@ sub saveHandGrade {
}
$newrecord{'resource.'.$new_part.'.regrader'}=
"$env{'user.name'}:$env{'user.domain'}";
+ my $totaltries = $record{'resource.'.$part.'.tries'};
+
+ my %last_resets = &get_last_resets($symb,$env{'request.course.id'},
+ [$new_part]);
+ my $aggtries =$totaltries;
+ if ($last_resets{$new_part}) {
+ $aggtries = &get_num_tries(\%record,$last_resets{$new_part},
+ $new_part);
+ }
+
+ my $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} :
@@ -2184,9 +2218,73 @@ 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,$partids) =@_;
+ my %last_resets;
+ my $cdom = $env{'course.'.$courseid.'.domain'};
+ my $cname = $env{'course.'.$courseid.'.num'};
+ my @keys;
+ foreach my $part (@{$partids}) {
+ push(@keys,"$symb\0$part\0resettime");
+ }
+ my %results=&Apache::lonnet::get('nohist_resourcetracker',\@keys,
+ $cdom,$cname);
+ foreach my $part (@{$partids}) {
+ $last_resets{$part}=$results{"$symb\0$part\0resettime"};
+ }
+ return %last_resets;
+}
+
# ----------- Handles creating versions for portfolio files as answers
sub version_portfiles {
my ($record, $parts_graded, $courseid, $symb, $domain, $stuname, $v_flag) = @_;
@@ -2376,7 +2474,7 @@ sub viewgrades_js {
if (selval[2].selected) {
document.classgrade["GD_"+user+'_'+partid+"_tries"].value = "0";
}
- }
+ }
}
function resetEntry(numpart) {
@@ -2509,11 +2607,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.='Score Part: '.$display_part.
@@ -2527,6 +2627,9 @@ sub viewgrades {
}
$result.=' | ';
+ my %last_resets =
+ &get_last_resets($symb,$env{'request.course.id'},\@partids);
+
#get info for each student
#list all the students - with points and grade status
my (undef,undef,$fullname) = &getclasslist($env{'form.section'},'1');
@@ -2534,7 +2637,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";
@@ -2551,10 +2654,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=' |