bfe78fd6e70c4c6ac42bad85d9fd4377ec378e6a
[pygrader.git] / README
1 ``pygrader`` is a directory-based grade database for grading course
2 assignments.  Besides tracking grades locally, you can also use it to
3 automatically mail grades to students and professors associated with
4 the course.  For secure communication, PGP_ can be used to sign and/or
5 encrypt any of these emails.
6
7 Installation
8 ============
9
10 Packages
11 --------
12
13 Gentoo
14 ~~~~~~
15
16 I've packaged ``pygrader`` for Gentoo_.  You need layman_ and
17 my `wtk overlay`_.  Install with::
18
19   # emerge -av app-portage/layman
20   # layman --add wtk
21   # emerge -av dev-python/pygrader
22
23 Dependencies
24 ------------
25
26 If you're installing by hand or packaging pycomedi for another
27 distribution, you'll need the following dependencies:
28
29 ========   ===================  ================  =========================
30 Package    Purpose              Debian_           Gentoo_
31 ========   ===================  ================  =========================
32 NumPy_     statistics           python-numpy      dev-python/numpy
33 pgp-mime_  secure email                           dev-python/pgp-mime [#pm]
34 nose_      testing (optional)   python-nose       dev-python/nose
35 =========  ===================  ================  =========================
36
37 If you are developing ``pygrader``, you can use `update-copyright`_ to
38 keep the copyright blurbs up to date.
39
40 .. [#pm] In the `wtk overlay`_.
41
42 Installing by hand
43 ------------------
44
45 ``pygrader`` is available as a Git_ repository::
46
47   $ git clone git://tremily.us/pygrader.git
48
49 See the homepage_ for details.  To install the checkout, run the
50 standard::
51
52   $ python setup.py install
53
54 Usage
55 =====
56
57 Pygrader will help keep you organized in a course where the students
58 submit homework via email, or the homework submissions are otherwise
59 digital (i.e. scanned in after submission).  You can also use it to
60 assign and `manage any type of grade via email`__.  In the following
61 sections, I'll walk you through local administration for the ``test``
62 course.
63
64 __ `Mailpipe details`_
65
66 All of the processing involves using the ``pg.py`` command.  Run::
67
68   $ pg.py --help
69
70 for details.
71
72 Sending email
73 -------------
74
75 Pygrader receives submissions and assigns grades via email.  In order
76 to send email, it needs to connect to an SMTP_ server.  See the
77 pgp-mime documentation for details on configuring you SMTP connection.
78 You can test your SMTP configuration by sending yourself a test
79 message::
80
81   $ pg.py -VVV smtp -a rincewind@uu.edu -t rincewind@uu.edu
82
83 Defining the course
84 -------------------
85
86 Once you've got email submission working, you need to configure the
87 course you'll be grading.  Each course lives in its own directory, and
88 the basic setup looks like the ``test`` example distributed with
89 pygrader.  The file that you need to get started is the config file in
90 the course directory::
91
92   $ cat test/course.conf
93   [course]
94   name: Physics 101
95   assignments: Attendance 1, Attendance 2, Attendance 3, Attendance 4,
96     Attendance 5, Attendance 6, Attendance 7, Attendance 8, Attendance 9,
97     Assignment 1, Assignment 2, Exam 1, Exam 2
98   robot: Robot101
99   professors: Gandalf
100   assistants: Sauron
101   students: Bilbo Baggins, Frodo Baggins, Aragorn
102
103   [Attendance 1]
104   points: 1
105   weight: 0.1/9
106   due: 2011-10-03
107
108   [Attendance 2]
109   points: 1
110   weight: 0.1/9
111   due: 2011-10-04
112
113   …
114
115   [Assignment 1]
116   points: 10
117   weight: 0.4/2
118   due: 2011-10-10
119   submittable: yes
120
121   …
122
123   [Exam 2]
124   points: 10
125   weight: 0.4/2
126   due: 2011-10-17
127
128   [Robot101]
129   nickname: phys-101 robot
130   emails: phys101@tower.edu
131   pgp-key: 4332B6E3
132
133   [Gandalf]
134   nickname: G-Man
135   emails: g@grey.edu
136   pgp-key: 4332B6E3
137
138   [Sauron]
139   emails: eye@tower.edu
140
141   [Bilbo Baggins]
142   nickname: Bill
143   emails: bb@shire.org, bb@greyhavens.net
144
145   …
146
147 The format is a bit wordy, but it is also explicit and easily
148 extensible.  The time it takes to construct this configuration file
149 should be a small portion of the time you will spend grading
150 submissions.
151
152 If a person has the ``pgp-key`` option set, that key will be used to
153 encrypt messages to that person and sign messages from that person
154 with PGP_.  It will also be used to authenticate ownership of incoming
155 emails.  You'll need to have GnuPG_ on your local host for this to
156 work, and the user running ``pygrader`` should have the associated
157 keys in their keychain.
158
159 The ``course.robot`` option defines a dummy person used to sign
160 automatically generated emails (e.g. responses to mailpipe-processed
161 submissions).
162
163 The ``submittable`` option marks assignments that accept direct
164 submission from students (e.g. homeworks).  You probably don't want to
165 set this option for attendance, since it would allow students to mark
166 themselves as having attended a class.  ``submittable`` default to
167 ``False``.
168
169 Processing submissions
170 ----------------------
171
172 As the due date approaches, student submissions will start arriving in
173 your inbox.  Use ``pg.py``'s ``mailpipe`` command to sort them into
174 directories (using the ``pygrader.handler.submission`` handler).  This
175 will also extract any files that were attached to the emails and place
176 them in that person's assignment directory::
177
178   $ pg.py -d test mailpipe -m maildir -i ~/.maildir -o ./mail-old
179
180 Use ``pg.py``'s ``todo`` command to check for ungraded submissions::
181
182   $ pg.py -d test todo mail grade
183
184 Then create ``grade`` files using your favorite editor.  The first
185 line of the grade file should be the student's grade for that
186 assigment, expressed in a syntax that Python's ``float()`` understands
187 (``1``, ``95``, ``2.5``, ``6.022e23``, etc.).  If you wish, you may
188 add additional comment lines after the grade line, offering
189 suggestions for improvement, etc.  This comment (if present) will be
190 mailed to the student along with the grade itself.  There are a number
191 of example grade files in the ``test`` directory in ``pygrader``'s Git
192 source.
193
194 To see how everyone's doing, you can print a table of grades with
195 ``pg.py``'s ``tabulate`` command::
196
197   $ pg.py -d test tabulate -s
198
199 When you want to notify students of their grades, you can send them
200 all out with ``pg.py``'s ``email`` command::
201
202   $ pg.py -d test email assignment 'Exam 1'
203
204 Mailpipe details
205 ~~~~~~~~~~~~~~~~
206
207 Besides accepting student submissions from incoming email,
208 ``mailpipe`` also accepts other types of requests, and can be
209 configured to respond automatically:
210
211 * Incoming student assignment submissions are archived (see the
212   ``submit`` command).
213 * Students can check their grades without having to bother anyone (see
214   the ``get`` commands).
215 * Professors and teaching assistants can request student submissions
216   so that they can grade them (see the ``get`` commands).
217 * Professors and TAs can request the grades for the entire class (see
218   the ``get`` commands).
219 * Professors and TAs can assign grades (see the ``grade`` command).
220
221 To enable automatic responses, you'll need to add the ``-r`` or
222 ``--respond`` argument when you call ``pg.py``.
223
224 If you get tired of filtering your inbox by hand using ``pg.py
225 mailpipe``, you can (depending on how your mail delivery is setup) use
226 procmail_ to automatically run ``mailpipe`` automatically on incoming
227 email.  There is an example ``.procmailrc`` in the
228 ``pygrader.mailpipe.mailpipe`` docstring that runs ``mailpipe``
229 whenever incoming emails have ``[phys160:submit]`` in their subject
230 somewhere.
231
232 The use of ``[TARGET]`` tags in the email subject allows users to
233 unambiguously specify the purpose of their email.  Currently supported
234 targets include (see the ``handlers`` argument to
235 ``pygrader.mailpipe``):
236
237 ``submit``
238   student assignment submission.  The remainder of the email subject
239   should include the case insensitive name of the assignment being
240   submitted (see ``pygrader.handler.submission._match_assignment``).
241   An example subject would be::
242
243     [submit] assignment 1
244
245 ``get``
246   request information from the grade database.  For students, the
247   remainder of the email subject is irrelevant.  Grades and comments
248   for all graded assignments are returned in a single email.  An
249   example subject would be::
250
251     [get] my grades
252
253   Professors and TAs may request either a table of all grades for the
254   course (à la ``tabulate``), the full grades for a particular
255   student, or a particular student's submission for a particular
256   assignment.  Example subjects are (respectively):
257
258     [get] don't match any student names
259     [get] Bilbo Baggins
260     [get] Bilbo Baggins Assignment 1
261
262 ``grade``
263   professors and TAs can submit a grade for a particular student on a
264   particular assignment.  The body of the (possibly signed or
265   encrypted) email should be identical to the grade file that the
266   sender wishes to create.  An example subject would be::
267
268     [grade] Bilbo Baggins Assignment 1
269
270 To allow you to easily sort the email, you can also prefix the target
271 with additional information (see
272 ``pygrader.mailpipe._get_message_target``).  For example, if you were
273 running several courses from the same email account, you'd want a way
274 for users to specify which course they were interacting with so you
275 could filter appropriately in your procmail rules.  Everything in the
276 subject tag before an optional semicolon is ignored by ``mailpipe``,
277 so the following subjects will be handled identically::
278
279   [submit] assignment 1
280   [phys101:submit] assignment 1
281   [phys101:section2:submit] assignment 1
282
283 Testing
284 =======
285
286 Run the internal unit tests using nose_::
287
288   $ nosetests --with-doctest --doctest-tests pygrader
289
290 If a Python-3-version of ``nosetests`` is not the default on your
291 system, you may need to try something like::
292
293   $ nosetests-3.2 --with-doctest --doctest-tests pygrader
294
295 Licence
296 =======
297
298 This project is distributed under the `GNU General Public License
299 Version 3`_ or greater.
300
301 Author
302 ======
303
304 W. Trevor King
305 wking@tremily.us
306
307 Related work
308 ============
309
310 For a similar project, see `Alex Heitzmann's pygrade`_, which keeps
311 the grade history in a single log file and provides more support for
312 using graphical interfaces.
313
314
315 .. _PGP: http://en.wikipedia.org/wiki/Pretty_Good_Privacy
316 .. _Gentoo: http://www.gentoo.org/
317 .. _layman: http://layman.sourceforge.net/
318 .. _wtk overlay: http://blog.tremily.us/posts/Gentoo_overlay/
319 .. _Debian: http://www.debian.org/
320 .. _Gentoo: http://www.gentoo.org/
321 .. _NumPy: http://numpy.scipy.org/
322 .. _pgp-mime: http://blog.tremily.us/posts/pgp-mime/
323 .. _update-copyright: http://blog.tremily.us/posts/update-copyright/
324 .. _Git: http://git-scm.com/
325 .. _homepage: http://blog.tremily.us/posts/pygrader/
326 .. _SMTP: http://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol
327 .. _GnuPG: http://www.gnupg.org/
328 .. _procmail: http://www.procmail.org/
329 .. _nose: http://readthedocs.org/docs/nose/en/latest/
330 .. _GNU General Public License Version 3: http://www.gnu.org/licenses/gpl.html
331 .. _Alex Heitzmann's pygrade: http://code.google.com/p/pygrade/