Diff for /loncom/homework/grades.pm between versions 1.423 and 1.424

version 1.423, 2007/07/24 21:21:31 version 1.424, 2007/07/25 00:00:23
Line 4357  sub updateGradeByPage { Line 4357  sub updateGradeByPage {
   
 =head1 Bubble sheet grading routines  =head1 Bubble sheet grading routines
   
   (For this documentation 'scanline' refers to the full line of characters    For this documentation:
    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)     '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 missed 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 is 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  =over 4
   
Line 4531  sub scantron_CODEunique { Line 4569  sub scantron_CODEunique {
   
   Generates the initial screen to start the bubble sheet process.    Generates the initial screen to start the bubble sheet process.
   Allows for - starting a grading run.    Allows for - starting a grading run.
              - downloading exisiting scan data (original, corrected               - downloading existing scan data (original, corrected
                                                 or skipped info)                                                  or skipped info)
   
              - uploading new scan data               - uploading new scan data
Line 4589  sub scantron_selectphase { Line 4627  sub scantron_selectphase {
     <td> Options: </td>      <td> Options: </td>
             <td>              <td>
        <label><input type="checkbox" name="scantron_options_redo" value="redo_skipped"/> Do only previously skipped records</label> <br />         <label><input type="checkbox" name="scantron_options_redo" value="redo_skipped"/> Do only previously skipped records</label> <br />
                <label><input type="checkbox" name="scantron_options_ignore" value="ignore_corrections"/> Remove all exisiting corrections</label> <br />                 <label><input type="checkbox" name="scantron_options_ignore" value="ignore_corrections"/> Remove all existing corrections</label> <br />
                <label><input type="checkbox" name="scantron_options_hidden" value="ignore_hidden"/> Skip hidden resources when grading</label>                 <label><input type="checkbox" name="scantron_options_hidden" value="ignore_hidden"/> Skip hidden resources when grading</label>
     </td>      </td>
           </tr>            </tr>
Line 4732  SCANTRONFORM Line 4770  SCANTRONFORM
                     'questions' start                      'questions' start
       Qlength     - number of columns comprising a single bubble line from        Qlength     - number of columns comprising a single bubble line from
                     the sheet. (usually either 1 or 10)                      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                      to signal a bubble was chosen in the positional setup, or
                     the string 'letter' if the letter of the chosen bubble is                      the string 'letter' if the letter of the chosen bubble is
                     in the final, or 'number' if a number representing the                      in the final, or 'number' if a number representing the
                     chosen bubble is in the file (1->A 0->J)                      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        PaperID     - if the scanning process generates a unique number for each
                     sheet scanned the column that this ID number starts in                      sheet scanned the column that this ID number starts in
       PaperIDlength - number of columns that comprise the unique ID number        PaperIDlength - number of columns that comprise the unique ID number
                       for the sheet of paper                        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        FirstNameLength - number of columns that the first name spans
     
       LastName    - column that the last name starts in        LastName    - column that the last name starts in
Line 4793  sub get_scantron_config { Line 4832  sub get_scantron_config {
   
     $classlist - reference to the class list hash. This is a hash      $classlist - reference to the class list hash. This is a hash
                  keyed by student name:domain  whose elements are references                   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).                   about the student. (See loncoursedata for more info).
   
   Returns    Returns
Line 4813  sub username_to_idmap { Line 4852  sub username_to_idmap {
   
 =pod  =pod
   
 =item scatron_fixup_scanline  =item scantron_fixup_scanline
   
    Process a requested correction to a scanline.     Process a requested correction to a scanline.
   
Line 4832  sub username_to_idmap { Line 4871  sub username_to_idmap {
    $args               - hash of additional info,     $args               - hash of additional info,
                           - 'ID'                             - 'ID' 
                                'newid' -> studentID to use in replacement                                 'newid' -> studentID to use in replacement
                                           of exisiting one                                            of existing one
                           - 'CODE'                             - 'CODE' 
                                'CODE_ignore_dup' - set to true if duplicates                                 'CODE_ignore_dup' - set to true if duplicates
                                                    should be ignored.                                                     should be ignored.
                        'CODE' - is new code or 'use_unfound'                         'CODE' - is new code or 'use_unfound'
                                         if the exisitng unfound code should                                          if the existing unfound code should
                                         be used as is                                          be used as is
                           - 'answer'                            - 'answer'
                                'response' - new answer or 'none' if blank                                 'response' - new answer or 'none' if blank
Line 4920  sub scantron_fixup_scanline { Line 4959  sub scantron_fixup_scanline {
   Arguments:    Arguments:
     $scan_data  - The hash (see scantron_getfile)      $scan_data  - The hash (see scantron_getfile)
     $key        - shorthand of the key to edit (actual key is      $key        - shorthand of the key to edit (actual key is
                   scatronfilename_key).                    scantronfilename_key).
     $data        - New value of the hash entry.      $data        - New value of the hash entry.
     $delete      - If true, the entry is removed from the hash.      $delete      - If true, the entry is removed from the hash.
   
Line 5107  sub scantron_parse_scanline { Line 5146  sub scantron_parse_scanline {
    queue of messages to be shown after grading pass is complete     queue of messages to be shown after grading pass is complete
   
  Arguments:   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     $scanline    - the scanline that caused the error
    $errormesage - the error message     $errormesage - the error message
    $errorcode   - a numeric code for the error     $errorcode   - a numeric code for the error
   
  Side Effects:   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  =cut
   
Line 5129  sub scantron_add_delay { Line 5168  sub scantron_add_delay {
   
 =item scantron_find_student  =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  =cut
   
 sub scantron_find_student {  sub scantron_find_student {
Line 5149  sub scantron_find_student { Line 5200  sub scantron_find_student {
   
 =item scantron_filter  =item scantron_filter
   
      Filter sub for lonnavmaps, filters out hidden resources if ignore
      hidden resources was selected
   
 =cut  =cut
   
 sub scantron_filter {  sub scantron_filter {
Line 5171  sub scantron_filter { Line 5225  sub scantron_filter {
   
 =item scantron_process_corrections  =item scantron_process_corrections
   
      Gets correction information out of submitted form data and corrects
      the scanline
   
 =cut  =cut
   
 sub scantron_process_corrections {  sub scantron_process_corrections {
Line 5234  sub scantron_process_corrections { Line 5291  sub scantron_process_corrections {
   
 =item reset_skipping_status  =item reset_skipping_status
   
      Forgets the current set of remember skipped scanlines (and thus
      reverts back to considering all lines in the
      scantron_skipped_<filename> file)
   
 =cut  =cut
   
 sub reset_skipping_status {  sub reset_skipping_status {
Line 5246  sub reset_skipping_status { Line 5307  sub reset_skipping_status {
   
 =item start_skipping  =item start_skipping
   
      Marks a scanline to be skipped. 
   
 =cut  =cut
   
 sub start_skipping {  sub start_skipping {
Line 5263  sub start_skipping { Line 5326  sub start_skipping {
   
 =item should_be_skipped  =item should_be_skipped
   
      Checks whether a scanline should be skipped.
   
 =cut  =cut
   
 sub should_be_skipped {  sub should_be_skipped {
Line 5284  sub should_be_skipped { Line 5349  sub should_be_skipped {
   
 =item remember_current_skipped  =item remember_current_skipped
   
      Discovers what scanlines are in the scantron_skipped_<filename>
      file and remembers them into scan_data for later use.
   
 =cut  =cut
   
 sub remember_current_skipped {  sub remember_current_skipped {
Line 5303  sub remember_current_skipped { Line 5371  sub remember_current_skipped {
   
 =item check_for_error  =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  =cut
   
 sub check_for_error {  sub check_for_error {
Line 5316  sub check_for_error { Line 5388  sub check_for_error {
   
 =item scantron_warning_screen  =item scantron_warning_screen
   
      Interstitial screen to make sure the operator has selected the
      correct options before we start the validation phase.
   
 =cut  =cut
   
 sub scantron_warning_screen {  sub scantron_warning_screen {
Line 5354  STUFF Line 5429  STUFF
   
 =item scantron_do_warning  =item scantron_do_warning
   
      Check if the operator has picked something for all required
      fields. Error out if something is missing.
   
 =cut  =cut
   
 sub scantron_do_warning {  sub scantron_do_warning {
Line 5391  STUFF Line 5469  STUFF
   
 =item scantron_form_start  =item scantron_form_start
   
       html hidden input for remembering all selected grading options
   
 =cut  =cut
   
 sub scantron_form_start {  sub scantron_form_start {
Line 5414  SCANTRONFORM Line 5494  SCANTRONFORM
   
 =item scantron_validate_file  =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  =cut
   
 sub scantron_validate_file {  sub scantron_validate_file {
Line 5423  sub scantron_validate_file { Line 5509  sub scantron_validate_file {
     my $default_form_data=&defaultFormData($symb);      my $default_form_data=&defaultFormData($symb);
           
     # do the detection of only doing skipped records first befroe we delete      # 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') {      if ($env{'form.scantron_options_redo'} ne 'redo_skipped_ready') {
  &reset_skipping_status();   &reset_skipping_status();
     }      }
Line 5442  sub scantron_validate_file { Line 5528  sub scantron_validate_file {
     if ($env{'form.scantron_corrections'}) {      if ($env{'form.scantron_corrections'}) {
  &scantron_process_corrections($r);   &scantron_process_corrections($r);
     }      }
     $r->print("<p>Gathering neccessary info.</p>");$r->rflush();      $r->print("<p>Gathering necessary info.</p>");$r->rflush();
     #get the student pick code ready      #get the student pick code ready
     $r->print(&Apache::loncommon::studentbrowser_javascript());      $r->print(&Apache::loncommon::studentbrowser_javascript());
     my $max_bubble=&scantron_get_maxbubble();      my $max_bubble=&scantron_get_maxbubble();
Line 5504  STUFF Line 5590  STUFF
   
 =item scantron_remove_file  =item scantron_remove_file
   
      Removes the requested bubble sheet data file, makes sure that
      scantron_original_<filename> is never removed
   
   
 =cut  =cut
   
 sub scantron_remove_file {  sub scantron_remove_file {
Line 5525  sub scantron_remove_file { Line 5615  sub scantron_remove_file {
   
 =item scantron_remove_scan_data  =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  =cut
   
 sub scantron_remove_scan_data {  sub scantron_remove_scan_data {
Line 5554  sub scantron_remove_scan_data { Line 5649  sub scantron_remove_scan_data {
   
 =item scantron_getfile  =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
   
 =cut  =cut
   
 sub scantron_getfile {  sub scantron_getfile {
Line 5592  sub scantron_getfile { Line 5705  sub scantron_getfile {
   
 =item lonnet_putfile  =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  =cut
   
 sub lonnet_putfile {  sub lonnet_putfile {
Line 5607  sub lonnet_putfile { Line 5729  sub lonnet_putfile {
   
 =item scantron_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  =cut
   
 sub scantron_putfile {  sub scantron_putfile {
Line 5633  sub scantron_putfile { Line 5765  sub scantron_putfile {
   
 =item scantron_get_line  =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  =cut
   
 sub scantron_get_line {  sub scantron_get_line {
Line 5647  sub scantron_get_line { Line 5795  sub scantron_get_line {
   
 =item scantron_todo_count  =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  =cut
   
 sub get_todo_count {  sub get_todo_count {
Line 5664  sub get_todo_count { Line 5823  sub get_todo_count {
   
 =item scantron_put_line  =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  =cut
   
 sub scantron_put_line {  sub scantron_put_line {
Line 5680  sub scantron_put_line { Line 5852  sub scantron_put_line {
   
 =item scantron_clear_skip  =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  =cut
   
 sub scantron_clear_skip {  sub scantron_clear_skip {
Line 5695  sub scantron_clear_skip { Line 5876  sub scantron_clear_skip {
   
 =item scantron_filter_not_exam  =item scantron_filter_not_exam
   
      Filter routine used by &Apache::lonnavmaps::retrieveResources(), to
      filter out resources that are not marked as 'exam' mode
   
 =cut  =cut
   
 sub scantron_filter_not_exam {  sub scantron_filter_not_exam {
Line 5717  sub scantron_filter_not_exam { Line 5901  sub scantron_filter_not_exam {
   
 =item scantron_validate_sequence  =item scantron_validate_sequence
   
       Validates the selected sequence, checking for resource that are
       not set to exam mode.
   
 =cut  =cut
   
 sub scantron_validate_sequence {  sub scantron_validate_sequence {
Line 5746  sub scantron_validate_sequence { Line 5933  sub scantron_validate_sequence {
   
 =item scantron_validate_ID  =item scantron_validate_ID
   
      Validates all scanlines in the selected file to not have any
      invalid or underspecified student IDs
   
 =cut  =cut
   
 sub scantron_validate_ID {  sub scantron_validate_ID {
Line 5814  sub scantron_validate_ID { Line 6004  sub scantron_validate_ID {
   
 =item scantron_get_correction  =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  =cut
   
 sub scantron_get_correction {  sub scantron_get_correction {
Line 5945  ENDSCRIPT Line 6159  ENDSCRIPT
 =item scantron_bubble_selector  =item scantron_bubble_selector
       
    Generates the html radiobuttons to correct a single bubble line     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:   Arguments:
     $r           - Apache request object      $r           - Apache request object
Line 6021  sub scantron_bubble_selector { Line 6235  sub scantron_bubble_selector {
   
 =item num_matches  =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  =cut
   
 sub num_matches {  sub num_matches {
Line 6038  sub num_matches { Line 6262  sub num_matches {
   
 =item scantron_get_closely_matching_CODEs  =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  =cut
   
 sub scantron_get_closely_matching_CODEs {  sub scantron_get_closely_matching_CODEs {
Line 6054  sub scantron_get_closely_matching_CODEs Line 6292  sub scantron_get_closely_matching_CODEs
   
 =item get_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  =cut
   
 sub get_codes {  sub get_codes {
Line 6082  sub get_codes { Line 6331  sub get_codes {
   
 =item scantron_validate_CODE  =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  =cut
   
 sub scantron_validate_CODE {  sub scantron_validate_CODE {
Line 6139  sub scantron_validate_CODE { Line 6392  sub scantron_validate_CODE {
   
 =item scantron_validate_doublebubble  =item scantron_validate_doublebubble
   
      Validates all scanlines in the selected file to not have any
      bubble lines with multiple bubbles marked.
   
 =cut  =cut
   
 sub scantron_validate_doublebubble {  sub scantron_validate_doublebubble {
Line 6168  sub scantron_validate_doublebubble { Line 6424  sub scantron_validate_doublebubble {
   
 =item scantron_get_maxbubble  =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  =cut
   
 sub scantron_get_maxbubble {      sub scantron_get_maxbubble {    
Line 6200  sub scantron_get_maxbubble { Line 6463  sub scantron_get_maxbubble {
   
 =item scantron_validate_missingbubbles  =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  =cut
   
 sub scantron_validate_missingbubbles {  sub scantron_validate_missingbubbles {
Line 6474  sub scantron_upload_scantron_data_save { Line 6740  sub scantron_upload_scantron_data_save {
   
 =item valid_file  =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  =cut
   

Removed from v.1.423  
changed lines
  Added in v.1.424


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>