Nugrade is one of the first scripts I wrote, way back at UMD, that anyone else ever used. I'm kind of proud of it because said user still uses it, and I haven't modified it in over two years. It doesn't have a lot of the nice things I might do (like pod) were I to write it now, but yeah, it's historical and neat and works.

Thank you Meesh for being such a loyal user, and great friend!

The source tarball with examples: nugrade.tgz Distributed under the GNU General Public License but please let me know if you use it, so I can do some of those nice things, including adding copying information to the source.

Smiles,
Grem

usage: grade [-help] [-format [name]] [-verbose n] gradefile(s)
  -help              get more extensive help.  Pipe it to more or less!

  -format [name]     create a file (optionally called _name_) in the format
                     specified, containing the output table of grades. 
                     format will be one of the following
      -txt (default) tab delimited text (default output to standard out)
      -html          html3 table (default output to 'basename.html')
      -latex         latex (not 2e) table (default output to 'basename.tex')  
      name           '$currfile' or '${currfile}' in the name will
                     be replaced by the file name being processed. 

  -verbose n
       n=0 (default) show warnings and errors 
       n=1           show executable name, version string, 
                     and progress messages.  
       n=2           show internal diagnostics
       n=-1          stay silent (will print a newline on error)


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The Grading Policy
==================

            Target _target_
            Sort [up|down]   _column_name_
1 or more:  _section_name_[!]  _weight_[-_dropcount_]

  _target_       the desired location of the median in letter grade assignment.
  _column_name_  the column to sort up or down by.  This is done after all
                 calculations have been performed.  Columns with positive 
                 maxima will be sorted numerically, the rest in dictionary 
                 order.
  _section_name_ grades are usually done in sections, like quizzes, homeworks,
                 and so on.  This name is used to identify the section that
                 a particular column belongs to in the _assignment_ line.
  !              an optional exclamation point after the section name will 
                 suppress output for that column. 
  _weight_       the contribution of this section to the total grade, as a
                 portion of the sum of all _weight_s for which the section 
                 subtotal is positive (there are assignments whose maxima are
                 nonzero).
  _dropcount_    the number of assignments in the section to drop.  This 
                 may not be greater than or equal to the number of assignments 
                 in the section. 

  WARNING: a blank line MUST follow the grading policy, and there may be no 
           blank lines within the grading policy. 


The Assignment Headings
=======================

  following the blank line, are the _assignment_ line, and the _maxima_ line.

            (_section_name_ [_assignment_])+
            (_maximum_|+|++|G|GG)+
1 or more:  _student_record_

  _section_name_ denotes the section to which this assignment belongs. 
  _assignment_   if present, denotes the particular assignment name.  If it
                 is NOT present, there may be only one assignment in the 
                 section.  _assignment_ may contain spaces.

  the maxima line must have exactly one maximum or directive for each 
  section-assignment pair in the assignment line. 

  _maximum_      is an integer value, the maximum achievable score for the 
                 assignment. 
  directive +    section average, which will be filled in.
  directive ++   grand average.  If this is not present, it will appear
                 as the last column of the output, with column name 'Total'. 
  directive G    section grade, which will be suggested based on the Hugue 
                 grading system (described below), and the target specified. 
  directive GG   grand grade. 
  DISCLAIMER:    letter grades are intended as preliminary guides to the 
                 students, and as mild suggestions to the professor.  The
                 author well understands that there are usually 'natural 
                 cutoffs' for grades, which make far more sense that the
                 ignorant algorithm used herein.
  _student_record_ is a space delimited list without line breaks containing
                 a student's scores on each assignment, in order.  Columns
                 containing data generated by directives will be automatically
                 inserted, so space need not be left. 


The Hugue Grading System
========================

The Hugue Grading System is a statistical algorithm for assigning
grades on a curve.  The assumption is that the best tests have the
most similar mean and median of test scores, and that a curve will
always boost, and never lower, a student's letter grade, from the 90,
80, 70, 60 curve.

Thus the letter grades are determined by the following algorithm:

    Let x_{1} .. x_{n}  ~ N(mu, sigma)
    Let med = median(x_{1} .. x_{n})
    Let target be the desired median grade
    then for each score x_{i} 
       Let adjscore_{i} = 10*((x_{i} - med) / sigma) + target
       if      adjscore_{i} >= 90 or x_{i} >= 90, let grade_{i} = A
       else if adjscore_{i} >= 80 or x_{i} >= 80, let grade_{i} = B
       else if adjscore_{i} >= 70 or x_{i} >= 70, let grade_{i} = C
       else if adjscore_{i} >= 60 or x_{i} >= 60, let grade_{i} = D
       otherwise let grade_{i}=F

DISCLAIMER: Letter grades are intended as preliminary guides to the
students, and as mild suggestions to the professor.  The author well
understands that there are usually 'natural cutoffs' for grades, which
make far more sense that the ignorant algorithm used herein.


Example
=======

Target 75
Sort down Quiz 4
ID 0
Exam 40
Midterm 30
Quiz 30-2
Bonus 0
Final 0

 ID! Quiz 1 Quiz 2 Quiz 3 Quiz 4 Quiz Avg Midterm A Midterm B Midterm Gr Bonus Final Avg Final Gr
   0     25     25     25     25        +       100       120          G     0        ++       GG

7333     29     24     19     18                 92       114                0
Fred     24     21     22     22                 87        87                3
42Art    20      0     20     20                 80       100                4 

Should produce the following text output:

#Since there are no assignments in section Exam,
# I'll drop its contribution of 40, by
# reducing the sum of section weights to 60.
ID      Quiz                                    Midterm                 Bonus   Final
        1       2       3       4       Avg     A       B       Gr              Avg     Gr
        25      25      25      25              100     120

        24      {21}    {22}    22      92      87      87      C       3       85.55   B
        {20}    {0}     20      20      80      80      100     B       0       80.91   B
        29      24      {19}    {18}    106     92      114     A       4       99.82   A

There are several points to note.  
  * The ID column does not appear in the output because of the exclamation 
    point after the word 'ID' in the assignment line.  
  * The ID column did not, in fact, disappear, only its values are blank. 
    This may be fixed in a later version.
  * One can specify average (+ or ++) independently of letter grade (G or GG).
  * Grades are all integers, but the maxima may be any size, and the scores 
    may be larger than the maxima (student 7333, Quiz 1)
  * If a section does not have any elements, it isn't counted (so you can plan
    ahead in the grading policy before the grades are all in).  
  * The grades dropped are not necessarily the lowest scores, but rather the
    weakest contributors (this can not be seen here). 
  * Grades that were dropped appear differently from those that weren't.  In
    this case (text output) denoted by curly braces, but this is a function of
    the output mode. 
  * One may sort by any column, including grade and score columns.  The default
    name of the ++ column (which is always generated) is 'Total' and appears as
    the last column unless otherwise specified.