Skip to content
/ pygrader Public

Manage a course's grade database with email-based communication.

License

Notifications You must be signed in to change notification settings

wking/pygrader

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

``pygrader`` is 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, PGP_ can be used to sign and/or
encrypt any of these emails.

Installation
============

Packages
--------

Gentoo
~~~~~~

I've packaged ``pygrader`` for Gentoo_.  You need layman_ and
my `wtk overlay`_.  Install with::

  # emerge -av app-portage/layman
  # layman --add wtk
  # emerge -av dev-python/pygrader

Dependencies
------------

If you're installing by hand or packaging ``pygrader`` for another
distribution, you'll need the following dependencies:

=========  =====================  ================  =========================
Package    Purpose                Debian_           Gentoo_
=========  =====================  ================  =========================
Jinja_     email templating       python-jinja2     dev-python/jinja
pgp-mime_  secure email                             dev-python/pgp-mime [#pm]
nose_      testing (optional)     python-nose       dev-python/nose
NumPy_     statistics (optional)  python-numpy      dev-python/numpy
=========  =====================  ================  =========================

If NumPy is not installed, we'll fall back to internal implementations
of the various statistical calculations.

If you are developing ``pygrader``, you can use `update-copyright`_ to
keep the copyright blurbs up to date.

.. [#pm] In the `wtk overlay`_.

Installing by hand
------------------

``pygrader`` is available as a Git_ repository::

  $ git clone git://tremily.us/pygrader.git

See the homepage_ for details.  To install the checkout, run the
standard::

  $ python setup.py install

Submodules
----------

pgp-mime_ depends on pyassuan_, which requires Python 3.3.  If your
distribution doesn't package Jinja_ or ``pgp-mime`` for Python 3.3,
you can use ``pygrader``'s Git submodules to easily fetch compatible
versions.  The submodules are stored in the ``dep/src`` directory with
symbolic links in ``dep`` itself.  For example, the ``pgp-mime``
submodule is kept in ``dep/src/pgp-mime`` with the symlink
``dep/pgp_mime`` pointing to ``dep/pgp-mime/pgp_mime``.  If you only
need a few submodules, you can initialize them explicitly::

  $ git submodule init pgp-mime pyassuan

If you want all of the submodules, use::

  $ git submodule init

Git submodule will fetch (when necessary) and unpack the gitlinked
commit of initialized submodules with::

  $ git submodule update

You'll want to run ``update`` again after any superproject (in this
case, ``pygrader``) action that updates the gitlinks.  Once you have
checked out the dependencies you need, point ``PYTHONPATH`` to the
``dep`` directory whenever you run ``pygrader``.  For example::

  $ PYTHONPATH=dep ./bin/pg.py ...

Usage
=====

Pygrader 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 and `manage any type of grade via email`__.  In the following
sections, I'll walk you through local administration for the ``test``
course.

__ `Mailpipe details`_

All of the processing involves using the ``pg.py`` command.  Run::

  $ pg.py --help

for details.

Sending email
-------------

Pygrader receives submissions and assigns grades via email.  In order
to send email, it needs to connect to an SMTP_ server.  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.edu

Defining the course
-------------------

Once 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 the ``test`` example 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 the ``pgp-key`` option set, that key will be used to
encrypt messages to that person and sign messages from that person
with PGP_.  It will also be used to authenticate ownership of incoming
emails.  You'll need to have GnuPG_ on your local host for this to
work, and the user running ``pygrader`` should have the associated
keys in their keychain.

The ``course.robot`` option defines a dummy person used to sign
automatically generated emails (e.g. responses to mailpipe-processed
submissions).

The ``submittable`` option 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.  ``submittable`` default to
``False``.

Processing submissions
----------------------

As the due date approaches, student submissions will start arriving in
your inbox.  Use ``pg.py``'s ``mailpipe`` command to sort them into
directories (using the ``pygrader.handler.submission`` handler).  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-old

Use ``pg.py``'s ``todo`` command to check for ungraded submissions::

  $ pg.py -d test todo mail grade

Then create ``grade`` files 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's ``float()`` 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 the ``test`` directory in ``pygrader``'s Git
source.

To see how everyone's doing, you can print a table of grades with
``pg.py``'s ``tabulate`` command::

  $ pg.py -d test tabulate -s

When you want to notify students of their grades, you can send them
all out with ``pg.py``'s ``email`` command::

  $ pg.py -d test email assignment 'Exam 1'

Mailpipe details
~~~~~~~~~~~~~~~~

Besides accepting student submissions from incoming email,
``mailpipe`` also accepts other types of requests, and can be
configured to respond automatically:

* Incoming student assignment submissions are archived (see the
  ``submit`` command).
* Students can check their grades without having to bother anyone (see
  the ``get`` commands).
* Professors and teaching assistants can request student submissions
  so that they can grade them (see the ``get`` commands).
* Professors and TAs can request the grades for the entire class (see
  the ``get`` commands).
* Professors and TAs can assign grades (see the ``grade`` command).

To enable automatic responses, you'll need to add the ``-r`` or
``--respond`` argument when you call ``pg.py``.

If you get tired of filtering your inbox by hand using ``pg.py
mailpipe``, you can (depending on how your mail delivery is setup) use
procmail_ to automatically run ``mailpipe`` automatically on incoming
email.  There is an example ``.procmailrc`` in the
``pygrader.mailpipe.mailpipe`` docstring that runs ``mailpipe``
whenever 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 the ``handlers`` argument to
``pygrader.mailpipe``):

