Before I post any of these ideas on the IPython Notebook wiki, I'd be grateful for feedback from our learners and instructors. Most of these (maybe all of them?) would be done as extensions, rather than as patches to IPyNB itself. Please let us know what you think; I'll revise and then cross-post to the IPyNB folks.

Our Users

Anna teaches scientists how to program. She usually does this by coding live in front of a small class (20-40 people), but also wants to create recordings for people to view outside class.

Farouk is a graduate student in chemistry who wants to learn how to program. He learns best when he can bounce ideas off other people.

Progressive Reveal


Anna knows that showing learners too much is just as bad as showing them too little. In particular, putting an entire lesson in front of people at once is distracting: she would prefer to reveal one snippet at a time so that they're always concentrating on the right thing. Slideshows are one way to do this, but Farouk finds slideshows frustrating, because everything he is shown disappears to make room for something new.


Add "progressive reveal" to the notebook, so that clicking on a button (or better yet, a key combination) will make the next section of the notebook visible. Visually, this will appear to append a cell (or a group of cells) to what's already in the notebook. However, the implementation should store everything in the notebook, and just use Javascript to show/hide sections. There should also be "unshow", "show all", etc.

The authoring interface used to define what gets revealed in turn is probably harder to design and implement than the actual display code. When editing, Anna will want to see the entire notebook at once, but will also want some sort of visual hints to show what the revealed blocks will be (e.g., an outline box around each section). Anna will also want an equally-intuitive way to define and change the scope and order of what's revealed.

Note: Anna will almost always reveal things in "append" order, but there are cases where she will want to reveal a block between already-visible blocks, i.e., go back and say, "So this is what we should have done at this point." There may also be cases where she will want to replace blocks rather than append to them, but there are good pedagogical reasons not to support this: the final display should be a record of everything that was said and done, not just the end result.

Multiple-Choice Questions


Peer instruction is a scalable teaching technique in which:

  • the instructor poses a multiple-choice question with 3-4 plausible answers
  • each learner votes for an answer (typically using a clicker)
  • learners discuss their answers in small groups (typically 3-4 people)
  • the instructor presents and explains the correct answer
  • learners discuss again in order to clear up one another's misconceptions

This process is inherently synchronous. In order to implement it online, Anna needs a way for learners to talk to one another in small groups, and a way for them to vote. The former is handled (badly, but handled) by Skype, Google Chat, and other tools; she'd like support in the notebook for the latter, both to support peer instruction, and also to handle "can we move on?" and "how are we doing?" questions in synchronous online classes being run in broadcast mode.


One possibility is to add support for simple real-time voting to the notebook as part of the implementation of multi-user servers. (A possible starting point or inspiration would be Socraticqs.) However, this is a specialized enough need that it should instead be used as a test of the plugin API for the multi-user server and notebook: it should be possible to add voting, tallying, and display without modifying the core.

Auto-Interrupt Based on Lines or Time


Farouk is learning how to write while loops. The results have been unsatisfying: infinite loops with print statements fill up his cells, while infinite loops without output are impossible to distinguish from a slow server or a bad network connection.


Allow users to specify how long the back-end should be allowed to process a command, and/or how much output it should be allowed to produce. This can be piggy-backed on top of the existing Ctrl-C interrupt mechanism: when execution starts, a timer is started in the browser, and an interrupt key press event is faked when the timer expires. Something similar could be done based on how much output is received (e.g., "halt the process at 100 lines"), though this is probably less important to implement.

Synchronizing Test Output to Changes in Code Under Test


Farouk is learning how to write unit tests in the notebook. He hasn't converted to test-driven development yet, so he:

  • writes a function
  • writes a few unit tests
  • runs the unit tests
  • tweaks the function
  • repeats

He is frequently interrupted by other tasks (like answering his phone or updating Facebook). When this happens, he sometimes forgets what he was doing, and thinks that the currently-visible output of his tests is in sync with the code, when in fact the code has changed and the tests haven't been re-run.


Farouk should be able to specify that some cells (the ones holding tests) are automatically run whenever changes are made to other cells (the ones holding the code under test). This is a restricted two-stage case of specifying arbitrary cell execution order: it may be enough to create two cell groups (one for code, one for tests) and re-execute everything in the test group whenever anything in the code group changes.

Timed Text Recording


Anna has been recording screencasts to show learners how to use lists, write functions, and so on. She and Farouk both find them frustrating:

  • the text in the videos is never as easy to read as they'd like
  • it's impossible to search for text in the video, or to copy and paste it into Farouk's browser

Anna would like the "video" to play in the notebook itself, in the same way that ttyrec replays a shell session inside a terminal window. She would also like this replay to be synchronized with a soundtrack.


  1. Record text events (typing and program output) with millisecond-level timestamps in the notebook. This data should be stored in an auxiliary file outside the notebook itself.
  2. Provide a tool like the notebook viewer that will reconstruct a notebook character by character (and image by image) given such a file.
  3. Use something like Popcorn.js to synchronize this replay with an audio soundtrack.

This post originally appeared in the Software Carpentry blog.