9 years agoquestion: Add the Question.multimedia attribute master
W. Trevor King [Fri, 26 Apr 2013 12:46:06 +0000 (08:46 -0400)]
question: Add the Question.multimedia attribute

Many questions have figures associated with the prompt text or the
answer choices.  This attribute provides a means to link to these
multimedia assets from the question.  Here's an example from the force
concept inventory, which I'm currently transcribing:

      "class": "ChoiceQuestion",
      "id": "sling shot",
      "prompt": "A heavy ball is attached to a string...",
      "multimedia": [
          "content-type": "image/png",
          "path": "force-concept-inventory/04.png"
      "display_choices": true,
      "answer": [
        "(A) in the figure",
        "(B) in the figure",
        "(C) in the figure",
        "(D) in the figure",
        "(E) in the figure"

The 'multimedia' attribute is an array because a question might
conceivably reference several assets (e.g. an image and an audio clip,
or multiple images).

To display the assets alongside the question, I've refactored the WSGI
handler to pull out QuestionApp._format_prompt(), which in turn
delegates to the new QuestionApp._format_multimedia().  This embeds a
link to the asset, using a MIME-appropriate container (currently just
<img> for image/* types).  The assets themselves are served as
media/<HASH>, where I hash the whole multimedia-defining dictionary to
avoid information leakage which might otherwise help in solving the
problem.  Using hash-based URLs also avoids problems with special
characters in the multimedia data.

In the CLI handler, we can't inline multimedia.  I use the user's
mailcap configuration (RFC 1524) to spawn their preferred
MIME-appropriate viewer when the prompt for a new question is being
generated.  If the user hasn't configured a viewer for the MIME type
in question, we just print a message referring to the asset by its
full path and let the user take it from there.

The mailcap viewer is adapted from an example I initially posted on my
blog in 2011 [1].  The path-quoting follows the Mutt docs [2]:

> The interpretion of shell meta-characters embedded in MIME
> parameters can lead to security problems in general. Mutt tries to
> quote parameters in expansion of `%s` syntaxes properly, and avoids
> risky characters by substituting them, see the `mailcap_sanitize`
> variable.

[1]: http://blog.tremily.us/posts/mailcap/mailcap-test.py
[2]: http://www.mutt.org/doc/manual/manual-5.html

9 years agoui.wsgi: Factor URL handling out into WSGI_UrlObject
W. Trevor King [Fri, 26 Apr 2013 11:48:53 +0000 (07:48 -0400)]
ui.wsgi: Factor URL handling out into WSGI_UrlObject

QuestionApp is complicated enough without this generic URL delegation
code being jumbled in.  This commit makes helps isolate the
quizzer-specific code from boilerplate WSGI utilities.

9 years agoRun update-copyright.py
W. Trevor King [Mon, 25 Mar 2013 11:44:53 +0000 (07:44 -0400)]
Run update-copyright.py

9 years agoutil: Support Python 3.2 by ignoring timeouts passed to invoke()
W. Trevor King [Sat, 23 Mar 2013 13:03:28 +0000 (09:03 -0400)]
util: Support Python 3.2 by ignoring timeouts passed to invoke()

If you're not asking ScriptQuestions, you don't care about this
feature, and it's good to be able to relax the Python 3.3 requirement.

9 years agoREADME: Describe the types of supported questions
W. Trevor King [Sat, 23 Mar 2013 13:02:32 +0000 (09:02 -0400)]
README: Describe the types of supported questions

9 years agoui.cli: Remove explicit return from QuestionCommandLine._extra_ps1_lines()
W. Trevor King [Sat, 23 Mar 2013 12:08:40 +0000 (08:08 -0400)]
ui.cli: Remove explicit return from QuestionCommandLine._extra_ps1_lines()

Mixing return statements and `yield`-based generators is bad practice.

9 years agoBump to version 0.4 v0.4
W. Trevor King [Sat, 23 Mar 2013 11:41:39 +0000 (07:41 -0400)]
Bump to version 0.4

Changes since 0.3:
* Added a WSGI-based HTML interface.
* Added user keys to answer database and stack (for multi-user support
  in the WSGI interface).
* Added Question.accept_all for open-ended questions.
* Extended ChoiceQuestion to support multiple choice questions
  (display_choices) which default to "select one of ...", but can be
  configured to "select all that apply" (multiple_answer).
* Added a new software-carpentry-pre-assessment quiz.
* Assorted minor fixups.

I bumped any existing quizzes that use new features to v0.4, but left
the others alone.

9 years agoquizzes/software-carpentry-pre-assessment: Allow multiple platforms
W. Trevor King [Fri, 22 Mar 2013 21:31:46 +0000 (17:31 -0400)]
quizzes/software-carpentry-pre-assessment: Allow multiple platforms

For mixed-OS environments (e.g. local OS X machine with department
Linux boxes).

9 years agoquestion: Add the ChoiceQuestion.multiple_answer attribute
W. Trevor King [Fri, 22 Mar 2013 21:29:44 +0000 (17:29 -0400)]
question: Add the ChoiceQuestion.multiple_answer attribute

This adds support for multiple choice questions where you are allowed
to select one or more of the possible choices.  In web forms, this is
usually done via checkboxes.

9 years agoui.cli: Don't record EOF or blank entries as answers
W. Trevor King [Fri, 22 Mar 2013 15:27:45 +0000 (11:27 -0400)]
ui.cli: Don't record EOF or blank entries as answers

If the user closes stdin, don't check and see if 'EOF' is an allowed
answer, just exit the QuestionCommandLine loop.  Don't try to process
blank entries either, just re-ask the question.

9 years agoquizzes/software-carpentry-pre-assessment: Automate the pre-assessment
W. Trevor King [Thu, 14 Mar 2013 12:24:29 +0000 (08:24 -0400)]
quizzes/software-carpentry-pre-assessment: Automate the pre-assessment

From swcarpentry/assets [1], as of 4a6d554 (Importing a whole bunch of
old material relevant to Software Carpentry, 2012-12-20).

[1]: https://github.com/swcarpentry/assets/blob/master/assessment/5.1/wilson-pre-assessment-2012-11.html

9 years agoquestion: Move ChoiceQuestion.open_ended to Question.accept_all
W. Trevor King [Thu, 14 Mar 2013 12:13:08 +0000 (08:13 -0400)]
question: Move ChoiceQuestion.open_ended to Question.accept_all

Accepting all answers is a more general case of an open ended multiple
choice question.  It also allows us to ask questions that are
difficult or impossible to grade automatically.  We just record the
student's answer for the grader to look at later.

9 years agoquizzer: Add ChoiceQuestion.open_ended
W. Trevor King [Thu, 14 Mar 2013 11:54:50 +0000 (07:54 -0400)]
quizzer: Add ChoiceQuestion.open_ended

This allows us to ask open-ended multiple-choice questions, like:

  Pick one:
  1) Answer-1
  2) Answer-2
  or fill in something else
  quizzer? Answer-3

9 years agoquizzer: Add ChoiceQuestion.display_choices
W. Trevor King [Thu, 14 Mar 2013 11:32:02 +0000 (07:32 -0400)]
quizzer: Add ChoiceQuestion.display_choices

This gives us more traditional multiple-choice questions.

9 years agoui.wsgi: Close the text-input tag
W. Trevor King [Thu, 14 Mar 2013 11:31:16 +0000 (07:31 -0400)]
ui.wsgi: Close the text-input tag

9 years agoquizzer: Add user keys to the answer database and stack
W. Trevor King [Thu, 14 Mar 2013 00:01:36 +0000 (20:01 -0400)]
quizzer: Add user keys to the answer database and stack

Instead of:

  answerdb[question.id] = [list, of, answers]
  ui.stack = [list, of, questions]

Now we have:

  answerdb[user.name][question.id] = [list, of, answers]
  ui.stack[user.name] = [list, of, questions]

This will allow us to use a single answer database and stack for a
multi-user interface (e.g. WSGI).  I've added the appropriate upgrade
rules to update existing answer databases once we bump to v0.4.

To reduce redundancy and ease future maintenance, I also factored out
AnswerDatabase._get_questions() from .get_unanswered() and friends.

There's a bit of hackery to deal with the default None user in the
answer database.  Because JSON objects (the equivalent of Python's
dicts) are keyed by strings, you get things like:

  >>> import json
  >>> json.dumps({None: 'value'})
  '{"null": "value"}'

We avoid this and preserve the None key through a save/load cycle by
replacing it with the empty string.  This means that you shouldn't use
the empty string as a user name when interacting with the database
from Python, and we'll raise a ValueError if you try to do that
through AnswerDatabase-specific methods.

9 years agoui.wsgi: Add a preliminary WSGI/HTML user interface
W. Trevor King [Wed, 13 Mar 2013 21:30:23 +0000 (17:30 -0400)]
ui.wsgi: Add a preliminary WSGI/HTML user interface

The basic WSGI handling (e.g. HandlerErrorApp and WSGI_DataObject) is
largely based on code I'd written for Bugs Everywhere.

9 years agoquestion: Question.check() now returns (correct, details)
W. Trevor King [Wed, 13 Mar 2013 22:06:05 +0000 (18:06 -0400)]
question: Question.check() now returns (correct, details)

When the answer is correct, details will be None.  When the answer is
incorrect, details may be None or an explanatory message that provides
details about why the answer is incorrect.  This is mostly useful for
`ScriptQuestion`s, where the difference between the answered and
expected output streams may help diagnose errors.

The details are returned as a string (instead of, for example, logging
them in invocation_difference) so they will be easy to display in user
interfaces that aren't built around the command line.

9 years agocli: Teach quizzer.cli.main() the --ui option
W. Trevor King [Wed, 13 Mar 2013 21:23:26 +0000 (17:23 -0400)]
cli: Teach quizzer.cli.main() the --ui option

This uses the new quizzer.ui.INTERFACES and quizzer.ui.get_ui() to
select from among the available interfaces (currently just the command
line interface).

9 years agoquizzes/monty-python: Fix JSON error (missing comma in copyright)
W. Trevor King [Wed, 13 Mar 2013 21:38:30 +0000 (17:38 -0400)]
quizzes/monty-python: Fix JSON error (missing comma in copyright)

This fixes a typo introduced in 5909e7f (quiz: Add copyright metadata,

9 years agoui.cli: Import UserInterface with an underscore
W. Trevor King [Thu, 7 Feb 2013 03:11:47 +0000 (22:11 -0500)]
ui.cli: Import UserInterface with an underscore

For a cleaner namespace.

9 years agoui: Remove UserInterface.display_results()
W. Trevor King [Thu, 7 Feb 2013 03:09:06 +0000 (22:09 -0500)]
ui: Remove UserInterface.display_results()

Having quizzer.cli.main() calling ui.display_results() does not
translate well to an HTML-based UI.

CommandLineInterface now displays results as part of its .run()

9 years agoquizzes: Bump quizzes to v0.3 because they have copyright data
W. Trevor King [Fri, 8 Mar 2013 03:10:19 +0000 (22:10 -0500)]
quizzes: Bump quizzes to v0.3 because they have copyright data

Copyright data was added after v0.2.  By bumping the quiz versions,
the quizzes will no longer work with quizzer clients too old to
understand this metadata.

9 years agoBump to version 0.3 v0.3
W. Trevor King [Thu, 7 Mar 2013 22:17:26 +0000 (17:17 -0500)]
Bump to version 0.3

Changes since 0.2:
* Add quiz copyright metadata and the `copyright` cli command.
* Cleaned up the data-upgrade framework, so we're ready for any future
  data format refactoring ;).

9 years agoquizzer: Get upgrade-from-v0.2-to-v0.3 methods in place
W. Trevor King [Thu, 7 Mar 2013 22:17:01 +0000 (17:17 -0500)]
quizzer: Get upgrade-from-v0.2-to-v0.3 methods in place

9 years agoquizzer: Add methods to upgrade data from v0.1 to v0.2
W. Trevor King [Thu, 7 Mar 2013 22:12:07 +0000 (17:12 -0500)]
quizzer: Add methods to upgrade data from v0.1 to v0.2

These are both no-ops that only bump the version number, since the
stored format didn't change between the two versions.

9 years agoquizzes/DiRAC-drivers-license: Add copyright and licensing info
W. Trevor King [Thu, 7 Mar 2013 22:01:03 +0000 (17:01 -0500)]
quizzes/DiRAC-drivers-license: Add copyright and licensing info

On Thu, Mar 07, 2013 at 06:35:09PM +0000, Mike Jackson wrote:
> Copyright is Software Carpentry and The University of Edinburgh and
> University College London and the licence is just CC-BY 3.0 as for
> Software Carpentry material. Hope that helps,

9 years agoMerge branch 'license'
W. Trevor King [Thu, 7 Mar 2013 21:55:36 +0000 (16:55 -0500)]
Merge branch 'license'

* license:
  quiz: Add copyright metadata

9 years agoquiz: Add copyright metadata
W. Trevor King [Fri, 15 Feb 2013 06:03:17 +0000 (01:03 -0500)]
quiz: Add copyright metadata

Because quizzer may be used to administer quizzes that are not under
the GPLv3+, make it easy to store and access per-quiz copyrights.

Also add a `copyright` command to ui.cli.QuestionCommandLine and add
copyright blurbs to the individual quizzes.

9 years agoBump to version 0.2 v0.2
W. Trevor King [Fri, 15 Feb 2013 05:18:16 +0000 (00:18 -0500)]
Bump to version 0.2

Changes since 0.1:
* Added optional pygments colorization.
* New `skip` and `shell` commands for ui.cli.
* New Quiz.introduction.
* New DiRAC driver's license sample quiz.
* Assorted cleanups.

9 years agoquizzes/DiRAC-drivers-license: First pass at automating the exam
W. Trevor King [Fri, 15 Feb 2013 05:10:37 +0000 (00:10 -0500)]
quizzes/DiRAC-drivers-license: First pass at automating the exam


I was unable to convert the code review question to the quizzer
format, because it's hard to evaluate refactorings automatically.

This quiz is probably not under the GPLv3.  The licensing for the
original quiz is unclear, but most Software Carpentry stuff is under
the Creative Commons Attribution 3.0 Unported (CC BY 3.0).

9 years agoui.cli: Add do_shell() and associated framework
W. Trevor King [Fri, 15 Feb 2013 03:03:24 +0000 (22:03 -0500)]
ui.cli: Add do_shell() and associated framework

For more open ended questions, users may need an interactive shell to
develop the answer, and we won't be able to bundle their answer with
setup and teardown instructions in a single script.  This commit
breaks setup and teardown into separate scripts, and moves the
TemporaryDirectory stuff over to quizzer.util.  If it's enabled via
allow_interactive, users can now drop into an interactive command
using !$COMMAND (e.g. !bash) from the cli user interface.

If you want to tweak environment variables for the answer script and
interactive commands, use the new environment dictionary.

For situations where you *do* need setup/teardown stuff in the answer
script (e.g. to check the current working directory or variables that
should have been altered by the user's answer action), you can use
the new pre_answer and post_answer.

Previous versions of ScriptQuestion compared the output of the single
setup/answer/teardown script to check for matches.  With this commit
we only compare the output of the teardown script, unless
compare_answers is set, in which case we compare both the answer
output and teardown output.  When we're not comparing the answer
output, we still plot nonempty user-answer standard errors, because
without seeing stderr, it can be difficult to determine where your
attempted command went wrong.

Existing quizzes were updated accordingly, with a few additional
tweaks and cleanups that I discovered while debugging.

9 years agoui.cli: Isolate ui.get_question() in QuestionCommandLine.get_question()
W. Trevor King [Thu, 14 Feb 2013 23:19:11 +0000 (18:19 -0500)]
ui.cli: Isolate ui.get_question() in QuestionCommandLine.get_question()

Ensure uniform handling across class methods by avoiding duplication.

9 years agoquizzes/git: Fix JSON indentation for GIT_AUTHOR_EMAIL
W. Trevor King [Thu, 14 Feb 2013 15:38:51 +0000 (10:38 -0500)]
quizzes/git: Fix JSON indentation for GIT_AUTHOR_EMAIL

9 years agoui.cli: Avoid divide-by-zero errors if no questions were answered
W. Trevor King [Thu, 14 Feb 2013 14:17:08 +0000 (09:17 -0500)]
ui.cli: Avoid divide-by-zero errors if no questions were answered

9 years agoquiz: Add Quiz.introduction for an optional intro message
W. Trevor King [Thu, 14 Feb 2013 14:16:18 +0000 (09:16 -0500)]
quiz: Add Quiz.introduction for an optional intro message

9 years agoui.cli: `skip` shifts the current question to the back of the stack
W. Trevor King [Fri, 8 Feb 2013 03:41:40 +0000 (22:41 -0500)]
ui.cli: `skip` shifts the current question to the back of the stack

Rather than dropping skipped questions, just save them for later.
This gives you another stab at them without having to restart the
quiz.  If you still can't answer the questions once you reach them
again, you can always `quit` ;).

9 years agoui.cli: Add a `skip` command to the quizzer shell
W. Trevor King [Fri, 8 Feb 2013 03:39:18 +0000 (22:39 -0500)]
ui.cli: Add a `skip` command to the quizzer shell

This lets you bypass a difficult question on the stack and continue
with the rest of the quiz.

9 years agoui.cli: Unwrap multiline answers in display_result
W. Trevor King [Thu, 7 Feb 2013 21:11:41 +0000 (16:11 -0500)]
ui.cli: Unwrap multiline answers in display_result

No need to surprise the user with the internal list representation.

9 years agoui.cli: Use pygments to colorize command line output
W. Trevor King [Thu, 7 Feb 2013 21:10:05 +0000 (16:10 -0500)]
ui.cli: Use pygments to colorize command line output

9 years agoquizzes/git: Don't timeout during the 'gitignore' question v0.1
W. Trevor King [Thu, 7 Feb 2013 01:20:44 +0000 (20:20 -0500)]
quizzes/git: Don't timeout during the 'gitignore' question

In case the user decides to spawn an editor to tweak .gitignore.

9 years agoquizzes/git: Add remote-related questions
W. Trevor King [Thu, 7 Feb 2013 01:09:58 +0000 (20:09 -0500)]
quizzes/git: Add remote-related questions

New questions:
* git remote add
* git remote -v
* git fetch REPOSITORY

9 years agoquizzer/git: Add 'git merge' question
W. Trevor King [Thu, 7 Feb 2013 00:43:45 +0000 (19:43 -0500)]
quizzer/git: Add 'git merge' question

9 years agoquizzes/git: Add 'git checkout *' questions
W. Trevor King [Thu, 7 Feb 2013 00:40:23 +0000 (19:40 -0500)]
quizzes/git: Add 'git checkout *' questions

New questions:
* git checkout
* git checkout -b
* git checkout -b NEW_BRANCH START_POINT

9 years agoquizzes/git: Add 'git branch *' questions
W. Trevor King [Thu, 7 Feb 2013 00:22:58 +0000 (19:22 -0500)]
quizzes/git: Add 'git branch *' questions

New questions:
* git branch
* git branch -a
* git branch -r
* git branch -d

9 years agoquizzes/git: Fix 'in repository' -> 'in your repository'
W. Trevor King [Thu, 7 Feb 2013 00:20:03 +0000 (19:20 -0500)]
quizzes/git: Fix 'in repository' -> 'in your repository'

For the 'git rm / commit' question.

9 years agoquizzes/git: Add 'git rm / commit' question
W. Trevor King [Wed, 6 Feb 2013 22:50:04 +0000 (17:50 -0500)]
quizzes/git: Add 'git rm / commit' question

9 years agoquizzes/git: Add 'git log *' questions
W. Trevor King [Wed, 6 Feb 2013 22:39:26 +0000 (17:39 -0500)]
quizzes/git: Add 'git log *' questions

New questions:
* git log
* git log -p
* git log --stat
* git log --all
* git log --oneline
* git log --oneline --graph
* git log --oneline --decorate

9 years agoquizzes/git: Add 'git diff *' questions
W. Trevor King [Wed, 6 Feb 2013 22:08:03 +0000 (17:08 -0500)]
quizzes/git: Add 'git diff *' questions

New questions:
* git diff
* git diff HEAD --
* git diff HEAD -- README
* git diff --cached

9 years agoquizzes/git: Avoid escaped double-quotes when single-quotes will do
W. Trevor King [Wed, 6 Feb 2013 22:03:23 +0000 (17:03 -0500)]
quizzes/git: Avoid escaped double-quotes when single-quotes will do

9 years agoquizzes/git: Add 'git commit -a' question
W. Trevor King [Wed, 6 Feb 2013 22:03:05 +0000 (17:03 -0500)]
quizzes/git: Add 'git commit -a' question

9 years agoui.cli: Don't start the QuestionCommandLine with an empty stack
W. Trevor King [Wed, 6 Feb 2013 21:55:15 +0000 (16:55 -0500)]
ui.cli: Don't start the QuestionCommandLine with an empty stack

There's not much point in a question-answering shell if there are no
questions to be answered.

9 years agoquizzes/git: Add 'git status' question
W. Trevor King [Wed, 6 Feb 2013 21:54:36 +0000 (16:54 -0500)]
quizzes/git: Add 'git status' question

9 years agoquizzes/git: Add 'gitignore' question
W. Trevor King [Wed, 6 Feb 2013 21:37:59 +0000 (16:37 -0500)]
quizzes/git: Add 'gitignore' question

9 years agoui.cli: Quit after the last question
W. Trevor King [Wed, 6 Feb 2013 21:35:57 +0000 (16:35 -0500)]
ui.cli: Quit after the last question

Oops, should have tested that when I transitioned to Cmd ;).

9 years agoui.cli: Fix ._set_ps1 when .question is None
W. Trevor King [Wed, 6 Feb 2013 21:38:40 +0000 (16:38 -0500)]
ui.cli: Fix ._set_ps1 when .question is None

Otherwise QuestionCommandLine will crash if its launched with an empty
stack (not that this should happen, but we should still avoid the

9 years agoquizzes/git: Add 'git help config' question
W. Trevor King [Wed, 6 Feb 2013 21:14:45 +0000 (16:14 -0500)]
quizzes/git: Add 'git help config' question

9 years agoui.cli: Fix single-line answer extraction
W. Trevor King [Wed, 6 Feb 2013 21:13:10 +0000 (16:13 -0500)]
ui.cli: Fix single-line answer extraction

`var.get(key, default)` only works for dicts.  I don't think there is
an equivalent that works for lists.

9 years agocli: Add --select to filter the stack by index
W. Trevor King [Wed, 6 Feb 2013 21:02:12 +0000 (16:02 -0500)]
cli: Add --select to filter the stack by index

For example, you can show the questions in a quiz with either the
`config` tag or the `checkout` tag:

  $ ./pq.py --all --tag config --tag checkout --questions quizzes/git.json
  Question 0:
  Configure your user-wide name to be `A U Thor`.

  Question 1:
  Configure your user-wide email to be `author@example.com`.

  Question 2:
  You've messed up your README file.
  Restore it to the last committed version.

Say questions 0 and 2 look interesting, and you'd like to try question
2 first.  Run:

  $ ./pq.py --all --tag config --tag checkout -s 2 -s 0 quizzes/git.json

9 years agoui.cli: Add an `answer` command to QuestionCommandLine
W. Trevor King [Wed, 6 Feb 2013 20:09:20 +0000 (15:09 -0500)]
ui.cli: Add an `answer` command to QuestionCommandLine

This allows you to bypass quizzer-shell command handling when your
answer line starts with a quizzer-shell command.

9 years agoui.cli: Repeat the basic help when the user calls `help`
W. Trevor King [Wed, 6 Feb 2013 20:01:17 +0000 (15:01 -0500)]
ui.cli: Repeat the basic help when the user calls `help`

9 years agoui.cli: Transition to a CLI based on cmd.Cmd
W. Trevor King [Wed, 6 Feb 2013 19:57:27 +0000 (14:57 -0500)]
ui.cli: Transition to a CLI based on cmd.Cmd

This makes command handling more robust, and makes adding additional
non-answer commands more organized.

9 years agoquizzes: Convert multi-line help to lists
W. Trevor King [Wed, 6 Feb 2013 18:02:40 +0000 (13:02 -0500)]
quizzes: Convert multi-line help to lists

9 years agoquestion: Add support for list-of-lines help
W. Trevor King [Wed, 6 Feb 2013 17:59:39 +0000 (12:59 -0500)]
question: Add support for list-of-lines help

We use lists of lines for other question attributes (e.g. setup,
teardown, answer, prompt).  Be consistent with multi-line help.

9 years agoquizzes/git: Convert multi-line prompts to lists
W. Trevor King [Wed, 6 Feb 2013 17:53:31 +0000 (12:53 -0500)]
quizzes/git: Convert multi-line prompts to lists

9 years agoquestion: Add support for list-of-lines prompts
W. Trevor King [Wed, 6 Feb 2013 17:47:06 +0000 (12:47 -0500)]
question: Add support for list-of-lines prompts

We use lists of lines for other question attributes (e.g. setup,
teardown, answer).  Be consistent with multi-line prompts.

The handling is in Question.format_prompt() for easy access by any
consumer.  The `newline` option will make it easy to support
non-terminal output formats (e.g. `newline='<br/>'` for HTML).

9 years agoquizzes: Use complete sentences with punctation for prompts
W. Trevor King [Wed, 6 Feb 2013 17:45:51 +0000 (12:45 -0500)]
quizzes: Use complete sentences with punctation for prompts

This makes multi-sentence prompts less awkward.

9 years agocli: Add the --questions option to list questions on the stack
W. Trevor King [Wed, 6 Feb 2013 17:41:23 +0000 (12:41 -0500)]
cli: Add the --questions option to list questions on the stack

This lets you see what a quiz will ask without actually taking the
quiz.  In the future, it may be useful for jumping to a specific

9 years agocli: Add the --tags option to list tags on the stack
W. Trevor King [Wed, 6 Feb 2013 14:59:11 +0000 (09:59 -0500)]
cli: Add the --tags option to list tags on the stack

9 years agoquizzes/git: Tag existing questions
W. Trevor King [Wed, 6 Feb 2013 14:57:16 +0000 (09:57 -0500)]
quizzes/git: Tag existing questions

9 years agoAdd --tag option and Question.tags sets for filtering large quizzes
W. Trevor King [Wed, 6 Feb 2013 14:56:47 +0000 (09:56 -0500)]
Add --tag option and Question.tags sets for filtering large quizzes

9 years agocli: Add --all for easy review of previously-answered questions
W. Trevor King [Wed, 6 Feb 2013 14:47:26 +0000 (09:47 -0500)]
cli: Add --all for easy review of previously-answered questions

9 years agoanswerdb: Timestamp answers
W. Trevor King [Wed, 6 Feb 2013 14:39:59 +0000 (09:39 -0500)]
answerdb: Timestamp answers

This may provide insight into the learning process (e.g. after I
reviewed the Git index, everyone started doing better).

9 years agoquizzes/git: Add 'git commit --amend' question
W. Trevor King [Wed, 6 Feb 2013 14:27:43 +0000 (09:27 -0500)]
quizzes/git: Add 'git commit --amend' question

9 years agoREADME.rst: Add a symlink for GitHub's README renderer
W. Trevor King [Wed, 6 Feb 2013 03:17:11 +0000 (22:17 -0500)]
README.rst: Add a symlink for GitHub's README renderer

9 years agoquizzes/git: Add 'git config --global user.{name,email}' questions
W. Trevor King [Wed, 6 Feb 2013 02:58:48 +0000 (21:58 -0500)]
quizzes/git: Add 'git config --global user.{name,email}' questions

9 years agoquizzes/git: Add 'git checkout HEAD -- FILE' question
W. Trevor King [Wed, 6 Feb 2013 02:43:06 +0000 (21:43 -0500)]
quizzes/git: Add 'git checkout HEAD -- FILE' question

9 years agoquestion: Add a trailing newline to ScriptQuestion scripts
W. Trevor King [Wed, 6 Feb 2013 02:31:01 +0000 (21:31 -0500)]
question: Add a trailing newline to ScriptQuestion scripts

9 years agoquestion: Pass stdin through to the ScriptQuestion-invoked script
W. Trevor King [Wed, 6 Feb 2013 02:21:07 +0000 (21:21 -0500)]
question: Pass stdin through to the ScriptQuestion-invoked script

Use a temporary script to hold the answer script, to leave stdin open.
This allows users to use commands that need stdin (e.g. `git commit`,
which spawns an `$EDITOR`).

9 years agoquizzes/git: Add 'git add / commit' question
W. Trevor King [Wed, 6 Feb 2013 01:56:06 +0000 (20:56 -0500)]
quizzes/git: Add 'git add / commit' question

Remove the default timeout, to give users who spawn `$EDITOR` via `git
commit` time to write and save their message.

9 years agoRun update-copyright.py
W. Trevor King [Tue, 5 Feb 2013 20:41:01 +0000 (15:41 -0500)]
Run update-copyright.py

9 years ago.update-copyright.conf: Configure update-copyright.py
W. Trevor King [Tue, 5 Feb 2013 20:38:11 +0000 (15:38 -0500)]
.update-copyright.conf: Configure update-copyright.py


9 years agoAdd `# Copyright` tags to Python files
W. Trevor King [Tue, 5 Feb 2013 20:37:04 +0000 (15:37 -0500)]
Add `# Copyright` tags to Python files

9 years ago.gitignore: Ignore MANIFEST and dist/ packaging side effects
W. Trevor King [Tue, 5 Feb 2013 20:33:32 +0000 (15:33 -0500)]
.gitignore: Ignore MANIFEST and dist/ packaging side effects

9 years agoMANIFEST.in: Distribute COPYING and quizzes/*.json
W. Trevor King [Tue, 5 Feb 2013 20:33:13 +0000 (15:33 -0500)]
MANIFEST.in: Distribute COPYING and quizzes/*.json

9 years agosetup.py: Package with distutils
W. Trevor King [Tue, 5 Feb 2013 20:31:03 +0000 (15:31 -0500)]
setup.py: Package with distutils

9 years agoREADME: Flesh out description and add example typescript
W. Trevor King [Tue, 5 Feb 2013 20:30:27 +0000 (15:30 -0500)]
README: Flesh out description and add example typescript

9 years agoREADME: Mention Python 3.3 dependency
W. Trevor King [Tue, 5 Feb 2013 20:11:44 +0000 (15:11 -0500)]
README: Mention Python 3.3 dependency

9 years agoCOPYING: Distribute quizzer under the GPLv3+
W. Trevor King [Tue, 5 Feb 2013 20:10:42 +0000 (15:10 -0500)]
COPYING: Distribute quizzer under the GPLv3+

9 years agoquizzes/git: Add preliminary Git quiz (repository creation)
W. Trevor King [Tue, 5 Feb 2013 20:09:41 +0000 (15:09 -0500)]
quizzes/git: Add preliminary Git quiz (repository creation)

9 years agoAdd Question.multiline and associated handling
W. Trevor King [Tue, 5 Feb 2013 20:07:32 +0000 (15:07 -0500)]
Add Question.multiline and associated handling

Some questions can't be answered in a single line without reqiring
more shell knowledge than we need (e.g. `&&`).

9 years agoui.cli: Import `readline` for more comfortable input() editing
W. Trevor King [Tue, 5 Feb 2013 19:39:02 +0000 (14:39 -0500)]
ui.cli: Import `readline` for more comfortable input() editing

9 years agoquizzes/posix-shell: Add a preliminary POSIX shell language quiz
W. Trevor King [Tue, 5 Feb 2013 19:37:21 +0000 (14:37 -0500)]
quizzes/posix-shell: Add a preliminary POSIX shell language quiz

9 years agoquizzes/posix-utilities: Rename from posix-shell.json and flesh out
W. Trevor King [Tue, 5 Feb 2013 19:10:03 +0000 (14:10 -0500)]
quizzes/posix-utilities: Rename from posix-shell.json and flesh out

Added few more questions:
* print the current directory to stdout
* change to your home directory
* change to the parent of your current working directory
* print the contents of README file to the terminal

The renaming is because the tests are testing knowledge of POSIX
utilities, not knowledge of the shell syntax itself.

9 years agoquestion: Normalize tempdir paths in stdout/stderr
W. Trevor King [Tue, 5 Feb 2013 19:09:05 +0000 (14:09 -0500)]
question: Normalize tempdir paths in stdout/stderr

Otherwise it's hard to test `pwd`, since tempdir will change between
the expected and user-supplied answer runs.

9 years agoquestion: Add ChoiceQuestion for one-of-several correct answers
W. Trevor King [Tue, 5 Feb 2013 18:54:18 +0000 (13:54 -0500)]
question: Add ChoiceQuestion for one-of-several correct answers

9 years agoquizzes: Move quizzes into a subdirectory
W. Trevor King [Tue, 5 Feb 2013 18:51:04 +0000 (13:51 -0500)]
quizzes: Move quizzes into a subdirectory

9 years agoAdd script invocation to ScriptQuestion
W. Trevor King [Tue, 5 Feb 2013 18:46:31 +0000 (13:46 -0500)]
Add script invocation to ScriptQuestion

We need Python >= 3.3 for the `timeout` argument to

9 years agoRemove debugging print(self.stack) from UserInterface.get_question()
W. Trevor King [Tue, 5 Feb 2013 17:19:18 +0000 (12:19 -0500)]
Remove debugging print(self.stack) from UserInterface.get_question()

9 years agoInitial ScriptQuestion framework
W. Trevor King [Tue, 5 Feb 2013 17:18:21 +0000 (12:18 -0500)]
Initial ScriptQuestion framework