Filename of scoring office file: '.$file_selector.'
+
'.&mt('Filename of scoring office file: [_1]',$file_selector).'
-
+
'.&Apache::loncommon::end_data_table_row().'
'.&Apache::loncommon::end_data_table().'
@@ -5098,7 +5065,7 @@ sub get_scantron_config {
$config{'IDstart'}=$config[5];
$config{'IDlength'}=$config[6];
$config{'Qstart'}=$config[7];
- $config{'Qlength'}=$config[8];
+ $config{'Qlength'}=$config[8];
$config{'Qoff'}=$config[9];
$config{'Qon'}=$config[10];
$config{'PaperID'}=$config[11];
@@ -5184,8 +5151,6 @@ 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');
@@ -5216,58 +5181,28 @@ 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 $length=$scantron_config->{'Qlength'};
my $off=$scantron_config->{'Qoff'};
my $on=$scantron_config->{'Qon'};
- 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 $answer=${off}x($bubbles_per_line*$bubble_count);
- 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');
+ 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'; }
} else {
- 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= $bubble_number+1;
- if ($answer == 10) { $answer = '0'; }
- } else {
- substr($answer,$bubble_number+$bubble_line*$bubbles_per_line,1)=$on;
- $final_answer = $answer;
- }
- &scan_data($scan_data,
- "$whichline.no_bubble.".$args->{'question'},undef,'1');
-
- # Positional notation already has the right final answer length..
-
- if (($on eq 'letter') || ($on eq 'number')) {
- for (my $l = 0; $l < $bubble_count; $l++) {
- if ($l eq $bubble_line) {
- $final_answer .= $answer;
- } else {
- $final_answer .= ' ';
- }
- }
- }
+ substr($answer,$args->{'response'},1)=$on;
}
- # $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*$length) = $final_answer;
+ &scan_data($scan_data,
+ "$whichline.no_bubble.".$args->{'question'},undef,'1');
}
+ my $where=$length*($args->{'question'}-1)+$scantron_config->{'Qstart'};
+ substr($line,$where-1,$length)=$answer;
}
return $line;
}
@@ -5301,6 +5236,39 @@ sub scan_data {
return $scan_data->{$filename.'_'.$key};
}
+# ----- These first few routines are general use routines.----
+
+# Return the number of occurences of a pattern in a string.
+
+sub occurence_count {
+ my ($string, $pattern) = @_;
+
+ my @matches = ($string =~ /$pattern/g);
+
+ return scalar(@matches);
+}
+
+
+# Take a string known to have digits and convert all the
+# digits into letters in the range J,A..I.
+
+sub digits_to_letters {
+ my ($input) = @_;
+
+ my @alphabet = ('J', 'A'..'I');
+
+ my @input = split(//, $input);
+ my $output ='';
+ for (my $i = 0; $i < scalar(@input); $i++) {
+ if ($input[$i] =~ /\d/) {
+ $output .= $alphabet[$input[$i]];
+ } else {
+ $output .= $input[$i];
+ }
+ }
+ return $output;
+}
+
=pod
=item scantron_parse_scanline
@@ -5403,13 +5371,12 @@ sub scantron_parse_scanline {
$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;
-
-
+ my $answer_length = ($$scantron_config{'Qlength'} * $answers_needed)
+ || 1;
$questnum++;
my $currentquest = substr($questions,0,$answer_length);
- $questions = substr($questions,0,$answer_length)='';
+ $questions = substr($questions,$answer_length);
if (length($currentquest) < $answer_length) { next; }
# Qon letter implies for each slot in currentquest we have:
@@ -5419,7 +5386,6 @@ sub scantron_parse_scanline {
if ($$scantron_config{'Qon'} eq 'letter') {
-
if ($currentquest =~ /\?/
|| $currentquest =~ /\*/
|| (&occurence_count($currentquest, "[A-Z]") > 1)) {
@@ -5448,7 +5414,8 @@ sub scantron_parse_scanline {
}
} else {
for (my $ans = 0; $ans < $answers_needed; $ans++) {
- $record{"scantron.$ansnum.answer"} = substr($currentquest, $ans, 1);
+ my $bubble = substr($currentquest, $ans, 1);
+ $record{"scantron.$ansnum.answer"} = $bubble;
$ansnum++;
}
}
@@ -5515,10 +5482,9 @@ sub scantron_parse_scanline {
push(@{$record{"scantron.missingerror"}},$questnum);
}
- # If the bubble is not the last position, there will be
- # 2 elements. If it is the last position, there will be 1 element.
- } elsif (scalar(@array) le 2) {
+
+ } elsif (scalar(@array) eq 2) {
my $location = length($array[0]);
my $line_num = int($location / $$scantron_config{'Qlength'});
@@ -5704,7 +5670,7 @@ sub scantron_process_corrections {
&scantron_fixup_scanline(\%scantron_config,$scan_data,$line,
$which,'answer',
{ 'question'=>$question,
- 'response'=>$env{"form.scantron_correct_Q_$question"}});
+ 'response'=>$env{"form.scantron_correct_Q_$question"}});
if ($err) { last; }
}
}
@@ -5809,7 +5775,7 @@ sub remember_current_skipped {
sub check_for_error {
my ($r,$result)=@_;
if ($result ne 'ok' && $result ne 'not_found' ) {
- $r->print("An error occurred ($result) when trying to Remove the existing corrections.");
+ $r->print(&mt("An error occurred ([_1]) when trying to remove the existing corrections.",$result));
}
}
@@ -5833,25 +5799,25 @@ sub scantron_warning_screen {
$CODElist=$env{'form.scantron_CODElist'};
if ($env{'form.scantron_CODElist'} eq '') { $CODElist='None'; }
$CODElist=
- '
List of CODES to validate against:
'.
+ '
'.&mt('List of CODES to validate against:').'
'.
$env{'form.scantron_CODElist'}.'
';
}
- return (<
-Please double check the information
- below before clicking on '$button_text'
+
+'.&mt('Please double check the information below before clicking on \'[_1]\'',&mt($button_text)).'
-
Sequence to be Graded:
$title
-
Data File that will be used:
$env{'form.scantron_selectfile'}
-$CODElist
+
'.&mt('Sequence to be Graded:').'
'.$title.'
+
'.&mt('Data File that will be used:').'
'.$env{'form.scantron_selectfile'}.'
+'.$CODElist.'
-
If this information is correct, please click on '$button_text'.
-
If something is incorrect, please click the 'Grading Menu' button to start over.
+
'.&mt('If this information is correct, please click on \'[_1]\'.',&mt($button_text)).'
+
'.&mt('If something is incorrect, please click the \'Grading Menu\' button to start over.').'
');
$r->rflush();
my $which="scantron_validate_".$validate_phases[$currentphase];
{
@@ -5997,12 +5963,12 @@ sub scantron_validate_file {
}
if (!$stop) {
my $warning=&scantron_warning_screen('Start Grading');
- $r->print(<
-$warning
-
+ $r->print('
+'.&mt('Validation process complete.').'
+'.$warning.'
+
-STUFF
+');
} else {
$r->print('');
@@ -6010,15 +5976,15 @@ STUFF
}
if ($stop) {
if ($validate_phases[$currentphase] eq 'sequence') {
- $r->print('');
- $r->print(' this error ');
+ $r->print('');
+ $r->print(' '.&mt('this error').' ');
- $r->print("
Or click the 'Grading Menu' button to start over.
");
+ $r->print("
".&mt("Or click the 'Grading Menu' button to start over.")."
");
} else {
- $r->print('');
- $r->print(' using corrected info ');
- $r->print("");
- $r->print(" this scanline saving it for later.");
+ $r->print('');
+ $r->print(' '.&mt('using corrected info').' ');
+ $r->print("");
+ $r->print(" ".&mt("this scanline saving it for later."));
}
}
$r->print(" ".&show_grading_menu_form($symb));
@@ -6079,7 +6045,10 @@ sub scantron_remove_scan_data {
}
my $result;
if (@todelete) {
- $result=&Apache::lonnet::del('nohist_scantrondata',\@todelete,$cdom,$cname);
+ $result = &Apache::lonnet::del('nohist_scantrondata',
+ \@todelete,$cdom,$cname);
+ } else {
+ $result = 'ok';
}
return $result;
}
@@ -6499,30 +6468,32 @@ sub scantron_get_correction {
#to show both the current line and the previous one and allow skipping
#the previous one or the current one
- $r->print("
An error was detected ($error)");
if ( $$scan_record{'scantron.PaperID'} =~ /\S/) {
- $r->print(" for PaperID ".
- $$scan_record{'scantron.PaperID'}." \n");
+ $r->print("
".&mt("An error was detected ($error)".
+ " for PaperID [_1]",
+ $$scan_record{'scantron.PaperID'})."
\n");
} else {
- $r->print(" in scanline $i
".
- $line."
\n");
- }
- my $message="
The ID on the form is ".
- $$scan_record{'scantron.ID'}." \n".
- "The name on the paper is ".
- $$scan_record{'scantron.LastName'}.",".
- $$scan_record{'scantron.FirstName'}."
";
+ $r->print("
".&mt("An error was detected ($error)".
+ " in scanline [_1]
[_2]
",
+ $i,$line)." \n");
+ }
+ my $message="
".&mt("The ID on the form is [_1] ".
+ "The name on the paper is [_2],[_3]",
+ $$scan_record{'scantron.ID'},
+ $$scan_record{'scantron.LastName'},
+ $$scan_record{'scantron.FirstName'})."
";
$r->print(''."\n");
$r->print(''."\n");
if ($error =~ /ID$/) {
if ($error eq 'incorrectID') {
- $r->print("The encoded ID is not in the classlist\n");
+ $r->print("
".&mt("The encoded ID is not in the classlist").
+ "
\n");
} elsif ($error eq 'duplicateID') {
- $r->print("The encoded ID has also been used by a previous paper $arg\n");
+ $r->print("
".&mt("The encoded ID has also been used by a previous paper [_1]",$arg)."
\n");
}
$r->print($message);
- $r->print("
How should I handle this? \n");
+ $r->print("
".&mt("How should I handle this?")." \n");
$r->print("\n
");
#FIXME it would be nice if this sent back the user ID and
#could do partial userID matches
@@ -6535,14 +6506,14 @@ sub scantron_get_correction {
$r->print('
There have been multiple bubbles scanned for a some question(s)
\n");
+ $r->print("
".&mt("There have been multiple bubbles scanned for a some question(s)")."
\n");
+
+ # The form field scantron_questions is acutally a list of line numbers.
+ # represented by this form so:
+
+ my $line_list = &questions_to_line_list($arg);
+
$r->print('');
+ $line_list.'" />');
$r->print($message);
- $r->print("
Please indicate which bubble should be used for grading
");
+ $r->print("
".&mt("Please indicate which bubble should be used for grading")."
There have been no bubbles scanned for some question(s)
\n");
+ $r->print("
".&mt("There have been no bubbles scanned for some question(s)")."
\n");
$r->print($message);
- $r->print("
Please indicate which bubble should be used for grading
");
- $r->print("Some questions have no scanned bubbles\n");
+ $r->print("
".&mt("Please indicate which bubble should be used for grading.")."
");
+ $r->print(&mt("Some questions have no scanned bubbles")."\n");
+
+ # The form field scantron_questinos is actually a list of line numbers not
+ # a list of question numbers. Therefore:
+ #
+
+ my $line_list = &questions_to_line_list($arg);
+
$r->print('');
+ $line_list.'" />');
foreach my $question (@{$arg}) {
- my $selected = &get_response_bubbles($scan_record, $question);
- my @select_array = split(/:/,$selected); # ought to be an array of empties.
- &scantron_bubble_selector($r,$scan_config,$question, @select_array);
+ &prompt_for_corrections($r, $question, $scan_config, $scan_record);
}
} else {
$r->print("\n
");
}
$r->print("\n
");
-
}
=pod
-=item scantron_bubble_selector
-
- Generates the html radiobuttons to correct a single bubble line
- possibly showing the existing the selected bubbles if known
+=item questions_to_line_list
- Arguments:
- $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.
+Converts a list of questions into a string of comma separated
+line numbers in the answer sheet used by the questions. This is
+used to fill in the scantron_questions form field.
+
+ Arguments:
+ questions - Reference to an array of questions.
=cut
-sub scantron_bubble_selector {
- my ($r,$scan_config,$quest,@lines)=@_;
- my $max=$$scan_config{'Qlength'};
+sub questions_to_line_list {
+ my ($questions) = @_;
+ my @lines;
- my $scmode=$$scan_config{'Qon'};
+ foreach my $question (@{$questions}) {
+ my $first = $first_bubble_line{$question-1} + 1;
+ my $count = $bubble_lines_per_response{$question-1};
+ my $last = $first+$count-1;
+ push(@lines, ($first..$last));
+ }
+ return join(',', @lines);
+}
- my $bubble_length = scalar(@lines);
+=pod
+=item prompt_for_corrections
- if ($scmode eq 'number' || $scmode eq 'letter') { $max=10; }
+Prompts for a potentially multiline correction to the
+user's bubbling (factors out common code from scantron_get_correction
+for multi and missing bubble cases).
- my $response = $quest-1;
- my $lines = $bubble_lines_per_response{$response};
+ Arguments:
+ $r - Apache request object.
+ $question - The question number to prompt for.
+ $scan_config - The scantron file configuration hash.
+ $scan_record - Reference to the hash that has the the parsed scanlines.
- my $total_lines = $lines*2;
- my @alphabet=('A'..'Z');
+ Implicit inputs:
+ %bubble_lines_per_response - Starting line numbers for each question.
+ Numbered from 0 (but question numbers are from
+ 1.
+ %first_bubble_line - Starting bubble line for each question.
- $r->print("
');
-
- }
+sub prompt_for_corrections {
+ my ($r, $question, $scan_config, $scan_record) = @_;
- if ($l == 0) {
- my $lspan = $total_lines * 2; # 2 table rows per bubble line.
+ my $lines = $bubble_lines_per_response{$question-1};
+ my $current_line = $first_bubble_line{$question-1} + 1 ;
- $r->print('
');
-
- }
+ if ($lines > 1) {
+ $r->print(&mt("The group of bubble lines below responds to a single question. Select at most one bubble in a single line and select 'No Bubble' in all the other lines. ")." ");
+ }
+ for (my $i =0; $i < $lines; $i++) {
+ my $selected = $$scan_record{"scantron.$current_line.answer"};
+ &scantron_bubble_selector($r, $scan_config, $current_line,
+ split('', $selected));
+ $current_line++;
+ }
+ if ($lines > 1) {
+ $r->print(" ");
+ }
+}
- $r->print('
');
+=pod
- # FIXME: This may have to be a bit more clever for
- # multiline questions (different values e.g..).
+=item scantron_bubble_selector
+
+ Generates the html radiobuttons to correct a single bubble line
+ possibly showing the existing the selected bubbles if known
- for (my $i=0;$i<$max;$i++) {
- my $value = "$l:$i"; # Relative bubble line #: Bubble in line.
- $r->print("\n".
- '
");
- }
- $r->print('
');
+ Arguments:
+ $r - Apache request object
+ $scan_config - hash from &get_scantron_config()
+ $line - Number of the line being displayed.
+ @selected - Array of bubbles picked on this line.
-
- }
- $r->print('
');
+=cut
+
+sub scantron_bubble_selector {
+ my ($r,$scan_config,$line,@selected)=@_;
+ my $max=$$scan_config{'Qlength'};
+
+ my $scmode=$$scan_config{'Qon'};
+ if ($scmode eq 'number' || $scmode eq 'letter') { $max=10; }
+
+ my @alphabet=('A'..'Z');
+ $r->print("
$line
");
+ for (my $i=0;$i<$max+1;$i++) {
+ $r->print("\n".'
');
+ for (my $i=0;$i<$max;$i++) {
+ $r->print("\n".
+ '
");
+ }
+ $r->print('
');
+ $r->print('
');
}
=pod
@@ -6935,7 +6966,6 @@ sub scantron_get_maxbubble {
my $bubble_line = 0;
foreach my $resource (@resources) {
my $symb = $resource->symb();
- &Apache::lonxml::clear_bubble_lines_for_part();
my $result=&Apache::lonnet::ssi($resource->src(),
('symb' => $resource->symb()),
('grade_target' => 'analyze'),
@@ -6951,9 +6981,10 @@ sub scantron_get_maxbubble {
foreach my $part_id (@{$analysis{'parts'}}) {
-
my $lines = $analysis{"$part_id.bubble_lines"};;
+
+
# TODO - make this a persistent hash not an array.
@@ -7165,7 +7196,7 @@ sub scantron_upload_scantron_data {
my $domsel=&Apache::loncommon::select_dom_form($env{'request.role.domain'},
'domainid');
my $default_form_data=&defaultFormData(&get_symb($r,1));
- $r->print(<print('
-
-UPLOAD
+');
return '';
}
@@ -7207,12 +7242,12 @@ sub scantron_upload_scantron_data_save {
my $doanotherupload=
' '."\n";
if (!&Apache::lonnet::allowed('usc',$env{'form.domainid'}) &&
!&Apache::lonnet::allowed('usc',
$env{'form.domainid'}.'_'.$env{'form.courseid'})) {
- $r->print("You are not allowed to upload Scantron data to the requested course. ");
+ $r->print(&mt("You are not allowed to upload Scantron data to the requested course.")." ");
if ($symb) {
$r->print(&show_grading_menu_form($symb));
} else {
@@ -7221,7 +7256,7 @@ sub scantron_upload_scantron_data_save {
return '';
}
my %coursedata=&Apache::lonnet::coursedescription($env{'form.domainid'}.'_'.$env{'form.courseid'});
- $r->print("Doing upload to ".$coursedata{'description'}." ");
+ $r->print(&mt("Doing upload to [_1]",$coursedata{'description'})." ");
my $fname=$env{'form.upfile.filename'};
#FIXME
#copied from lonnet::userfileupload()
@@ -7239,13 +7274,18 @@ sub scantron_upload_scantron_data_save {
my $uploadedfile=$fname;
$fname='scantron_orig_'.$fname;
if (length($env{'form.upfile'}) < 2) {
- $r->print("Error: The file you attempted to upload, ".&HTML::Entities::encode($env{'form.upfile.filename'},'<>&"').", contained no information. Please check that you entered the correct filename.");
+ $r->print(&mt("Error: The file you attempted to upload, [_1] contained no information. Please check that you entered the correct filename.",''.&HTML::Entities::encode($env{'form.upfile.filename'},'<>&"').""));
} else {
my $result=&Apache::lonnet::finishuserfileupload($env{'form.courseid'},$env{'form.domainid'},'upfile',$fname);
if ($result =~ m|^/uploaded/|) {
- $r->print("Success: Successfully uploaded ".(length($env{'form.upfile'})-1)." bytes of data into location ".$result."");
+ $r->print(&mt("Success: Successfully uploaded [_1] bytes of data into location [_2]",
+ (length($env{'form.upfile'})-1),
+ ''.$result.""));
} else {
- $r->print("Error: An error (".$result.") occurred when attempting to upload the file, ".&HTML::Entities::encode($env{'form.upfile.filename'},'<>&"')."");
+ $r->print(&mt("Error: An error ([_1]) occurred when attempting to upload the file, [_2]",
+ $result,
+ ''.&HTML::Entities::encode($env{'form.upfile.filename'},'<>&"').""));
+
}
}
if ($symb) {
@@ -7289,11 +7329,11 @@ sub scantron_download_scantron_data {
my $cdom=$env{'course.'.$env{'request.course.id'}.'.domain'};
my $file=$env{'form.scantron_selectfile'};
if (! &valid_file($file)) {
- $r->print(<print('
- The requested file name was invalid.
+ '.&mt('The requested file name was invalid.').'
- Original file as uploaded by the scantron office.
+ '.&mt('[_1]Original[_2] file as uploaded by the scantron office.',
+ '','').'
- Corrections, a file of corrected records that were used in grading.
+ '.&mt('[_1]Corrections[_2], a file of corrected records that were used in grading.',
+ '','').'
- Skipped, a file of records that were skipped.
+ '.&mt('[_1]Skipped[_2], a file of records that were skipped.',
+ '','').'