Created
October 4, 2012 22:32
-
-
Save minrk/3836889 to your computer and use it in GitHub Desktop.
Demo of hideable hints and scrubbing solutions from IPython notebooks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
""" | |
simple example script for scrubping solution code cells from IPython notebooks | |
Usage: `scrub_code.py foo.ipynb [bar.ipynb [...]]` | |
Marked code cells are scrubbed from the notebook | |
""" | |
import io | |
import os | |
import sys | |
from IPython.nbformat.current import read, write | |
def scrub_code_cells(nb): | |
scrubbed = 0 | |
cells = 0 | |
for ws in nb.worksheets: | |
for cell in ws.cells: | |
if cell.cell_type != 'code': | |
continue | |
cells += 1 | |
# scrub cells marked with initial '# Solution' comment | |
# any other marker will do, or it could be unconditional | |
if cell.input.startswith("# Solution"): | |
cell.input = u'# Solution goes here' | |
scrubbed += 1 | |
cell.outputs = [] | |
print "scrubbed %i/%i code cells from notebook %s" % (scrubbed, cells, nb.metadata.name) | |
if __name__ == '__main__': | |
for ipynb in sys.argv[1:]: | |
print "scrubbing %s" % ipynb | |
with io.open(ipynb, encoding='utf8') as f: | |
nb = read(f, 'json') | |
scrub_code_cells(nb) | |
base, ext = os.path.splitext(ipynb) | |
new_ipynb = "%s_scrub%s" % (base, ext) | |
with io.open(new_ipynb, 'w', encoding='utf8') as f: | |
write(nb, f, 'json') | |
print "wrote %s" % new_ipynb |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"metadata": { | |
"name": "SWCDemo" | |
}, | |
"nbformat": 3, | |
"nbformat_minor": 0, | |
"worksheets": [ | |
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Initial cell has buttons to show/hide all hint cells" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"<script>\n", | |
" toggle_md_cell = function(divid) {\n", | |
" $(\"#\" + divid).parent().parent().toggle();\n", | |
" };\n", | |
" hide_all_hints = function() {\n", | |
" $(\"div.hint\").parent().parent().hide();\n", | |
" };\n", | |
" show_all_hints = function() {\n", | |
" $(\"div.hint\").parent().parent().show();\n", | |
" };\n", | |
"</script>\n", | |
"\n", | |
"<button onclick=\"show_all_hints();\">show hints</button> <button onclick=\"hide_all_hints();\">hide hints</button>" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# this code cell isn't marked, so it survives\n", | |
"print \"Welcome to Software Carpentry!\"" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Welcome to Software Carpentry!\n" | |
] | |
} | |
], | |
"prompt_number": 4 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 1, | |
"metadata": {}, | |
"source": [ | |
"Problem 1" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Click this button to reveal a hint: <button onclick=\"toggle_md_cell('hint1');\">hint</button>" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## This is Hint # 1\n", | |
"\n", | |
"We mark each hint cell with an empty div:\n", | |
"\n", | |
" <div id=\"hint2\" class=\"hint\"></div>\n", | |
"\n", | |
"<div id=\"hint1\" class=\"hint\"></div>" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# Solution goes here" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 2 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 1, | |
"metadata": {}, | |
"source": [ | |
"Problem 2" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Click this button to reveal the next hint: <button onclick=\"toggle_md_cell('hint2');\">hint</button>" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### This is Hint #2\n", | |
"\n", | |
"Here is how we are toggling hints:\n", | |
"\n", | |
" <button onclick=\"toggle_md_cell('hint2');\">toggle hint</button>\n", | |
"\n", | |
"<div id=\"hint2\" class=\"hint\"></div>" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# Solution goes here" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 3 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"*footer that hides all hints on load*\n", | |
"\n", | |
"Alternatively, one could add individual hides inside each hint cell,\n", | |
"but this is the simplest way to hide all of them on page load.\n", | |
"\n", | |
"<script>\n", | |
" hide_all_hints();\n", | |
"</script>" | |
] | |
} | |
], | |
"metadata": {} | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment