--- loncom/homework/grades.pm 2007/10/26 00:32:06 1.466
+++ loncom/homework/grades.pm 2007/11/05 10:19:03 1.479
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# The LON-CAPA Grading handler
#
-# $Id: grades.pm,v 1.466 2007/10/26 00:32:06 albertel Exp $
+# $Id: grades.pm,v 1.479 2007/11/05 10:19:03 foxr Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -42,6 +42,7 @@ use Apache::Constants qw(:common);
use Apache::lonlocal;
use Apache::lonenc;
use String::Similarity;
+use Data::Dumper;
use LONCAPA;
use POSIX qw(floor);
@@ -865,7 +866,7 @@ LISTJAVASCRIPT
my $saveStatus = $stu_status eq '' ? 'Active' : $stu_status;
$env{'form.Status'} = $saveStatus;
$gradeTable.=''."\n".
- ''."\n".
+ ''."\n".
''."\n".
' '."\n".
' Grading Increments:
');
+ $request->print('');#LC_grade_show_user_body
+ $request->print('');#LC_grade_show_user
# print end of form
@@ -3149,14 +3174,12 @@ sub viewgrades {
$sectionClass=&mt('Students in Section(s) [_1]',$section_display).'';
}
$result.='
'.&mt('Assign Common Grade To [_1]',$sectionClass);
- $result.= '
'."\n".
- '
';
+ $result.= &Apache::loncommon::start_data_table();
#radio buttons/text box for assigning points for a section or class.
#handles different parts of a problem
my ($partlist,$handgrade,$responseType) = &response_type($symb);
my %weight = ();
my $ctsparts = 0;
- $result.='
';
my %seen = ();
my @part_response_id = &flatten_responseType($responseType);
foreach my $part_response_id (@part_response_id) {
@@ -3168,12 +3191,14 @@ sub viewgrades {
my $wgt = &Apache::lonnet::EXT('resource.'.$partid.'.weight',$symb);
$weight{$partid} = $wgt eq '' ? '1' : $wgt;
+ $result.=&Apache::loncommon::start_data_table_row().'
';
$result.=''."\n";
$result.=''."\n";
my $display_part=&get_display_part($partid,$symb);
- $result.='
Part: '.$display_part.' Point:
';
+ $result.=
+ 'Part: '.$display_part.' Point:
';
$result.='
';
my $ctr = 0;
while ($ctr<=$weight{$partid}) { # display radio buttons in a nice table 10 across
@@ -3188,26 +3213,27 @@ sub viewgrades {
$partid.'" size="4" '.'onChange="javascript:writePoint(\''.
$partid.'\','.$weight{$partid}.',\'textval\')" /> /'.
$weight{$partid}.' (problem weight)'."\n";
- $result.= '
'."\n".
+ $result.=&Apache::loncommon::end_data_table()."\n".
'';
$result.='';
+ 'onClick="javascript:resetEntry('.$ctsparts.');" />';
#table listing all the students in a section/class
#header of table
$result.= '
Assign Grade to Specific Students in '.$sectionClass;
- $result.= '
';
+ $result.=&Apache::loncommon::end_data_table_header_row();
my %last_resets =
&get_last_resets($symb,$env{'request.course.id'},\@partids);
@@ -3248,7 +3274,7 @@ sub viewgrades {
$result.=&viewstudentgrade($symb,$env{'request.course.id'},
$_,$$fullname{$_},\@parts,\%weight,$ctr,\%last_resets);
}
- $result.='
';
+ $result.=&Apache::loncommon::end_data_table();
$result.=''."\n";
$result.=''."\n";
@@ -3271,7 +3297,7 @@ sub viewstudentgrade {
my ($uname,$udom) = split(/:/,$student);
my %record=&Apache::lonnet::restore($symb,$courseid,$udom,$uname);
my %aggregates = ();
- my $result='
'.
+ my $result=&Apache::loncommon::start_data_table_row().'
'.
''.
"\n".$ctr.'
'.
'
'."\n";
}
}
- $result.='
';
+ $result.=&Apache::loncommon::end_data_table_row();
return $result;
}
@@ -3337,15 +3363,14 @@ sub editgrades {
my $symb=&get_symb($request);
my $section_display = join (", ",&Apache::loncommon::get_env_multiple('form.section'));
- my $title='
'."\n";
- my $noupdate;
+ $result .= &Apache::loncommon::end_data_table_header_row().
+ &Apache::loncommon::start_data_table_header_row().
+ $header.
+ &Apache::loncommon::end_data_table_header_row();
+ my @noupdate;
my ($updateCtr,$noupdateCtr) = (1,1);
for ($i=0; $i<$env{'form.total'}; $i++) {
my $line;
@@ -3407,7 +3433,9 @@ sub editgrades {
my $usec=$classlist->{"$uname:$udom"}[5];
if (!&canmodify($usec)) {
my $numcols=scalar(@partid)*4+2;
- $noupdate.=$line."
Not allowed to modify student
";
+ push(@noupdate,
+ $line."
".
+ &mt('Not allowed to modify student')."
");
next;
}
my %aggregate = ();
@@ -3476,7 +3504,7 @@ sub editgrades {
'
'.$awarded.'
';
}
}
- $line.=''."\n";
+ $line.="\n";
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
@@ -3509,10 +3537,13 @@ sub editgrades {
}
}
- $result.='
'.
+ &mt('Number of records updated = [_1] for [quant,_2,student].',
+ $rec_update,$count).' '.
+ ''.&mt('Total number of students = [_1]',$env{'form.total'}).
+ '
';
return $title.$msg.$result;
}
@@ -4273,30 +4316,33 @@ sub displaySubByDates {
my $isCODE=0;
my $isTask = ($symb =~/\.task$/);
if (exists($record->{'resource.CODE'})) { $isCODE=1; }
- my $studentTable='
'.
- '
'.
- '
Date/Time
'.
- ($isCODE?'
CODE
':'').
- '
Submission
'.
- '
Status
';
+ my $studentTable=&Apache::loncommon::start_data_table().
+ &Apache::loncommon::start_data_table_header_row().
+ '
'.&mt('Date/Time').'
'.
+ ($isCODE?'
'.&mt('CODE').'
':'').
+ '
'.&mt('Submission').'
'.
+ '
'.&mt('Status').'
'.
+ &Apache::loncommon::end_data_table_header_row();
my ($version);
my %mark;
my %orders;
$mark{'correct_by_student'} = $checkIcon;
if (!exists($$record{'1:timestamp'})) {
- return ' Nothing submitted - no attempts ';
+ return ' '.&mt('Nothing submitted - no attempts').' ';
}
my $interaction;
for ($version=1;$version<=$$record{'version'};$version++) {
- my $timestamp = scalar(localtime($$record{$version.':timestamp'}));
+ my $timestamp =
+ &Apache::lonlocal::locallocaltime($$record{$version.':timestamp'});
if (exists($$record{$version.':resource.0.version'})) {
$interaction = $$record{$version.':resource.0.version'};
}
my $where = ($isTask ? "$version:resource.$interaction"
: "$version:resource");
- $studentTable.='
';
+ $studentTable.=&Apache::loncommon::end_data_table();
return $studentTable;
}
@@ -5071,7 +5117,8 @@ sub username_to_idmap {
sub scantron_fixup_scanline {
my ($scantron_config,$scan_data,$line,$whichline,$field,$args)=@_;
-
+
+
if ($field eq 'ID') {
if (length($args->{'newid'}) > $$scantron_config{'IDlength'}) {
return ($line,1,'New value too large');
@@ -5102,28 +5149,54 @@ sub scantron_fixup_scanline {
$$scantron_config{'CODElength'})=$args->{'CODE'};
}
} elsif ($field eq 'answer') {
+ &scantron_get_maxbubble(); # Need the bubble counter info.
my $length=$scantron_config->{'Qlength'};
my $off=$scantron_config->{'Qoff'};
my $on=$scantron_config->{'Qon'};
my $answer=${off}x$length;
- if ($args->{'response'} eq 'none') {
- &scan_data($scan_data,
- "$whichline.no_bubble.".$args->{'question'},'1');
- } else {
- if ($on eq 'letter') {
- my @alphabet=('A'..'Z');
- $answer=$alphabet[$args->{'response'}];
- } elsif ($on eq 'number') {
- $answer=$args->{'response'}+1;
- if ($answer == 10) { $answer = '0'; }
+ my $question_number = $args->{'question'} -1;
+ my $first_position = $first_bubble_line{$question_number};
+ my $bubble_count = $bubble_lines_per_response{$question_number};
+ my $bubbles_per_line= $$scantron_config{'Qlength'};
+ my $final_answer;
+ if ($$scantron_config{'Qon'} eq 'letter' ||
+ $$scantron_config{'Qon'} eq 'number') {
+ $bubbles_per_line = 10;
+ }
+ if (defined $args->{'response'}) {
+
+ if ($args->{'response'} eq 'none') {
+ &scan_data($scan_data,
+ "$whichline.no_bubble.".$args->{'question'},'1');
} else {
- substr($answer,$args->{'response'},1)=$on;
+ my ($bubble_line, $bubble_number) = split(/:/,$args->{'response'});
+ if ($on eq 'letter') {
+ my @alphabet=('A'..'Z');
+ $answer=$alphabet[$bubble_number];
+ } elsif ($on eq 'number') {
+ $answer=$args->$bubble_number+1;
+ if ($answer == 10) { $answer = '0'; }
+ } else {
+ substr($answer,$args->{'response'},1)=$on;
+ }
+ my $before = Dumper($scan_data);
+ &scan_data($scan_data,
+ "$whichline.no_bubble.".$args->{'question'},undef,'1');
+ my $after = Dumper($scan_data);
+ for (my $l = 0; $l < $bubble_count; $l++) {
+ if ($l eq $bubble_line) {
+ $final_answer .= $answer;
+ } else {
+ $final_answer .= ' ';
+ }
+ }
}
- &scan_data($scan_data,
- "$whichline.no_bubble.".$args->{'question'},undef,'1');
+ # $where=$length*($args->{'question'}-1)+$scantron_config->{'Qstart'};
+ #substr($line,$where-1,$length)=$answer;
+ substr($line,
+ $scantron_config->{'Qstart'}+$first_position-1,
+ $bubbles_per_line) = $final_answer;
}
- my $where=$length*($args->{'question'}-1)+$scantron_config->{'Qstart'};
- substr($line,$where-1,$length)=$answer;
}
return $line;
}
@@ -5216,6 +5289,7 @@ sub scan_data {
sub scantron_parse_scanline {
my ($line,$whichline,$scantron_config,$scan_data,$just_header)=@_;
+
my %record;
my $questions=substr($line,$$scantron_config{'Qstart'}-1); # Answers
my $data=substr($line,0,$$scantron_config{'Qstart'}-1); # earlier stuff
@@ -5254,7 +5328,9 @@ sub scantron_parse_scanline {
my $questnum=0;
my $ansnum =1; # Multiple 'answer lines'/question.
- while ($questions) {
+ chomp($questions); # Get rid of any trailing \n.
+ $questions =~ s/\r$//; # Get rid of trailing \r too (MAC or Win uploads).
+ while (length($questions)) {
my $answers_needed = $bubble_lines_per_response{$questnum};
my $answer_length = $$scantron_config{'Qlength'} * $answers_needed;
@@ -5297,9 +5373,8 @@ sub scantron_parse_scanline {
}
if (!&scan_data($scan_data,"$whichline.no_bubble.$questnum")) {
push(@{$record{"scantron.missingerror"}},$questnum);
- $ansnum += $answers_needed;
+ # $ansnum += $answers_needed;
}
-
} else {
for (my $ans = 0; $ans < $answers_needed; $ans++) {
$record{"scantron.$ansnum.answer"} = substr($currentquest, $ans, 1);
@@ -6445,6 +6520,7 @@ ENDSCRIPT
foreach my $question (@{$arg}) {
my $selected = &get_response_bubbles($scan_record, $question);
my @select_array = split(/:/,$selected);
+ &Apache::lonnet::logthis("Questnum: $question, bubbles: $selected scanline $i");
&scantron_bubble_selector($r,$scan_config,$question,
@select_array);
}
@@ -6457,7 +6533,8 @@ ENDSCRIPT
join(',',@{$arg}).'" />');
foreach my $question (@{$arg}) {
my $selected = &get_response_bubbles($scan_record, $question);
- &scantron_bubble_selector($r,$scan_config,$question);
+ my @select_array = split(/:/,$selected); # ought to be an array of empties.
+ &scantron_bubble_selector($r,$scan_config,$question, @select_array);
}
} else {
$r->print("\n
");
@@ -6477,7 +6554,7 @@ ENDSCRIPT
$r - Apache request object
$scan_config - hash from &get_scantron_config()
$quest - number of the bubble line to make a corrector for
- $lines - array of answer lines.
+ @lines - array of answer lines.
=cut
@@ -6498,6 +6575,7 @@ sub scantron_bubble_selector {
my $total_lines = $lines*2;
my @alphabet=('A'..'Z');
+
$r->print("
$quest
");
for (my $l = 0; $l < $lines; $l++) {
@@ -6531,9 +6609,10 @@ sub scantron_bubble_selector {
# multiline questions (different values e.g..).
for (my $i=0;$i<$max;$i++) {
+ my $value = "$l:$i"; # Relative bubble line #: Bubble in line.
$r->print("\n".
'