--- loncom/homework/grades.pm 2002/07/25 21:25:38 1.41 +++ loncom/homework/grades.pm 2002/07/30 19:59:58 1.43 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # The LON-CAPA Grading handler # -# $Id: grades.pm,v 1.41 2002/07/25 21:25:38 ng Exp $ +# $Id: grades.pm,v 1.43 2002/07/30 19:59:58 ng Exp $ # # Copyright Michigan State University Board of Trustees # @@ -131,7 +131,7 @@ sub response_type { my %seen = (); my (@partlist,%handgrade); foreach (split(/,/,&Apache::lonnet::metadata($url,'packages'))) { - if (/^\w+response_\d{1,2}.*/) { + if (/^\w+response_\d+.*/) { my ($responsetype,$part) = split(/_/,$_,2); my ($partid,$respid) = split(/_/,$part); $handgrade{$part} = $responsetype.':'.($allkeys =~ /parameter_$part\_handgrade/ ? 'yes' : 'no'); @@ -158,7 +158,7 @@ sub listStudents { for (sort keys(%$handgrade)) { my ($responsetype,$handgrade)=split(/:/,$$handgrade{$_}); $ENV{'form.handgrade'} = 'yes' if ($handgrade eq 'yes'); - $result.='Part id: '.$_.''. + $result.='Part id: '.(split(/_/))[0].''. 'Type: '.$responsetype.''. 'Handgrade: '.$handgrade.''; } @@ -196,7 +196,7 @@ ENDTABLEST ' Select  Username '. ' Fullname  Domain '; foreach (sort(@$partlist)) { - $result.=' Part ID '.$_.' Status '; + $result.=' Part ID '.(split(/_/))[0].' Status '; } $request->print($result.''."\n"); @@ -206,7 +206,7 @@ ENDTABLEST my $statusflg = ''; foreach (keys(%status)) { $statusflg = 1 if ($status{$_} ne 'nothing'); - my ($foo,$partid,$foo) = split(/\./,$_); + my ($foo,$partid,$foo1) = split(/\./,$_); if ($status{'resource.'.$partid.'.submitted_by'} ne '') { $statusflg = ''; $request->print('\n"; - } else { - #$result.="$stuname:$part:$type:unchanged $oldscore to $newscore:
\n"; - } - } - } - if ( scalar(keys(%newrecord)) > 0 ) { - $newrecord{'resource.regrader'}="$ENV{'user.name'}:$ENV{'user.domain'}"; -# &Apache::lonnet::cstore(\%newrecord,$symb,$courseid,$domain,$stuname); - - $result.="Stored away ".scalar(keys(%newrecord))." elements.
\n"; - } - return $result; -} - sub print_hash { my ($request, $hash) = @_; $request->print(''); @@ -480,11 +431,12 @@ KEYWORDS # Student info $request->print(($counter == 0 ? '' : '
')); - my $fullname = ($ENV{'form.fullname'} ne '' ? $ENV{'form.fullname'} : &get_fullname($uname,$udom)); +# my $fullname = ($ENV{'form.fullname'} ne '' ? $ENV{'form.fullname'} : &get_fullname($uname,$udom)); my $result='
KeyValue
'. '
'; - $result.='
Fullname: '.$fullname. + $result.=''; - $result.=''."\n"; $result.=''. + $result.=''. ''. ''; } @@ -976,10 +928,7 @@ sub view_edit_entire_class_form { foreach (sort (@$sections)) { $result.= ''."\n"; } - $result.= '
Fullname: '.$ENV{'form.fullname'}. +# $result.=''; if ($ENV{'form.handgrade'} eq 'yes') { @@ -604,8 +556,8 @@ KEYWORDS $result.='
Fullname: '.$fullname. '   Username: '.$uname. '   Domain: '.$udom.'
'; # display radio buttons in a nice table 10 across while ($ctr<=$wgt) { $result.= '\n"; $result.=(($ctr+1)%10 == 0 ? '' : ''); @@ -614,18 +566,18 @@ KEYWORDS $result.='
'.$ctr."
'; $result.='
 or /'.$wgt.' '.$wgtmsg.' '; - $result.=''."  \n"; @@ -809,7 +761,7 @@ sub processHandGrade { my $statusflg = ''; foreach (keys(%status)) { $statusflg = 1 if ($status{$_} ne 'nothing'); - my ($foo,$partid,$foo) = split(/\./,$_); + my ($foo,$partid,$foo1) = split(/\./,$_); $statusflg = '' if ($status{'resource.'.$partid.'.submitted_by'} ne ''); } next if ($statusflg eq ''); @@ -845,11 +797,11 @@ sub saveHandGrade { # my %record=&Apache::lonnet::restore($symb,$ENV{'request.course.id'},$domain,$stuname); my %newrecord; foreach (split(/:/,$ENV{'form.partlist'.$newflg})) { - if ($ENV{'form.GRADE_SEL'.$newflg.'_'.$_} eq 'excused') { + if ($ENV{'form.GD_SEL'.$newflg.'_'.$_} eq 'excused') { $newrecord{'resource.'.$_.'.solved'} = 'excused'; } else { - my $pts = ($ENV{'form.GRADE_BOX'.$newflg.'_'.$_} ne '' ? - $ENV{'form.GRADE_BOX'.$newflg.'_'.$_} : $ENV{'form.RADVAL'.$newflg.'_'.$_}); + my $pts = ($ENV{'form.GD_BOX'.$newflg.'_'.$_} ne '' ? + $ENV{'form.GD_BOX'.$newflg.'_'.$_} : $ENV{'form.RADVAL'.$newflg.'_'.$_}); if ($pts eq '') { &userError($request,'No point was assigned for part id '.$_.' and for username '.$stuname.'.'); return 'error'; @@ -906,7 +858,7 @@ sub gradingmenu { my ($responsetype,$handgrade)=split(/:/,$$handgrade{$_}); $resptype = $responsetype; $hdgrade = $handgrade if ($handgrade eq 'yes'); - $result.='