``submit``
  student assignment submission.  The remainder of the email subject
  should include the case insensitive name of the assignment being
  submitted (see ``pygrader.handler.submission._match_assignment``).
  An example subject would be::

    [submit] assignment 1

``get``
  request 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 grades

  Professors and TAs may request either a table of all grades for the
  course (à la ``tabulate``), 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 1

``grade``
  professors 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 1

To allow you to easily sort the email, you can also prefix the target
with additional information (see
``pygrader.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 by ``mailpipe``,
so the following subjects will be handled identically::

  [submit] assignment 1
  [phys101:submit] assignment 1
  [phys101:section2:submit] assignment 1

Testing
=======

Run the internal unit tests using nose_::

  $ nosetests --with-doctest --doctest-tests pygrader

If a Python-3-version of ``nosetests`` is not the default on your
system, you may need to try something like::

  $ nosetests-3.2 --with-doctest --doctest-tests pygrader

Licence
=======

This project is distributed under the `GNU General Public License
Version 3`_ or greater.

Author
======

W. Trevor King
wking@tremily.us

Related work
============

For a similar project, see `Alex Heitzmann's pygrade`_, which keeps
the grade history in a single log file and provides more support for
using graphical interfaces.


.. _PGP: http://en.wikipedia.org/wiki/Pretty_Good_Privacy
.. _Gentoo: http://www.gentoo.org/
.. _layman: http://layman.sourceforge.net/
.. _wtk overlay: http://blog.tremily.us/posts/Gentoo_overlay/
.. _Debian: http://www.debian.org/
.. _Jinja: http://jinja.pocoo.org/
.. _pgp-mime: http://blog.tremily.us/posts/pgp-mime/
.. _pyassuan: http://blog.tremily.us/posts/pyassuan/
.. _NumPy: http://numpy.scipy.org/
.. _update-copyright: http://blog.tremily.us/posts/update-copyright/
.. _Git: http://git-scm.com/
.. _homepage: http://blog.tremily.us/posts/pygrader/
.. _SMTP: http://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol
.. _GnuPG: http://www.gnupg.org/
.. _procmail: http://www.procmail.org/
.. _nose: http://readthedocs.org/docs/nose/en/latest/
.. _GNU General Public License Version 3: http://www.gnu.org/licenses/gpl.html
.. _Alex Heitzmann's pygrade: http://code.google.com/p/pygrade/

About

Manage a course's grade database with email-based communication.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages