[IPython-dev] prose, notebooks, and thrashing (and a re-direct to another list)

Greg Wilson gvwilson at third-bit.com
Mon Jul 29 11:13:17 EDT 2013


Hi,
I posted the message below to the Software Carpentry discussion list a 
few minutes ago.  I'd appreciate input from the IPython Notebook 
community as well.
Thanks,
Greg
p.s. if anyone has a good way to manage discussion that spans two 
independent mailing lists, I'm all ears... :-)

---------------------------------------------------------------------------------------------------

Hi,

I'm trying to figure out how to satisfy four sets of needs for 
instructional material using IPython Notebooks in Software Carpentry. I 
feel like I'm thrashing, so I'd appreciate your help.

My four use cases are:

* instructor's guide: to help instructors prepare for a bootcamp
* lecture notes: what instructors use during a bootcamp
* workbook: what learners are given to use during a bootcamp
* textbook: what learners use on their own outside a bootcamp

To make this more concrete, have a look at 
http://swcarpentry.github.io/bc/lessons/guide-shell/tutorial.html, which 
describes how I teach the shell:

* 
http://swcarpentry.github.io/bc/lessons/guide-shell/tutorial.html#s:shell:instructors 
is a high-level intro for instructors.  Learners might find it useful, 
but it's not really aimed at them.

* Each topic opens with objectives (see 
http://swcarpentry.github.io/bc/lessons/guide-shell/tutorial.html#s:shell:filedir:objectives 
for an example).  This belongs in the instructor's guide ("Here's what 
you're supposed to teach"), possibly the lecture notes ("Hi class, 
here's what I'm about to teach"), probably not the workbook, and 
definitely the textbook.

* Each topic ends with key points and challenge exercises: see 
http://swcarpentry.github.io/bc/lessons/guide-shell/tutorial.html#s:shell:filedir:keypoints, 
and 
http://swcarpentry.github.io/bc/lessons/guide-shell/tutorial.html#s:shell:filedir:challenges 
for examples.  Again, both belong in the instructor's guide and the 
textbook; they probably belong in the lecture notes, and probably also 
in the workbook (as a starting point for learners' own notes, and so 
that they know what to work on during practicals).

Problem #1: how do we manage material that ought to appear in multiple 
documents?  Right now, each snippet is a separate HTML file that is 
%include'd to assemble the entire document (see 
https://raw.github.com/swcarpentry/bc/gh-pages/lessons/guide-shell/tutorial.html). 
That works OK for HTML pages, but not for notebooks: as far as I know, 
there's no way to %include file X in notebook Y.

Problem #2: what exactly ought to be in the lecture notes?  For example, 
compare 
http://swcarpentry.github.io/bc/lessons/guide-pyblocks/tutorial.html#s:pyblocks:logic:lesson 
(the introduction to "if/else" in the incomplete instructor's guide to 
basic Python programming using IPythonBlocks) to 
http://nbviewer.ipython.org/urls/raw.github.com/swcarpentry/bc/gh-pages/lessons/guide-pyblocks/pyblocks-logic.ipynb 
(an IPython Notebook with the same handful of examples).  The former is 
much too verbose to put in front of learners in a classroom setting.  I 
feel the latter is too sparse, but when I add point-form notes and then 
lecture over the result, it feels clumsy:

* If the item I'm currently talking about is centered on the screen, 
learners can see my next points on screen below it.  This is distracting 
--- so distracting that tools like PowerPoint and other slideshow tools 
were invented in part to prevent it happening.  If the notebook 
supported progressive reveal of pre-made cells, that problem would lessen.

* Even with that, though, one of the most compelling reasons to use the 
notebook as a lecture tool is lost.  Learners really like us typing code 
in as we teach: it slows us down, which makes it more likely that we'll 
walk through the code at a comprehensible pace, and it makes it a lot 
easier for us to extemporize in response to their questions or 
confusion.  We lose both benefits if we start using "reveal next", 
though we're still better off than if we use slides.

Problem #3: what ought to be in the workbook (the notebook we give 
students as a starting point)?  Option A is "nothing": they should type 
things in as the lecture proceeds.  This forces them to learn hands-on 
(which is good), but greatly increases the risk that they'll fall behind:

* They're more likely to mis-type something than the instructor, so 
their actual lines-per-second is (much) lower.
* They want to take notes, which slows them down even further.

Option B is to give learners a notebook with notes and code already in 
it, but that gets us back to them (a) being distracted by material they 
haven't seen yet, but which is already on their screen, and (b) not 
having to be hands-on while learning.  On the other hand, these are 
grownups, and there's only so much we can do with existing tools.

So here's what I think I've come to:

1. For now, we create two documents: an instructor's guide that doubles 
as a textbook (no harm in learners reading notes for instructors, and 
possibly some benefit), and a notebook that interleaves point-form notes 
with code examples that instructors will use for lecturing, and learners 
will be given as a starting point.

2. We build a tool to extract point-form notes from an IPython Notebook 
to create the "objectives.html" and "keypoints.html" sections that are 
%include'd in #1 above.  This will help keep the notebook and the guide 
in step; whoever changes the notebook will still have to read the 
section of the guide to make sure, but it's a step.

3. The code cells in our notebooks have markers for the instructors and 
the learners to fill in.  For example, instead of giving people:

     for char in "GATTACA":
         if char == "A":
             print "found an A"

we have:

     for ________ in "GATTACA":
         if ________:
             print "found an A"

Filling in the ________'s in the code snippets forces the instructor and 
the learners to do some typing. As a bonus, if chosen judiciously they 
will also encourage both to focus on the key features of the example.

But there are problems.  (You knew there would be...)

* (medium-sized) In order to extract stuff from notebooks for use 
elsewhere, we need a way to tag the cells that contain objectives, notes 
for the key point summary, etc., so that our tool can find and 
differentiate them.  I *think* this can be done via a plugin: the 
notebook has an extensible metadata field per cell, which we've already 
exploited for another tool, so adding something that allows "right click 
and select tag" should be straightforward. It would be nice if this info 
was available as a class on the HTML element containing the material, so 
that it could be styled via CSS, but that's a bonus.

* (large) Literal ________'s in our code will make it invalid, so our 
notebooks either won't have any output (because we didn't execute the 
code) or will be littered with error messages (because we did).  The 
former's not bad, but if we do that, we need two version of each 
notebook: one with the blanks, and one with them filled in.  As always, 
keeping variants of a single document in sync will be a pain.

If the code in cells was stored as HTML, we could put something like 
<span class="fillin">char == "A"</span> in the code, then use Javascript 
to display ________, erase it when the learner started typing, or fill 
it in with the right answer when the learner just wanted to catch up or 
see the answer. Problem is, the code *isn't* stored as HTML; it's stored 
as JSON that looks like this:

     {
      "cell_type": "code",
      "collapsed": false,
      "input": [
       "import math\n",
       "print \"pi is\", math.pi\n",
       "print \"square root of 5 is\", math.sqrt(5)"
      ],
      "language": "python",
      "metadata": {},
      "outputs": [
       {
        "output_type": "stream",
        "stream": "stdout",
        "text": [
         "pi is 3.14159265359\n",
         "square root of 5 is 2.2360679775\n"
        ]
       }
      ],
      "prompt_number": 1
     }

We could use character offsets to identify subsections of the code, then 
intercept rendering to insert span elements, but that way lies madness...

So as I said at the outset, I feel like I'm thrashing here, and would 
welcome suggestions on how to proceed.

Thanks,
Greg




More information about the IPython-dev mailing list