Part id: '.$_.'
Part ID: '.(split(/_/))[0].'Type: '.$responsetype.'Handgrade: '.$handgrade.'
'."\n"; $result.='
'."\n"; @@ -1067,8 +1016,9 @@ sub verifyReceipt_form { return $result; } -sub viewgrades { - my ($request) = @_; +sub viewgrades_js { + my ($request) = shift; + $request->print(< function viewOneStudent(user) { @@ -1076,38 +1026,160 @@ sub viewgrades { document.onestudent.submit(); } - function writePoint(partid,weight,point) { + var radioButton = eval("document.classgrade.RADVAL_"+partid); + var textbox = eval("document.classgrade.TEXTVAL_"+partid); + if (point == "textval") { + var point = eval("document.classgrade.TEXTVAL_"+partid+".value"); + if (isNaN(point) || point < 0) { + alert("A number equal or greater than 0 is expected. Entered value = "+point); + var resetbox = false; + for (var i=0; i VIEWJAVASCRIPT +} + +sub viewgrades { + my ($request) = shift; + &viewgrades_js($request); my ($symb,$url) = ($ENV{'form.symb'},$ENV{'form.url'}); - $request->print ('

Manual Grading

'); + my $result='

Manual Grading

'; - my $result=''; - $result.=''."\n"; - my ($partlist,$handgrade) = &response_type($ENV{'form.url'}); - my %weight = (); - for (sort keys(%$handgrade)) { - my ($responsetype,$handgrade)=split(/:/,$$handgrade{$_}); - my ($partid,$respid) = split (/_/); - my $wgt = &Apache::lonnet::EXT('resource.'.$partid.'.weight',$symb); - $weight{$partid} = $wgt eq '' ? '1' : $wgt; - $result.=''. - ''. - ''."\n"; - } - $request->print($result.'
Resource: '.$ENV{'form.url'}. - '
Part id: '.$partid.'Type: '.$responsetype.'Handgrade: '.$handgrade.'
'."\n"); + $result.='Resource: '.$ENV{'form.url'}.''."\n"; #view individual student submission form - called using Javascript viewOneStudent - $result = '
'."\n". + $result.= ''."\n". ''."\n". ''."\n". ''."\n". @@ -1120,26 +1192,52 @@ VIEWJAVASCRIPT ''."\n". ''."\n". ''."\n"; - $result.='To assign the same score for all the students use the radio buttons or box below. '. - 'To assign individual score fill in the score for each student in the table below.
'; + + $result.='To assign the same score for all the students use the radio buttons or '. + 'text box below. To assign scores individually fill in the score boxes for '. + 'each student in the table below. A score that has already '. + 'been graded does not get changed using the radio buttons or text box. '. + 'If needed, it has to be changed individually.'; + + my ($partlist,$handgrade) = &response_type($ENV{'form.url'}); + my %weight = (); + my $ctsparts = 0; $result.=''; - for (sort keys (%weight)) { + for (sort keys(%$handgrade)) { + my ($responsetype,$handgrade)=split(/:/,$$handgrade{$_}); + my ($partid,$respid) = split (/_/); + my $wgt = &Apache::lonnet::EXT('resource.'.$partid.'.weight',$symb); + $weight{$partid} = $wgt eq '' ? '1' : $wgt; + + $result.=''."\n"; + $result.='
Part ID: '.$partid.'   '; + $result.=''; my $ctr = 0; - $result.=''."\n"; + $result.= ''."\n"; + $ctsparts++; } - $result.='
Part '.$_.''; - $result.=''; # display radio buttons in a nice table 10 across - while ($ctr<=$weight{$_}) { - $result.= '\n"; $result.=(($ctr+1)%10 == 0 ? '' : ''); $ctr++; } $result.='
'.$ctr."
'; + $result.= '
or /'. + $weight{$partid}.' (problem weight)
'; + $result.='
'; + $result.='    '; +# $result.=''."\n"; + $result.= ''."\n"; - $result.= ''."\n". - '
'."\n". + $result.= '
'."\n". ''. ''."\n"; #get list of parts for this problem @@ -1151,10 +1249,11 @@ VIEWJAVASCRIPT if ($display =~ /^Partial Credit Factor/) { $_ = $display; my ($partid) = /.*?(\d+).*/; - $result.=''."\n"; + $result.=''."\n"; next; } - $display =~ s/Problem Status/Grade Status/; + $display =~ s/Problem Status/Grade Status
/; $result.=''."\n"; } $result.=''; @@ -1163,7 +1262,7 @@ VIEWJAVASCRIPT my $ctr = 0; foreach ( sort(@{ $$classlist{$ENV{'form.section'}} }) ) { (my $username = $_) = split(/:/); - $result.=''."\n"; + $result.=''."\n"; $result.=&viewstudentgrade($url,$symb,$ENV{'request.course.id'}, $_,$$fullname{$_},\@parts,\%weight); $ctr++; @@ -1187,20 +1286,24 @@ sub viewstudentgrade { my $score=$record{"resource.$part.$type"}; next if $type eq 'tries'; if ($type eq 'awarded') { - my $pts = $score*$$weight{$part}; - $result.=''."\n"; -# $result.=''."\n"; -# } elsif ($type eq 'tries') { -# $result.=''."\n"; + my $pts = $score eq '' ? '' : $score*$$weight{$part}; + $result.=''."\n"; + $result.=''."\n"; } elsif ($type eq 'solved') { my ($status,$foo)=split(/_/,$score,2); - $result.="\n"; } @@ -1214,25 +1317,143 @@ sub editgrades { my ($request) = @_; my $symb=$ENV{'form.symb'}; - if ($symb eq '') { $request->print("Unable to handle ambiguous references:$symb:$ENV{'form.url'}"); return ''; } - my $url=$ENV{'form.url'}; + my $url =$ENV{'form.url'}; + my $result='

Current Grade Status

'; + $result.='Resource: '.$ENV{'form.url'}.'
'."\n"; + $result.='Section: '.$ENV{'form.section'}.''."\n"; + $result.= &show_grading_menu_form ($symb,$url); + $result.= '
UsernameFullnameDomainScore Part '.$partid.'
(weight = '.$weight{$partid}.')
Score Part '.$partid.'
(weight = '. + $weight{$partid}.')
'.$display.'
'.$score.' '."\n"; + $result.='
'."\n"; + if ($updateflag) { + $newrecord{'resource.regrader'}="$ENV{'user.name'}:$ENV{'user.domain'}"; + &Apache::lonnet::cstore(\%newrecord,$symb,$ENV{'request.course.id'}, + $udom,$user); + } + } + $result .= '
'."\n"; + $result.= ''. + ''."\n"; + + my %scoreptr = ( + 'correct' =>'correct_by_override', + 'incorrect'=>'incorrect_by_override', + 'excused' =>'excused', + 'ungraded' =>'ungraded_attempted', + 'nothing' => '', + ); + my ($classlist,$seclist,$ids,$stusec,$fullname) = &getclasslist($ENV{'form.section'},'0'); - my $result.=''."\n". - ''."\n". - ''."\n". - ''."\n". - '
'."\n"; - - my (@parts) = &getpartlist($url); - my ($classlist) = &getclasslist($ENV{'form.section'},'0'); - foreach my $student ( sort(@{ $$classlist{$ENV{'form.section'}} }) ) { - $result.=&setstudentgrade($url,$symb,$ENV{'request.course.id'},$student,@parts); + my (@partid); + my %weight = (); + my ($i,$ctr) = (0,0); + while ($ctr < $ENV{'form.totalparts'}) { + my $partid = $ENV{'form.partid_'.$ctr}; + push @partid,$partid; + my $wgt = &Apache::lonnet::EXT('resource.'.$partid.'.weight',$symb); + $weight{$partid} = $wgt eq '' ? '1' : $wgt; + $ctr++; + $result .= ''; } + $result .= ''; + foreach (@partid) { + $result .= ''. + ''; + } + $result .= ''."\n"; + + for ($i=0; $i<$ENV{'form.total'}; $i++) { + my $user = $ENV{'form.ctr'.$i}; + my %newrecord; + my $updateflag = 0; + my @userdom = grep /^$user:/,keys %$classlist; + my ($foo,$udom) = split(/:/,$userdom[0]); + + $result .= ''; + + foreach (@partid) { + my $old_aw = $ENV{'form.GD_'.$user.'_'.$_.'_aw_s'}; + my $old_part = $old_aw eq '' ? '' : $old_aw/$weight{$_}; + my $old_score = $scoreptr{$ENV{'form.GD_'.$user.'_'.$_.'_sv_s'}}; + + my $awarded = $ENV{'form.GD_'.$user.'_'.$_.'_aw'}; + my $partial = $awarded eq '' ? '' : $awarded/$weight{$_}; + my $score; + if ($partial eq '') { + $score = $scoreptr{$ENV{'form.GD_'.$user.'_'.$_.'_sv_s'}}; + } elsif ($partial > 0) { + $score = 'correct_by_override'; + } elsif ($partial == 0) { + $score = 'incorrect_by_override'; + } + $score = 'excused' if (($ENV{'form.GD_'.$user.'_'.$_.'_sv'} eq 'excused') && + ($score ne 'excused')); + $result .= ''. + ''; + + next if ($old_part eq $partial && $old_score eq $score); + + $updateflag = 1; + $newrecord{'resource.'.$_.'.awarded'} = $partial if $partial ne ''; + $newrecord{'resource.'.$_.'.solved'} = $score; - $result.='
UsernameFullname Part ID '.$partid. + ' (Weight = '.$weight{$partid}.')
 Old Score  New Score 
'.$user.' '. + $$fullname{$userdom[0]}.' '.$old_aw.' '.$awarded. + ($score eq 'excused' ? $score : '').' 
'; + } + $result .= '
'."\n"; return $result; } + +#FIXME need to look at the metadata spec on what type of data to accept and provide an +#interface based on that, also do that to above function. +sub setstudentgrade { + my ($url,$symb,$courseid,$student,@parts) = @_; + my $result =''; + my ($stuname,$domain) = split(/:/,$student); + my %record=&Apache::lonnet::restore($symb,$courseid,$domain,$stuname); + my %newrecord; + + foreach my $part (@parts) { + my ($temp,$part,$type)=split(/_/,$part); + my $oldscore=$record{"resource.$part.$type"}; + my $newscore=$ENV{"form.GD.$student.$part.$type"}; + if ($type eq 'solved') { + my $update=0; + if ($newscore eq 'nothing' ) { + if ($oldscore ne '') { + $update=1; + $newscore = ''; + } + } elsif ($oldscore !~ m/^$newscore/) { + $update=1; + $result.="Updating $stuname to $newscore
\n"; + if ($newscore eq 'correct') { $newscore = 'correct_by_override'; } + if ($newscore eq 'incorrect') { $newscore = 'incorrect_by_override'; } + if ($newscore eq 'excused') { $newscore = 'excused'; } + if ($newscore eq 'ungraded') { $newscore = 'ungraded_attempted'; } + } else { + #$result.="$stuname:$part:$type:unchanged $oldscore to $newscore:
\n"; + } + if ($update) { $newrecord{"resource.$part.$type"}=$newscore; } + } else { + if ($oldscore ne $newscore) { + $newrecord{"resource.$part.$type"}=$newscore; + $result.="Updating $student"."'s status for $part.$type to $newscore
\n"; + } else { + #$result.="$stuname:$part:$type:unchanged $oldscore to $newscore:
\n"; + } + } + } + if ( scalar(keys(%newrecord)) > 0 ) { + $newrecord{'resource.regrader'}="$ENV{'user.name'}:$ENV{'user.domain'}"; +# &Apache::lonnet::cstore(\%newrecord,$symb,$courseid,$domain,$stuname); + + $result.="Stored away ".scalar(keys(%newrecord))." elements.
\n"; + } + return $result; +} + + sub sub_page_js { my $request = shift; $request->print(<