--- loncom/homework/grades.pm 2007/10/17 10:48:20 1.461 +++ loncom/homework/grades.pm 2007/10/26 00:27:55 1.465 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # The LON-CAPA Grading handler # -# $Id: grades.pm,v 1.461 2007/10/17 10:48:20 foxr Exp $ +# $Id: grades.pm,v 1.465 2007/10/26 00:27:55 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -1480,43 +1480,43 @@ INNERJS pDoc.write("<form action=\\"inactive\\" name=\\"msgcenter\\">"); pDoc.write("<input value=\\""+usrctr+"\\" name=\\"usrctr\\" type=\\"hidden\\">"); - pDoc.write("<h3><span class=\\"LC_info\\"> Compose Message for \"+fullname+\"</span></h3><br /><br />"); + pDoc.write("<h3><span class=\\"LC_info\\"> Compose Message for \"+fullname+\"<\\/span><\\/h3><br /><br />"); pDoc.write("<table border=0 width=100%><tr><td bgcolor=\\"#777777\\">"); pDoc.write("<table border=0 width=100%><tr bgcolor=\\"#ddffff\\">"); - pDoc.write("<td><b>Type</b></td><td><b>Include</b></td><td><b>Message</td></tr>"); + pDoc.write("<td><b>Type<\\/b><\\/td><td><b>Include<\\/b><\\/td><td><b>Message<\\/td><\\/tr>"); } function displaySubject(msg,shwsel) { pDoc = pWin.document; pDoc.write("<tr bgcolor=\\"#ffffdd\\">"); - pDoc.write("<td>Subject</td>"); - pDoc.write("<td align=\\"center\\"><input name=\\"subchk\\" type=\\"checkbox\\"" +shwsel+"></td>"); - pDoc.write("<td><input name=\\"msgsub\\" type=\\"text\\" value=\\""+msg+"\\"size=\\"60\\" maxlength=\\"80\\"></td></tr>"); + pDoc.write("<td>Subject<\\/td>"); + pDoc.write("<td align=\\"center\\"><input name=\\"subchk\\" type=\\"checkbox\\"" +shwsel+"><\\/td>"); + pDoc.write("<td><input name=\\"msgsub\\" type=\\"text\\" value=\\""+msg+"\\"size=\\"60\\" maxlength=\\"80\\"><\\/td><\\/tr>"); } function displaySavedMsg(ctr,msg,shwsel) { pDoc = pWin.document; pDoc.write("<tr bgcolor=\\"#ffffdd\\">"); - pDoc.write("<td align=\\"center\\">"+ctr+"</td>"); - pDoc.write("<td align=\\"center\\"><input name=\\"msgn"+ctr+"\\" type=\\"checkbox\\"" +shwsel+"></td>"); - pDoc.write("<td><textarea name=\\"msg"+ctr+"\\" cols=\\"60\\" rows=\\"3\\">"+msg+"</textarea></td></tr>"); + pDoc.write("<td align=\\"center\\">"+ctr+"<\\/td>"); + pDoc.write("<td align=\\"center\\"><input name=\\"msgn"+ctr+"\\" type=\\"checkbox\\"" +shwsel+"><\\/td>"); + pDoc.write("<td><textarea name=\\"msg"+ctr+"\\" cols=\\"60\\" rows=\\"3\\">"+msg+"<\\/textarea><\\/td><\\/tr>"); } function newMsg(newmsg,shwsel) { pDoc = pWin.document; pDoc.write("<tr bgcolor=\\"#ffffdd\\">"); - pDoc.write("<td align=\\"center\\">New</td>"); - pDoc.write("<td align=\\"center\\"><input name=\\"newmsgchk\\" type=\\"checkbox\\"" +shwsel+"></td>"); - pDoc.write("<td><textarea name=\\"newmsg\\" cols=\\"60\\" rows=\\"3\\" onchange=\\"javascript:this.form.newmsgchk.checked=true\\" >"+newmsg+"</textarea></td></tr>"); + pDoc.write("<td align=\\"center\\">New<\\/td>"); + pDoc.write("<td align=\\"center\\"><input name=\\"newmsgchk\\" type=\\"checkbox\\"" +shwsel+"><\\/td>"); + pDoc.write("<td><textarea name=\\"newmsg\\" cols=\\"60\\" rows=\\"3\\" onchange=\\"javascript:this.form.newmsgchk.checked=true\\" >"+newmsg+"<\\/textarea><\\/td><\\/tr>"); } function msgTail() { pDoc = pWin.document; - pDoc.write("</table>"); - pDoc.write("</td></tr></table> "); + pDoc.write("<\\/table>"); + pDoc.write("<\\/td><\\/tr><\\/table> "); pDoc.write("<input type=\\"button\\" value=\\"Save\\" onClick=\\"javascript:checkInput()\\"> "); pDoc.write("<input type=\\"button\\" value=\\"Cancel\\" onClick=\\"self.close()\\"><br /><br />"); - pDoc.write("</form>"); + pDoc.write("<\\/form>"); pDoc.write('$end_page_msg_central'); pDoc.close(); } @@ -1565,32 +1565,32 @@ INNERJS hDoc.$docopen; hDoc.write('$start_page_highlight_central'); hDoc.write("<form action=\\"inactive\\" name=\\"hlCenter\\">"); - hDoc.write("<h3><span class=\\"LC_info\\"> Keyword Highlight Options</span></h3><br /><br />"); + hDoc.write("<h3><span class=\\"LC_info\\"> Keyword Highlight Options<\\/span><\\/h3><br /><br />"); hDoc.write("<table border=0 width=100%><tr><td bgcolor=\\"#777777\\">"); hDoc.write("<table border=0 width=100%><tr bgcolor=\\"#ddffff\\">"); - hDoc.write("<td><b>Text Color</b></td><td><b>Font Size</b></td><td><b>Font Style</td></tr>"); + hDoc.write("<td><b>Text Color<\\/b><\\/td><td><b>Font Size<\\/b><\\/td><td><b>Font Style<\\/td><\\/tr>"); } function highlightbody(clrval,clrtxt,clrsel,szval,sztxt,szsel,syval,sytxt,sysel) { var hDoc = hwdWin.document; hDoc.write("<tr bgcolor=\\"#ffffdd\\">"); hDoc.write("<td align=\\"left\\">"); - hDoc.write("<input name=\\"kwdclr\\" type=\\"radio\\" value=\\""+clrval+"\\" "+clrsel+"> "+clrtxt+"</td>"); + hDoc.write("<input name=\\"kwdclr\\" type=\\"radio\\" value=\\""+clrval+"\\" "+clrsel+"> "+clrtxt+"<\\/td>"); hDoc.write("<td align=\\"left\\">"); - hDoc.write("<input name=\\"kwdsize\\" type=\\"radio\\" value=\\""+szval+"\\" "+szsel+"> "+sztxt+"</td>"); + hDoc.write("<input name=\\"kwdsize\\" type=\\"radio\\" value=\\""+szval+"\\" "+szsel+"> "+sztxt+"<\\/td>"); hDoc.write("<td align=\\"left\\">"); - hDoc.write("<input name=\\"kwdstyle\\" type=\\"radio\\" value=\\""+syval+"\\" "+sysel+"> "+sytxt+"</td>"); - hDoc.write("</tr>"); + hDoc.write("<input name=\\"kwdstyle\\" type=\\"radio\\" value=\\""+syval+"\\" "+sysel+"> "+sytxt+"<\\/td>"); + hDoc.write("<\\/tr>"); } function highlightend() { var hDoc = hwdWin.document; - hDoc.write("</table>"); - hDoc.write("</td></tr></table> "); + hDoc.write("<\\/table>"); + hDoc.write("<\\/td><\\/tr><\\/table> "); hDoc.write("<input type=\\"button\\" value=\\"Save\\" onClick=\\"javascript:updateChoice(1)\\"> "); hDoc.write("<input type=\\"button\\" value=\\"Cancel\\" onClick=\\"self.close()\\"><br /><br />"); - hDoc.write("</form>"); + hDoc.write("<\\/form>"); hDoc.write('$end_page_highlight_central'); hDoc.close(); } @@ -1960,7 +1960,7 @@ KEYWORDS # This is where output for one specific student would start my $bgcolor='#DDEEDD'; - if (int($counter/2) eq $counter) { $bgcolor='#DDDDEE'; } + if ($counter%2) { $bgcolor='#DDDDEE'; } $request->print("\n\n". '<p><table border="2"><tr><th bgcolor="'.$bgcolor.'">'.$env{'form.fullname'}.'</th></tr><tr><td bgcolor="'.$bgcolor.'">'); @@ -1990,60 +1990,13 @@ KEYWORDS '" value="'.$env{'form.fullname'}.'" />'."\n"; # If any part of the problem is an essay-response (handgraded), then check for collaborators - my @col_fullnames; - my ($classlist,$fullname); + my $fullname; + my $col_fullnames = []; if ($env{'form.handgrade'} eq 'yes') { - ($classlist,undef,$fullname) = &getclasslist('all','0'); - for (keys (%$handgrade)) { - my $ncol = &Apache::lonnet::EXT('resource.'.$_. - '.maxcollaborators', - $symb,$udom,$uname); - next if ($ncol <= 0); - s/\_/\./g; - next if ($record{'resource.'.$_.'.collaborators'} eq ''); - my @goodcollaborators = (); - my @badcollaborators = (); - foreach (split(/,?\s+/,$record{'resource.'.$_.'.collaborators'})) { - $_ =~ s/[\$\^\(\)]//g; - next if ($_ eq ''); - my ($co_name,$co_dom) = split /\@|:/,$_; - $co_dom = $udom if (! defined($co_dom) || $co_dom =~ /^domain$/i); - next if ($co_name eq $uname && $co_dom eq $udom); - # Doing this grep allows 'fuzzy' specification - my @Matches = grep /^$co_name:$co_dom$/i,keys %$classlist; - if (! scalar(@Matches)) { - push @badcollaborators,$_; - } else { - push @goodcollaborators, @Matches; - } - } - if (scalar(@goodcollaborators) != 0) { - $result.='<b>Collaborators: </b>'; - foreach (@goodcollaborators) { - my ($lastname,$givenn) = split(/,/,$$fullname{$_}); - push @col_fullnames, $givenn.' '.$lastname; - $result.=$$fullname{$_}.' '; - } - $result.='<br />'."\n"; - my ($part)=split(/\./,$_); - $result.='<input type="hidden" name="collaborator'.$counter. - '" value="'.$part.':'.(join ':',@goodcollaborators).'" />'. - "\n"; - } - if (scalar(@badcollaborators) > 0) { - $result.='<table border="0"><tr bgcolor="#ffbbbb"><td>'; - $result.='This student has submitted '; - $result.=(scalar(@badcollaborators) == 1) ? 'an invalid collaborator' : 'invalid collaborators'; - $result .= ': '.join(', ',@badcollaborators); - $result .= '</td></tr></table>'; - } - if (scalar(@badcollaborators > $ncol)) { - $result .= '<table border="0"><tr bgcolor="#ffbbbb"><td>'; - $result .= 'This student has submitted too many '. - 'collaborators. Maximum is '.$ncol.'.'; - $result .= '</td></tr></table>'; - } - } + (my $sub_result,$fullname,$col_fullnames)= + &check_collaborators($symb,$uname,$udom,\%record,$handgrade, + $counter); + $result.=$sub_result; } $request->print($result."\n"); @@ -2179,16 +2132,16 @@ KEYWORDS if ($env{'form.handgrade'} eq 'yes') { my ($lastname,$givenn) = split(/,/,$env{'form.fullname'}); my $msgfor = $givenn.' '.$lastname; - if (scalar(@col_fullnames) > 0) { - my $lastone = pop @col_fullnames; - $msgfor .= ', '.(join ', ',@col_fullnames).' and '.$lastone.'.'; + if (scalar(@$col_fullnames) > 0) { + my $lastone = pop(@$col_fullnames); + $msgfor .= ', '.(join ', ',@$col_fullnames).' and '.$lastone.'.'; } $msgfor =~ s/\'/\\'/g; #' stupid emacs - no! javascript $result='<input type="hidden" name="includemsg'.$counter.'" value="" />'."\n". '<input type="hidden" name="newmsg'.$counter.'" value="" />'."\n"; $result.=' <a href="javascript:msgCenter(document.SCORE,'.$counter. ',\''.$msgfor.'\');" target="_self">'. - &mt('Compose message to student').(scalar(@col_fullnames) >= 1 ? 's' : '').'</a><label> ('. + &mt('Compose message to student').(scalar(@$col_fullnames) >= 1 ? 's' : '').'</a><label> ('. &mt('incl. grades').' <input type="checkbox" name="withgrades'.$counter.'" /></label>)'. '<img src="'.$request->dir_config('lonIconsURL'). '/mailbkgrd.gif" width="14" height="10" name="mailicon'.$counter.'" />'."\n". @@ -2266,6 +2219,62 @@ KEYWORDS return ''; } +sub check_collaborators { + my ($symb,$uname,$udom,$record,$handgrade,$counter) = @_; + my ($result,@col_fullnames); + my ($classlist,undef,$fullname) = &getclasslist('all','0'); + foreach my $part (keys(%$handgrade)) { + my $ncol = &Apache::lonnet::EXT('resource.'.$part. + '.maxcollaborators', + $symb,$udom,$uname); + next if ($ncol <= 0); + $part =~ s/\_/\./g; + next if ($record->{'resource.'.$part.'.collaborators'} eq ''); + my (@good_collaborators, @bad_collaborators); + foreach my $possible_collaborator + (split(/,?\s+/,$record->{'resource.'.$part.'.collaborators'})) { + $possible_collaborator =~ s/[\$\^\(\)]//g; + next if ($possible_collaborator eq ''); + my ($co_name,$co_dom) = split(/\@|:/,$possible_collaborator); + $co_dom = $udom if (! defined($co_dom) || $co_dom =~ /^domain$/i); + next if ($co_name eq $uname && $co_dom eq $udom); + # Doing this grep allows 'fuzzy' specification + my @matches = grep(/^\Q$co_name\E:\Q$co_dom\E$/i, + keys(%$classlist)); + if (! scalar(@matches)) { + push(@bad_collaborators, $possible_collaborator); + } else { + push(@good_collaborators, @matches); + } + } + if (scalar(@good_collaborators) != 0) { + $result.='<b>Collaborators: </b>'; + foreach my $name (@good_collaborators) { + my ($lastname,$givenn) = split(/,/,$$fullname{$name}); + push(@col_fullnames, $givenn.' '.$lastname); + $result.=$fullname->{$name}.' '; + } + $result.='<br />'."\n"; + my ($part)=split(/\./,$_); + $result.='<input type="hidden" name="collaborator'.$counter. + '" value="'.$part.':'.(join ':',@good_collaborators).'" />'. + "\n"; + } + if (scalar(@bad_collaborators) > 0) { + $result.='<div class="LC_error">'; + $result.=&mt('This student has submitted [quant,_1,invalid collaborator]: [_2]',scalar(@bad_collaborators),join(', ',@bad_collaborators)); + $result .= '</div>'; + } + if (scalar(@bad_collaborators > $ncol)) { + $result .= '<div class="LC_error">'; + $result .= &mt('This student has submitted too many '. + 'collaborators. Maximum is [_1].',$ncol); + $result .= '</div>'; + } + } + return ($result,$fullname,\@col_fullnames); +} + #--- Retrieve the last submission for all the parts sub get_last_submission { my ($returnhash)=@_; @@ -3912,7 +3921,8 @@ sub csvuploadassign { if ($wgt) { $entries{$fields{$dest}}=~s/\s//g; my $pcr=$entries{$fields{$dest}} / $wgt; - my $award='correct_by_override'; + my $award=($pcr == 0) ? 'incorrect_by_override' + : 'correct_by_override'; $grades{"resource.$part.awarded"}=$pcr; $grades{"resource.$part.solved"}=$award; $points{$part}=1; @@ -5383,20 +5393,22 @@ sub scantron_parse_scanline { my $first_answer = $ansnum; for (my $ans =0; $ans < $answers_needed; $ans++) { - $record{"scantron.$ansnum.answer"} = ''; - $ans++; + my $item = $first_answer+$ans; + $record{"scantron.$item.answer"} = ''; } my @ans=@array; - my $i=length($ans[0]);shift(@ans); + my $i=0; + my $increment = 0; while ($#ans) { - $i+=length($ans[0])+1; - my $line = $i/$$scantron_config{'Qlength'} + $first_answer; + $i+=length($ans[0]) + $increment; + my $line = int($i/$$scantron_config{'Qlength'} + $first_answer); my $bubble = $i%$$scantron_config{'Qlength'}; - $record{"scantron.$line.answer"}.=$alphabet[$bubble]; shift(@ans); + $increment = 1; } + $ansnum += $answers_needed; } } } @@ -6492,8 +6504,8 @@ sub scantron_bubble_selector { if ($l != 0) { $r->print('<tr>'); } + my @selected = split(//,$lines[$l]); for (my $i=0;$i<$max;$i++) { - my @selected = split(//,$lines[$l]); $r->print("\n".'<td align="center">'); if ($selected[0] eq $alphabet[$i]) { $r->print('X'); @@ -7192,10 +7204,6 @@ sub grading_menu { my $probTitle = &Apache::lonnet::gettitle($symb); my ($table,undef,$hdgrade) = &showResourceInfo($symb,$probTitle); - # - # Define menu data - $env{'form.probTitle'} = &Apache::lonnet::gettitle($symb); - my ($table) = &showResourceInfo($symb,$env{'form.probTitle'}); $request->print($table); my %fields = ('symb'=>&Apache::lonenc::check_encrypt($symb), 'handgrade'=>$hdgrade,