Package: pygrader
pygraderis a directory-based grade database for grading course
assignments.  Besides tracking grades locally, you can also use it to
automatically mail grades to students and professors associated with
the course.  For secure communication,PGPcan be used to sign and/or
encrypt any of these emails.InstallationPackagesGentooI’ve packagedpygraderforGentoo.  You needlaymanand
mywtk overlay.  Install with:# emerge -av app-portage/layman
# layman --add wtk
# emerge -av dev-python/pygraderDependenciesIf you’re installing by hand or packagingpygraderfor another
distribution, you’ll need the following dependencies:PackagePurposeDebianGentooJinjaemail templatingpython-jinja2dev-python/jinjapgp-mimesecure emaildev-python/pgp-mime [#pm]nosetesting (optional)python-nosedev-python/noseNumPystatistics (optional)python-numpydev-python/numpyIf NumPy is not installed, we’ll fall back to internal implementations
of the various statistical calculations.If you are developingpygrader, you can useupdate-copyrightto
keep the copyright blurbs up to date.[1]In thewtk overlay.Installing by handpygraderis available as aGitrepository:$ git clone git://tremily.us/pygrader.gitSee thehomepagefor details.  To install the checkout, run the
standard:$ python setup.py installSubmodulespgp-mimedepends onpyassuan, which requires Python 3.3.  If your
distribution doesn’t packageJinjaorpgp-mimefor Python 3.3,
you can usepygrader’s Git submodules to easily fetch compatible
versions.  The submodules are stored in thedep/srcdirectory with
symbolic links indepitself.  For example, thepgp-mimesubmodule is kept indep/src/pgp-mimewith the symlinkdep/pgp_mimepointing todep/pgp-mime/pgp_mime.  If you only
need a few submodules, you can initialize them explicitly:$ git submodule init pgp-mime pyassuanIf you want all of the submodules, use:$ git submodule initGit submodule will fetch (when necessary) and unpack the gitlinked
commit of initialized submodules with:$ git submodule updateYou’ll want to runupdateagain after any superproject (in this
case,pygrader) action that updates the gitlinks.  Once you have
checked out the dependencies you need, pointPYTHONPATHto thedepdirectory whenever you runpygrader.  For example:$ PYTHONPATH=dep ./bin/pg.py ...UsagePygrader will help keep you organized in a course where the students
submit homework via email, or the homework submissions are otherwise
digital (i.e. scanned in after submission).  You can also use it to
assign andmanage any type of grade via email.  In the following
sections, I’ll walk you through local administration for thetestcourse.All of the processing involves using thepg.pycommand.  Run:$ pg.py --helpfor details.Sending emailPygrader receives submissions and assigns grades via email.  In order
to send email, it needs to connect to anSMTPserver.  See the
pgp-mime documentation for details on configuring you SMTP connection.
You can test your SMTP configuration by sending yourself a test
message:$ pg.py -VVV smtp -a rincewind@uu.edu -t rincewind@uu.eduDefining the courseOnce you’ve got email submission working, you need to configure the
course you’ll be grading.  Each course lives in its own directory, and
the basic setup looks like thetestexample distributed with
pygrader.  The file that you need to get started is the config file in
the course directory:$ cat test/course.conf
[course]
name: Physics 101
assignments: Attendance 1, Attendance 2, Attendance 3, Attendance 4,
  Attendance 5, Attendance 6, Attendance 7, Attendance 8, Attendance 9,
  Assignment 1, Assignment 2, Exam 1, Exam 2
robot: Robot101
professors: Gandalf
assistants: Sauron
students: Bilbo Baggins, Frodo Baggins, Aragorn

[Attendance 1]
points: 1
weight: 0.1/9
due: 2011-10-03

[Attendance 2]
points: 1
weight: 0.1/9
due: 2011-10-04

…

[Assignment 1]
points: 10
weight: 0.4/2
due: 2011-10-10
submittable: yes

…

[Exam 2]
points: 10
weight: 0.4/2
due: 2011-10-17

[Robot101]
nickname: phys-101 robot
emails: phys101@tower.edu
pgp-key: 4332B6E3

[Gandalf]
nickname: G-Man
emails: g@grey.edu
pgp-key: 4332B6E3

[Sauron]
emails: eye@tower.edu

[Bilbo Baggins]
nickname: Bill
emails: bb@shire.org, bb@greyhavens.net

…The format is a bit wordy, but it is also explicit and easily
extensible.  The time it takes to construct this configuration file
should be a small portion of the time you will spend grading
submissions.If a person has thepgp-keyoption set, that key will be used to
encrypt messages to that person and sign messages from that person
withPGP.  It will also be used to authenticate ownership of incoming
emails.  You’ll need to haveGnuPGon your local host for this to
work, and the user runningpygradershould have the associated
keys in their keychain.Thecourse.robotoption defines a dummy person used to sign
automatically generated emails (e.g. responses to mailpipe-processed
submissions).Thesubmittableoption marks assignments that accept direct
submission from students (e.g. homeworks).  You probably don’t want to
set this option for attendance, since it would allow students to mark
themselves as having attended a class.submittabledefault toFalse.Processing submissionsAs the due date approaches, student submissions will start arriving in
your inbox.  Usepg.py’smailpipecommand to sort them into
directories (using thepygrader.handler.submissionhandler).  This
will also extract any files that were attached to the emails and place
them in that person’s assignment directory:$ pg.py -d test mailpipe -m maildir -i ~/.maildir -o ./mail-oldUsepg.py’stodocommand to check for ungraded submissions:$ pg.py -d test todo mail gradeThen creategradefiles using your favorite editor.  The first
line of the grade file should be the student’s grade for that
assigment, expressed in a syntax that Python’sfloat()understands
(1,95,2.5,6.022e23, etc.).  If you wish, you may
add additional comment lines after the grade line, offering
suggestions for improvement, etc.  This comment (if present) will be
mailed to the student along with the grade itself.  There are a number
of example grade files in thetestdirectory inpygrader’s Git
source.To see how everyone’s doing, you can print a table of grades withpg.py’stabulatecommand:$ pg.py -d test tabulate -sWhen you want to notify students of their grades, you can send them
all out withpg.py’semailcommand:$ pg.py -d test email assignment 'Exam 1'Mailpipe detailsBesides accepting student submissions from incoming email,mailpipealso accepts other types of requests, and can be
configured to respond automatically:Incoming student assignment submissions are archived (see thesubmitcommand).Students can check their grades without having to bother anyone (see
thegetcommands).Professors and teaching assistants can request student submissions
so that they can grade them (see thegetcommands).Professors and TAs can request the grades for the entire class (see
thegetcommands).Professors and TAs can assign grades (see thegradecommand).To enable automatic responses, you’ll need to add the-ror--respondargument when you callpg.py.If you get tired of filtering your inbox by hand usingpg.py mailpipe, you can (depending on how your mail delivery is setup) useprocmailto automatically runmailpipeautomatically on incoming
email.  There is an example.procmailrcin thepygrader.mailpipe.mailpipedocstring that runsmailpipewhenever incoming emails have[phys160:submit]in their subject
somewhere.The use of[TARGET]tags in the email subject allows users to
unambiguously specify the purpose of their email.  Currently supported
targets include (see thehandlersargument topygrader.mailpipe):submitstudent assignment submission.  The remainder of the email subject
should include the case insensitive name of the assignment being
submitted (seepygrader.handler.submission._match_assignment).
An example subject would be:[submit] assignment 1getrequest information from the grade database.  For students, the
remainder of the email subject is irrelevant.  Grades and comments
for all graded assignments are returned in a single email.  An
example subject would be:[get] my gradesProfessors and TAs may request either a table of all grades for the
course (à latabulate), the full grades for a particular
student, or a particular student’s submission for a particular
assignment.  Example subjects are (respectively):[get] don’t match any student names
[get] Bilbo Baggins
[get] Bilbo Baggins Assignment 1gradeprofessors and TAs can submit a grade for a particular student on a
particular assignment.  The body of the (possibly signed or
encrypted) email should be identical to the grade file that the
sender wishes to create.  An example subject would be:[grade] Bilbo Baggins Assignment 1To allow you to easily sort the email, you can also prefix the target
with additional information (seepygrader.mailpipe._get_message_target).  For example, if you were
running several courses from the same email account, you’d want a way
for users to specify which course they were interacting with so you
could filter appropriately in your procmail rules.  Everything in the
subject tag before an optional semicolon is ignored bymailpipe,
so the following subjects will be handled identically:[submit] assignment 1
[phys101:submit] assignment 1
[phys101:section2:submit] assignment 1TestingRun the internal unit tests usingnose:$ nosetests --with-doctest --doctest-tests pygraderIf a Python-3-version ofnosetestsis not the default on your
system, you may need to try something like:$ nosetests-3.2 --with-doctest --doctest-tests pygraderLicenceThis project is distributed under theGNU General Public License
Version 3or greater.AuthorW. Trevor Kingwking@tremily.usRelated workFor a similar project, seeAlex Heitzmann’s pygrade, which keeps
the grade history in a single log file and provides more support for
using graphical interfaces.