--- loncom/homework/grades.pm 2005/05/26 21:15:04 1.267
+++ loncom/homework/grades.pm 2005/10/04 17:02:41 1.292
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# The LON-CAPA Grading handler
#
-# $Id: grades.pm,v 1.267 2005/05/26 21:15:04 albertel Exp $
+# $Id: grades.pm,v 1.292 2005/10/04 17:02:41 albertel Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -152,6 +152,7 @@ sub get_display_part {
}
return $display;
}
+
#--- Show resource title
#--- and parts and response type
sub showResourceInfo {
@@ -284,6 +285,11 @@ sub cleanRecord {
}
$answer =~ s-\n- -g;
return '
'.&keywords_highlight($answer).'
';
+ } elsif ( $response eq 'organic') {
+ my $result='Smile representation: "'.$answer.'"';
+ my $jme=$record->{$version."resource.$partid.$respid.molecule"};
+ $result.=&Apache::chemresponse::jme_img($jme,$answer,400);
+ return $result;
}
return $answer;
}
@@ -328,7 +334,16 @@ COMMONJSFUNCTIONS
#--- section, ids and fullnames for each user.
sub getclasslist {
my ($getsec,$filterlist) = @_;
- $getsec = $getsec eq '' ? 'all' : $getsec;
+ my @getsec;
+ if (!ref($getsec)) {
+ if ($getsec ne '' && $getsec ne 'all') {
+ @getsec=($getsec);
+ }
+ } else {
+ @getsec=@{$getsec};
+ }
+ if (grep(/^all$/,@getsec)) { undef(@getsec); }
+
my $classlist=&Apache::loncoursedata::get_classlist();
# Bail out if we were unable to get the classlist
return if (! defined($classlist));
@@ -357,7 +372,7 @@ sub getclasslist {
}
$section = ($section ne '' ? $section : 'none');
if (&canview($section)) {
- if ($getsec eq 'all' || $getsec eq $section) {
+ if (!@getsec || grep(/^\Q$section\E$/,@getsec)) {
$sections{$section}++;
$fullnames{$student}=$fullname;
} else {
@@ -465,6 +480,10 @@ sub most_similar {
$uessay=~s/\W+/ /gs;
+# ignore empty submissions (occuring when only files are sent)
+
+ unless ($uessay=~/\w+/) { return ''; }
+
# these will be returned. Do not care if not at least 50 percent similar
my $limit=0.6;
my $sname='';
@@ -737,7 +756,7 @@ LISTJAVASCRIPT
if ($env{'form.showgrading'} eq 'yes' && $submitonly ne 'all') {
foreach (sort keys(%status)) {
next if (/^resource.*?submitted_by$/);
- $gradeTable.='
'.$status{$_}.'
'."\n";
+ $gradeTable.='
'.$status{$_}.'
'."\n";
}
}
# $gradeTable.='
' if ($ctr%2 ==1);
@@ -1346,16 +1365,24 @@ 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";
my $ctr = 0;
$result.='
'."\n"; # display radio buttons in a nice table 10 across
while ($ctr<=$wgt) {
- $result.= '
\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.='
';
+ 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 +2654,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,20 +2671,36 @@ 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";
+ $student=~s/:/_/; # colon doen't work in javascript for names
foreach my $apart (@$parts) {
my ($part,$type) = &split_part_type($apart);
my $score=$record{"resource.$part.$type"};
- $result.='
' : '');
$ptr++;
}
@@ -3332,7 +3486,11 @@ sub displayPage {
my $navmap = Apache::lonnavmaps::navmap->new();
my ($mapUrl, $id, $resUrl)=&Apache::lonnet::decode_symb($env{'form.page'});
my $map = $navmap->getResourceByUrl($resUrl); # add to navmaps
-
+ if (!$map) {
+ $request->print('Unable to view requested sequence. ('.$resUrl.')');
+ $request->print(&show_grading_menu_form($symb,$url));
+ return;
+ }
my $iterator = $navmap->getIterator($map->map_start(),
$map->map_finish());
@@ -3538,7 +3696,12 @@ sub updateGradeByPage {
my $navmap = Apache::lonnavmaps::navmap->new();
my ($mapUrl, $id, $resUrl) = &Apache::lonnet::decode_symb( $env{'form.page'});
my $map = $navmap->getResourceByUrl($resUrl); # add to navmaps
-
+ if (!$map) {
+ $request->print('Unable to grade requested sequence. ('.$resUrl.')');
+ my ($symb,$url)=&get_symb_and_url($request);
+ $request->print(&show_grading_menu_form($symb,$url));
+ return;
+ }
my $iterator = $navmap->getIterator($map->map_start(),
$map->map_finish());
@@ -3566,6 +3729,8 @@ sub updateGradeByPage {
my %newrecord=();
my @displayPts=();
+ my %aggregate = ();
+ my $aggregateflag = 0;
foreach my $partid (@{$parts}) {
my $newpts = $env{'form.GD_BOX'.$question.'_'.$partid};
my $oldpts = $env{'form.oldpts'.$question.'_'.$partid};
@@ -3592,6 +3757,14 @@ sub updateGradeByPage {
$newrecord{'resource.'.$partid.'.regrader'} = "$env{'user.name'}:$env{'user.domain'}";
$changeflag++;
$newpts = '';
+
+ my $aggtries = $env{'form.aggtries'.$question.'_'.$partid};
+ my $totaltries = $env{'form.totaltries'.$question.'_'.$partid};
+ my $solvedstatus = $env{'form.solved'.$question.'_'.$partid};
+ if ($aggtries > 0) {
+ &decrement_aggs($symbx,$partid,\%aggregate,$aggtries,$totaltries,$solvedstatus);
+ $aggregateflag = 1;
+ }
}
my $display_part=&get_display_part($partid,undef,
$curRes->symb());
@@ -3617,6 +3790,11 @@ sub updateGradeByPage {
&Apache::lonnet::cstore(\%newrecord,$symbx,$env{'request.course.id'},
$udom,$uname);
}
+ if ($aggregateflag) {
+ &Apache::lonnet::cinc('nohist_resourcetracker',\%aggregate,
+ $env{'course.'.$env{'request.course.id'}.'.domain'},
+ $env{'course.'.$env{'request.course.id'}.'.num'});
+ }
$studentTable.='
'.$displayPts[0].'
'.
'
'.$displayPts[1].'
'.
@@ -3718,6 +3896,7 @@ sub scantron_CODElist {
my $namechoice='';
foreach my $name (sort {uc($a) cmp uc($b)} @names) {
if ($name =~ /^error: 2 /) { next; }
+ if ($name =~ /^type\0/) { next; }
$namechoice.='';
}
$namechoice='';
@@ -3726,12 +3905,12 @@ sub scantron_CODElist {
sub scantron_CODEunique {
my $result='
- Yes
+ Yes
- No
+ No ';
return $result;
}
@@ -3781,8 +3960,8 @@ sub scantron_selectphase {
Options:
- Do only previously skipped records
- Remove all exisiting corrections
+ Do only previously skipped records
+ Remove all exisiting corrections
@@ -3961,7 +4140,14 @@ sub scantron_fixup_scanline {
&scan_data($scan_data,
"$whichline.no_bubble.".$args->{'question'},'1');
} else {
- substr($answer,$args->{'response'},1)=$on;
+ if ($on eq 'letter') {
+ my @alphabet=('A'..'Z');
+ $answer=$alphabet[$args->{'response'}];
+ } elsif ($on eq 'number') {
+ $answer=$args->{'response'}+1;
+ } else {
+ substr($answer,$args->{'response'},1)=$on;
+ }
&scan_data($scan_data,
"$whichline.no_bubble.".$args->{'question'},undef,'1');
}
@@ -3986,8 +4172,11 @@ sub scantron_parse_scanline {
my %record;
my $questions=substr($line,$$scantron_config{'Qstart'}-1);
my $data=substr($line,0,$$scantron_config{'Qstart'}-1);
- if ($$scantron_config{'CODElocation'} ne 0) {
- if ($$scantron_config{'CODElocation'} < 0) {
+ if (!($$scantron_config{'CODElocation'} eq 0 ||
+ $$scantron_config{'CODElocation'} eq 'none')) {
+ if ($$scantron_config{'CODElocation'} < 0 ||
+ $$scantron_config{'CODElocation'} eq 'letter' ||
+ $$scantron_config{'CODElocation'} eq 'number') {
$record{'scantron.CODE'}=substr($data,
$$scantron_config{'CODEstart'}-1,
$$scantron_config{'CODElength'});
@@ -4022,8 +4211,12 @@ sub scantron_parse_scanline {
substr($questions,0,$$scantron_config{'Qlength'})='';
if (length($currentquest) < $$scantron_config{'Qlength'}) { next; }
if ($$scantron_config{'Qon'} eq 'letter') {
- if (!$currentquest || $currentquest eq $$scantron_config{'Qoff'} ||
- $currentquest !~ /^[A-Z]$/) {
+ if ($currentquest eq '?') {
+ push(@{$record{'scantron.doubleerror'}},$questnum);
+ $record{"scantron.$questnum.answer"}='';
+ } elsif (!$currentquest
+ || $currentquest eq $$scantron_config{'Qoff'}
+ || $currentquest !~ /^[A-Z]$/) {
$record{"scantron.$questnum.answer"}='';
if (!&scan_data($scan_data,"$whichline.no_bubble.$questnum")) {
push(@{$record{"scantron.missingerror"}},$questnum);
@@ -4032,8 +4225,12 @@ sub scantron_parse_scanline {
$record{"scantron.$questnum.answer"}=$currentquest;
}
} elsif ($$scantron_config{'Qon'} eq 'number') {
- if (!$currentquest || $currentquest eq $$scantron_config{'Qoff'} ||
- $currentquest !~ /^\d$/) {
+ if ($currentquest eq '?') {
+ push(@{$record{'scantron.doubleerror'}},$questnum);
+ $record{"scantron.$questnum.answer"}='';
+ } elsif (!$currentquest
+ || $currentquest eq $$scantron_config{'Qoff'}
+ || $currentquest !~ /^\d$/) {
$record{"scantron.$questnum.answer"}='';
if (!&scan_data($scan_data,"$whichline.no_bubble.$questnum")) {
push(@{$record{"scantron.missingerror"}},$questnum);
@@ -4150,7 +4347,7 @@ sub scantron_process_corrections {
}
}
if ($err) {
- $r->print("Unable to accept last correction, an error occurred :$errmsg:");
+ $r->print("Unable to accept last correction, an error occurred :$errmsg:");
} else {
&scantron_put_line($scanlines,$scan_data,$which,$line,$skip);
&scantron_putfile($scanlines,$scan_data);
@@ -4204,14 +4401,26 @@ sub check_for_error {
sub scantron_warning_screen {
my ($button_text)=@_;
my $title=&Apache::lonnet::gettitle($env{'form.selectpage'});
+ my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
+ my $CODElist="a";
+ if ($scantron_config{'CODElocation'} &&
+ $scantron_config{'CODEstart'} &&
+ $scantron_config{'CODElength'}) {
+ $CODElist=$env{'form.scantron_CODElist'};
+ if ($CODElist eq '') { $CODElist='None'; }
+ $CODElist=
+ '
List of CODES to validate against:
'.
+ $CODElist.'
';
+ }
return (<
Please double check the information
below before clicking on '$button_text'
-
Sequence To be Graded:
$title
+
Sequence to be Graded:
$title
Data File that will be used:
$env{'form.scantron_selectfile'}
+$CODElist
@@ -4418,9 +4627,8 @@ sub lonnet_putfile {
my ($contents,$filename)=@_;
my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'};
my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'};
- my $docuhome=$env{'course.'.$env{'request.course.id'}.'.home'};
$env{'form.sillywaytopassafilearound'}=$contents;
- &Apache::lonnet::finishuserfileupload($docuname,$docudom,$docuhome,'sillywaytopassafilearound',$filename);
+ &Apache::lonnet::finishuserfileupload($docuname,$docudom,'sillywaytopassafilearound',$filename);
}
@@ -4588,19 +4796,24 @@ sub scantron_get_correction {
$r->print("
How should I handle this? \n");
$r->print("\n ");
my $i=0;
- if ($error eq 'incorrectCODE') {
+ if ($error eq 'incorrectCODE'
+ && $$scan_record{'scantron.CODE'}=~/\S/ ) {
my ($max,$closest)=&scantron_get_closely_matching_CODEs($arg,$$scan_record{'scantron.CODE'});
- foreach my $testcode (@{$closest}) {
- my $checked='';
- if (!$i) { $checked=' checked="on" '; }
- $r->print(" Use the similar CODE ".$testcode." instead.");
- $r->print("\n ");
- $i++;
+ if ($closest > 0) {
+ foreach my $testcode (@{$closest}) {
+ my $checked='';
+ if (!$i) { $checked=' checked="on" '; }
+ $r->print(" Use the similar CODE ".$testcode." instead.");
+ $r->print("\n ");
+ $i++;
+ }
}
}
- my $checked; if (!$i) { $checked=' checked="on" '; }
- $r->print(" Use the CODE ".$$scan_record{'scantron.CODE'}." that is was on the paper, ignoring the error.");
- $r->print("\n ");
+ if ($$scan_record{'scantron.CODE'}=~/\S/ ) {
+ my $checked; if (!$i) { $checked=' checked="on" '; }
+ $r->print(" Use the CODE ".$$scan_record{'scantron.CODE'}." that is was on the paper, ignoring the error.");
+ $r->print("\n ");
+ }
$r->print(<
@@ -4619,9 +4832,9 @@ ENDSCRIPT
"&scantron_CODElist=".&Apache::lonnet::escape($env{'form.scantron_CODElist'}).
"&curCODE=".&Apache::lonnet::escape($$scan_record{'scantron.CODE'}).
"&scantron_selectfile=".&Apache::lonnet::escape($env{'form.scantron_selectfile'});
- $r->print(" Select a CODE from the list of all CODEs and use it. Selected CODE is ");
+ $r->print("Select a CODE from the list of all CODEs and use it. Selected CODE is ");
$r->print("\n ");
- $r->print(" Use as the CODE.");
+ $r->print(" Use as the CODE.");
$r->print("\n