quizzer
Version:
Quizzer is a webserver for collaborative writing lab support. Based on a _fail early, fail often? approach to written language, the tool is particularly suited to second-language learners. The workflow (essay - error - quiz - exam) treats mistakes as an o
210 lines (167 loc) • 8.75 kB
Markdown
## Overview
Quizzer is an online support tool for academic writing instruction.
It can be installed with a single command, requires no student IDs or
passwords, and works well with classes made up of students at varying
stages of language acquisition, and from diverse language backgrounds.
The basic concept is to use student writing as the basis for a flood
of pattern-recognition exercises, cast as online quizzes delivered by
email. By raising the pace of iteration, the aim is to help students
internalize a sense of grammatical anomalies and stylistic
infelicities.
While Quizzer can be used to generate multiple-choice quizzes for
a variety of purposes, the workflow it was built for runs like this:
1. Students submit a 400-word essay once each week on an arbitrary
topic.
2. The instructor selects representative errors of style and grammar
from the submissions, and composes a multiple-choice question
consisting of the student's own sentence, two alternatives that
also contain errors, and a corrected version.
3. After constructing one question from each submitted essay, students
are sent personalized links to the resulting quiz.
4. Students submit their responses, which are recorded on the Quizzer
server. Students receive feedback immediately feedback on their
incorrect responses. *Neither the essays nor the quiz results are
assessed.*
5. Class commenters (TAs, instructors, and other experienced writers)
post short explanations of why the wrong answers were wrong. Where
appropriate, commenters from the students' own language domain can
be brought in to provide supplementary native-language guidance.
6. Class commenters of the target language domain can set persistent
"rules" on-the-fly to cover issues that arise frequently. These
rules can then to set as comments on specific wrong answers, and
they can be translated by native-language commenters, for reference
by students of the same language domain.
7. When students revisit their quiz links, they will find
their errors attached with explanatory rule, comments, and a list
of classmates who answered the question correctly.
8. Students are given an assessed, paper-based, multiple-choice
supplementary mid-term and final exam, consisting entirely of
questions from the quizzes.
Quiz distribution, commenting, exam composition, and marking are all
managed by Quizzer. Paper tests are randomized as a hedge against
cheating, and marked with a barcode reader for quick assessment.
The initial inspiration for Quizzer was a small [code
sample](http://chetan0389.blogspot.jp/2013/06/quiz-using-htmlcss-jquery-xml-javascript.html)
posted by Chetan Jain. The code has been refactored and extended
considerably for this project, but I gratefully acknowledge the
starting point for this frolic. Hats off also to the developers of
`node.js`, and LaTeX and, well, everything else. Quizzer was built on
short notice to fill a critical need, and it has been a real pleasure
to see how quickly it could be brought together, and how smoothly
it could be extended.
## Requirements
Quizzer is a `node.js` module. To get the website running, the
minimum requirements are:
> * `npm` >=1.3.x
> * `node` >=0.10.x
In addition, the following external utilities are required
for the typesetting of exams:
> * `pandoc` >=1.11.x (preferably compiled with texmath support)
> * either `pdflatex`, or `platex` and `dvipdfmx` (the latter pair is needed
> only if Japanese text must be handled)
LaTex (pLaTeX) documents created by Quizzer use the following
packages:
> * `makebarcode`
> * `marginnote`
> * `graphicx`
> * `tikz`
> * `ctable`
> * `float`
> * `hyphenat`
> * `amsmath`
Quizzer must have access to a mail transfer agent (MTA). This can
either be a `sendmail` instance running on the same server, or a mail
API to a service such as GMail.
With the above requirements in place, Quizzer can be run on a
workstation for initial trials, accessed via a port on `localhost`
(aka `127.0.0.1`). For production use, Quizzer should be placed behind
a webserver, such as `lighttpd` or `apache`. Instructions for setting
up the former are given below.
## Basic Installation
Install quizzer from the `npm` repository:
npm install quizzer
Run the server by saving the following code to a file (say, `quizServer.js`):
var qz = require('quizzer');
qz.run();
Run the script from command line like this:
node ./quizServer.js
The script will whinge on first run, asking for some essential
details:
usage: quizServer.js [-h] [-v] [-H PROXY_HOSTNAME] [-Q QUIZZER_PATH]
[-p REAL_PORT] [-e EMAIL_ACCOUNT] [-s SMTP_HOST]
[-l LOCALE] [-P] [-E]
Quizzer, a quiz server
Optional arguments:
-h, --help Show this help message and exit.
-v, --version Show program's version number and exit.
-H PROXY_HOSTNAME, --proxy-hostname PROXY_HOSTNAME
Host name for external access
-Q QUIZZER_PATH, --quizzer-path QUIZZER_PATH
Server path to quizzer (default: "/quizzer/")
-p REAL_PORT, --real-port REAL_PORT
Port on which to listen for local connections
(defaults to 3498)
-e EMAIL_ACCOUNT, --email-account EMAIL_ACCOUNT
Full username of email account (e.g. useme.com)
-s SMTP_HOST, --smtp-host SMTP_HOST
SMTP host name (e.g. smtp.gmail.com)
-l LOCALE, --locale LOCALE
Language locale for admin interface ("en" or "ja")
-P, --use-platex Use platex engine + dvipdfmx for PDF generation
-E, --use-euc-jp Convert input text from UTF8 to legacy EUC-JP
encoding before LaTeX processing
ERROR: must set option proxy_hostname
ERROR: must set option email_account
To get Quizzer running, set `proxy_hostname` to `localhost` (or `127.0.0.1`), and
set `email_account` to your mail address (`me.com` in the example below):
node ./quizServer -H localhost -e me.com
Quizzer will come up with a message like the following:
Wrote config parameters to quizzer-3498.cfg
Quizzer can now be run with the single option: -p 3498
Message: no mypwd.txt file found, will use local Sendmail transport
Using local Sendmail transport
Admin URL: http://localhost:3498/?admin=179359xq
Adding admin role
Loaded class membership keys
Woke up the mail schedulers
Done. Ready to shake, rattle and roll!
The website can now be accessed at the URL reported in the fifth line.
(Note that the `admin` key is automatically generated, and will differ
from that shown in the example above.)
The database and configuration files are created in the directory from
which the script is run, named after the port number. The server can
be shut down with `CTRL-c` (`SIGINT`), and as the startup message
says, it can be restarted with the single option `-p <REAL_PORT>`
A full explanation of the remaining options will be added to this
README as time permits.
## Running Quizzer behind a Proxy
When `PROXY_HOSTNAME` is set to a fully qualified domain name
(e.g. `myschool.edu`), it will assume that it is being run behind a
reverse proxy, and adjust URLs accordingly. Quizzer itself has only
the thinnest concept of security, and should be run behind a proxy in
production (and preferably over SSL). Access to the administrator
display depends on a key set in the URL of a GET request. Rewrite
rules on the front-end web server should be used to assure that
attempts to set the key directly are rerouted through a
password-protected URL.
If `lighttpd` is used as the front-end server, and Quizzer is run from
a directory `quizzer` to which the server has access, configuration
settings like the following should do the trick:
url.rewrite = (
"^(?!/quizzer)(.*)\?admin=[^&]+(?:&(.*))*" => "/quizzer/admin.html$1?$2",
"^(?!/quizzer)(.*)&admin=[^&]+(?:&(.*))*" => "/quizzer/admin.html$1&$2",
"^/quizzer/admin.html$" => "/quizzer/admin.html?admin=fyvg19vx",
"^/quizzer/admin.html\?(.*)$" => "/quizzer/admin.html?admin=fyvg19vx&$1"
)
$HTTP["host"] == "faculty.of.things.edu" {
proxy.server = ( "/quizzer" => ( ( "host" => "127.0.0.1", "port" => 3498 ) ) )
}
auth.backend = "htdigest"
auth.backend.htdigest.userfile = "/etc/lighttpd/lighttpd.user"
auth.require = ( "/quizzer/admin.html" =>
(
"method" => "basic",
"realm" => "Quiz Admin",
"require" => "user=quizmaster"
)
)