From ebbfd78c9a78c54ecfa012cb6aedcb4fa2aa98f4 Mon Sep 17 00:00:00 2001 From: Raniere Silva Date: Fri, 13 Jan 2017 19:56:51 +0000 Subject: [PATCH 1/2] Proposal for use of Jupyter Notebook --- Makefile | 25 +- _config.yml | 3 + .../{07-maintenance.md => 08-maintenance.md} | 0 _episodes/{08-coffee.md => 09-coffee.md} | 0 _episodes_ipynb/07-jupyter.ipynb | 214 ++++++++++++++++++ _layouts/ipynb2md.tpl | 78 +++++++ 6 files changed, 310 insertions(+), 10 deletions(-) rename _episodes/{07-maintenance.md => 08-maintenance.md} (100%) rename _episodes/{08-coffee.md => 09-coffee.md} (100%) create mode 100644 _episodes_ipynb/07-jupyter.ipynb create mode 100644 _layouts/ipynb2md.tpl diff --git a/Makefile b/Makefile index b5dfe2fa..9300ee0c 100644 --- a/Makefile +++ b/Makefile @@ -6,10 +6,10 @@ MAKEFILES=Makefile $(wildcard *.mk) JEKYLL=jekyll PARSER=bin/markdown_ast.rb DST=_site +JUPYTER=jupyter # Controls .PHONY : commands clean files -.NOTPARALLEL: all : commands ## commands : show all commands. @@ -17,11 +17,11 @@ commands : @grep -h -E '^##' ${MAKEFILES} | sed -e 's/## //g' ## serve : run a local server. -serve : lesson-md +serve : lesson-rmd lesson-jupyter ${JEKYLL} serve ## site : build files but do not run a server. -site : lesson-md +site : lesson-rmd lesson-jupyter ${JEKYLL} build # repo-check : check repository settings. @@ -54,12 +54,16 @@ workshop-check : ## ---------------------------------------- ## Commands specific to lesson websites. -.PHONY : lesson-check lesson-md lesson-files lesson-fixme +.PHONY : lesson-check lesson-rmd lesson-files lesson-fixme # RMarkdown files RMD_SRC = $(wildcard _episodes_rmd/??-*.Rmd) RMD_DST = $(patsubst _episodes_rmd/%.Rmd,_episodes/%.md,$(RMD_SRC)) +# JUPYTER files +JUPYTER_SRC = $(wildcard _episodes_ipynb/??-*.ipynb) +JUPYTER_DST = $(patsubst _episodes_ipynb/%.ipynb,_episodes/%.ipynb,$(JUPYTER_SRC)) + # Lesson source files in the order they appear in the navigation menu. MARKDOWN_SRC = \ index.md \ @@ -80,16 +84,17 @@ HTML_DST = \ $(patsubst _extras/%.md,${DST}/%/index.html,$(wildcard _extras/*.md)) \ ${DST}/license/index.html -## lesson-md : convert Rmarkdown files to markdown -lesson-md : ${RMD_DST} +## lesson-rmd : convert Rmarkdown files to markdown +lesson-rmd: $(RMD_SRC) + @bin/knit_lessons.sh $(RMD_SRC) -# Use of .NOTPARALLEL makes rule execute only once -${RMD_DST} : ${RMD_SRC} - @bin/knit_lessons.sh ${RMD_SRC} +## lesson-jupyter : convert Jupyter Notebook files to markdown +lesson-jupyter: $(JUPYTER_SRC) + ${JUPYTER} nbconvert -y --execute --allow-errors --to markdown --output-dir=_episodes --NbConvertApp.output_files_dir="" --template=_layouts/ipynb2md.tpl $(JUPYTER_SRC) ## lesson-check : validate lesson Markdown. lesson-check : - @bin/lesson_check.py -s . -p ${PARSER} -r _includes/links.md + @bin/lesson_check.py -s . -p ${PARSER} ## lesson-check-all : validate lesson Markdown, checking line lengths and trailing whitespace. lesson-check-all : diff --git a/_config.yml b/_config.yml index cc650eec..1fb2afaf 100644 --- a/_config.yml +++ b/_config.yml @@ -67,3 +67,6 @@ exclude: # Turn off built-in syntax highlighting. highlighter: false + +kramdown: + parse_block_html: true diff --git a/_episodes/07-maintenance.md b/_episodes/08-maintenance.md similarity index 100% rename from _episodes/07-maintenance.md rename to _episodes/08-maintenance.md diff --git a/_episodes/08-coffee.md b/_episodes/09-coffee.md similarity index 100% rename from _episodes/08-coffee.md rename to _episodes/09-coffee.md diff --git a/_episodes_ipynb/07-jupyter.ipynb b/_episodes_ipynb/07-jupyter.ipynb new file mode 100644 index 00000000..b91d31a1 --- /dev/null +++ b/_episodes_ipynb/07-jupyter.ipynb @@ -0,0 +1,214 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "title: Using Jupyter Notebook \n", + "teaching: 10\n", + "exercises: 1\n", + "questions:\n", + "- \"How to write a lesson using Jupyter Notebook?\"\n", + "objectives:\n", + "- \"Explain how to use Jupyter Notebook with the new lesson template.\"\n", + "- \"Demonstrate how to include pieces of code, figures, and challenges.\"\n", + "keypoints:\n", + "- \"It shouldn't be difficult\"\n", + "---\n", + "\n", + "The lesson should be written with a mix of code cells and Markdown cells,\n", + "just like you'd normally do." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1.15000000000000" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "1 + 1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Output with error message:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "ename": "TypeError", + "evalue": "'sage.symbolic.expression.Expression' object does not support indexing", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mx\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mInteger\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m10\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m: 'sage.symbolic.expression.Expression' object does not support indexing" + ] + } + ], + "source": [ + "x[10]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Output generating figures:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "% matplotlib inline" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\nAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot\n", + "\n", + "matplotlib.pyplot.plot([1,2,3], [1,2,3])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For the challenges you need to pay attention\n", + "to include `
` before it\n", + "and `<\\blockquote>` after it.\n", + "And for the solutions you need to pay attention\n", + "to include `
` before it\n", + "and `<\\blockquote>` after it.\n", + "**This hacks is necessary for allow include Jupyter cells on challenges and solutions.**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "
\n", + "## Challenge: Can you do it?\n", + "\n", + "What is the output of this command?\n", + "\n", + "~~~\n", + "\"a\" + \"b\"\n", + "~~~\n", + "{: .source}\n", + "\n", + "
\n", + "## Solution" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'ab'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\"a\" + \"b\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "
" + ] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python [default]", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.1" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/_layouts/ipynb2md.tpl b/_layouts/ipynb2md.tpl new file mode 100644 index 00000000..805dc2b3 --- /dev/null +++ b/_layouts/ipynb2md.tpl @@ -0,0 +1,78 @@ +{% extends 'display_priority.tpl' %} + + +{% block in_prompt %} +{% endblock in_prompt %} + +{% block output_prompt %} +{%- endblock output_prompt %} + +{% block input %} +~~~ +{{ cell.source}} +~~~ +{: .source {% if nb.metadata.language_info %}.{{ nb.metadata.language_info.name }}{% endif %}} +{% endblock input %} + +{% block error %} +~~~ +{{- super()|replace("\n\n", "\n")|replace(" ", "") -}} +~~~ +{: .error} +{% endblock error %} + +{% block traceback_line %} +{{ line | indent | strip_ansi }} +{% endblock traceback_line %} + +{% block execute_result %} +{% block data_priority scoped %} +{{ super() }} +{% endblock %} +{% endblock execute_result %} + +{% block stream %} +~~~ +{{ output.text }} +~~~ +{: .output} +{% endblock stream %} + +{% block data_svg %} +![svg](../{{ output.metadata.filenames['image/svg+xml'] | path2url }}) +{% endblock data_svg %} + +{% block data_png %} +![png](../{{ output.metadata.filenames['image/png'] | path2url }}) +{% endblock data_png %} + +{% block data_jpg %} +![jpeg](../{{ output.metadata.filenames['image/jpeg'] | path2url }}) +{% endblock data_jpg %} + +{% block data_latex %} +{{ output.data['text/latex'] }} +{% endblock data_latex %} + +{% block data_html scoped %} +{{ output.data['text/html'] }} +{% endblock data_html %} + +{% block data_markdown scoped %} +{{ output.data['text/markdown'] }} +{% endblock data_markdown %} + +{% block data_text scoped %} +~~~ +{{ output.data['text/plain'] }} +~~~ +{: .output} +{% endblock data_text %} + +{%- block markdowncell scoped -%} +{{ cell.source }} +{% endblock markdowncell %} + +{% block unknowncell scoped %} +unknown type {{ cell.type }} +{% endblock unknowncell %} From 7c87782ac886139ed40af558e576e8bc8f8994e3 Mon Sep 17 00:00:00 2001 From: Raniere Silva Date: Thu, 19 Jan 2017 00:35:15 +0000 Subject: [PATCH 2/2] Add compiled files from Jupyter Notebook --- _episodes/07-jupyter.md | 111 +++++++++++++++++++++++++++++++++++ _episodes/07-jupyter_6_1.png | Bin 0 -> 10337 bytes 2 files changed, 111 insertions(+) create mode 100644 _episodes/07-jupyter.md create mode 100644 _episodes/07-jupyter_6_1.png diff --git a/_episodes/07-jupyter.md b/_episodes/07-jupyter.md new file mode 100644 index 00000000..b801914d --- /dev/null +++ b/_episodes/07-jupyter.md @@ -0,0 +1,111 @@ +--- +title: Using Jupyter Notebook +teaching: 10 +exercises: 1 +questions: +- "How to write a lesson using Jupyter Notebook?" +objectives: +- "Explain how to use Jupyter Notebook with the new lesson template." +- "Demonstrate how to include pieces of code, figures, and challenges." +keypoints: +- "It shouldn't be difficult" +--- + +The lesson should be written with a mix of code cells and Markdown cells, +just like you'd normally do. + + +~~~ +1 + 1 +~~~ +{: .source .python} + + + +~~~ +2 +~~~ +{: .output} + + +Output with error message: + + +~~~ +x[10] +~~~ +{: .source .python} + +~~~ +--------------------------------------------------------------------------- +NameError Traceback (most recent call last) + in () +----> 1 x[10] + +NameError: name 'x' is not defined +~~~ +{: .error} +Output generating figures: + + +~~~ +% matplotlib inline +~~~ +{: .source .python} + + +~~~ +import matplotlib.pyplot + +matplotlib.pyplot.plot([1,2,3], [1,2,3]) +~~~ +{: .source .python} + + + +~~~ +[] +~~~ +{: .output} + + + + +![png](../07-jupyter_6_1.png) + +For the challenges you need to pay attention +to include `
` before it +and `<\blockquote>` after it. +And for the solutions you need to pay attention +to include `
` before it +and `<\blockquote>` after it. +**This hacks is necessary for allow include Jupyter cells on challenges and solutions.** +
+## Challenge: Can you do it? + +What is the output of this command? + +~~~ +"a" + "b" +~~~ +{: .source} + +
+## Solution + + +~~~ +"a" + "b" +~~~ +{: .source .python} + + + +~~~ +'ab' +~~~ +{: .output} + + +
+
diff --git a/_episodes/07-jupyter_6_1.png b/_episodes/07-jupyter_6_1.png new file mode 100644 index 0000000000000000000000000000000000000000..5058f76418a81f3a8112883c10a5096d740f7c3d GIT binary patch literal 10337 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