--- loncom/homework/grades.pm 2009/12/27 01:25:26 1.586
+++ loncom/homework/grades.pm 2011/11/29 17:00:19 1.664
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# The LON-CAPA Grading handler
#
-# $Id: grades.pm,v 1.586 2009/12/27 01:25:26 raeburn Exp $
+# $Id: grades.pm,v 1.664 2011/11/29 17:00:19 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -40,9 +40,12 @@ use Apache::lonhomework;
use Apache::lonpickcode;
use Apache::loncoursedata;
use Apache::lonmsg();
-use Apache::Constants qw(:common);
+use Apache::Constants qw(:common :http);
use Apache::lonlocal;
use Apache::lonenc;
+use Apache::lonstathelpers;
+use Apache::lonquickgrades;
+use Apache::bridgetask();
use String::Similarity;
use LONCAPA;
@@ -96,6 +99,9 @@ sub ssi_print_error {
#
# --- Retrieve the parts from the metadata file.---
+# Returns an array of everything that the resources stores away
+#
+
sub getpartlist {
my ($symb,$errorref) = @_;
@@ -120,21 +126,6 @@ sub getpartlist {
return @stores;
}
-# --- Get the symbolic name of a problem and the url
-sub get_symb {
- my ($request,$silent) = @_;
- (my $url=$env{'form.url'}) =~ s-^http://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--;
- my $symb=($env{'form.symb'} ne '' ? $env{'form.symb'} : (&Apache::lonnet::symbread($url)));
- if ($symb eq '') {
- if (!$silent) {
- $request->print("Unable to handle ambiguous references:$url:.");
- return ();
- }
- }
- &Apache::lonenc::check_decrypt(\$symb);
- return ($symb);
-}
-
#--- Format fullname, username:domain if different for display
#--- Use anywhere where the student names are listed
sub nameUserString {
@@ -149,6 +140,7 @@ sub nameUserString {
#--- Get the partlist and the response type for a given problem. ---
#--- Indicate if a response type is coded handgraded or not. ---
+#--- Sets response_error pointer to "1" if navmaps object broken ---
sub response_type {
my ($symb,$response_error) = @_;
@@ -160,6 +152,10 @@ sub response_type {
return;
}
my $res = $navmap->getBySymb($symb);
+ unless (ref($res)) {
+ $$response_error = 1;
+ return;
+ }
my $partlist = $res->parts();
my %vPart =
map { $_ => 1 } (&Apache::loncommon::get_env_multiple('form.vPart'));
@@ -203,55 +199,6 @@ sub get_display_part {
return $display;
}
-#--- Show resource title
-#--- and parts and response type
-sub showResourceInfo {
- my ($symb,$probTitle,$checkboxes,$res_error) = @_;
- my $result = '
'.&mt('Current Resource').': '.$probTitle.'
'."\n";
- my ($partlist,$handgrade,$responseType) = &response_type($symb,$res_error);
- if (ref($res_error)) {
- if ($$res_error) {
- return;
- }
- }
- $result.=&Apache::loncommon::start_data_table()
- .&Apache::loncommon::start_data_table_header_row();
- if ($checkboxes) {
- $result.='
';
- }
- $result.='
'.&mt('Problem Part').'
'
- .'
'.&mt('Res. ID').'
'
- .'
'.&mt('Type').'
'
- .&Apache::loncommon::end_data_table_header_row();
- my %resptype = ();
- my $hdgrade='no';
- my %partsseen;
- foreach my $partID (sort(keys(%$responseType))) {
- foreach my $resID (sort(keys(%{ $responseType->{$partID} }))) {
- my $handgrade=$$handgrade{$partID.'_'.$resID};
- my $responsetype = $responseType->{$partID}->{$resID};
- $hdgrade = $handgrade if ($handgrade eq 'yes');
- $result.=&Apache::loncommon::start_data_table_row();
- if ($checkboxes) {
- if (exists($partsseen{$partID})) {
- $result.="
'."\n";
+ &mt('Verifying Receipt Number [_1]',$receipt).
+ ''."\n";
my ($string,$contents,$matches) = ('','',0);
my (undef,undef,$fullname) = &getclasslist('all','0');
@@ -852,7 +820,7 @@ sub verifyreceipt {
$contents.
&Apache::loncommon::end_data_table()."\n";
}
- return $string.&show_grading_menu_form($symb);
+ return $string;
}
#--- This is called by a number of programs.
@@ -860,30 +828,25 @@ sub verifyreceipt {
#--- Also called directly when one clicks on the subm button
# on the problem page.
sub listStudents {
- my ($request) = shift;
+ my ($request,$symb,$submitonly) = @_;
- my ($symb) = &get_symb($request);
my $cdom = $env{"course.$env{'request.course.id'}.domain"};
my $cnum = $env{"course.$env{'request.course.id'}.num"};
my $getsec = $env{'form.section'} eq '' ? 'all' : $env{'form.section'};
my $getgroup = $env{'form.group'} eq '' ? 'all' : $env{'form.group'};
- my $submitonly= $env{'form.submitonly'} eq '' ? 'all' : $env{'form.submitonly'};
- my $viewgrade = $env{'form.showgrading'} eq 'yes' ? 'View/Grade/Regrade' : 'View';
- $env{'form.probTitle'} = $env{'form.probTitle'} eq '' ?
- &Apache::lonnet::gettitle($symb) : $env{'form.probTitle'};
-
- my $result='
'
- .&mt("$viewgrade Submissions for a Student or a Group of Students")
- .'
';
+ unless ($submitonly) {
+ $submitonly= $env{'form.submitonly'} eq '' ? 'all' : $env{'form.submitonly'};
+ }
- my ($table,undef,$hdgrade,$partlist,$handgrade) = &showResourceInfo($symb,$env{'form.probTitle'},($env{'form.showgrading'} eq 'yes'));
+ my $result='';
+ my $res_error;
+ my ($partlist,$handgrade,$responseType) = &response_type($symb,\$res_error);
my %lt = &Apache::lonlocal::texthash (
'multiple' => 'Please select a student or group of students before clicking on the Next button.',
'single' => 'Please select the student before clicking on the Next button.',
);
- $request->print(<
+ $request->print(&Apache::lonhtmlcommon::scripttag(<
LISTJAVASCRIPT
&commonJSfunctions($request);
$request->print($result);
- my $checkhdgrade = ($env{'form.handgrade'} eq 'yes' && scalar(@$partlist) > 1 ) ? 'checked="checked"' : '';
- my $checklastsub = $checkhdgrade eq '' ? 'checked="checked"' : '';
my $gradeTable=''."\n";
+ ''."\n";
if ($ctr == 0) {
my $num_students=(scalar(keys(%$fullname)));
if ($num_students eq 0) {
@@ -1131,7 +1085,6 @@ LISTJAVASCRIPT
} elsif ($ctr == 1) {
$gradeTable =~ s/type="checkbox"/type="checkbox" checked="checked"/;
}
- $gradeTable.=&show_grading_menu_form($symb);
$request->print($gradeTable);
return '';
}
@@ -1140,7 +1093,7 @@ LISTJAVASCRIPT
sub check_script {
my ($form, $type)=@_;
- my $chkallscript=''."\n";
+'."\n");
return $chkallscript;
}
@@ -1185,7 +1138,7 @@ sub check_buttons {
# Displays the submissions for one student or a group of students
sub processGroup {
- my ($request) = shift;
+ my ($request,$symb) = @_;
my $ctr = 0;
my @stuchecked = &Apache::loncommon::get_env_multiple('form.stuinfo');
my $total = scalar(@stuchecked)-1;
@@ -1195,7 +1148,7 @@ sub processGroup {
$env{'form.student'} = $uname;
$env{'form.userdom'} = $udom;
$env{'form.fullname'} = $fullname;
- &submission($request,$ctr,$total);
+ &submission($request,$ctr,$total,$symb);
$ctr++;
}
return '';
@@ -1210,8 +1163,7 @@ sub processGroup {
sub sub_page_js {
my $request = shift;
my $alertmsg = &mt('A number equal or greater than 0 is expected. Entered value = ');
- $request->print(<
+ $request->print(&Apache::lonhtmlcommon::scripttag(<
SUBJAVASCRIPT
}
@@ -1389,8 +1333,8 @@ sub sub_page_kw_js {
my $iconpath = $request->dir_config('lonIconsURL');
&commonJSfunctions($request);
- my $inner_js_msg_central=<
+ my $inner_js_msg_central= (<
function checkInput() {
opener.document.SCORE.msgsub.value = opener.checkEntities(document.msgcenter.msgsub.value);
var nmsg = opener.document.SCORE.savemsgN.value;
@@ -1427,11 +1371,11 @@ sub sub_page_kw_js {
self.close()
}
-
+
INNERJS
- my $inner_js_highlight_central=<
+ my $inner_js_highlight_central= (<
function updateChoice(flag) {
opener.document.SCORE.kwclr.value = opener.radioSelection(document.hlCenter.kwdclr);
opener.document.SCORE.kwsize.value = opener.radioSelection(document.hlCenter.kwdsize);
@@ -1465,13 +1409,28 @@ INNERJS
my $docopen=&Apache::lonhtmlcommon::javascript_docopen();
$docopen=~s/^document\.//;
- my $alertmsg = &mt('Please select a word or group of words from document and then click this link.');
- $request->print(<
+ my %lt = &Apache::lonlocal::texthash(
+ keyw => 'Keywords list, separated by a space. Add/delete to list if desired.',
+ plse => 'Please select a word or group of words from document and then click this link.',
+ adds => 'Add selection to keyword list? Edit if desired.',
+ comp => 'Compose Message for: ',
+ incl => 'Include',
+ type => 'Type',
+ subj => 'Subject',
+ mesa => 'Message',
+ new => 'New',
+ save => 'Save',
+ canc => 'Cancel',
+ kehi => 'Keyword Highlight Options',
+ txtc => 'Text Color',
+ font => 'Font Size',
+ fnst => 'Font Style',
+ );
+ $request->print(&Apache::lonhtmlcommon::scripttag(<");
pDoc.write("");
- pDoc.write("
Compose Message for \"+fullname+\"<\\/span><\\/h3>
");
+ pDoc.write("
$lt{'comp'}\"+fullname+\"<\\/span><\\/h3>
");
pDoc.write('
');
pDoc.write('
');
- pDoc.write("
Type<\\/b><\\/td>
Include<\\/b><\\/td>
Message<\\/td><\\/tr>");
+ pDoc.write("
$lt{'type'}<\\/b><\\/td>
$lt{'incl'}<\\/b><\\/td>
$lt{'mesa'}<\\/td><\\/tr>");
}
function displaySubject(msg,shwsel) {
pDoc = pWin.document;
pDoc.write("
';
@@ -4801,7 +4818,6 @@ sub updateGradeByPage {
}
$studentTable.=&Apache::loncommon::end_data_table();
- $studentTable.=&show_grading_menu_form($env{'form.symb'});
my $grademsg=($changeflag == 0 ? &mt('No score was changed or updated.') :
&mt('The scores were changed for [quant,_1,problem].',
$changeflag));
@@ -4828,12 +4844,12 @@ sub updateGradeByPage {
from the file that we are parsing that represents one entire sheet
'bubble line' refers to the data
- representing the line of bubbles that are on the physical bubble sheet
+ representing the line of bubbles that are on the physical bubblesheet
-The overall process is that a scanned in bubble sheet data is uploaded
+The overall process is that a scanned in bubblesheet data is uploaded
into a course. When a user wants to grade, they select a
-sequence/folder of resources, a file of bubble sheet info, and pick
+sequence/folder of resources, a file of bubblesheet info, and pick
one of the predefined configurations for what each scanline looks
like.
@@ -4849,14 +4865,14 @@ username:domain.
During the validation phase the instructor can choose to skip scanlines.
-After the validation phase, there are now 3 bubble sheet files
+After the validation phase, there are now 3 bubblesheet files
scantron_original_filename (unmodified original file)
scantron_corrected_filename (file where the corrected information has replaced the original information)
scantron_skipped_filename (contains the exact text of scanlines that where skipped)
Also there is a separate hash nohist_scantrondata that contains extra
-correction information that isn't representable in the bubble sheet
+correction information that isn't representable in the bubblesheet
file (see &scantron_getfile() for more information)
After all scanlines are either valid, marked as valid or skipped, then
@@ -4879,9 +4895,7 @@ the homework problem.
sub defaultFormData {
my ($symb)=@_;
- return ''."\n".
- ''."\n".
- ''."\n";
+ return '';
}
@@ -4992,14 +5006,16 @@ sub scantron_filenames {
my $cdom=$env{'course.'.$env{'request.course.id'}.'.domain'};
my $cname=$env{'course.'.$env{'request.course.id'}.'.num'};
my $getpropath = 1;
- my @files=&Apache::lonnet::dirlist('userfiles',$cdom,$cname,
- $getpropath);
+ my ($dirlist,$listerror) = &Apache::lonnet::dirlist('userfiles',$cdom,
+ $cname,$getpropath);
my @possiblenames;
- foreach my $filename (sort(@files)) {
- ($filename)=split(/&/,$filename);
- if ($filename!~/^scantron_orig_/) { next ; }
- $filename=~s/^scantron_orig_//;
- push(@possiblenames,$filename);
+ if (ref($dirlist) eq 'ARRAY') {
+ foreach my $filename (sort(@{$dirlist})) {
+ ($filename)=split(/&/,$filename);
+ if ($filename!~/^scantron_orig_/) { next ; }
+ $filename=~s/^scantron_orig_//;
+ push(@possiblenames,$filename);
+ }
}
return @possiblenames;
}
@@ -5153,7 +5169,7 @@ sub scantron_CODEunique {
=item scantron_selectphase
- Generates the initial screen to start the bubble sheet process.
+ Generates the initial screen to start the bubblesheet process.
Allows for - starting a grading run.
- downloading existing scan data (original, corrected
or skipped info)
@@ -5167,8 +5183,7 @@ sub scantron_CODEunique {
=cut
sub scantron_selectphase {
- my ($r,$file2grade) = @_;
- my ($symb)=&get_symb($r);
+ my ($r,$file2grade,$symb) = @_;
if (!$symb) {return '';}
my $map_error;
my $sequence_selector=&getSequenceDropDown($symb,\$map_error);
@@ -5177,7 +5192,6 @@ sub scantron_selectphase {
return;
}
my $default_form_data=&defaultFormData($symb);
- my $grading_menu_button=&show_grading_menu_form($symb);
my $file_selector=&scantron_uploads($file2grade);
my $format_selector=&scantron_scantab();
my $CODE_selector=&scantron_CODElist();
@@ -5186,6 +5200,52 @@ sub scantron_selectphase {
$ssi_error = 0;
+ if (&Apache::lonnet::allowed('usc',$env{'request.role.domain'}) ||
+ &Apache::lonnet::allowed('usc',$env{'request.course.id'})) {
+
+ # Chunk of form to prompt for a scantron file upload.
+
+ $r->print('
+
+ '.&Apache::loncommon::start_data_table('LC_scantron_action').'
+ '.&Apache::loncommon::start_data_table_header_row().'
+
+ '.&mt('Specify a bubblesheet data file to upload.').'
+
+');
+ my $default_form_data=&defaultFormData($symb);
+ my $cdom= $env{'course.'.$env{'request.course.id'}.'.domain'};
+ my $cnum= $env{'course.'.$env{'request.course.id'}.'.num'};
+ $r->print(&Apache::lonhtmlcommon::scripttag('
+ function checkUpload(formname) {
+ if (formname.upfile.value == "") {
+ alert("'.&mt('Please use the browse button to select a file from your local directory.').'");
+ return false;
+ }
+ formname.submit();
+ }'));
+ $r->print('
+
+ '.&Apache::loncommon::end_data_table_row().'
+ '.&Apache::loncommon::end_data_table().'
+');
+ }
+
# Chunk of form to prompt for a file to grade and how:
$result.= '
@@ -5233,53 +5293,7 @@ sub scantron_selectphase {
$r->print($result);
- if (&Apache::lonnet::allowed('usc',$env{'request.role.domain'}) ||
- &Apache::lonnet::allowed('usc',$env{'request.course.id'})) {
-
- # Chunk of form to prompt for a scantron file upload.
-
- $r->print('
-
- '.&Apache::loncommon::start_data_table('LC_scantron_action').'
- '.&Apache::loncommon::start_data_table_header_row().'
-
- '.&mt('Specify a bubblesheet data file to upload.').'
-
- '.&Apache::loncommon::end_data_table_row().'
- '.&Apache::loncommon::end_data_table().'
-');
- }
# Chunk of the form that prompts to view a scoring office file,
# corrected file, skipped records in a file.
@@ -5339,7 +5353,6 @@ sub scantron_selectphase {
&Apache::loncommon::end_data_table_row()."\n".
&Apache::loncommon::end_data_table()."\n".
' ');
- $r->print($grading_menu_button);
return;
}
@@ -5397,7 +5410,8 @@ sub scantron_selectphase {
LastName - column that the last name starts in
LastNameLength - number of columns that the last name spans
-
+ BubblesPerRow - number of bubbles available in each row used to
+ bubble an answer. (If not specified, 10 assumed).
=cut
sub get_scantron_config {
@@ -5427,6 +5441,7 @@ sub get_scantron_config {
$config{'FirstNamelength'}=$config[14];
$config{'LastName'}=$config[15];
$config{'LastNamelength'}=$config[16];
+ $config{'BubblesPerRow'}=$config[17];
last;
}
return %config;
@@ -6176,7 +6191,7 @@ sub remember_current_skipped {
=item check_for_error
Checks if there was an error when attempting to remove a specific
- scantron_.. bubble sheet data file. Prints out an error if
+ scantron_.. bubblesheet data file. Prints out an error if
something went wrong.
=cut
@@ -6198,7 +6213,7 @@ sub check_for_error {
=cut
sub scantron_warning_screen {
- my ($button_text)=@_;
+ my ($button_text,$symb)=@_;
my $title=&Apache::lonnet::gettitle($env{'form.selectpage'});
my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
my $CODElist;
@@ -6211,6 +6226,12 @@ sub scantron_warning_screen {
'
'.&mt('List of CODES to validate against:').'
'.
$env{'form.scantron_CODElist'}.'
';
}
+ my $lastbubblepoints;
+ if ($env{'form.scantron_lastbubblepoints'} ne '') {
+ $lastbubblepoints =
+ '
'.&mt('Hand-graded items: points from last bubble in row').'
'.
+ $env{'form.scantron_lastbubblepoints'}.'
';
+ }
return ('
@@ -6219,11 +6240,10 @@ sub scantron_warning_screen {
'.&mt('Sequence to be Graded:').'
'.$title.'
'.&mt('Data File that will be used:').'
'.$env{'form.scantron_selectfile'}.'
-'.$CODElist.'
+'.$CODElist.$lastbubblepoints.'
-
-
'.&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.').'
+
'.&mt('If this information is correct, please click on \'[_1]\'.',&mt($button_text)).'
+'.&mt('If something is incorrect, please return to [_1]Grade/Manage/Review Bubblesheets[_2] to start over.','','').'
');
@@ -6239,33 +6259,33 @@ sub scantron_warning_screen {
=cut
sub scantron_do_warning {
- my ($r)=@_;
- my ($symb)=&get_symb($r);
+ my ($r,$symb)=@_;
if (!$symb) {return '';}
my $default_form_data=&defaultFormData($symb);
$r->print(&scantron_form_start().$default_form_data);
if ( $env{'form.selectpage'} eq '' ||
$env{'form.scantron_selectfile'} eq '' ||
$env{'form.scantron_format'} eq '' ) {
- $r->print("
".&mt('You have forgetten to specify some information. Please go Back and try again.')."
");
+ $r->print("
".&mt('You have forgotten to specify some information. Please go Back and try again.')."
");
if ( $env{'form.selectpage'} eq '') {
$r->print('
'.&mt('You have not selected a Sequence to grade').'
');
}
if ( $env{'form.scantron_selectfile'} eq '') {
- $r->print('
'.&mt('You have not selected a file that contains the student\'s response data.').'
');
+ $r->print('
'.&mt("You have not selected a file that contains the student's response data.").'
');
}
if ( $env{'form.scantron_format'} eq '') {
- $r->print('
'.&mt('You have not selected a the format of the student\'s response data.').'
');
+ $r->print('
'.&mt("You have not selected the format of the student's response data.").'
');
}
} else {
- my $warning=&scantron_warning_screen('Grading: Validate Records');
+ my $warning=&scantron_warning_screen('Grading: Validate Records',$symb);
+ my $bubbledbyhand=&hand_bubble_option();
$r->print('
-'.$warning.'
+'.$warning.$bubbledbyhand.'
');
}
- $r->print(" ".&show_grading_menu_form($symb));
+ $r->print(" ");
return '';
}
@@ -6312,7 +6332,7 @@ SCANTRONFORM
=item scantron_validate_file
- Dispatch routine for doing validation of a bubble sheet data file.
+ Dispatch routine for doing validation of a bubblesheet data file.
Also processes any necessary information resets that need to
occur before validation begins (ignore previous corrections,
@@ -6321,8 +6341,7 @@ SCANTRONFORM
=cut
sub scantron_validate_file {
- my ($r) = @_;
- my ($symb)=&get_symb($r);
+ my ($r,$symb) = @_;
if (!$symb) {return '';}
my $default_form_data=&defaultFormData($symb);
@@ -6350,12 +6369,16 @@ sub scantron_validate_file {
#get the student pick code ready
$r->print(&Apache::loncommon::studentbrowser_javascript());
my $nav_error;
- my $max_bubble=&scantron_get_maxbubble(\$nav_error);
+ my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
+ my $max_bubble=&scantron_get_maxbubble(\$nav_error,\%scantron_config);
if ($nav_error) {
$r->print(&navmap_errormsg());
return '';
}
my $result=&scantron_form_start($max_bubble).$default_form_data;
+ if ($env{'form.scantron_lastbubblepoints'} ne '') {
+ $result .= '';
+ }
$r->print($result);
my @validate_phases=( 'sequence',
@@ -6380,7 +6403,7 @@ sub scantron_validate_file {
}
}
if (!$stop) {
- my $warning=&scantron_warning_screen('Start Grading');
+ my $warning=&scantron_warning_screen('Start Grading',$symb);
$r->print(&mt('Validation process complete.').' '.
$warning.
&mt('Perform verification for each student after storage of submissions?').
@@ -6390,7 +6413,7 @@ sub scantron_validate_file {
''.&mt('No').
' '.
&mt('Grading will take longer if you use verification.').' '.
- &mt("Alternatively, the 'Review bubblesheet data' utility (see grading menu) can be used for all students after grading is complete.").'
'.
+ &mt('Otherwise, Grade/Manage/Review Bubblesheets [_1] Review bubblesheet data can be used once grading is complete.','»').'
".&mt("Or click the 'Grading Menu' button to start over.")."
");
+ $r->print('
'.&mt('Or return to [_1]Grade/Manage/Review Bubblesheets[_2] to start over.','','').'
');
} else {
if ($validate_phases[$currentphase] eq 'doublebubble' || $validate_phases[$currentphase] eq 'missingbubbles') {
$r->print('');
@@ -6414,7 +6437,7 @@ sub scantron_validate_file {
$r->print(" ".&mt("this scanline saving it for later."));
}
}
- $r->print(" ".&show_grading_menu_form($symb));
+ $r->print(" ");
return '';
}
@@ -6423,7 +6446,7 @@ sub scantron_validate_file {
=item scantron_remove_file
- Removes the requested bubble sheet data file, makes sure that
+ Removes the requested bubblesheet data file, makes sure that
scantron_original_ is never removed
@@ -6448,7 +6471,7 @@ sub scantron_remove_file {
=item scantron_remove_scan_data
- Removes all scan_data correction for the requested bubble sheet
+ Removes all scan_data correction for the requested bubblesheet
data file. (In the case that both the are doing skipped records we need
to remember the old skipped lines for the time being so that element
persists for a while.)
@@ -6485,7 +6508,7 @@ sub scantron_remove_scan_data {
=item scantron_getfile
- Fetches the requested bubble sheet data file (all 3 versions), and
+ Fetches the requested bubblesheet data file (all 3 versions), and
the scan_data hash
Arguments:
@@ -6585,7 +6608,7 @@ sub lonnet_putfile {
=item scantron_putfile
- Stores the current version of the bubble sheet data files, and the
+ Stores the current version of the bubblesheet data files, and the
scan_data hash. (Does not modify the original version only the
corrected and skipped versions.
@@ -6679,7 +6702,7 @@ sub get_todo_count {
=item scantron_put_line
- Updates the 'corrected' or 'skipped' versions of the bubble sheet
+ Updates the 'corrected' or 'skipped' versions of the bubblesheet
data file.
Arguments:
@@ -6803,7 +6826,7 @@ sub scantron_validate_ID {
my ($scanlines,$scan_data)=&scantron_getfile();
my $nav_error;
- &scantron_get_maxbubble(\$nav_error); # parse needs the bubble_lines.. array.
+ &scantron_get_maxbubble(\$nav_error,\%scantron_config); # parse needs the bubble_lines.. array.
if ($nav_error) {
$r->print(&navmap_errormsg());
return(1,$currentphase);
@@ -6868,19 +6891,28 @@ sub scantron_get_correction {
#the previous one or the current one
if ( $$scan_record{'scantron.PaperID'} =~ /\S/) {
- $r->print("
".&mt("An error was detected ($error)".
- " for PaperID [_1]",
- $$scan_record{'scantron.PaperID'})."
\n");
+ $r->print(
+ '
'
+ .&mt('An error was detected ([_1]) for PaperID [_2]',
+ "$error",
+ ''.$$scan_record{'scantron.PaperID'}.'')
+ ."
\n");
} else {
- $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(
+ '
'
+ .&mt('An error was detected ([_1]) in scanline [_2] [_3]',
+ "$error", $i, "
$line
")
+ ." \n");
+ }
+ my $message =
+ '
'
+ .&mt('The ID on the form is [_1]',
+ "$$scan_record{'scantron.ID'}")
+ .' '
+ .&mt('The name on the paper is [_2], [_3]',
+ $$scan_record{'scantron.LastName'},
+ $$scan_record{'scantron.FirstName'})
+ .'
';
$r->print(''."\n");
$r->print(''."\n");
@@ -6890,10 +6922,10 @@ sub scantron_get_correction {
if ($error =~ /ID$/) {
if ($error eq 'incorrectID') {
- $r->print("
".&mt("The encoded ID is not in the classlist").
+ $r->print('
'.&mt("The encoded ID is not in the classlist").
"
".&mt("There have been multiple bubbles scanned for some question(s)")."
\n");
+ $r->print('
'.&mt("There have been multiple bubbles scanned for some question(s)")."
\n");
# The form field scantron_questions is acutally a list of line numbers.
# represented by this form so:
@@ -7001,7 +7032,7 @@ ENDSCRIPT
}
$r->print(&verify_bubbles_checked(@lines_to_correct));
} elsif ($error eq 'missingbubble') {
- $r->print("
".&mt("There have been no bubbles scanned for some question(s)")."
\n");
+ $r->print('
'.&mt("There have been [_1]no[_2] bubbles scanned for some question(s)",'','')."
\n");
$r->print($message);
$r->print("
".&mt("Please indicate which bubble should be used for grading.")."
");
$r->print(&mt("Some questions have no scanned bubbles.")."\n");
@@ -7030,8 +7061,7 @@ sub verify_bubbles_checked {
my (@ansnums) = @_;
my $ansnumstr = join('","',@ansnums);
my $warning = &mt("A bubble or 'No bubble' selection has not been made for one or more lines.");
- my $output = (<
+ my $output = &Apache::lonhtmlcommon::scripttag((<
ENDSCRIPT
return $output;
}
@@ -7206,7 +7235,19 @@ sub scantron_bubble_selector {
my $max=$$scan_config{'Qlength'};
my $scmode=$$scan_config{'Qon'};
- if ($scmode eq 'number' || $scmode eq 'letter') { $max=10; }
+ if ($scmode eq 'number' || $scmode eq 'letter') {
+ if (($$scan_config{'BubblesPerRow'} =~ /^\d+$/) &&
+ ($$scan_config{'BubblesPerRow'} > 0)) {
+ $max=$$scan_config{'BubblesPerRow'};
+ if (($scmode eq 'number') && ($max > 10)) {
+ $max = 10;
+ } elsif (($scmode eq 'letter') && $max > 26) {
+ $max = 26;
+ }
+ } else {
+ $max = 10;
+ }
+ }
my @alphabet=('A'..'Z');
$r->print(&Apache::loncommon::start_data_table().
@@ -7361,7 +7402,7 @@ sub scantron_validate_CODE {
my %allcodes=&get_codes();
my $nav_error;
- &scantron_get_maxbubble(\$nav_error); # parse needs the lines per response array.
+ &scantron_get_maxbubble(\$nav_error,\%scantron_config); # parse needs the lines per response array.
if ($nav_error) {
$r->print(&navmap_errormsg());
return(1,$currentphase);
@@ -7420,7 +7461,7 @@ sub scantron_validate_doublebubble {
my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
my ($scanlines,$scan_data)=&scantron_getfile();
my $nav_error;
- &scantron_get_maxbubble(\$nav_error); # parse needs the bubble line array.
+ &scantron_get_maxbubble(\$nav_error,\%scantron_config); # parse needs the bubble line array.
if ($nav_error) {
$r->print(&navmap_errormsg());
return(1,$currentphase);
@@ -7442,7 +7483,7 @@ sub scantron_validate_doublebubble {
sub scantron_get_maxbubble {
- my ($nav_error) = @_;
+ my ($nav_error,$scantron_config) = @_;
if (defined($env{'form.scantron_maxbubble'}) &&
$env{'form.scantron_maxbubble'}) {
&restore_bubble_lines();
@@ -7457,9 +7498,11 @@ sub scantron_get_maxbubble {
if (ref($nav_error)) {
$$nav_error = 1;
}
+ return;
}
my $map=$navmap->getResourceByUrl($sequence);
my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0);
+ my $bubbles_per_row = &bubblesheet_bubbles_per_row($scantron_config);
&Apache::lonxml::clear_problem_counter();
@@ -7475,7 +7518,7 @@ sub scantron_get_maxbubble {
my $response_number = 0;
my $bubble_line = 0;
foreach my $resource (@resources) {
- my ($analysis,$parts) = &scantron_partids_tograde($resource,$cid,$uname,$udom);
+ my ($analysis,$parts) = &scantron_partids_tograde($resource,$cid,$uname,$udom,undef,$bubbles_per_row);
if ((ref($analysis) eq 'HASH') && (ref($parts) eq 'ARRAY')) {
foreach my $part_id (@{$parts}) {
my $lines;
@@ -7504,9 +7547,10 @@ sub scantron_get_maxbubble {
if (ref($analysis->{$part_id.'.shown'}) eq 'ARRAY') {
$numshown = scalar(@{$analysis->{$part_id.'.shown'}});
}
- my $bubbles_per_line = 10;
- my $inner_bubble_lines = int($numbub/$bubbles_per_line);
- if (($numbub % $bubbles_per_line) != 0) {
+ my $bubbles_per_row =
+ &bubblesheet_bubbles_per_row($scantron_config);
+ my $inner_bubble_lines = int($numbub/$bubbles_per_row);
+ if (($numbub % $bubbles_per_row) != 0) {
$inner_bubble_lines++;
}
for (my $i=0; $i<$numshown; $i++) {
@@ -7517,7 +7561,7 @@ sub scantron_get_maxbubble {
$lines = $numshown * $inner_bubble_lines;
} else {
$lines = $analysis->{"$part_id.bubble_lines"};
- }
+ }
$first_bubble_line{$response_number} = $bubble_line;
$bubble_lines_per_response{$response_number} = $lines;
@@ -7538,6 +7582,18 @@ sub scantron_get_maxbubble {
return $env{'form.scantron_maxbubble'};
}
+sub bubblesheet_bubbles_per_row {
+ my ($scantron_config) = @_;
+ my $bubbles_per_row;
+ if (ref($scantron_config) eq 'HASH') {
+ $bubbles_per_row = $scantron_config->{'BubblesPerRow'};
+ }
+ if ((!$bubbles_per_row) || ($bubbles_per_row < 1)) {
+ $bubbles_per_row = 10;
+ }
+ return $bubbles_per_row;
+}
+
sub scantron_validate_missingbubbles {
my ($r,$currentphase) = @_;
#get student info
@@ -7548,7 +7604,7 @@ sub scantron_validate_missingbubbles {
my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
my ($scanlines,$scan_data)=&scantron_getfile();
my $nav_error;
- my $max_bubble=&scantron_get_maxbubble(\$nav_error);
+ my $max_bubble=&scantron_get_maxbubble(\$nav_error,\%scantron_config);
if ($nav_error) {
return(1,$currentphase);
}
@@ -7595,18 +7651,54 @@ sub scantron_validate_missingbubbles {
return (0,$currentphase+1);
}
+sub hand_bubble_option {
+ my (undef, undef, $sequence) =
+ &Apache::lonnet::decode_symb($env{'form.selectpage'});
+ return if ($sequence eq '');
+ my $navmap = Apache::lonnavmaps::navmap->new();
+ unless (ref($navmap)) {
+ return;
+ }
+ my $needs_hand_bubbles;
+ my $map=$navmap->getResourceByUrl($sequence);
+ my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0);
+ foreach my $res (@resources) {
+ if (ref($res)) {
+ if ($res->is_problem()) {
+ my $partlist = $res->parts();
+ foreach my $part (@{ $partlist }) {
+ my @types = $res->responseType($part);
+ if (grep(/^(chem|essay|image|formula|math|string|functionplot)$/,@types)) {
+ $needs_hand_bubbles = 1;
+ last;
+ }
+ }
+ }
+ }
+ }
+ if ($needs_hand_bubbles) {
+ my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
+ my $bubbles_per_row = &bubblesheet_bubbles_per_row(\%scantron_config);
+ return &mt('The sequence to be graded contains response types which are handgraded.').'
'.
+ &mt('If you have already graded these by bubbling sheets to indicate points awarded, [_1]what point value is assigned to a filled last bubble in each row?',' ').
+ ' '.&mt('or').' '.
+ '
';
+ }
+ return;
+}
sub scantron_process_students {
- my ($r) = @_;
+ my ($r,$symb) = @_;
my (undef,undef,$sequence)=&Apache::lonnet::decode_symb($env{'form.selectpage'});
- my ($symb)=&get_symb($r);
if (!$symb) {
return '';
}
my $default_form_data=&defaultFormData($symb);
my %scantron_config=&get_scantron_config($env{'form.scantron_format'});
+ my $bubbles_per_row =
+ &bubblesheet_bubbles_per_row(\%scantron_config);
my ($scanlines,$scan_data)=&scantron_getfile();
my $classlist=&Apache::loncoursedata::get_classlist();
my %idmap=&username_to_idmap($classlist);
@@ -7619,7 +7711,7 @@ sub scantron_process_students {
my @resources=$navmap->retrieveResources($map,\&scantron_filter,1,0);
my (%grader_partids_by_symb,%grader_randomlists_by_symb);
&graders_resources_pass(\@resources,\%grader_partids_by_symb,
- \%grader_randomlists_by_symb);
+ \%grader_randomlists_by_symb,$bubbles_per_row);
my $resource_error;
foreach my $resource (@resources) {
my $ressymb;
@@ -7631,7 +7723,7 @@ sub scantron_process_students {
}
my ($analysis,$parts) =
&scantron_partids_tograde($resource,$env{'request.course.id'},
- $env{'user.name'},$env{'user.domain'},1);
+ $env{'user.name'},$env{'user.domain'},1,$bubbles_per_row);
$grader_partids_by_symb{$ressymb} = $parts;
if (ref($analysis) eq 'HASH') {
if (ref($analysis->{'parts_withrandomlist'}) eq 'ARRAY') {
@@ -7669,7 +7761,7 @@ SCANTRONFORM
my $started;
my $nav_error;
- &scantron_get_maxbubble(\$nav_error); # Need the bubble lines array to parse.
+ &scantron_get_maxbubble(\$nav_error,\%scantron_config); # Need the bubble lines array to parse.
if ($nav_error) {
$r->print(&navmap_errormsg());
return '';
@@ -7681,7 +7773,6 @@ SCANTRONFORM
if ($ssi_error) {
$r->print("");
&ssi_print_error($r);
- $r->print(&show_grading_menu_form($symb));
&Apache::lonnet::remove_lock($lock);
return ''; # Dunno why the other returns return '' rather than just returning.
}
@@ -7726,7 +7817,7 @@ SCANTRONFORM
if ((exists($grader_randomlists_by_symb{$ressymb})) ||
(ref($grader_partids_by_symb{$ressymb}) ne 'ARRAY')) {
my ($analysis,$parts) =
- &scantron_partids_tograde($resource,$env{'request.course.id'},$uname,$udom);
+ &scantron_partids_tograde($resource,$env{'request.course.id'},$uname,$udom,undef,$bubbles_per_row);
$partids_by_symb{$ressymb} = $parts;
} else {
$partids_by_symb{$ressymb} = $grader_partids_by_symb{$ressymb};
@@ -7755,11 +7846,11 @@ SCANTRONFORM
}
if (&grade_student_bubbles($r,$uname,$udom,$scan_record,$scancode,
- \@resources,\%partids_by_symb) eq 'ssi_error') {
+ \@resources,\%partids_by_symb,
+ $bubbles_per_row) eq 'ssi_error') {
$ssi_error = 0; # So end of handler error message does not trigger.
$r->print("");
&ssi_print_error($r);
- $r->print(&show_grading_menu_form($symb));
&Apache::lonnet::remove_lock($lock);
return ''; # Why return ''? Beats me.
}
@@ -7783,11 +7874,11 @@ SCANTRONFORM
if ($studentrecord ne $studentdata) {
&Apache::lonxml::clear_problem_counter();
if (&grade_student_bubbles($r,$uname,$udom,$scan_record,$scancode,
- \@resources,\%partids_by_symb) eq 'ssi_error') {
+ \@resources,\%partids_by_symb,
+ $bubbles_per_row) eq 'ssi_error') {
$ssi_error = 0; # So end of handler error message does not trigger.
$r->print("");
&ssi_print_error($r);
- $r->print(&show_grading_menu_form($symb));
&Apache::lonnet::remove_lock($lock);
delete($completedstudents{$uname});
return '';
@@ -7803,12 +7894,12 @@ SCANTRONFORM
$studentrecord .= $recording;
}
if ($studentrecord ne $studentdata) {
- $r->print('
');
+ $r->print('
');
if ($scancode eq '') {
- $r->print(&mt('Mismatch grading bubble sheet for user: [_1] with ID: [_2].',
+ $r->print(&mt('Mismatch grading bubblesheet for user: [_1] with ID: [_2].',
$uname.':'.$udom,$scan_record->{'scantron.ID'}));
} else {
- $r->print(&mt('Mismatch grading bubble sheet for user: [_1] with ID: [_2] and CODE: [_3].',
+ $r->print(&mt('Mismatch grading bubblesheet for user: [_1] with ID: [_2] and CODE: [_3].',
$uname.':'.$udom,$scan_record->{'scantron.ID'},$scancode));
}
$r->print(' '.&Apache::loncommon::start_data_table()."\n".
@@ -7816,12 +7907,12 @@ SCANTRONFORM
'
");
$r->print("");
- $r->print(&show_grading_menu_form($symb));
return '';
}
sub graders_resources_pass {
- my ($resources,$grader_partids_by_symb,$grader_randomlists_by_symb) = @_;
+ my ($resources,$grader_partids_by_symb,$grader_randomlists_by_symb,
+ $bubbles_per_row) = @_;
if ((ref($resources) eq 'ARRAY') && (ref($grader_partids_by_symb)) &&
(ref($grader_randomlists_by_symb) eq 'HASH')) {
foreach my $resource (@{$resources}) {
my $ressymb = $resource->symb();
my ($analysis,$parts) =
&scantron_partids_tograde($resource,$env{'request.course.id'},
- $env{'user.name'},$env{'user.domain'},1);
+ $env{'user.name'},$env{'user.domain'},1,$bubbles_per_row);
$grader_partids_by_symb->{$ressymb} = $parts;
if (ref($analysis) eq 'HASH') {
if (ref($analysis->{'parts_withrandomlist'}) eq 'ARRAY') {
@@ -7869,7 +7960,8 @@ sub graders_resources_pass {
}
sub grade_student_bubbles {
- my ($r,$uname,$udom,$scan_record,$scancode,$resources,$parts) = @_;
+ my ($r,$uname,$udom,$scan_record,$scancode,$resources,$parts,$bubbles_per_row) = @_;
+# Walk folder as student here to get resources in order student sees.
if (ref($resources) eq 'ARRAY') {
my $count = 0;
foreach my $resource (@{$resources}) {
@@ -7882,6 +7974,12 @@ sub grade_student_bubbles {
'grade_symb' => $ressymb,
'CODE' => $scancode
);
+ if ($bubbles_per_row ne '') {
+ $form{'bubbles_per_row'} = $bubbles_per_row;
+ }
+ if ($env{'form.scantron_lastbubblepoints'} ne '') {
+ $form{'scantron_lastbubblepoints'} = $env{'form.scantron_lastbubblepoints'};
+ }
if (ref($parts) eq 'HASH') {
if (ref($parts->{$ressymb}) eq 'ARRAY') {
foreach my $part (@{$parts->{$ressymb}}) {
@@ -7900,7 +7998,7 @@ sub grade_student_bubbles {
}
sub scantron_upload_scantron_data {
- my ($r)=@_;
+ my ($r,$symb)=@_;
my $dom = $env{'request.role.domain'};
my $domdesc = &Apache::lonnet::domain($dom,'description');
$r->print(&Apache::loncommon::coursebrowser_javascript($dom));
@@ -7909,11 +8007,10 @@ sub scantron_upload_scantron_data {
'coursename',$dom);
my $syllabuslink = ''.&mt('Syllabus').''.
(' 'x2).&mt('(shows course personnel)');
- my $default_form_data=&defaultFormData(&get_symb($r,1));
+ my $default_form_data=&defaultFormData($symb);
my $nofile_alert = &mt('Please use the browse button to select a file from your local directory.');
my $nocourseid_alert = &mt("Please use the 'Select Course' link to open a separate window where you can search for a course to which a file can be uploaded.");
- $r->print('
-
-
-
'.&mt('Send scanned bubblesheet data to a course').'
');
return '';
@@ -7970,8 +8067,7 @@ sub scantron_upload_scantron_data {
sub scantron_upload_scantron_data_save {
- my($r)=@_;
- my ($symb)=&get_symb($r,1);
+ my($r,$symb)=@_;
my $doanotherupload=
'
'."\n".
''."\n".
@@ -7981,9 +8077,7 @@ sub scantron_upload_scantron_data_save {
!&Apache::lonnet::allowed('usc',
$env{'form.domainid'}.'_'.$env{'form.courseid'})) {
$r->print(&mt("You are not allowed to upload bubblesheet data to the requested course.")." ");
- if ($symb) {
- $r->print(&show_grading_menu_form($symb));
- } else {
+ unless ($symb) {
$r->print($doanotherupload);
}
return '';
@@ -8011,7 +8105,7 @@ sub scantron_upload_scantron_data_save {
}
}
if ($symb) {
- $r->print(&scantron_selectphase($r,$uploadedfile));
+ $r->print(&scantron_selectphase($r,$uploadedfile,$symb));
} else {
$r->print($doanotherupload);
}
@@ -8113,8 +8207,8 @@ sub valid_file {
}
sub scantron_download_scantron_data {
- my ($r)=@_;
- my $default_form_data=&defaultFormData(&get_symb($r,1));
+ my ($r,$symb)=@_;
+ my $default_form_data=&defaultFormData($symb);
my $cname=$env{'course.'.$env{'request.course.id'}.'.num'};
my $cdom=$env{'course.'.$env{'request.course.id'}.'.domain'};
my $file=$env{'form.scantron_selectfile'};
@@ -8124,7 +8218,6 @@ sub scantron_download_scantron_data {
'.&mt('The requested file name was invalid.').'
');
- $r->print(&show_grading_menu_form(&get_symb($r,1)));
return;
}
my $orig='/uploaded/'.$cdom.'/'.$cname.'/scantron_orig_'.$file;
@@ -8147,15 +8240,12 @@ sub scantron_download_scantron_data {
'','').'
');
- $r->print(&show_grading_menu_form(&get_symb($r,1)));
return '';
}
sub checkscantron_results {
- my ($r) = @_;
- my ($symb)=&get_symb($r);
+ my ($r,$symb) = @_;
if (!$symb) {return '';}
- my $grading_menu_button=&show_grading_menu_form($symb);
my $cid = $env{'request.course.id'};
my %lettdig = &letter_to_digits();
my $numletts = scalar(keys(%lettdig));
@@ -8165,6 +8255,7 @@ sub checkscantron_results {
my %record;
my %scantron_config =
&Apache::grades::get_scantron_config($env{'form.scantron_format'});
+ my $bubbles_per_row = &bubblesheet_bubbles_per_row(\%scantron_config);
my ($scanlines,$scan_data)=&Apache::grades::scantron_getfile();
my $classlist=&Apache::loncoursedata::get_classlist();
my %idmap=&Apache::grades::username_to_idmap($classlist);
@@ -8192,7 +8283,7 @@ sub checkscantron_results {
'inline',undef,'checkscantron');
my ($username,$domain,$started);
my $nav_error;
- &scantron_get_maxbubble(\$nav_error); # Need the bubble lines array to parse.
+ &scantron_get_maxbubble(\$nav_error,\%scantron_config); # Need the bubble lines array to parse.
if ($nav_error) {
$r->print(&navmap_errormsg());
return '';
@@ -8242,7 +8333,7 @@ sub checkscantron_results {
if ((exists($grader_randomlists_by_symb{$ressymb})) ||
(ref($grader_partids_by_symb{$ressymb}) ne 'ARRAY')) {
(my $analysis,$parts) =
- &scantron_partids_tograde($resource,$env{'request.course.id'},$username,$domain);
+ &scantron_partids_tograde($resource,$env{'request.course.id'},$username,$domain,undef,$bubbles_per_row);
} else {
$parts = $grader_partids_by_symb{$ressymb};
}
@@ -8287,7 +8378,15 @@ sub checkscantron_results {
}
}
}
- $r->print('
'.&mt('Comparison of bubblesheet data (including corrections) with corresponding submission records (most recent submission) for [quant,_1,student] ([_2] scantron lines/student).',$numstudents,$env{'form.scantron_maxbubble'}).'
');
+ $r->print(
+ '
'
+ .&mt('Comparison of bubblesheet data (including corrections) with corresponding submission records (most recent submission) for [_1][quant,_2,student][_3] ([quant,_4,bubblesheet line] per student).',
+ '',
+ $numstudents,
+ '',
+ $env{'form.scantron_maxbubble'})
+ .'
'
+ );
$r->print('
'.&mt('Exact matches for [quant,_1,student].',$passed).' '.&mt('Discrepancies detected for [quant,_1,student].',$failed).'
');
if ($passed) {
$r->print(&mt('Students with exact correspondence between bubblesheet data and submissions are as follows:').'
');
@@ -8308,7 +8407,7 @@ sub checkscantron_results {
&Apache::loncommon::end_data_table()).' '.
&mt('Differences can occur if submissions were modified using manual grading after a bubblesheet grading pass.').' '.&mt('If unexpected discrepancies were detected, it is recommended that you inspect the original bubblesheets.');
}
- $r->print('
'.$grading_menu_button);
+ $r->print(' ');
return;
}
@@ -8450,48 +8549,34 @@ sub letter_to_digits {
#-------------------------- Menu interface -------------------------
#
-#--- Show a Grading Menu button - Calls the next routine ---
-sub show_grading_menu_form {
- my ($symb)=@_;
- my $result.='
\n";
# Attempt to restore parameters from last session, set defaults if not present
my %Saveable_Parameters=&clicker_grading_parameters();
&Apache::loncommon::restore_course_settings('grades_clicker',
@@ -8871,7 +8902,7 @@ sub process_clicker {
}
}
- my $upload=&mt("Upload File");
+ my $upload=&mt("Evaluate File");
my $type=&mt("Type");
my $attendance=&mt("Award points just for participation");
my $personnel=&mt("Correctness determined from response by course personnel");
@@ -8881,11 +8912,10 @@ sub process_clicker {
my $pcorrect=&mt("Percentage points for correct solution");
my $pincorrect=&mt("Percentage points for incorrect solution");
my $selectform=&Apache::loncommon::select_form($env{'form.upfiletype'},'upfiletype',
- ('iclicker' => 'i>clicker',
- 'interwrite' => 'interwrite PRS'));
+ {'iclicker' => 'i>clicker',
+ 'interwrite' => 'interwrite PRS'});
$symb = &Apache::lonenc::check_encrypt($symb);
- $result.=<
+ $result.= &Apache::lonhtmlcommon::scripttag(<
+ENDUPFORM
+ $result.= <
-
-
-
-
-
+ENDUPFORM
+ $result.='
'.
+ &Apache::loncommon::end_data_table_row().
+ &Apache::loncommon::end_data_table();
return $result;
}
sub process_clicker_file {
- my ($r)=@_;
- my ($symb)=&get_symb($r);
+ my ($r,$symb)=@_;
if (!$symb) {return '';}
my %Saveable_Parameters=&clicker_grading_parameters();
&Apache::loncommon::store_course_settings('grades_clicker',
\%Saveable_Parameters);
-
- my ($result) = &showResourceInfo($symb,$env{'form.probTitle'});
+ my $result='';
if (($env{'form.gradingmechanism'} eq 'specific') && ($env{'form.specificid'}!~/\w/)) {
$result.=''.&mt('You need to specify a clicker ID for the correct answer').'';
- return $result.&show_grading_menu_form($symb);
+ return $result;
}
if (($env{'form.gradingmechanism'} eq 'given') && ($env{'form.givenanswer'}!~/\S/)) {
$result.=''.&mt('You need to specify the correct answer').'';
- return $result.&show_grading_menu_form($symb);
+ return $result;
}
my $foundgiven=0;
if ($env{'form.gradingmechanism'} eq 'given') {
$env{'form.givenanswer'}=~s/^\s*//gs;
$env{'form.givenanswer'}=~s/\s*$//gs;
- $env{'form.givenanswer'}=~s/[^a-zA-Z0-9\.\*\-]+/\,/g;
+ $env{'form.givenanswer'}=~s/[^a-zA-Z0-9\.\*\-\+]+/\,/g;
$env{'form.givenanswer'}=uc($env{'form.givenanswer'});
my @answers=split(/\,/,$env{'form.givenanswer'});
$foundgiven=$#answers+1;
@@ -9013,7 +9046,7 @@ sub process_clicker_file {
$result.="\n";
if ($number==0) {
$result.=''.&mt('No IDs found to determine correct answer').'';
- return $result.&show_grading_menu_form($symb);
+ return $result;
}
}
if (length($env{'form.upfile'}) < 2) {
@@ -9021,23 +9054,22 @@ sub process_clicker_file {
'',
'',
''.&HTML::Entities::encode($env{'form.upfile.filename'},'<>&"').'');
- return $result.&show_grading_menu_form($symb);
+ return $result;
}
# Were able to get all the info needed, now analyze the file
$result.=&Apache::loncommon::studentbrowser_javascript();
$symb = &Apache::lonenc::check_encrypt($symb);
- my $heading=&mt('Scanning clicker file');
- $result.=(<
-
-
@@ -9062,7 +9094,7 @@ ENDHEADER
' ';
if (($env{'form.gradingmechanism'} eq 'given') && ($number!=$foundgiven)) {
$result.=''.&mt('Number of given answers does not agree with number of questions in file.').'';
- return $result.&show_grading_menu_form($symb);
+ return $result;
}
# Remember Question Titles
# FIXME: Possibly need delimiter other than ":"
@@ -9082,7 +9114,9 @@ ENDHEADER
} elsif ($clicker_ids{$id}) {
if ($clicker_ids{$id}=~/\,/) {
# More than one user with the same clicker!
- $result.="\n".&mt('Clicker registered more than once').": ".$id." ";
+ $result.="".&Apache::loncommon::end_data_table_row().
+ &Apache::loncommon::start_data_table_row()."
".
+ &mt('Clicker registered more than once').": ".$id." ";
$result.="\n".''.
"
'.
+ &Apache::loncommon::end_data_table_row().
+ &Apache::loncommon::end_data_table();
+ return $result;
}
sub iclicker_eval {
@@ -9146,6 +9183,7 @@ sub iclicker_eval {
$id=~s/^[\#0]+//;
for (my $i=0;$i<$number;$i++) {
my $idx=3+$i*6;
+ $entries[$idx]=~s/[^a-zA-Z0-9\.\*\-\+]+//g;
push(@idresponses,$entries[$idx]);
}
$$responses{$id}=join(',',@idresponses);
@@ -9186,8 +9224,7 @@ sub interwrite_eval {
}
sub assign_clicker_grades {
- my ($r)=@_;
- my ($symb)=&get_symb($r);
+ my ($r,$symb)=@_;
if (!$symb) {return '';}
# See which part we are saving to
my $res_error;
@@ -9198,14 +9235,11 @@ sub assign_clicker_grades {
# FIXME: This should probably look for the first handgradeable part
my $part=$$partlist[0];
# Start screen output
- my ($result) = &showResourceInfo($symb,$env{'form.probTitle'});
-
- my $heading=&mt('Assigning grades based on clicker file');
- $result.=(<
-
-$heading
-ENDHEADER
+ my $result=&Apache::loncommon::start_data_table().
+ &Apache::loncommon::start_data_table_header_row().
+ '
'.
&mt('An error occurred retrieving information about resources in the course.').' '.
- &mt('It is recommended that you [_1]re-initialize the course[_2] and then return to this grading page..','','').
+ &mt('It is recommended that you [_1]re-initialize the course[_2] and then return to this grading page.','','').
'
');
}
}
if ($ssi_error) {
&ssi_print_error($request);
}
+ &Apache::lonquickgrades::endGradeScreen($request);
$request->print(&Apache::loncommon::end_page());
&reset_caches();
- return '';
+ return OK;
}
1;
@@ -9537,6 +9675,8 @@ ssi_with_retries()
calling routine should trap the error condition and display the warning
found in &navmap_errormsg().
+ $scantron_config - Reference to bubblesheet format configuration hash.
+
Returns the maximum number of bubble lines that are expected to
occur. Does this by walking the selected sequence rendering the
resource and then checking &Apache::lonxml::get_problem_counter()
@@ -9560,7 +9700,7 @@ ssi_with_retries()
=item scantron_process_students() :
- Routine that does the actual grading of the bubble sheet information.
+ Routine that does the actual grading of the bubblesheet information.
The parsed scanline hash is added to %env
@@ -9580,7 +9720,7 @@ ssi_with_retries()
=item scantron_upload_scantron_data() :
- Creates the screen for adding a new bubble sheet data file to a course.
+ Creates the screen for adding a new bubblesheet data file to a course.
=item scantron_upload_scantron_data_save() :
@@ -9594,7 +9734,7 @@ ssi_with_retries()
=item scantron_download_scantron_data() :
Shows a list of the three internal files (original, corrected,
- skipped) for a specific bubble sheet data file that exists in the
+ skipped) for a specific bubblesheet data file that exists in the
course.
=item scantron_validate_ID() :