--- loncom/homework/grades.pm 2006/02/14 15:11:09 1.313 +++ loncom/homework/grades.pm 2006/02/27 02:06:52 1.319 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # The LON-CAPA Grading handler # -# $Id: grades.pm,v 1.313 2006/02/14 15:11:09 banghart Exp $ +# $Id: grades.pm,v 1.319 2006/02/27 02:06:52 bowersj2 Exp $ # # Copyright Michigan State University Board of Trustees # @@ -40,6 +40,7 @@ use Apache::lonmsg qw(:user_normal_msg); use Apache::Constants qw(:common); use Apache::lonlocal; use String::Similarity; +use POSIX qw(floor); my %oldessays=(); my %perm=(); @@ -467,6 +468,33 @@ sub jscriptNform { return $jscript; } +# Given the score (as a number [0-1] and the weight) what is the final +# point value? This function will round to the nearest tenth, third, +# or quarter if one of those is within the tolerance of .00001. +sub compute_points { + my ($score, $weight) = @_; + + my $tolerance = .00001; + my $points = $score * $weight; + + # Check for nearness to 1/x. + my $check_for_nearness = sub { + my ($factor) = @_; + my $num = ($points * $factor) + $tolerance; + my $floored_num = floor($num); + if ($num - $floored_num < 2 * $tolerance * $factor) { + return $floored_num / $factor; + } + return $points; + }; + + $points = $check_for_nearness->(10); + $points = $check_for_nearness->(3); + $points = $check_for_nearness->(4); + + return $points; +} + #------------------ End of general use routines -------------------- # @@ -1385,7 +1413,7 @@ SUBJAVASCRIPT #--- displays the grading box, used in essay type problem and grading by page/sequence sub gradeBox { - my ($request,$symb,$uname,$udom,$counter,$partid,$record) = @_; + my ($request,$symb,$uname,$udom,$counter,$partid,$record,$respid) = @_; my $checkIcon = '<img src="'.$request->dir_config('lonIconsURL'). '/check.gif" height="16" border="0" />'; my $wgt = &Apache::lonnet::EXT('resource.'.$partid.'.weight',$symb,$udom,$uname); @@ -1393,8 +1421,9 @@ sub gradeBox { '<font color="red">problem weight assigned by computer</font>'); $wgt = ($wgt > 0 ? $wgt : '1'); my $score = ($$record{'resource.'.$partid.'.awarded'} eq '' ? - '' : $$record{'resource.'.$partid.'.awarded'}*$wgt); + '' : compute_points($$record{'resource.'.$partid.'.awarded'},$wgt)); my $result='<input type="hidden" name="WGT'.$counter.'_'.$partid.'" value="'.$wgt.'" />'."\n"; + $result.='<br />'.$partid.' - '.$respid.'<br />'; my $display_part=&get_display_part($partid,undef,$symb); my %last_resets = &get_last_resets($symb,$env{'request.course.id'}, [$partid]); @@ -1443,19 +1472,23 @@ sub gradeBox { '<input type="hidden" name="aggtries'.$counter.'_'.$partid.'" value="'. $aggtries.'" />'."\n"; $result.='</td></tr></table>'."\n"; - my $files=&get_submitted_files($udom,$uname,$partid,$counter,$record); + $result.=&handbackBox($uname,$udom,$counter,$partid,$record,$respid); + return $result; +} +sub handbackBox { + my ($uname,$udom,$counter,$partid,$record,$respid) = @_; + my $files=&get_submitted_files($udom,$uname,$partid,$respid,$record); + my $result; if (@$files) { my $file_counter = 0; foreach my $file (@$files) { $result.=' Return commented document to student. <input type="file" name="part'.$partid.'_returndoc'; $result.=$file_counter.'" />'."\n"; - $result.='<input type="hidden" name="respid" value="'.$counter.'" />'; - $result.='<input type="hidden" name="returndocorig'.$file_counter.'" value="'.$file.'" />'; + $result.='<input type="hidden" name="respid" value="'.$respid.'" />'; + $result.='<input type="hidden" name="returndocorig'.$file_counter.'" value="'.$file.'" /><br />'; } } - - - return $result; + return $result; } sub show_problem { @@ -1797,22 +1830,13 @@ KEYWORDS $display_part.' <font color="#999999">( ID '.$respid. ' )</font> '; my $files=&get_submitted_files($udom,$uname,$partid,$respid,\%record); -# if ($record{"resource.$partid.$respid.portfiles"}) { -# my $file_url = '/uploaded/'.$udom.'/'.$uname.'/portfolio'; -# foreach my $file (split(',',$record{"resource.$partid.$respid.portfiles"})) { -# push(@files,$file_url.$file); -# } -# } -# if ($record{"resource.$partid.$respid.uploadedurl"}) { -# push(@files,$record{"resource.$partid.$respid.uploadedurl"}); -# } if (@$files) { $lastsubonly.='<br /><font color="red" size="1">Like all files provided by users, this file may contain virusses</font><br />'; my $file_counter = 0; foreach my $file (@$files) { $file_counter ++; &Apache::lonnet::allowuploaded('/adm/grades',$file); - $lastsubonly.='<br /><a href="'.$file.'" target="lonGRDs"><img src="'.&Apache::loncommon::icon($file).'" border=0"> '.$file.'</a>'; + $lastsubonly.='<br /><a href="'.$file.'" target="lonGRDs"><img src="'.&Apache::loncommon::icon($file).'" border="0"> '.$file.'</a>'; } $lastsubonly.='<br />'; } @@ -1890,15 +1914,18 @@ KEYWORDS my %seen = (); my @partlist; my @gradePartRespid; - for (sort keys(%$handgrade)) { - my ($partid,$respid) = split(/_/); - next if ($seen{$partid} > 0); + for my $part_resp(sort keys(%$handgrade)) { + my ($partid,$respid) = split(/_/, $part_resp); + #next if ($seen{$partid} > 0); + if ($seen{$partid} > 0) { + $request->print(&handbackBox($uname,$udom,$counter,$partid,\%record,$respid)); + next; + } $seen{$partid}++; - next if ($$handgrade{$_} =~ /:no$/ && $env{'form.lastSub'} =~ /^(hdgrade)$/); + next if ($$handgrade{$part_resp} =~ /:no$/ && $env{'form.lastSub'} =~ /^(hdgrade)$/); push @partlist,$partid; push @gradePartRespid,$partid.'.'.$respid; - - $request->print(&gradeBox($request,$symb,$uname,$udom,$counter,$partid,\%record)); + $request->print(&gradeBox($request,$symb,$uname,$udom,$counter,$partid,\%record,$respid)); } $result='<input type="hidden" name="partlist'.$counter. '" value="'.(join ":",@partlist).'" />'."\n"; @@ -2866,7 +2893,7 @@ sub viewstudentgrade { $aggregates{$part} = 1; } if ($type eq 'awarded') { - my $pts = $score eq '' ? '' : $score*$$weight{$part}; + my $pts = $score eq '' ? '' : compute_points($score,$$weight{$part}); $result.='<input type="hidden" name="'. 'GD_'.$student.'_'.$part.'_awarded_s" value="'.$pts.'" />'."\n"; $result.='<input type="text" name="'.