'."\n".
'';
#radio buttons/text box for assigning points for a section or class.
@@ -3076,8 +3118,11 @@ sub viewgrades {
'onClick="javascript:submit();" target="_self" />'."\n";
if (scalar(%$fullname) eq 0) {
my $colspan=3+scalar(@parts);
- $result='There are no students in section "'.$env{'form.section'}.
- '" with enrollment status "'.$env{'form.Status'}.'" to modify or grade.';
+ my $section_display = join (", ",&Apache::loncommon::get_env_multiple('form.section'));
+ $result=''.
+ &mt('There are no students in section(s) [_1] with enrollment status [_2] to modify or grade',
+ $section_display, $env{'form.Status'}).
+ '';
}
$result.=&show_grading_menu_form($symb);
return $result;
@@ -3154,9 +3199,10 @@ sub editgrades {
my ($request) = @_;
my $symb=&get_symb($request);
- my $title='Current Grade Status';
- $title.='Current Resource: '.$env{'form.probTitle'}.' '."\n";
- $title.='Section: '.$env{'form.section'}.''."\n";
+ my $section_display = join (", ",&Apache::loncommon::get_env_multiple('form.section'));
+ my $title=''.&mt('Current Grade Status').'';
+ $title.=''.&mt('Current Resource: [_1]',$env{'form.probTitle'}).' '."\n";
+ $title.=''.&mt('Section: [_1]',$section_display).''."\n";
my $result= ''."\n";
$result.= ''.
@@ -3354,7 +3400,7 @@ sub split_part_type {
my ($partstr) = @_;
my ($temp,@allparts)=split(/_/,$partstr);
my $type=pop(@allparts);
- my $part=join('.',@allparts);
+ my $part=join('_',@allparts);
return ($part,$type);
}
@@ -3857,9 +3903,9 @@ LISTJAVASCRIPT
''."\n".
''."\n".
''."\n";
-
- $result.=''."\n".
- ''."\n".
+
+ $result.=&build_section_inputs();
+ $result.=''."\n".
''."\n".
''."\n".
''." \n";
@@ -4357,9 +4403,47 @@ sub updateGradeByPage {
=head1 Bubble sheet grading routines
- (For this documentation 'scanline' refers to the full line of characters
- from the file that we are parsing 'bubble line' refers to the data
- representing the line of bubbles that are on the physical bubble sheet)
+ For this documentation:
+
+ 'scanline' refers to the full line of characters
+ 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
+
+
+The overall process is that a scanned in bubble sheet 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
+one of the predefined configurations for what each scanline looks
+like.
+
+Next each scanline is checked for any errors of either 'missing
+bubbles' (it's an error because it may have been mis-scanned
+because too light bubbling), 'double bubble' (each bubble line should
+have no more that one letter picked), invalid or duplicated CODE,
+invalid student ID
+
+If the CODE option is used that determines the randomization of the
+homework problems, either way the student ID is looked up into a
+username:domain.
+
+During the validation phase the instructor can choose to skip scanlines.
+
+After the validation phase, there are now 3 bubble sheet 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
+file (see &scantron_getfile() for more information)
+
+After all scanlines are either valid, marked as valid or skipped, then
+foreach line foreach problem in the picked sequence, an ssi request is
+made that simulates a user submitting their selected letter(s) against
+the homework problem.
=over 4
@@ -4531,7 +4615,7 @@ sub scantron_CODEunique {
Generates the initial screen to start the bubble sheet process.
Allows for - starting a grading run.
- - downloading exisiting scan data (original, corrected
+ - downloading existing scan data (original, corrected
or skipped info)
- uploading new scan data
@@ -4589,7 +4673,7 @@ sub scantron_selectphase {
Options: |
-
+
|
@@ -4732,17 +4816,18 @@ SCANTRONFORM
'questions' start
Qlength - number of columns comprising a single bubble line from
the sheet. (usually either 1 or 10)
- Qon - either a single charater representing the character used
+ Qon - either a single character representing the character used
to signal a bubble was chosen in the positional setup, or
the string 'letter' if the letter of the chosen bubble is
in the final, or 'number' if a number representing the
chosen bubble is in the file (1->A 0->J)
- Qoff - the character used to represent that a buble was left blank
+ Qoff - the character used to represent that a bubble was
+ left blank
PaperID - if the scanning process generates a unique number for each
sheet scanned the column that this ID number starts in
PaperIDlength - number of columns that comprise the unique ID number
for the sheet of paper
- FirstName - column that the firs tname starts in
+ FirstName - column that the first name starts in
FirstNameLength - number of columns that the first name spans
LastName - column that the last name starts in
@@ -4793,7 +4878,7 @@ sub get_scantron_config {
$classlist - reference to the class list hash. This is a hash
keyed by student name:domain whose elements are references
- to arrays containng various chunks of information
+ to arrays containing various chunks of information
about the student. (See loncoursedata for more info).
Returns
@@ -4813,7 +4898,7 @@ sub username_to_idmap {
=pod
-=item scatron_fixup_scanline
+=item scantron_fixup_scanline
Process a requested correction to a scanline.
@@ -4832,12 +4917,12 @@ sub username_to_idmap {
$args - hash of additional info,
- 'ID'
'newid' -> studentID to use in replacement
- of exisiting one
+ of existing one
- 'CODE'
'CODE_ignore_dup' - set to true if duplicates
should be ignored.
'CODE' - is new code or 'use_unfound'
- if the exisitng unfound code should
+ if the existing unfound code should
be used as is
- 'answer'
'response' - new answer or 'none' if blank
@@ -4920,7 +5005,7 @@ sub scantron_fixup_scanline {
Arguments:
$scan_data - The hash (see scantron_getfile)
$key - shorthand of the key to edit (actual key is
- scatronfilename_key).
+ scantronfilename_key).
$data - New value of the hash entry.
$delete - If true, the entry is removed from the hash.
@@ -5107,13 +5192,13 @@ sub scantron_parse_scanline {
queue of messages to be shown after grading pass is complete
Arguments:
- $delayqueue - arrary ref of hash ref of erro messages
+ $delayqueue - arrary ref of hash ref of error messages
$scanline - the scanline that caused the error
$errormesage - the error message
$errorcode - a numeric code for the error
Side Effects:
- updates the $dealyqueue to have a new hash ref of the error
+ updates the $delayqueue to have a new hash ref of the error
=cut
@@ -5129,6 +5214,18 @@ sub scantron_add_delay {
=item scantron_find_student
+ Finds the username for the current scanline
+
+ Arguments:
+ $scantron_record - hash result from scantron_parse_scanline
+ $scan_data - hash of correction information
+ (see &scantron_getfile() form more information)
+ $idmap - hash from &username_to_idmap()
+ $line - number of current scanline
+
+ Returns:
+ Either 'username:domain' or undef if unknown
+
=cut
sub scantron_find_student {
@@ -5149,6 +5246,9 @@ sub scantron_find_student {
=item scantron_filter
+ Filter sub for lonnavmaps, filters out hidden resources if ignore
+ hidden resources was selected
+
=cut
sub scantron_filter {
@@ -5171,6 +5271,9 @@ sub scantron_filter {
=item scantron_process_corrections
+ Gets correction information out of submitted form data and corrects
+ the scanline
+
=cut
sub scantron_process_corrections {
@@ -5234,6 +5337,10 @@ sub scantron_process_corrections {
=item reset_skipping_status
+ Forgets the current set of remember skipped scanlines (and thus
+ reverts back to considering all lines in the
+ scantron_skipped_ file)
+
=cut
sub reset_skipping_status {
@@ -5246,6 +5353,8 @@ sub reset_skipping_status {
=item start_skipping
+ Marks a scanline to be skipped.
+
=cut
sub start_skipping {
@@ -5263,6 +5372,8 @@ sub start_skipping {
=item should_be_skipped
+ Checks whether a scanline should be skipped.
+
=cut
sub should_be_skipped {
@@ -5284,6 +5395,9 @@ sub should_be_skipped {
=item remember_current_skipped
+ Discovers what scanlines are in the scantron_skipped_
+ file and remembers them into scan_data for later use.
+
=cut
sub remember_current_skipped {
@@ -5303,6 +5417,10 @@ 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
+ something went wrong.
+
=cut
sub check_for_error {
@@ -5316,6 +5434,9 @@ sub check_for_error {
=item scantron_warning_screen
+ Interstitial screen to make sure the operator has selected the
+ correct options before we start the validation phase.
+
=cut
sub scantron_warning_screen {
@@ -5354,6 +5475,9 @@ STUFF
=item scantron_do_warning
+ Check if the operator has picked something for all required
+ fields. Error out if something is missing.
+
=cut
sub scantron_do_warning {
@@ -5391,6 +5515,8 @@ STUFF
=item scantron_form_start
+ html hidden input for remembering all selected grading options
+
=cut
sub scantron_form_start {
@@ -5414,6 +5540,12 @@ SCANTRONFORM
=item scantron_validate_file
+ Dispatch routine for doing validation of a bubble sheet data file.
+
+ Also processes any necessary information resets that need to
+ occur before validation begins (ignore previous corrections,
+ restarting the skipped records processing)
+
=cut
sub scantron_validate_file {
@@ -5423,7 +5555,7 @@ sub scantron_validate_file {
my $default_form_data=&defaultFormData($symb);
# do the detection of only doing skipped records first befroe we delete
- # them when doing the corrections reset
+ # them when doing the corrections reset
if ($env{'form.scantron_options_redo'} ne 'redo_skipped_ready') {
&reset_skipping_status();
}
@@ -5442,7 +5574,7 @@ sub scantron_validate_file {
if ($env{'form.scantron_corrections'}) {
&scantron_process_corrections($r);
}
- $r->print("Gathering neccessary info. ");$r->rflush();
+ $r->print("Gathering necessary info. ");$r->rflush();
#get the student pick code ready
$r->print(&Apache::loncommon::studentbrowser_javascript());
my $max_bubble=&scantron_get_maxbubble();
@@ -5504,6 +5636,10 @@ STUFF
=item scantron_remove_file
+ Removes the requested bubble sheet data file, makes sure that
+ scantron_original_ is never removed
+
+
=cut
sub scantron_remove_file {
@@ -5525,6 +5661,11 @@ sub scantron_remove_file {
=item scantron_remove_scan_data
+ Removes all scan_data correction for the requested bubble sheet
+ 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.)
+
=cut
sub scantron_remove_scan_data {
@@ -5554,6 +5695,44 @@ sub scantron_remove_scan_data {
=item scantron_getfile
+ Fetches the requested bubble sheet data file (all 3 versions), and
+ the scan_data hash
+
+ Arguments:
+ None
+
+ Returns:
+ 2 hash references
+
+ - first one has
+ orig -
+ corrected -
+ skipped - each of which points to an array ref of the specified
+ file broken up into individual lines
+ count - number of scanlines
+
+ - second is the scan_data hash possible keys are
+ ($number refers to scanline numbered $number and thus the key affects
+ only that scanline
+ $bubline refers to the specific bubble line element and the aspects
+ refers to that specific bubble line element)
+
+ $number.user - username:domain to use
+ $number.CODE_ignore_dup
+ - ignore the duplicate CODE error
+ $number.useCODE
+ - use the CODE in the scanline as is
+ $number.no_bubble.$bubline
+ - it is valid that there is no bubbled in bubble
+ at $number $bubline
+ remember_skipping
+ - a frozen hash containing keys of $number and values
+ of either
+ 1 - we are on a 'do skipped records pass' and plan
+ on processing this line
+ 2 - we are on a 'do skipped records pass' and this
+ scanline has been marked to skip yet again
+
=cut
sub scantron_getfile {
@@ -5592,6 +5771,15 @@ sub scantron_getfile {
=item lonnet_putfile
+ Wrapper routine to call &Apache::lonnet::finishuserfileupload
+
+ Arguments:
+ $contents - data to store
+ $filename - filename to store $contents into
+
+ Returns:
+ result value from &Apache::lonnet::finishuserfileupload
+
=cut
sub lonnet_putfile {
@@ -5607,6 +5795,16 @@ sub lonnet_putfile {
=item scantron_putfile
+ Stores the current version of the bubble sheet data files, and the
+ scan_data hash. (Does not modify the original version only the
+ corrected and skipped versions.
+
+ Arguments:
+ $scanlines - hash ref that looks like the first return value from
+ &scantron_getfile()
+ $scan_data - hash ref that looks like the second return value from
+ &scantron_getfile()
+
=cut
sub scantron_putfile {
@@ -5633,6 +5831,22 @@ sub scantron_putfile {
=item scantron_get_line
+ Returns the correct version of the scanline
+
+ Arguments:
+ $scanlines - hash ref that looks like the first return value from
+ &scantron_getfile()
+ $scan_data - hash ref that looks like the second return value from
+ &scantron_getfile()
+ $i - number of the requested line (starts at 0)
+
+ Returns:
+ A scanline, (either the original or the corrected one if it
+ exists), or undef if the requested scanline should be
+ skipped. (Either because it's an skipped scanline, or it's an
+ unskipped scanline and we are not doing a 'do skipped scanlines'
+ pass.
+
=cut
sub scantron_get_line {
@@ -5647,6 +5861,17 @@ sub scantron_get_line {
=item scantron_todo_count
+ Counts the number of scanlines that need processing.
+
+ Arguments:
+ $scanlines - hash ref that looks like the first return value from
+ &scantron_getfile()
+ $scan_data - hash ref that looks like the second return value from
+ &scantron_getfile()
+
+ Returns:
+ $count - number of scanlines to process
+
=cut
sub get_todo_count {
@@ -5664,6 +5889,19 @@ sub get_todo_count {
=item scantron_put_line
+ Updates the 'corrected' or 'skipped' versions of the bubble sheet
+ data file.
+
+ Arguments:
+ $scanlines - hash ref that looks like the first return value from
+ &scantron_getfile()
+ $scan_data - hash ref that looks like the second return value from
+ &scantron_getfile()
+ $i - line number to update
+ $newline - contents of the updated scanline
+ $skip - if true make the line for skipping and update the
+ 'skipped' file
+
=cut
sub scantron_put_line {
@@ -5680,6 +5918,15 @@ sub scantron_put_line {
=item scantron_clear_skip
+ Remove a line from the 'skipped' file
+
+ Arguments:
+ $scanlines - hash ref that looks like the first return value from
+ &scantron_getfile()
+ $scan_data - hash ref that looks like the second return value from
+ &scantron_getfile()
+ $i - line number to update
+
=cut
sub scantron_clear_skip {
@@ -5695,6 +5942,9 @@ sub scantron_clear_skip {
=item scantron_filter_not_exam
+ Filter routine used by &Apache::lonnavmaps::retrieveResources(), to
+ filter out resources that are not marked as 'exam' mode
+
=cut
sub scantron_filter_not_exam {
@@ -5717,6 +5967,9 @@ sub scantron_filter_not_exam {
=item scantron_validate_sequence
+ Validates the selected sequence, checking for resource that are
+ not set to exam mode.
+
=cut
sub scantron_validate_sequence {
@@ -5746,6 +5999,9 @@ sub scantron_validate_sequence {
=item scantron_validate_ID
+ Validates all scanlines in the selected file to not have any
+ invalid or underspecified student IDs
+
=cut
sub scantron_validate_ID {
@@ -5814,6 +6070,30 @@ sub scantron_validate_ID {
=item scantron_get_correction
+ Builds the interface screen to interact with the operator to fix a
+ specific error condition in a specific scanline
+
+ Arguments:
+ $r - Apache request object
+ $i - number of the current scanline
+ $scan_record - hash ref as returned from &scantron_parse_scanline()
+ $scan_config - hash ref as returned from &get_scantron_config()
+ $line - full contents of the current scanline
+ $error - error condition, valid values are
+ 'incorrectCODE', 'duplicateCODE',
+ 'doublebubble', 'missingbubble',
+ 'duplicateID', 'incorrectID'
+ $arg - extra information needed
+ For errors:
+ - duplicateID - paper number that this studentID was seen before on
+ - duplicateCODE - array ref of the paper numbers this CODE was
+ seen on before
+ - incorrectCODE - current incorrect CODE
+ - doublebubble - array ref of the bubble lines that have double
+ bubble errors
+ - missingbubble - array ref of the bubble lines that have missing
+ bubble errors
+
=cut
sub scantron_get_correction {
@@ -5945,7 +6225,7 @@ ENDSCRIPT
=item scantron_bubble_selector
Generates the html radiobuttons to correct a single bubble line
- possibly showing the exisiting the selected bubbles if known
+ possibly showing the existing the selected bubbles if known
Arguments:
$r - Apache request object
@@ -6021,6 +6301,16 @@ sub scantron_bubble_selector {
=item num_matches
+ Counts the number of characters that are the same between the two arguments.
+
+ Arguments:
+ $orig - CODE from the scanline
+ $code - CODE to match against
+
+ Returns:
+ $count - integer count of the number of same characters between the
+ two arguments
+
=cut
sub num_matches {
@@ -6038,6 +6328,20 @@ sub num_matches {
=item scantron_get_closely_matching_CODEs
+ Cycles through all CODEs and finds the set that has the greatest
+ number of same characters as the provided CODE
+
+ Arguments:
+ $allcodes - hash ref returned by &get_codes()
+ $CODE - CODE from the current scanline
+
+ Returns:
+ 2 element list
+ - first elements is number of how closely matching the best fit is
+ (5 means best set has 5 matching characters)
+ - second element is an arrary ref containing the set of valid CODEs
+ that best fit the passed in CODE
+
=cut
sub scantron_get_closely_matching_CODEs {
@@ -6054,6 +6358,17 @@ sub scantron_get_closely_matching_CODEs
=item get_codes
+ Builds a hash which has keys of all of the valid CODEs from the selected
+ set of remembered CODEs.
+
+ Arguments:
+ $old_name - name of the set of remembered CODEs
+ $cdom - domain of the course
+ $cnum - internal course name
+
+ Returns:
+ %allcodes - keys are the valid CODEs, values are all 1
+
=cut
sub get_codes {
@@ -6082,6 +6397,10 @@ sub get_codes {
=item scantron_validate_CODE
+ Validates all scanlines in the selected file to not have any
+ invalid or underspecified CODEs and that none of the codes are
+ duplicated if this was requested.
+
=cut
sub scantron_validate_CODE {
@@ -6139,6 +6458,9 @@ sub scantron_validate_CODE {
=item scantron_validate_doublebubble
+ Validates all scanlines in the selected file to not have any
+ bubble lines with multiple bubbles marked.
+
=cut
sub scantron_validate_doublebubble {
@@ -6168,9 +6490,17 @@ sub scantron_validate_doublebubble {
=item scantron_get_maxbubble
+ 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()
+ for what the current value of the problem counter is.
+
+ Caches the result to $env{'form.scantron_maxbubble'}
+
=cut
sub scantron_get_maxbubble {
+
if (defined($env{'form.scantron_maxbubble'}) &&
$env{'form.scantron_maxbubble'}) {
return $env{'form.scantron_maxbubble'};
@@ -6185,14 +6515,40 @@ sub scantron_get_maxbubble {
&Apache::lonxml::clear_problem_counter();
+ my $uname = $env{'form.student'};
+ my $udom = $env{'form.userdom'};
+ my $cid = $env{'request.course.id'};
+ my $total_lines = 0;
+ %bubble_lines_per_response = ();
+
foreach my $resource (@resources) {
+ my $symb = $resource->symb();
my $result=&Apache::lonnet::ssi($resource->src(),
- ('symb' => $resource->symb()));
+ ('symb' => $resource->symb()),
+ ('grade_target' => 'analyze'),
+ ('grade_courseid' => $cid),
+ ('grade_domain' => $udom),
+ ('grade_username' => $uname));
+ my (undef, $an) =
+ split(/_HASH_REF__/,$result, 2);
+
+ my %analysis = &Apache::lonnet::str2hash($an);
+
+
+
+ foreach my $part_id (@{$analysis{'parts'}}) {
+ my $bubble_lines = $analysis{"$part_id.bubble_lines"}[0];
+ if (!$bubble_lines) {
+ $bubble_lines = 1;
+ }
+ $bubble_lines_per_response{"$symb.$part_id"} = $bubble_lines;
+ $total_lines = $total_lines + $bubble_lines;
+ }
+
}
&Apache::lonnet::delenv('scantron\.');
$env{'form.scantron_maxbubble'} =
- &Apache::lonxml::get_problem_counter()-1;
-
+ $total_lines;
return $env{'form.scantron_maxbubble'};
}
@@ -6200,6 +6556,9 @@ sub scantron_get_maxbubble {
=item scantron_validate_missingbubbles
+ Validates all scanlines in the selected file to not have any
+ bubble lines with missing bubbles that haven't been verified as missing.
+
=cut
sub scantron_validate_missingbubbles {
@@ -6474,7 +6833,7 @@ sub scantron_upload_scantron_data_save {
=item valid_file
- Vaildates that the requested bubble data file has exists in the course.
+ Validates that the requested bubble data file exists in the course.
=cut
@@ -6638,7 +6997,7 @@ GRADINGMENUJS
$result.='';
$result.=''."\n".
- ' '.&mt('Select Section').': |
|
|
|