`: This will show you a side-by-side comparison of two Notebooks in the web-browser:"
48 | ]
49 | },
50 | {
51 | "cell_type": "markdown",
52 | "metadata": {},
53 | "source": [
54 | "A notebook is a JSON document that's not the easiest to read raw:"
55 | ]
56 | },
57 | {
58 | "cell_type": "code",
59 | "execution_count": null,
60 | "metadata": {},
61 | "outputs": [],
62 | "source": [
63 | "with open('nbdime-before.ipynb') as f:\n",
64 | " for line in f.readlines()[:64]:\n",
65 | " line = line.rstrip()\n",
66 | " if len(line) > 80:\n",
67 | " line = line[:64] + '...(%i chars)' % len(line)\n",
68 | " print(line)"
69 | ]
70 | },
71 | {
72 | "cell_type": "markdown",
73 | "metadata": {},
74 | "source": [
75 | "`nbshow` gives you a nice readable format, and can focus on particular information,\n",
76 | "such as showing only source code with `-s`:"
77 | ]
78 | },
79 | {
80 | "cell_type": "code",
81 | "execution_count": null,
82 | "metadata": {},
83 | "outputs": [],
84 | "source": [
85 | "!nbshow nbdime-after.ipynb -s"
86 | ]
87 | },
88 | {
89 | "cell_type": "markdown",
90 | "metadata": {},
91 | "source": [
92 | "nbdime also provides diffing commands. `nbdiff` shows you a diff in the terminal, similarly formatted to `nbshow`:"
93 | ]
94 | },
95 | {
96 | "cell_type": "code",
97 | "execution_count": null,
98 | "metadata": {},
99 | "outputs": [],
100 | "source": [
101 | "!nbdiff nbdime-before.ipynb nbdime-after.ipynb"
102 | ]
103 | },
104 | {
105 | "cell_type": "markdown",
106 | "metadata": {},
107 | "source": [
108 | "And `nbdiff-web` opens a browser to show a rendered diff, including side-by-side images:"
109 | ]
110 | },
111 | {
112 | "cell_type": "code",
113 | "execution_count": null,
114 | "metadata": {},
115 | "outputs": [],
116 | "source": [
117 | "!nbdiff-web nbdime-before.ipynb nbdime-after.ipynb"
118 | ]
119 | },
120 | {
121 | "cell_type": "markdown",
122 | "metadata": {},
123 | "source": [
124 | "## Git integration\n",
125 | "\n",
126 | "If you want nbdime to integrate with git, you will have to tell git about how to use nbdime. You can configure this manually, but for convenience nbdime includes some commands to register itself in the most common configuration. Starting out, you simply need to run:"
127 | ]
128 | },
129 | {
130 | "cell_type": "code",
131 | "execution_count": null,
132 | "metadata": {
133 | "collapsed": true
134 | },
135 | "outputs": [],
136 | "source": [
137 | "!nbdime config-git --enable --global"
138 | ]
139 | },
140 | {
141 | "cell_type": "markdown",
142 | "metadata": {},
143 | "source": [
144 | "With the default configuration, nbdime will automatically be used for `.ipynb` files when:\n",
145 | " - you call `git diff` on the command-line\n",
146 | " - git is trying to resolve conflicting changes (*merge conflicts*)\n",
147 | " \n",
148 | "It is worth noting that `nbdiff` and `nbdiff-web` can also be used to show you the changes to Notebooks in a git repository. Simply calling `nbdiff-web` without any arguments in your repository will show you the diff for all the Notebooks that have changed:"
149 | ]
150 | },
151 | {
152 | "cell_type": "code",
153 | "execution_count": null,
154 | "metadata": {
155 | "collapsed": true
156 | },
157 | "outputs": [],
158 | "source": [
159 | "!nbdiff-web origin/master nbdime.ipynb"
160 | ]
161 | }
162 | ],
163 | "metadata": {
164 | "kernelspec": {
165 | "display_name": "Python 3",
166 | "language": "python",
167 | "name": "python3"
168 | },
169 | "language_info": {
170 | "codemirror_mode": {
171 | "name": "ipython",
172 | "version": 3
173 | },
174 | "file_extension": ".py",
175 | "mimetype": "text/x-python",
176 | "name": "python",
177 | "nbconvert_exporter": "python",
178 | "pygments_lexer": "ipython3",
179 | "version": "3.6.0"
180 | }
181 | },
182 | "nbformat": 4,
183 | "nbformat_minor": 2
184 | }
185 |
--------------------------------------------------------------------------------
/Part-3/Beat Frequencies.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Exploring Beat Frequencies using the `Audio` Object"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "This example uses the `Audio` object and Matplotlib to explore the phenomenon of beat frequencies."
15 | ]
16 | },
17 | {
18 | "cell_type": "code",
19 | "execution_count": null,
20 | "metadata": {
21 | "collapsed": false
22 | },
23 | "outputs": [],
24 | "source": [
25 | "%matplotlib inline\n",
26 | "import matplotlib.pyplot as plt\n",
27 | "import numpy as np"
28 | ]
29 | },
30 | {
31 | "cell_type": "code",
32 | "execution_count": null,
33 | "metadata": {
34 | "collapsed": false
35 | },
36 | "outputs": [],
37 | "source": [
38 | "from ipywidgets import interactive\n",
39 | "from IPython.display import Audio, display\n",
40 | "import numpy as np"
41 | ]
42 | },
43 | {
44 | "cell_type": "code",
45 | "execution_count": null,
46 | "metadata": {
47 | "collapsed": false
48 | },
49 | "outputs": [],
50 | "source": [
51 | "def beat_freq(f1=220.0, f2=224.0):\n",
52 | " max_time = 3\n",
53 | " rate = 8000\n",
54 | " times = np.linspace(0,max_time,rate*max_time)\n",
55 | " signal = np.sin(2*np.pi*f1*times) + np.sin(2*np.pi*f2*times)\n",
56 | " print(f1, f2, abs(f1-f2))\n",
57 | " display(Audio(data=signal, rate=rate, autoplay=True))\n",
58 | " return signal"
59 | ]
60 | },
61 | {
62 | "cell_type": "code",
63 | "execution_count": null,
64 | "metadata": {
65 | "collapsed": false
66 | },
67 | "outputs": [],
68 | "source": [
69 | "v = interactive(beat_freq, f1=(200.0,300.0), f2=(200.0,300.0))\n",
70 | "display(v)"
71 | ]
72 | },
73 | {
74 | "cell_type": "code",
75 | "execution_count": null,
76 | "metadata": {
77 | "collapsed": false
78 | },
79 | "outputs": [],
80 | "source": [
81 | "v.kwargs"
82 | ]
83 | },
84 | {
85 | "cell_type": "code",
86 | "execution_count": null,
87 | "metadata": {
88 | "collapsed": false
89 | },
90 | "outputs": [],
91 | "source": [
92 | "f1, f2 = v.children\n",
93 | "f1.value = 255\n",
94 | "f2.value = 260\n",
95 | "plt.plot(v.result[0:6000]);"
96 | ]
97 | }
98 | ],
99 | "metadata": {
100 | "kernelspec": {
101 | "display_name": "Python 3",
102 | "language": "python",
103 | "name": "python3"
104 | },
105 | "language_info": {
106 | "codemirror_mode": {
107 | "name": "ipython",
108 | "version": 3
109 | },
110 | "file_extension": ".py",
111 | "mimetype": "text/x-python",
112 | "name": "python",
113 | "nbconvert_exporter": "python",
114 | "pygments_lexer": "ipython3",
115 | "version": "3.5.1"
116 | },
117 | "widgets": {
118 | "state": {},
119 | "version": "1.1.1"
120 | }
121 | },
122 | "nbformat": 4,
123 | "nbformat_minor": 0
124 | }
125 |
--------------------------------------------------------------------------------
/Part-3/Exploring Graphs.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "## Explore Random Graphs Using NetworkX"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "In this example, we build a simple UI for exploring random graphs with [NetworkX](http://networkx.github.io/)."
15 | ]
16 | },
17 | {
18 | "cell_type": "code",
19 | "execution_count": null,
20 | "metadata": {
21 | "collapsed": false
22 | },
23 | "outputs": [],
24 | "source": [
25 | "from ipywidgets import interact"
26 | ]
27 | },
28 | {
29 | "cell_type": "code",
30 | "execution_count": null,
31 | "metadata": {
32 | "collapsed": false
33 | },
34 | "outputs": [],
35 | "source": [
36 | "%matplotlib inline\n",
37 | "import matplotlib.pyplot as plt"
38 | ]
39 | },
40 | {
41 | "cell_type": "code",
42 | "execution_count": null,
43 | "metadata": {
44 | "collapsed": false
45 | },
46 | "outputs": [],
47 | "source": [
48 | "import networkx as nx"
49 | ]
50 | },
51 | {
52 | "cell_type": "code",
53 | "execution_count": null,
54 | "metadata": {
55 | "collapsed": false
56 | },
57 | "outputs": [],
58 | "source": [
59 | "# wrap a few graph generation functions so they have the same signature\n",
60 | "\n",
61 | "def random_lobster(n, m, k, p):\n",
62 | " return nx.random_lobster(n, p, p / m)\n",
63 | "\n",
64 | "def powerlaw_cluster(n, m, k, p):\n",
65 | " return nx.powerlaw_cluster_graph(n, m, p)\n",
66 | "\n",
67 | "def erdos_renyi(n, m, k, p):\n",
68 | " return nx.erdos_renyi_graph(n, p)\n",
69 | "\n",
70 | "def newman_watts_strogatz(n, m, k, p):\n",
71 | " return nx.newman_watts_strogatz_graph(n, k, p)\n",
72 | "\n",
73 | "def plot_random_graph(n, m, k, p, generator):\n",
74 | " g = generator(n, m, k, p)\n",
75 | " nx.draw(g)\n",
76 | " plt.show()"
77 | ]
78 | },
79 | {
80 | "cell_type": "code",
81 | "execution_count": null,
82 | "metadata": {
83 | "collapsed": false
84 | },
85 | "outputs": [],
86 | "source": [
87 | "interact(plot_random_graph, n=(2,30), m=(1,10), k=(1,10), p=(0.0, 1.0, 0.001),\n",
88 | " generator={'lobster': random_lobster,\n",
89 | " 'power law': powerlaw_cluster,\n",
90 | " 'Newman-Watts-Strogatz': newman_watts_strogatz,\n",
91 | " u'Erdős-Rényi': erdos_renyi,\n",
92 | " });"
93 | ]
94 | }
95 | ],
96 | "metadata": {
97 | "kernelspec": {
98 | "display_name": "Python 3",
99 | "language": "python",
100 | "name": "python3"
101 | },
102 | "language_info": {
103 | "codemirror_mode": {
104 | "name": "ipython",
105 | "version": 3
106 | },
107 | "file_extension": ".py",
108 | "mimetype": "text/x-python",
109 | "name": "python",
110 | "nbconvert_exporter": "python",
111 | "pygments_lexer": "ipython3",
112 | "version": "3.4.0"
113 | }
114 | },
115 | "nbformat": 4,
116 | "nbformat_minor": 0
117 | }
118 |
--------------------------------------------------------------------------------
/Part-3/Export As (nbconvert).ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": null,
6 | "metadata": {
7 | "collapsed": false
8 | },
9 | "outputs": [],
10 | "source": [
11 | "# Widget related imports\n",
12 | "import ipywidgets as widgets\n",
13 | "from IPython.display import display, clear_output, Javascript\n",
14 | "from traitlets import Unicode\n",
15 | "\n",
16 | "# nbconvert related imports\n",
17 | "from IPython.nbconvert import get_export_names, export_by_name\n",
18 | "from IPython.nbconvert.writers import FilesWriter\n",
19 | "from IPython.nbformat import read, NO_CONVERT\n",
20 | "from IPython.nbconvert.utils.exceptions import ConversionException"
21 | ]
22 | },
23 | {
24 | "cell_type": "markdown",
25 | "metadata": {},
26 | "source": [
27 | "This notebook shows a really roundabout way to get the name of the notebook file using widgets. The true purpose of this demo is to demonstrate how Javascript and Python widget models are related by `id`."
28 | ]
29 | },
30 | {
31 | "cell_type": "markdown",
32 | "metadata": {},
33 | "source": [
34 | "Create a text Widget without displaying it. The widget will be used to store the notebook's name which is otherwise only available in the front-end."
35 | ]
36 | },
37 | {
38 | "cell_type": "code",
39 | "execution_count": null,
40 | "metadata": {
41 | "collapsed": false
42 | },
43 | "outputs": [],
44 | "source": [
45 | "notebook_name = widgets.Text()"
46 | ]
47 | },
48 | {
49 | "cell_type": "markdown",
50 | "metadata": {},
51 | "source": [
52 | "Get the current notebook's name by pushing JavaScript to the browser that sets the notebook name in a string widget."
53 | ]
54 | },
55 | {
56 | "cell_type": "code",
57 | "execution_count": null,
58 | "metadata": {
59 | "collapsed": false
60 | },
61 | "outputs": [],
62 | "source": [
63 | "js = \"\"\"IPython.notebook.kernel.widget_manager.get_model('%s').then(function(model) {\n",
64 | " model.set('value', IPython.notebook.notebook_name);\n",
65 | " model.save();\n",
66 | "});\n",
67 | "\"\"\" % notebook_name.model_id\n",
68 | "display(Javascript(data=js))"
69 | ]
70 | },
71 | {
72 | "cell_type": "code",
73 | "execution_count": null,
74 | "metadata": {
75 | "collapsed": false
76 | },
77 | "outputs": [],
78 | "source": [
79 | "filename = notebook_name.value\n",
80 | "filename"
81 | ]
82 | },
83 | {
84 | "cell_type": "markdown",
85 | "metadata": {},
86 | "source": [
87 | "Create the widget that will allow the user to Export the current notebook."
88 | ]
89 | },
90 | {
91 | "cell_type": "code",
92 | "execution_count": null,
93 | "metadata": {
94 | "collapsed": false
95 | },
96 | "outputs": [],
97 | "source": [
98 | "exporter_names = widgets.Dropdown(options=get_export_names(), value='html')\n",
99 | "export_button = widgets.Button(description=\"Export\")\n",
100 | "download_link = widgets.HTML(visible=False)"
101 | ]
102 | },
103 | {
104 | "cell_type": "markdown",
105 | "metadata": {},
106 | "source": [
107 | "Export the notebook when the export button is clicked."
108 | ]
109 | },
110 | {
111 | "cell_type": "code",
112 | "execution_count": null,
113 | "metadata": {
114 | "collapsed": false
115 | },
116 | "outputs": [],
117 | "source": [
118 | "file_writer = FilesWriter()\n",
119 | "\n",
120 | "def export(name, nb):\n",
121 | " \n",
122 | " # Get a unique key for the notebook and set it in the resources object.\n",
123 | " notebook_name = name[:name.rfind('.')]\n",
124 | " resources = {}\n",
125 | " resources['unique_key'] = notebook_name\n",
126 | " resources['output_files_dir'] = '%s_files' % notebook_name\n",
127 | "\n",
128 | " # Try to export\n",
129 | " try:\n",
130 | " output, resources = export_by_name(exporter_names.value, nb)\n",
131 | " except ConversionException as e:\n",
132 | " download_link.value = \" Could not export notebook!\"\n",
133 | " else:\n",
134 | " write_results = file_writer.write(output, resources, notebook_name=notebook_name)\n",
135 | " \n",
136 | " download_link.value = \" Results: \\\"{filename}\\\" \".format(filename=write_results)\n",
137 | " download_link.visible = True\n",
138 | " \n",
139 | "def handle_export(widget):\n",
140 | " with open(filename, 'r') as f:\n",
141 | " export(filename, read(f, NO_CONVERT))\n",
142 | " \n",
143 | "export_button.on_click(handle_export)"
144 | ]
145 | },
146 | {
147 | "cell_type": "markdown",
148 | "metadata": {},
149 | "source": [
150 | "Display the controls."
151 | ]
152 | },
153 | {
154 | "cell_type": "code",
155 | "execution_count": null,
156 | "metadata": {
157 | "collapsed": false
158 | },
159 | "outputs": [],
160 | "source": [
161 | "display(exporter_names, export_button, download_link)"
162 | ]
163 | }
164 | ],
165 | "metadata": {
166 | "kernelspec": {
167 | "display_name": "Python 3",
168 | "language": "python",
169 | "name": "python3"
170 | },
171 | "language_info": {
172 | "codemirror_mode": {
173 | "name": "ipython",
174 | "version": 3
175 | },
176 | "file_extension": ".py",
177 | "mimetype": "text/x-python",
178 | "name": "python",
179 | "nbconvert_exporter": "python",
180 | "pygments_lexer": "ipython3",
181 | "version": "3.4.0"
182 | }
183 | },
184 | "nbformat": 4,
185 | "nbformat_minor": 0
186 | }
187 |
--------------------------------------------------------------------------------
/Part-3/Image Browser.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "## Image Browser"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "This example shows how to browse through a set of images with a slider."
15 | ]
16 | },
17 | {
18 | "cell_type": "code",
19 | "execution_count": null,
20 | "metadata": {
21 | "collapsed": false
22 | },
23 | "outputs": [],
24 | "source": [
25 | "%matplotlib inline\n",
26 | "import matplotlib.pyplot as plt"
27 | ]
28 | },
29 | {
30 | "cell_type": "code",
31 | "execution_count": null,
32 | "metadata": {
33 | "collapsed": false
34 | },
35 | "outputs": [],
36 | "source": [
37 | "from ipywidgets import interact"
38 | ]
39 | },
40 | {
41 | "cell_type": "code",
42 | "execution_count": null,
43 | "metadata": {
44 | "collapsed": false
45 | },
46 | "outputs": [],
47 | "source": [
48 | "from sklearn import datasets"
49 | ]
50 | },
51 | {
52 | "cell_type": "markdown",
53 | "metadata": {},
54 | "source": [
55 | "We will use the digits dataset from [scikit-learn](http://scikit-learn.org/stable/)."
56 | ]
57 | },
58 | {
59 | "cell_type": "code",
60 | "execution_count": null,
61 | "metadata": {
62 | "collapsed": false
63 | },
64 | "outputs": [],
65 | "source": [
66 | "digits = datasets.load_digits()"
67 | ]
68 | },
69 | {
70 | "cell_type": "code",
71 | "execution_count": null,
72 | "metadata": {
73 | "collapsed": false
74 | },
75 | "outputs": [],
76 | "source": [
77 | "def browse_images(digits):\n",
78 | " n = len(digits.images)\n",
79 | " def view_image(i):\n",
80 | " plt.imshow(digits.images[i], cmap=plt.cm.gray_r, interpolation='nearest')\n",
81 | " plt.title('Training: %s' % digits.target[i])\n",
82 | " plt.show()\n",
83 | " interact(view_image, i=(0,n-1))"
84 | ]
85 | },
86 | {
87 | "cell_type": "code",
88 | "execution_count": null,
89 | "metadata": {
90 | "collapsed": false
91 | },
92 | "outputs": [],
93 | "source": [
94 | "browse_images(digits)"
95 | ]
96 | }
97 | ],
98 | "metadata": {
99 | "kernelspec": {
100 | "display_name": "Python 3",
101 | "language": "python",
102 | "name": "python3"
103 | },
104 | "language_info": {
105 | "codemirror_mode": {
106 | "name": "ipython",
107 | "version": 3
108 | },
109 | "file_extension": ".py",
110 | "mimetype": "text/x-python",
111 | "name": "python",
112 | "nbconvert_exporter": "python",
113 | "pygments_lexer": "ipython3",
114 | "version": "3.4.0"
115 | }
116 | },
117 | "nbformat": 4,
118 | "nbformat_minor": 0
119 | }
120 |
--------------------------------------------------------------------------------
/Part-3/Index.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | " "
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "# Day 2 (Morning): Interactive Widgets\n",
15 | "\n",
16 | "IPython includes an architecture for interactive widgets that tie together Python code running in the kernel and JavaScript/HTML/CSS running in the browser. These widgets enable users to explore their code and data interactively.\n",
17 | "\n",
18 | "## Interactive HTML Widgets\n",
19 | "\n",
20 | "- [Using Interact](Using Interact.ipynb)\n",
21 | "- [Widget Basics](Widget Basics.ipynb) \n",
22 | "- [Widget List](Widget List.ipynb)\n",
23 | "- [Widget Events](Widget Events.ipynb) \n",
24 | "\n",
25 | "## Exercises\n",
26 | "\n",
27 | "* [Interact Basics](exercises/InteractBasics.ipynb)\n",
28 | "* [Image Processing](exercises/Image Processing.ipynb)\n",
29 | "* [Comparing two images](exercises/ImageCompare.ipynb)\n",
30 | "* [Basics of Widgets](exercises/WidgetBasics.ipynb)\n",
31 | "* [Interacting with Matplotlib](exercises/Interact%20with%20matplotlib%20figures.ipynb)\n",
32 | "\n",
33 | "---------\n",
34 | "\n",
35 | "# Additional materials for further reading\n",
36 | "\n",
37 | "## More Examples using `interact`/`interactive`\n",
38 | "\n",
39 | "* [Beat Frequencies](Beat Frequencies.ipynb)\n",
40 | "* [Exploring Graphs](Exploring Graphs.ipynb)\n",
41 | "* [Image Browser](Image Browser.ipynb)\n",
42 | "* [Lorenz Differential Equations](Lorenz Differential Equations.ipynb)\n",
43 | "\n",
44 | "## Examples of custom widgets\n",
45 | "\n",
46 | "- [Widget Styling](Widget Styling.ipynb)\n",
47 | "- [Custom Widget](Custom Widget - Hello World.ipynb)\n",
48 | "- [Variable Inspector](Variable Inspector.ipynb) \n",
49 | "- [Export As (nbconvert)](Export As (nbconvert%29.ipynb) \n",
50 | "- [Nonblocking Console](Nonblocking Console.ipynb) \n",
51 | "- [File Upload Widget](File Upload Widget.ipynb)"
52 | ]
53 | }
54 | ],
55 | "metadata": {
56 | "kernelspec": {
57 | "display_name": "Python 3",
58 | "language": "python",
59 | "name": "python3"
60 | },
61 | "language_info": {
62 | "codemirror_mode": {
63 | "name": "ipython",
64 | "version": 3
65 | },
66 | "file_extension": ".py",
67 | "mimetype": "text/x-python",
68 | "name": "python",
69 | "nbconvert_exporter": "python",
70 | "pygments_lexer": "ipython3",
71 | "version": "3.5.2"
72 | },
73 | "widgets": {
74 | "state": {},
75 | "version": "1.1.1"
76 | }
77 | },
78 | "nbformat": 4,
79 | "nbformat_minor": 1
80 | }
81 |
--------------------------------------------------------------------------------
/Part-3/exercises/Image Processing.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Image Manipulation with skimage"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "In this exercise, we build a simple UI for performing basic image manipulation with [scikit-image](http://scikit-image.org/)."
15 | ]
16 | },
17 | {
18 | "cell_type": "code",
19 | "execution_count": null,
20 | "metadata": {},
21 | "outputs": [],
22 | "source": [
23 | "from ipywidgets import interact, interactive, fixed\n",
24 | "from IPython.display import display\n",
25 | "\n",
26 | "import skimage\n",
27 | "from skimage import data, filters, io"
28 | ]
29 | },
30 | {
31 | "cell_type": "markdown",
32 | "metadata": {},
33 | "source": [
34 | "Scikit-image provides some pre-loaded example data, let's load the nice espresso cup:"
35 | ]
36 | },
37 | {
38 | "cell_type": "code",
39 | "execution_count": null,
40 | "metadata": {},
41 | "outputs": [],
42 | "source": [
43 | "%matplotlib inline\n",
44 | "i = data.coffee()\n",
45 | "io.imshow(i)"
46 | ]
47 | },
48 | {
49 | "cell_type": "markdown",
50 | "metadata": {},
51 | "source": [
52 | "The image `i`, which we see as a colored coffee cup, is to the computer an array:"
53 | ]
54 | },
55 | {
56 | "cell_type": "code",
57 | "execution_count": null,
58 | "metadata": {},
59 | "outputs": [],
60 | "source": [
61 | "i.shape"
62 | ]
63 | },
64 | {
65 | "cell_type": "markdown",
66 | "metadata": {},
67 | "source": [
68 | "The first two dimensions are the XxY spatial dimensions of the image, and the third dimension indicates that there's actually three \"layers\", or \"channels\". In fact, while we see it in color, that's because we interpret it as such when rendering it on a monitor; in the computer, what we have are three 400x600 arrays of numbers that represent color intensities in each of these channels, one for red, one for green, one for blue.\n",
69 | "\n",
70 | "A very rudimentary \"image editor\" can be constructed by modifying the amount of each of these channels that the final image is composed of. We can multiply the orignal value at each pixel by a multiplier, altering the color balance of the original image.\n",
71 | "\n",
72 | "In addition, we'll toss in a blurring effect, courtesy of the fact that scikit-image provides out of the box a filter that convolves our image with a Gaussian of a specified width, effectively blurring the original image.\n",
73 | "\n",
74 | "Putting together these operations (multiplying each color channel by a certain amount and convolving the image with a Gaussian), we have our little image editor in the following function:"
75 | ]
76 | },
77 | {
78 | "cell_type": "code",
79 | "execution_count": null,
80 | "metadata": {},
81 | "outputs": [],
82 | "source": [
83 | "def edit_image(image, sigma=0.1, r=1.0, g=1.0, b=1.0):\n",
84 | " new_image = filters.gaussian_filter(image, sigma=sigma, multichannel=True)\n",
85 | " new_image[:,:,0] = r*new_image[:,:,0]\n",
86 | " new_image[:,:,1] = g*new_image[:,:,1]\n",
87 | " new_image[:,:,2] = b*new_image[:,:,2]\n",
88 | " io.imshow(new_image)"
89 | ]
90 | },
91 | {
92 | "cell_type": "markdown",
93 | "metadata": {},
94 | "source": [
95 | "We can for example blur our image with a gaussian of radius 5 pixels and knock out the red channel by 50%:"
96 | ]
97 | },
98 | {
99 | "cell_type": "code",
100 | "execution_count": null,
101 | "metadata": {},
102 | "outputs": [],
103 | "source": [
104 | "edit_image(i, sigma=5, r=0.5)"
105 | ]
106 | },
107 | {
108 | "cell_type": "markdown",
109 | "metadata": {},
110 | "source": [
111 | "# Exercise\n",
112 | "\n",
113 | "Using IPython's `interact`, provide a slider for `sigma` that ranges from 0.1 to 10, as well as sliders for the red, green and blue channels that range from 0 to 1."
114 | ]
115 | },
116 | {
117 | "cell_type": "code",
118 | "execution_count": null,
119 | "metadata": {},
120 | "outputs": [],
121 | "source": [
122 | "# Your code here"
123 | ]
124 | },
125 | {
126 | "cell_type": "markdown",
127 | "metadata": {},
128 | "source": [
129 | "## Extra credit\n",
130 | "\n",
131 | "How would you have to modify the function to accept R, G, B sliders that could go beyond one?"
132 | ]
133 | }
134 | ],
135 | "metadata": {
136 | "kernelspec": {
137 | "display_name": "Python 3",
138 | "language": "python",
139 | "name": "python3"
140 | },
141 | "language_info": {
142 | "codemirror_mode": {
143 | "name": "ipython",
144 | "version": 3
145 | },
146 | "file_extension": ".py",
147 | "mimetype": "text/x-python",
148 | "name": "python",
149 | "nbconvert_exporter": "python",
150 | "pygments_lexer": "ipython3",
151 | "version": "3.5.2"
152 | }
153 | },
154 | "nbformat": 4,
155 | "nbformat_minor": 1
156 | }
157 |
--------------------------------------------------------------------------------
/Part-3/exercises/InteractBasics.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "nbgrader": {}
7 | },
8 | "source": [
9 | "# Interact Basics"
10 | ]
11 | },
12 | {
13 | "cell_type": "markdown",
14 | "metadata": {
15 | "nbgrader": {}
16 | },
17 | "source": [
18 | "## Import"
19 | ]
20 | },
21 | {
22 | "cell_type": "code",
23 | "execution_count": null,
24 | "metadata": {
25 | "nbgrader": {}
26 | },
27 | "outputs": [],
28 | "source": [
29 | "from ipywidgets import interact, interactive, fixed\n",
30 | "from IPython.display import display"
31 | ]
32 | },
33 | {
34 | "cell_type": "markdown",
35 | "metadata": {
36 | "nbgrader": {}
37 | },
38 | "source": [
39 | "## Adding numbers"
40 | ]
41 | },
42 | {
43 | "cell_type": "markdown",
44 | "metadata": {
45 | "nbgrader": {}
46 | },
47 | "source": [
48 | "Write a `print_sum` function that `prints` the sum of its arguments `a` and `b`."
49 | ]
50 | },
51 | {
52 | "cell_type": "code",
53 | "execution_count": null,
54 | "metadata": {
55 | "collapsed": true,
56 | "nbgrader": {}
57 | },
58 | "outputs": [],
59 | "source": [
60 | "def print_sum(a, b):\n",
61 | " \"\"\"Print the sum of the arguments a and b.\"\"\""
62 | ]
63 | },
64 | {
65 | "cell_type": "markdown",
66 | "metadata": {
67 | "nbgrader": {}
68 | },
69 | "source": [
70 | "Use the `interact` function to interact with the `print_sum` function.\n",
71 | "\n",
72 | "* `a` should be a floating point slider over the interval `[-10., 10.]` with step sizes of `0.1`\n",
73 | "* `b` should be an integer slider the interval [-8, 8] with step sizes of `2`."
74 | ]
75 | },
76 | {
77 | "cell_type": "code",
78 | "execution_count": null,
79 | "metadata": {
80 | "nbgrader": {
81 | "solution": true
82 | }
83 | },
84 | "outputs": [],
85 | "source": [
86 | "# Your code here"
87 | ]
88 | },
89 | {
90 | "cell_type": "markdown",
91 | "metadata": {
92 | "nbgrader": {}
93 | },
94 | "source": [
95 | "## Optional flags\n",
96 | "Write a function named `print_string` that prints a string and additionally prints the length of that string if a boolean parameter is `True`."
97 | ]
98 | },
99 | {
100 | "cell_type": "code",
101 | "execution_count": null,
102 | "metadata": {
103 | "collapsed": true,
104 | "nbgrader": {}
105 | },
106 | "outputs": [],
107 | "source": [
108 | "def print_string(s, length=False):\n",
109 | " \"\"\"Print the string s and optionally its length.\"\"\""
110 | ]
111 | },
112 | {
113 | "cell_type": "markdown",
114 | "metadata": {
115 | "nbgrader": {}
116 | },
117 | "source": [
118 | "Use the `interact` function to interact with the `print_string` function.\n",
119 | "\n",
120 | "* `s` should be a textbox with the initial value `\"Hello World!\"`.\n",
121 | "* `length` should be a checkbox with an initial value of `True`."
122 | ]
123 | },
124 | {
125 | "cell_type": "code",
126 | "execution_count": null,
127 | "metadata": {
128 | "nbgrader": {
129 | "solution": true
130 | }
131 | },
132 | "outputs": [],
133 | "source": [
134 | "# Your code here"
135 | ]
136 | },
137 | {
138 | "cell_type": "markdown",
139 | "metadata": {},
140 | "source": [
141 | "# Using SymPy to play with Polynomials"
142 | ]
143 | },
144 | {
145 | "cell_type": "markdown",
146 | "metadata": {},
147 | "source": [
148 | "We now show that IPython's `interact` capabilities are not limited to basic Python types, with an exercise that uses [SymPy](http://sympy.org/en/index.html) to factor polynomials. \n",
149 | "\n",
150 | "We begin by initializing SymPy to display its results with proper mathematical formatting in the browser:"
151 | ]
152 | },
153 | {
154 | "cell_type": "code",
155 | "execution_count": null,
156 | "metadata": {},
157 | "outputs": [],
158 | "source": [
159 | "from sympy import Symbol, Eq, factor, init_printing\n",
160 | "init_printing(use_latex='mathjax')"
161 | ]
162 | },
163 | {
164 | "cell_type": "markdown",
165 | "metadata": {},
166 | "source": [
167 | "Now, we create a symbolic variable, $x$, to build symbolic polynomials with:"
168 | ]
169 | },
170 | {
171 | "cell_type": "code",
172 | "execution_count": null,
173 | "metadata": {},
174 | "outputs": [],
175 | "source": [
176 | "x = Symbol('x')"
177 | ]
178 | },
179 | {
180 | "cell_type": "markdown",
181 | "metadata": {},
182 | "source": [
183 | "We can then, for example, factor a polynomial:"
184 | ]
185 | },
186 | {
187 | "cell_type": "code",
188 | "execution_count": null,
189 | "metadata": {},
190 | "outputs": [],
191 | "source": [
192 | "factor(x**5-1)"
193 | ]
194 | },
195 | {
196 | "cell_type": "markdown",
197 | "metadata": {},
198 | "source": [
199 | "## Exercise\n",
200 | "Write a function that takes an argument $n$, and will display both the polynomial $x^n-1$ and its factorization.\n",
201 | "\n",
202 | "Then, use IPython's `interact` to provide a control to visualize how the result varies with a slider control that allows $n$ to vary over the range from 2 to 40.\n",
203 | "\n",
204 | "*Hint:* Look up the help for the sympy function `Eq`."
205 | ]
206 | },
207 | {
208 | "cell_type": "code",
209 | "execution_count": null,
210 | "metadata": {},
211 | "outputs": [],
212 | "source": [
213 | "def factorit(n):\n",
214 | "# Your code here"
215 | ]
216 | },
217 | {
218 | "cell_type": "code",
219 | "execution_count": null,
220 | "metadata": {},
221 | "outputs": [],
222 | "source": [
223 | "# Your code here"
224 | ]
225 | }
226 | ],
227 | "metadata": {
228 | "celltoolbar": "Create Assignment",
229 | "kernelspec": {
230 | "display_name": "Python 3",
231 | "language": "python",
232 | "name": "python3"
233 | },
234 | "language_info": {
235 | "codemirror_mode": {
236 | "name": "ipython",
237 | "version": 3
238 | },
239 | "file_extension": ".py",
240 | "mimetype": "text/x-python",
241 | "name": "python",
242 | "nbconvert_exporter": "python",
243 | "pygments_lexer": "ipython3",
244 | "version": "3.5.2"
245 | },
246 | "name": "_merged"
247 | },
248 | "nbformat": 4,
249 | "nbformat_minor": 1
250 | }
251 |
--------------------------------------------------------------------------------
/Part-3/exercises/University_of_Sheffield_coat_of_arms_new.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jupyter/ngcm-tutorial/e2acd3365c8a18cb4360ee7ecd4b74a9e1d9ce27/Part-3/exercises/University_of_Sheffield_coat_of_arms_new.png
--------------------------------------------------------------------------------
/Part-3/exercises/University_of_Sheffield_coat_of_arms_old.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jupyter/ngcm-tutorial/e2acd3365c8a18cb4360ee7ecd4b74a9e1d9ce27/Part-3/exercises/University_of_Sheffield_coat_of_arms_old.png
--------------------------------------------------------------------------------
/Part-3/exercises/WidgetBasics.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Widget Exercises"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {
14 | "collapsed": true
15 | },
16 | "outputs": [],
17 | "source": [
18 | "from ipywidgets import *\n",
19 | "from IPython.display import display\n",
20 | "from traitlets import link"
21 | ]
22 | },
23 | {
24 | "cell_type": "markdown",
25 | "metadata": {},
26 | "source": [
27 | "### Text Widget"
28 | ]
29 | },
30 | {
31 | "cell_type": "markdown",
32 | "metadata": {},
33 | "source": [
34 | "Create and display a `Text` widget. Change the Text widget's font color and background color. Set the properties in the constructor of the widget."
35 | ]
36 | },
37 | {
38 | "cell_type": "code",
39 | "execution_count": null,
40 | "metadata": {
41 | "collapsed": true
42 | },
43 | "outputs": [],
44 | "source": []
45 | },
46 | {
47 | "cell_type": "markdown",
48 | "metadata": {},
49 | "source": [
50 | "Do the same, but this time set the properties after the widget is constructed."
51 | ]
52 | },
53 | {
54 | "cell_type": "code",
55 | "execution_count": null,
56 | "metadata": {
57 | "collapsed": true
58 | },
59 | "outputs": [],
60 | "source": []
61 | },
62 | {
63 | "cell_type": "markdown",
64 | "metadata": {},
65 | "source": [
66 | "### Link"
67 | ]
68 | },
69 | {
70 | "cell_type": "markdown",
71 | "metadata": {},
72 | "source": [
73 | "Use a link to link the values of a `Textarea` and an `HTML` widget. Display the widgets and try typing HTML in the textarea. "
74 | ]
75 | },
76 | {
77 | "cell_type": "code",
78 | "execution_count": null,
79 | "metadata": {},
80 | "outputs": [],
81 | "source": []
82 | },
83 | {
84 | "cell_type": "markdown",
85 | "metadata": {},
86 | "source": [
87 | "### Popup"
88 | ]
89 | },
90 | {
91 | "cell_type": "markdown",
92 | "metadata": {},
93 | "source": [
94 | "Display a widget in the `Popup` widget."
95 | ]
96 | },
97 | {
98 | "cell_type": "code",
99 | "execution_count": null,
100 | "metadata": {
101 | "collapsed": true
102 | },
103 | "outputs": [],
104 | "source": []
105 | },
106 | {
107 | "cell_type": "markdown",
108 | "metadata": {},
109 | "source": [
110 | "## Widget events"
111 | ]
112 | },
113 | {
114 | "cell_type": "markdown",
115 | "metadata": {},
116 | "source": [
117 | "### on_submit event"
118 | ]
119 | },
120 | {
121 | "cell_type": "markdown",
122 | "metadata": {},
123 | "source": [
124 | "Create and display a `Text`. Use the `on_submit` event to print the value of the textbox just before you clear the textbox. \n",
125 | "\n",
126 | "*Hint: The `on_submit` callback must accept one argument, the `sender`.*"
127 | ]
128 | },
129 | {
130 | "cell_type": "code",
131 | "execution_count": null,
132 | "metadata": {},
133 | "outputs": [],
134 | "source": []
135 | },
136 | {
137 | "cell_type": "markdown",
138 | "metadata": {},
139 | "source": [
140 | "### on_trait_change event"
141 | ]
142 | },
143 | {
144 | "cell_type": "markdown",
145 | "metadata": {},
146 | "source": [
147 | "Create and display a `Text`. Use the `on_trait_change` method to register a callback that prints the value of the textbox without clearing it. Observe the difference in behavior to Exercise 1."
148 | ]
149 | },
150 | {
151 | "cell_type": "code",
152 | "execution_count": null,
153 | "metadata": {},
154 | "outputs": [],
155 | "source": []
156 | },
157 | {
158 | "cell_type": "markdown",
159 | "metadata": {},
160 | "source": [
161 | "## Widget styling"
162 | ]
163 | },
164 | {
165 | "cell_type": "markdown",
166 | "metadata": {},
167 | "source": [
168 | "### Colored text"
169 | ]
170 | },
171 | {
172 | "cell_type": "markdown",
173 | "metadata": {},
174 | "source": [
175 | "Create and display an `HTML` with a value of your choice (i.e. \"Hello World\"). Change the widget's background color and font color."
176 | ]
177 | },
178 | {
179 | "cell_type": "code",
180 | "execution_count": null,
181 | "metadata": {},
182 | "outputs": [],
183 | "source": []
184 | }
185 | ],
186 | "metadata": {
187 | "kernelspec": {
188 | "display_name": "Python 3",
189 | "language": "python",
190 | "name": "python3"
191 | },
192 | "language_info": {
193 | "codemirror_mode": {
194 | "name": "ipython",
195 | "version": 3
196 | },
197 | "file_extension": ".py",
198 | "mimetype": "text/x-python",
199 | "name": "python",
200 | "nbconvert_exporter": "python",
201 | "pygments_lexer": "ipython3",
202 | "version": "3.5.2"
203 | }
204 | },
205 | "nbformat": 4,
206 | "nbformat_minor": 1
207 | }
208 |
--------------------------------------------------------------------------------
/Part-3/images/MultilanguageKernels.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jupyter/ngcm-tutorial/e2acd3365c8a18cb4360ee7ecd4b74a9e1d9ce27/Part-3/images/MultilanguageKernels.png
--------------------------------------------------------------------------------
/Part-3/images/ParallelKernels.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jupyter/ngcm-tutorial/e2acd3365c8a18cb4360ee7ecd4b74a9e1d9ce27/Part-3/images/ParallelKernels.png
--------------------------------------------------------------------------------
/Part-3/images/VizInteractCompute.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jupyter/ngcm-tutorial/e2acd3365c8a18cb4360ee7ecd4b74a9e1d9ce27/Part-3/images/VizInteractCompute.png
--------------------------------------------------------------------------------
/Part-3/images/WidgetArch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jupyter/ngcm-tutorial/e2acd3365c8a18cb4360ee7ecd4b74a9e1d9ce27/Part-3/images/WidgetArch.png
--------------------------------------------------------------------------------
/Part-3/images/WidgetModelView.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jupyter/ngcm-tutorial/e2acd3365c8a18cb4360ee7ecd4b74a9e1d9ce27/Part-3/images/WidgetModelView.png
--------------------------------------------------------------------------------
/Part-3/images/ipython_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jupyter/ngcm-tutorial/e2acd3365c8a18cb4360ee7ecd4b74a9e1d9ce27/Part-3/images/ipython_logo.png
--------------------------------------------------------------------------------
/Part-4/Index.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Day 2 (Afternoon): ipyparallel\n",
8 | "\n",
9 | "## Interactive (parallel) Python"
10 | ]
11 | },
12 | {
13 | "cell_type": "markdown",
14 | "metadata": {},
15 | "source": [
16 | "# Installation and dependencies\n",
17 | "\n",
18 | "You will need ipyparallel >= 5.x, and pyzmq ≥ 13. To use the demo notebooks, you will also need tornado ≥ 4. I will also make use of numpy and matplotlib. If you have Canopy or Anaconda, you already have all of these.\n",
19 | "\n",
20 | "Quick one-line install for IPython and its dependencies:\n",
21 | " \n",
22 | " pip install ipyparallel\n",
23 | " \n",
24 | "Or get everything for the tutorial with conda:\n",
25 | "\n",
26 | " conda install ipyparallel\n",
27 | "\n",
28 | "For those who prefer pip or otherwise manual package installation, the following packages will be used:\n",
29 | "\n",
30 | "ipython\n",
31 | "ipyparallel\n",
32 | "numpy\n",
33 | "matplotlib\n",
34 | "networkx\n",
35 | "scikit-image\n",
36 | "requests\n",
37 | "beautifulsoup\n",
38 | "mpi4py\n",
39 | "\n",
40 | "\n",
41 | "Optional dependencies: I will use [NetworkX](http://networkx.lanl.gov/)\n",
42 | "for one demo, and `scikit-image` for another, but they are not critical. Both packages are in in Anaconda.\n",
43 | "\n",
44 | "For the image-related demos, all you need are some images on your computer. The notebooks will try to fetch images from Wikimedia Commons, but since the networks can be untrustworty, we have [bundled some images here](http://s3.amazonaws.com/ipython-parallel-data/images.zip)."
45 | ]
46 | },
47 | {
48 | "cell_type": "markdown",
49 | "metadata": {},
50 | "source": [
51 | "## Outline\n",
52 | "\n",
53 | "- [Motivating Example](examples/Parallel%20image%20processing.ipynb)\n",
54 | "- [Overview](Overview.ipynb)\n",
55 | "- [Tutorial](tutorial)\n",
56 | " - [Remote Execution](tutorial/Remote%20Execution.ipynb)\n",
57 | " - [Multiplexing](tutorial/Multiplexing.ipynb)\n",
58 | " - [Load-Balancing](tutorial/Load-Balancing.ipynb)\n",
59 | " - [Both!](tutorial/All%20Together.ipynb)\n",
60 | " - [Parallel Magics](tutorial/Parallel%20Magics.ipynb)\n",
61 | "- [Examples](examples)\n",
62 | "- [Exercises](exercises)\n"
63 | ]
64 | }
65 | ],
66 | "metadata": {
67 | "kernelspec": {
68 | "display_name": "Python 3",
69 | "language": "python",
70 | "name": "python3"
71 | },
72 | "language_info": {
73 | "codemirror_mode": {
74 | "name": "ipython",
75 | "version": 3
76 | },
77 | "file_extension": ".py",
78 | "mimetype": "text/x-python",
79 | "name": "python",
80 | "nbconvert_exporter": "python",
81 | "pygments_lexer": "ipython3",
82 | "version": "3.6.0"
83 | },
84 | "widgets": {
85 | "state": {},
86 | "version": "1.1.1"
87 | }
88 | },
89 | "nbformat": 4,
90 | "nbformat_minor": 1
91 | }
92 |
--------------------------------------------------------------------------------
/Part-4/Summary.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "metadata": {
3 | "name": ""
4 | },
5 | "nbformat": 3,
6 | "nbformat_minor": 0,
7 | "worksheets": [
8 | {
9 | "cells": [
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "# Summary of what we have covered\n",
15 | "\n",
16 | "* Simple remote execution of functions, or statements\n",
17 | "* Distribution of data\n",
18 | "* Parallel map\n",
19 | "* Multiplexed execution\n",
20 | "* Load-Balanced task farming\n",
21 | "* Asynchronous task submission and result retrieval\n",
22 | "* More efficient data movememnt with memmap and MPI"
23 | ]
24 | },
25 | {
26 | "cell_type": "markdown",
27 | "metadata": {},
28 | "source": [
29 | "# And further things we have *not* covered\n",
30 | "\n",
31 | "* Functional Task Dependencies\n",
32 | "* Configuring the IPython cluster (working with profiles, SGE, MongoDB, etc.)\n",
33 | "* Tuning the IPython Cluster (TaskScheduler.hwm, custom serialization, etc.)\n",
34 | "* Inter-engine communication with PyZMQ or MPI\n",
35 | "* decorators for parallel and remote functions\n",
36 | "* Result caching, and task metadata\n",
37 | "* The TaskResult Database\n",
38 | "* Task resubmission\n",
39 | "* Queue monitoring and management\n",
40 | "\n",
41 | "See the [IPython.parallel docs](http://ipython.org/ipython-doc/dev/parallel) for more detailed coverage of these topics, and check out our [examples](https://www.github.com/ipython/ipython/tree/master/docs/examples/parallel)."
42 | ]
43 | }
44 | ],
45 | "metadata": {}
46 | }
47 | ]
48 | }
49 |
--------------------------------------------------------------------------------
/Part-4/download-images.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Downloading images from Wikimedia Commons"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "This notebook defines a few functions to download images with specified search terms from Wikimedia, via the mediawiki search API.\n",
15 | "\n",
16 | "The results are used in the [Parallel face detection notebook](Parallel%20face%20detection.ipynb).\n",
17 | "\n",
18 | "For some caching, you can use requests_cache:\n",
19 | "\n",
20 | " pip install requests_cache"
21 | ]
22 | },
23 | {
24 | "cell_type": "code",
25 | "execution_count": null,
26 | "metadata": {},
27 | "outputs": [],
28 | "source": [
29 | "import sys, os\n",
30 | "\n",
31 | "import requests\n",
32 | "try:\n",
33 | " import requests_cache\n",
34 | "except ImportError:\n",
35 | " print(\"no cache, no worries\")\n",
36 | "else:\n",
37 | " requests_cache.install_cache(\"mediawiki\")\n",
38 | "\n",
39 | "api_url = \"http://commons.wikimedia.org/w/api.php\""
40 | ]
41 | },
42 | {
43 | "cell_type": "code",
44 | "execution_count": null,
45 | "metadata": {},
46 | "outputs": [],
47 | "source": [
48 | "def api_request(**kwargs):\n",
49 | " \"\"\"Make a request of the Wikimedia Commons API\n",
50 | " \n",
51 | " Returns data after parsing JSON\n",
52 | " \"\"\"\n",
53 | " sys.stdout.write('.')\n",
54 | " sys.stdout.flush()\n",
55 | " \n",
56 | "\n",
57 | " params = dict(\n",
58 | " action='query',\n",
59 | " format='json',\n",
60 | " )\n",
61 | " params.update(kwargs)\n",
62 | " r = requests.get(api_url, params=params)\n",
63 | " r.raise_for_status()\n",
64 | " return r.json()\n",
65 | "\n",
66 | "\n",
67 | "import json\n",
68 | "\n",
69 | "def search_images(search, limit=100, size_limit=2e6):\n",
70 | " \"\"\"search wikimedia commons for a given term\n",
71 | " \n",
72 | " returns a list of `limit` URLs for images\n",
73 | " \"\"\"\n",
74 | " continue_params = {}\n",
75 | " while limit > 0:\n",
76 | " data = api_request(\n",
77 | " srnamespace=6,\n",
78 | " prop='imageinfo',\n",
79 | " list='search',\n",
80 | " srsearch=search,\n",
81 | " srlimit=min(limit, 50),\n",
82 | " **continue_params\n",
83 | " )\n",
84 | "# continue_params = data['query-continue']['search']\n",
85 | " continue_params = data['continue']\n",
86 | "\n",
87 | " total = data['query']['searchinfo']['totalhits']\n",
88 | " results = data['query']['search']\n",
89 | " for r in results:\n",
90 | " title = r['title']\n",
91 | " \n",
92 | " data = api_request(\n",
93 | " prop='imageinfo',\n",
94 | " titles=title,\n",
95 | " iiprop='url|size|mime')\n",
96 | " imageinfo = list(data['query']['pages'].values())[0]['imageinfo'][0]\n",
97 | " if imageinfo['mime'] in ('image/png', 'image/jpeg') and imageinfo['size'] <= size_limit:\n",
98 | " yield imageinfo['url']\n",
99 | " limit -= 1\n",
100 | " if limit <= 0:\n",
101 | " return\n",
102 | "# else:\n",
103 | "# import pprint\n",
104 | "# pprint.pprint(imageinfo)\n"
105 | ]
106 | },
107 | {
108 | "cell_type": "code",
109 | "execution_count": null,
110 | "metadata": {},
111 | "outputs": [],
112 | "source": [
113 | "def download_images(search, n):\n",
114 | " \"\"\"download images from mediawiki commons to folders based on the search term\"\"\"\n",
115 | " if not os.path.exists('images'):\n",
116 | " os.mkdir('images')\n",
117 | " tagdir = os.path.join('images', search)\n",
118 | " if not os.path.exists(tagdir):\n",
119 | " os.mkdir(tagdir)\n",
120 | " for url in search_images(search, n):\n",
121 | " r = requests.get(url)\n",
122 | " fname = url.rsplit('/')[-1]\n",
123 | " dest = os.path.join(tagdir, fname)\n",
124 | " # print(\"downloading %s => %s\" % (url, dest))\n",
125 | " sys.stdout.write('+')\n",
126 | " sys.stdout.flush()\n",
127 | " with open(dest, 'wb') as f:\n",
128 | " f.write(r.content)"
129 | ]
130 | },
131 | {
132 | "cell_type": "code",
133 | "execution_count": null,
134 | "metadata": {},
135 | "outputs": [],
136 | "source": [
137 | "download_images('castle', 100)"
138 | ]
139 | },
140 | {
141 | "cell_type": "code",
142 | "execution_count": null,
143 | "metadata": {},
144 | "outputs": [],
145 | "source": [
146 | "download_images('portrait', 100)"
147 | ]
148 | },
149 | {
150 | "cell_type": "code",
151 | "execution_count": null,
152 | "metadata": {},
153 | "outputs": [],
154 | "source": [
155 | "download_images('face', 100)"
156 | ]
157 | },
158 | {
159 | "cell_type": "code",
160 | "execution_count": null,
161 | "metadata": {
162 | "collapsed": true
163 | },
164 | "outputs": [],
165 | "source": [
166 | "download_images('child', 100)"
167 | ]
168 | }
169 | ],
170 | "metadata": {
171 | "kernelspec": {
172 | "display_name": "Python 3",
173 | "language": "python",
174 | "name": "python3"
175 | },
176 | "language_info": {
177 | "codemirror_mode": {
178 | "name": "ipython",
179 | "version": 3
180 | },
181 | "file_extension": ".py",
182 | "mimetype": "text/x-python",
183 | "name": "python",
184 | "nbconvert_exporter": "python",
185 | "pygments_lexer": "ipython3",
186 | "version": "3.6.0"
187 | },
188 | "widgets": {
189 | "state": {},
190 | "version": "1.1.1"
191 | }
192 | },
193 | "nbformat": 4,
194 | "nbformat_minor": 1
195 | }
196 |
--------------------------------------------------------------------------------
/Part-4/examples/MPI Broadcast.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# More efficient data movement with MPI"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "Just like [we did](memmap.ipynb) manually with memmap,\n",
15 | "you can move data more efficiently with MPI by sending it to just one engine,\n",
16 | "and using MPI to broadcast it to the rest of the engines.\n"
17 | ]
18 | },
19 | {
20 | "cell_type": "code",
21 | "execution_count": 1,
22 | "metadata": {
23 | "collapsed": false
24 | },
25 | "outputs": [],
26 | "source": [
27 | "import socket\n",
28 | "import os, sys, re\n",
29 | "\n",
30 | "import numpy as np\n",
31 | "\n",
32 | "import ipyparallel as parallel"
33 | ]
34 | },
35 | {
36 | "cell_type": "markdown",
37 | "metadata": {},
38 | "source": [
39 | "For this demo, I will connect to a cluster with engines started with MPI.\n",
40 | "If you have MPI and mpi4py on your machine, you can start a local cluster with MPI with:\n",
41 | "\n",
42 | " ipcluster start -n 8 --engines=MPI --profile mpi"
43 | ]
44 | },
45 | {
46 | "cell_type": "code",
47 | "execution_count": null,
48 | "metadata": {
49 | "collapsed": false
50 | },
51 | "outputs": [],
52 | "source": [
53 | "mpi_profile = 'dirac'\n",
54 | "rc = parallel.Client(profile=mpi_profile)\n",
55 | "eall = rc[:]\n",
56 | "root = rc[-1]"
57 | ]
58 | },
59 | {
60 | "cell_type": "code",
61 | "execution_count": null,
62 | "metadata": {
63 | "collapsed": false
64 | },
65 | "outputs": [],
66 | "source": [
67 | "%px from mpi4py.MPI import COMM_WORLD as MPI"
68 | ]
69 | },
70 | {
71 | "cell_type": "code",
72 | "execution_count": null,
73 | "metadata": {
74 | "collapsed": false
75 | },
76 | "outputs": [],
77 | "source": [
78 | "mpi_ranks = eall.apply_async(lambda : MPI.Get_rank()).get_dict()\n",
79 | "root_rank = root.apply_sync(lambda : MPI.Get_rank())\n",
80 | "mpi_ranks"
81 | ]
82 | },
83 | {
84 | "cell_type": "code",
85 | "execution_count": null,
86 | "metadata": {
87 | "collapsed": false
88 | },
89 | "outputs": [],
90 | "source": [
91 | "sz = 256\n",
92 | "data = np.random.random((sz, sz))\n",
93 | "data = data.dot(data.T)"
94 | ]
95 | },
96 | {
97 | "cell_type": "code",
98 | "execution_count": null,
99 | "metadata": {
100 | "collapsed": false
101 | },
102 | "outputs": [],
103 | "source": [
104 | "%%time \n",
105 | "ar = eall.push({'data': data}, block=False)\n",
106 | "ar.wait_interactive()"
107 | ]
108 | },
109 | {
110 | "cell_type": "code",
111 | "execution_count": null,
112 | "metadata": {
113 | "collapsed": false
114 | },
115 | "outputs": [],
116 | "source": [
117 | "@parallel.interactive\n",
118 | "def _bcast(key, root_rank):\n",
119 | " \"\"\"function to run on engines as part of broadcast\"\"\"\n",
120 | " g = globals()\n",
121 | " obj = g.get(key, None)\n",
122 | " obj = MPI.bcast(obj, root_rank)\n",
123 | " g[key] = obj\n",
124 | "\n",
125 | "def broadcast(key, obj, dv, root, root_rank):\n",
126 | " \"\"\"More efficient broadcast by doing push to root,\n",
127 | " and MPI broadcast to other engines.\n",
128 | " \n",
129 | " Still O(N) messages, but all but one message is always small.\n",
130 | " \"\"\"\n",
131 | " root.push({key : obj}, block=False)\n",
132 | " return dv.apply_async(_bcast, key, root_rank)"
133 | ]
134 | },
135 | {
136 | "cell_type": "code",
137 | "execution_count": null,
138 | "metadata": {
139 | "collapsed": false
140 | },
141 | "outputs": [],
142 | "source": [
143 | "%%time\n",
144 | "ar = broadcast('data', data, eall, root, root_rank)\n",
145 | "ar.wait_interactive()"
146 | ]
147 | },
148 | {
149 | "cell_type": "code",
150 | "execution_count": null,
151 | "metadata": {
152 | "collapsed": false
153 | },
154 | "outputs": [],
155 | "source": [
156 | "eall.apply_sync(np.linalg.norm, parallel.Reference('data'), 2)"
157 | ]
158 | }
159 | ],
160 | "metadata": {
161 | "kernelspec": {
162 | "display_name": "Python 3",
163 | "language": "python",
164 | "name": "python3"
165 | },
166 | "language_info": {
167 | "codemirror_mode": {
168 | "name": "ipython",
169 | "version": 3
170 | },
171 | "file_extension": ".py",
172 | "mimetype": "text/x-python",
173 | "name": "python",
174 | "nbconvert_exporter": "python",
175 | "pygments_lexer": "ipython3",
176 | "version": "3.4.3"
177 | }
178 | },
179 | "nbformat": 4,
180 | "nbformat_minor": 0
181 | }
182 |
--------------------------------------------------------------------------------
/Part-4/examples/wikipedia/eventful_dict.py:
--------------------------------------------------------------------------------
1 | import time
2 |
3 | class EventfulDict(dict):
4 | """Eventful dictionary"""
5 |
6 | def __init__(self, *args, **kwargs):
7 | """Sleep is an optional float that allows you to tell the
8 | dictionary to hang for the given amount of seconds on each
9 | event. This is usefull for animations."""
10 | self._sleep = kwargs.pop('sleep', 0.0)
11 | self._add_callbacks = []
12 | self._del_callbacks = []
13 | self._set_callbacks = []
14 | dict.__init__(self, *args, **kwargs)
15 |
16 | def on_add(self, callback, remove=False):
17 | self._register_callback(self._add_callbacks, callback, remove)
18 | def on_del(self, callback, remove=False):
19 | self._register_callback(self._del_callbacks, callback, remove)
20 | def on_set(self, callback, remove=False):
21 | self._register_callback(self._set_callbacks, callback, remove)
22 | def _register_callback(self, callback_list, callback, remove=False):
23 | if callable(callback):
24 | if remove and callback in callback_list:
25 | callback_list.remove(callback)
26 | elif not remove and not callback in callback_list:
27 | callback_list.append(callback)
28 | else:
29 | raise Exception('Callback must be callable.')
30 |
31 | def _handle_add(self, key, value):
32 | self._try_callbacks(self._add_callbacks, key, value)
33 | self._try_sleep()
34 | def _handle_del(self, key):
35 | self._try_callbacks(self._del_callbacks, key)
36 | self._try_sleep()
37 | def _handle_set(self, key, value):
38 | self._try_callbacks(self._set_callbacks, key, value)
39 | self._try_sleep()
40 | def _try_callbacks(self, callback_list, *pargs, **kwargs):
41 | for callback in callback_list:
42 | callback(*pargs, **kwargs)
43 |
44 | def _try_sleep(self):
45 | if self._sleep > 0.0:
46 | time.sleep(self._sleep)
47 |
48 | def __setitem__(self, key, value):
49 | return_val = None
50 | exists = False
51 | if key in self:
52 | exists = True
53 |
54 | # If the user sets the property to a new dict, make the dict
55 | # eventful and listen to the changes of it ONLY if it is not
56 | # already eventful. Any modification to this new dict will
57 | # fire a set event of the parent dict.
58 | if isinstance(value, dict) and not isinstance(value, EventfulDict):
59 | new_dict = EventfulDict(value)
60 |
61 | def handle_change(*pargs, **kwargs):
62 | self._try_callbacks(self._set_callbacks, key, dict.__getitem__(self, key))
63 |
64 | new_dict.on_add(handle_change)
65 | new_dict.on_del(handle_change)
66 | new_dict.on_set(handle_change)
67 | return_val = dict.__setitem__(self, key, new_dict)
68 | else:
69 | return_val = dict.__setitem__(self, key, value)
70 |
71 | if exists:
72 | self._handle_set(key, value)
73 | else:
74 | self._handle_add(key, value)
75 | return return_val
76 |
77 | def __delitem__(self, key):
78 | return_val = dict.__delitem__(self, key)
79 | self._handle_del(key)
80 | return return_val
81 |
82 | def pop(self, key):
83 | return_val = dict.pop(self, key)
84 | if key in self:
85 | self._handle_del(key)
86 | return return_val
87 |
88 | def popitem(self):
89 | popped = dict.popitem(self)
90 | if popped is not None and popped[0] is not None:
91 | self._handle_del(popped[0])
92 | return popped
93 |
94 | def update(self, other_dict):
95 | for (key, value) in other_dict.items():
96 | self[key] = value
97 |
98 | def clear(self):
99 | for key in list(self.keys()):
100 | del self[key]
--------------------------------------------------------------------------------
/Part-4/examples/wikipedia/eventful_graph.py:
--------------------------------------------------------------------------------
1 | """NetworkX graphs do not have events that can be listened to. In order to
2 | watch the NetworkX graph object for changes a custom eventful graph object must
3 | be created. The custom eventful graph object will inherit from the base graph
4 | object and use special eventful dictionaries instead of standard Python dict
5 | instances. Because NetworkX nests dictionaries inside dictionaries, it's
6 | important that the eventful dictionary is capable of recognizing when a
7 | dictionary value is set to another dictionary instance. When this happens, the
8 | eventful dictionary needs to also make the new dictionary an eventful
9 | dictionary. This allows the eventful dictionary to listen to changes made to
10 | dictionaries within dictionaries."""
11 | import networkx
12 | from networkx.generators.classic import empty_graph
13 |
14 | from eventful_dict import EventfulDict
15 |
16 | class EventfulGraph(networkx.Graph):
17 |
18 | _constructed_callback = None
19 |
20 | @staticmethod
21 | def on_constructed(callback):
22 | """Register a callback to be called when a graph is constructed."""
23 | if callback is None or callable(callback):
24 | EventfulGraph._constructed_callback = callback
25 |
26 | def __init__(self, *pargs, **kwargs):
27 | """Initialize a graph with edges, name, graph attributes.
28 |
29 | Parameters
30 | sleep: float
31 | optional float that allows you to tell the
32 | dictionary to hang for the given amount of seconds on each
33 | event. This is usefull for animations."""
34 | super(EventfulGraph, self).__init__(*pargs, **kwargs)
35 |
36 | # Override internal dictionaries with custom eventful ones.
37 | sleep = kwargs.get('sleep', 0.0)
38 | self.graph = EventfulDict(self.graph, sleep=sleep)
39 | self.node = EventfulDict(self.node, sleep=sleep)
40 | self.adj = EventfulDict(self.adj, sleep=sleep)
41 |
42 | # Notify callback of construction event.
43 | if EventfulGraph._constructed_callback:
44 | EventfulGraph._constructed_callback(self)
45 |
46 |
47 | def empty_eventfulgraph_hook(*pargs, **kwargs):
48 | def wrapped(*wpargs, **wkwargs):
49 | """Wrapper for networkx.generators.classic.empty_graph(...)"""
50 | wkwargs['create_using'] = EventfulGraph(*pargs, **kwargs)
51 | return empty_graph(*wpargs, **wkwargs)
52 | return wrapped
53 |
--------------------------------------------------------------------------------
/Part-4/examples/wikipedia/widget_forcedirectedgraph.py:
--------------------------------------------------------------------------------
1 | import ipywidgets as widgets # Widget definitions
2 | from traitlets import Unicode, CInt, CFloat # Import the base Widget class and the traitlets Unicode class.
3 | from IPython.display import display, Javascript
4 |
5 | def publish_js():
6 | with open('./widget_forcedirectedgraph.js', 'r') as f:
7 | display(Javascript(data=f.read()))
8 |
9 |
10 | # Define our ForceDirectedGraphWidget and its target model and default view.
11 | class ForceDirectedGraphWidget(widgets.DOMWidget):
12 | _view_name = Unicode('D3ForceDirectedGraphView').tag(sync=True)
13 |
14 | width = CInt(400).tag(sync=True)
15 | height = CInt(300).tag(sync=True)
16 | charge = CFloat(270.).tag(sync=True)
17 | distance = CInt(30.).tag(sync=True)
18 | strength = CInt(0.3).tag(sync=True)
19 |
20 | def __init__(self, eventful_graph, *pargs, **kwargs):
21 | widgets.DOMWidget.__init__(self, *pargs, **kwargs)
22 |
23 | self._eventful_graph = eventful_graph
24 | self._send_dict_changes(eventful_graph.graph, 'graph')
25 | self._send_dict_changes(eventful_graph.node, 'node')
26 | self._send_dict_changes(eventful_graph.adj, 'adj')
27 |
28 | def _ipython_display_(self, *pargs, **kwargs):
29 |
30 | # Show the widget, then send the current state
31 | widgets.DOMWidget._ipython_display_(self, *pargs, **kwargs)
32 | for (key, value) in self._eventful_graph.graph.items():
33 | self.send({'dict': 'graph', 'action': 'add', 'key': key, 'value': value})
34 | for (key, value) in self._eventful_graph.node.items():
35 | self.send({'dict': 'node', 'action': 'add', 'key': key, 'value': value})
36 | for (key, value) in self._eventful_graph.adj.items():
37 | self.send({'dict': 'adj', 'action': 'add', 'key': key, 'value': value})
38 |
39 | def _send_dict_changes(self, eventful_dict, dict_name):
40 | def key_add(key, value):
41 | self.send({'dict': dict_name, 'action': 'add', 'key': key, 'value': value})
42 | def key_set(key, value):
43 | self.send({'dict': dict_name, 'action': 'set', 'key': key, 'value': value})
44 | def key_del(key):
45 | self.send({'dict': dict_name, 'action': 'del', 'key': key})
46 | eventful_dict.on_add(key_add)
47 | eventful_dict.on_set(key_set)
48 | eventful_dict.on_del(key_del)
49 |
--------------------------------------------------------------------------------
/Part-4/exercises/Monte Carlo π.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Multiplexing Exercise - Monte Carlo π\n",
8 | "\n",
9 | "A simple toy problem to get a handle on multiple engines is a Monte\n",
10 | "Carlo approximation of π.\n",
11 | "\n",
12 | "Let's say we have a dartboard with a round target inscribed on a square\n",
13 | "board. If you threw darts randomly, and they land evenly distributed on\n",
14 | "the square board, how many darts would you expect to hit the target?\n",
15 | "\n",
16 | " "
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "$$\n",
24 | "\\frac{A_c}{A_{sq}} = \\frac{\\pi r^2}{(2r)^2} = \\frac{\\pi}{4}\n",
25 | "$$"
26 | ]
27 | },
28 | {
29 | "cell_type": "code",
30 | "execution_count": null,
31 | "metadata": {},
32 | "outputs": [],
33 | "source": [
34 | "from __future__ import print_function\n",
35 | "\n",
36 | "from random import random\n",
37 | "from math import pi\n",
38 | "\n",
39 | "def mcpi(nsamples):\n",
40 | " s = 0\n",
41 | " for i in range(nsamples):\n",
42 | " x = random()\n",
43 | " y = random()\n",
44 | " if x*x + y*y <= 1:\n",
45 | " s+=1\n",
46 | " return 4.*s/nsamples"
47 | ]
48 | },
49 | {
50 | "cell_type": "code",
51 | "execution_count": null,
52 | "metadata": {},
53 | "outputs": [],
54 | "source": [
55 | "for n in [10, 100, 1000, 10000, 100000, 1000000]:\n",
56 | " print(\"%8i\" % n, end=' ')\n",
57 | " for i in range(3):\n",
58 | " print(\"%.5f\" % mcpi(n), end=' ')\n",
59 | " print()"
60 | ]
61 | },
62 | {
63 | "cell_type": "code",
64 | "execution_count": null,
65 | "metadata": {},
66 | "outputs": [],
67 | "source": [
68 | "%timeit mcpi(1000000)"
69 | ]
70 | },
71 | {
72 | "cell_type": "markdown",
73 | "metadata": {},
74 | "source": [
75 | "It takes a lot of samples to get a good approximation. Can you write a\n",
76 | "function that will use your engines to break up the work?\n",
77 | "\n",
78 | "```python\n",
79 | "def multi_mcpi(dview, nsamples):\n",
80 | " raise NotImplementedError(\"you write this\")\n",
81 | "```"
82 | ]
83 | },
84 | {
85 | "cell_type": "code",
86 | "execution_count": null,
87 | "metadata": {},
88 | "outputs": [],
89 | "source": [
90 | "import ipyparallel as ipp\n",
91 | "rc = ipp.Client()\n",
92 | "\n",
93 | "view = rc[:]"
94 | ]
95 | },
96 | {
97 | "cell_type": "code",
98 | "execution_count": null,
99 | "metadata": {
100 | "collapsed": true
101 | },
102 | "outputs": [],
103 | "source": [
104 | "%load ../soln/mcpi.py"
105 | ]
106 | },
107 | {
108 | "cell_type": "code",
109 | "execution_count": null,
110 | "metadata": {},
111 | "outputs": [],
112 | "source": [
113 | "multi_mcpi(view, 10000000)"
114 | ]
115 | },
116 | {
117 | "cell_type": "code",
118 | "execution_count": null,
119 | "metadata": {
120 | "collapsed": true
121 | },
122 | "outputs": [],
123 | "source": [
124 | "# bonus: plot convergence like we did for Monte Carlo integration"
125 | ]
126 | }
127 | ],
128 | "metadata": {
129 | "kernelspec": {
130 | "display_name": "Python 3",
131 | "language": "python",
132 | "name": "python3"
133 | },
134 | "language_info": {
135 | "codemirror_mode": {
136 | "name": "ipython",
137 | "version": 3
138 | },
139 | "file_extension": ".py",
140 | "mimetype": "text/x-python",
141 | "name": "python",
142 | "nbconvert_exporter": "python",
143 | "pygments_lexer": "ipython3",
144 | "version": "3.6.0"
145 | },
146 | "widgets": {
147 | "state": {},
148 | "version": "1.1.1"
149 | }
150 | },
151 | "nbformat": 4,
152 | "nbformat_minor": 1
153 | }
154 |
--------------------------------------------------------------------------------
/Part-4/figs/allconnections.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jupyter/ngcm-tutorial/e2acd3365c8a18cb4360ee7ecd4b74a9e1d9ce27/Part-4/figs/allconnections.png
--------------------------------------------------------------------------------
/Part-4/figs/darts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jupyter/ngcm-tutorial/e2acd3365c8a18cb4360ee7ecd4b74a9e1d9ce27/Part-4/figs/darts.png
--------------------------------------------------------------------------------
/Part-4/figs/latency.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jupyter/ngcm-tutorial/e2acd3365c8a18cb4360ee7ecd4b74a9e1d9ce27/Part-4/figs/latency.png
--------------------------------------------------------------------------------
/Part-4/figs/latency2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jupyter/ngcm-tutorial/e2acd3365c8a18cb4360ee7ecd4b74a9e1d9ce27/Part-4/figs/latency2.png
--------------------------------------------------------------------------------
/Part-4/figs/map.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jupyter/ngcm-tutorial/e2acd3365c8a18cb4360ee7ecd4b74a9e1d9ce27/Part-4/figs/map.png
--------------------------------------------------------------------------------
/Part-4/figs/throughput1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jupyter/ngcm-tutorial/e2acd3365c8a18cb4360ee7ecd4b74a9e1d9ce27/Part-4/figs/throughput1.png
--------------------------------------------------------------------------------
/Part-4/figs/throughput2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jupyter/ngcm-tutorial/e2acd3365c8a18cb4360ee7ecd4b74a9e1d9ce27/Part-4/figs/throughput2.png
--------------------------------------------------------------------------------
/Part-4/figs/wideView.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jupyter/ngcm-tutorial/e2acd3365c8a18cb4360ee7ecd4b74a9e1d9ce27/Part-4/figs/wideView.png
--------------------------------------------------------------------------------
/Part-4/hints.py:
--------------------------------------------------------------------------------
1 | from IPython.display import display, HTML
2 |
3 | def mmhint():
4 | display(HTML("""
5 | hint 1
6 |
7 | Remember - multiply rows of one by the columns of the other.
8 |
9 |
10 |
11 | hint 2
12 |
13 | easiest implementation involves one each of: push, scatter, execute, gather
14 |
15 |
19 | """))
20 |
21 | def nesthint():
22 | display(HTML("""
23 |
24 | hint
25 |
26 |
27 |
28 | `itertools.product` and `zip` will be helpful.
29 |
30 |
33 | """))
--------------------------------------------------------------------------------
/Part-4/hubble-tiles.py:
--------------------------------------------------------------------------------
1 | """Construct tiles of a high-res hubble image
2 | for sample data
3 | """
4 |
5 | import os, sys
6 |
7 | import requests
8 | import skimage.io
9 |
10 | from ipywidgets import IntProgress
11 | from IPython.display import display
12 |
13 | url = 'http://imgsrc.hubblesite.org/hvi/uploads/image_file/image_attachment/9077/full_jpg.jpg'
14 | here = os.path.dirname(__file__)
15 | full_size_file = os.path.join(here, 'hubble.jpg')
16 |
17 | def download_original():
18 | p = IntProgress(max=1, description="Downloading")
19 | display(p)
20 | if os.path.exists(full_size_file):
21 | print("Already have %s" % full_size_file)
22 | p.value = p.max
23 | else:
24 | r = requests.get(url, stream=True)
25 | content_length = r.headers.get('content-length', int(1e8))
26 | print("Downloading %s" % url)
27 | p.max = content_length
28 | r.raise_for_status()
29 |
30 | with open(full_size_file, 'wb') as f:
31 | for chunk in r.iter_content(chunk_size=8096):
32 | p.value += len(chunk)
33 | f.write(chunk)
34 | p.value = p.max
35 |
36 | def tile_image(full_size_path, tile_size=400):
37 | p = IntProgress(description='Tiling', max=1)
38 | display(p)
39 | root_dir = os.path.dirname(full_size_path)
40 | name, ext = os.path.splitext(os.path.basename(full_size_path))
41 | tile_dir = os.path.join(root_dir, '{0}-{1}x{1}'.format(name, tile_size))
42 | if not os.path.exists(tile_dir):
43 | os.mkdir(tile_dir)
44 | tpl = os.path.join(tile_dir, '{name}-{i:02}-{j:02}{ext}')
45 | full_size = skimage.io.imread(full_size_path)
46 | X, Y = full_size.shape[:2]
47 | total_tiles = (X // tile_size) * (Y // tile_size)
48 | p.max = total_tiles
49 | print("Creating %i tiles in %s" % (total_tiles, tile_dir))
50 |
51 | for i in range(X // tile_size):
52 | for j in range(Y // tile_size):
53 | tile = full_size[
54 | i * tile_size: (i+1) * tile_size,
55 | j * tile_size: (j+1) * tile_size,
56 | :
57 | ]
58 | fname = tpl.format(**locals())
59 | p.value += 1
60 | skimage.io.imsave(fname, tile)
61 | p.value = p.max
62 |
63 | if __name__ == '__main__':
64 | download_original()
65 | tile_image(full_size_file)
66 |
--------------------------------------------------------------------------------
/Part-4/images_common.py:
--------------------------------------------------------------------------------
1 | import os
2 | import matplotlib.pyplot as plt
3 |
4 | from skimage.io import imread
5 |
6 | def plot_corners(img, corners, show=True):
7 | """Display the image and plot all contours found"""
8 | plt.imshow(img, cmap='gray')
9 | plt.plot(corners[:,1], corners[:,0], 'r+', markeredgewidth=1.5, markersize=8) # Plot corners
10 | plt.axis('image')
11 | plt.xticks([])
12 | plt.yticks([])
13 | if show:
14 | plt.show()
15 |
16 | def find_corners(path, min_distance=5):
17 | """Find corners in an image at path
18 |
19 | Returns the image and the corner lists.
20 | """
21 | from skimage.feature import corner_harris, corner_peaks
22 | img = imread(path, flatten=True)
23 | corners = corner_peaks(corner_harris(img), min_distance=min_distance)
24 | return img, corners
25 |
26 | def get_corners_image(path):
27 | """Given a path, return a PNG of the image with contour lines
28 |
29 | Calls both find_contours and plot_contours
30 | """
31 | from IPython.core.pylabtools import print_figure
32 |
33 | img, corners = find_corners(path)
34 | plot_corners(img, corners, show=False)
35 | fig = plt.gcf()
36 | pngdata = print_figure(fig)
37 | plt.close(fig)
38 | return pngdata
39 |
40 | def get_pictures(pictures_dir):
41 | """Return a list of picture files found in pictures_dir"""
42 |
43 | pictures = []
44 | for directory, subdirs, files in os.walk(pictures_dir):
45 | for fname in files:
46 | if fname.lower().endswith(('.jpg', '.png')):
47 | pictures.append(os.path.join(directory, fname))
48 |
49 | return pictures
50 |
51 |
52 | def find_blobs(img_path):
53 | """Find the blobs in an image"""
54 | from skimage.color import rgb2gray
55 | from skimage.feature import blob_doh
56 | from skimage.io import imread
57 |
58 | image = imread(img_path)
59 | image_gray = rgb2gray(image)
60 | return image, blob_doh(image_gray, max_sigma=30, threshold=.01)
61 |
62 |
63 | def plot_blobs(image, blobs):
64 | """Plot the blobs in an image"""
65 | fig, ax = plt.subplots()
66 | ax.grid(False)
67 | ax.imshow(image, interpolation='nearest')
68 | ax.set_xticks([])
69 | ax.set_yticks([])
70 | for blob in blobs:
71 | y, x, r = blob
72 | c = plt.Circle((x, y), r, color='r', linewidth=2, fill=False)
73 | ax.add_patch(c)
74 |
75 |
--------------------------------------------------------------------------------
/Part-4/soln/matmul.py:
--------------------------------------------------------------------------------
1 | def pdot(v, A, B):
2 | v['B'] = B # push B everywhere
3 | v.scatter('A', A) # scatter A
4 | v.execute('C=A.dot(B)') # compute the dot-product
5 | return v.gather('C', block=True) # gather the resulting sub-arrays
6 |
--------------------------------------------------------------------------------
/Part-4/soln/mcpi.py:
--------------------------------------------------------------------------------
1 | def mcpi(nsamples):
2 | from random import random
3 | s = 0
4 | for i in range(nsamples):
5 | x = random()
6 | y = random()
7 | if x*x + y*y <= 1:
8 | s += 1
9 | return 4. * s / nsamples
10 |
11 | def multi_mcpi(view, nsamples):
12 | p = len(view.targets)
13 | if nsamples % p:
14 | # ensure even divisibility
15 | nsamples += p - (nsamples % p)
16 |
17 | subsamples = nsamples // p
18 |
19 | ar = view.apply_async(mcpi, subsamples)
20 | return sum(ar) / p
--------------------------------------------------------------------------------
/Part-4/soln/nestedloop.py:
--------------------------------------------------------------------------------
1 | # To parallelize every call with map, you just need to get a list for each argument.
2 | # You can use `itertools.product` + `zip` to get this:
3 |
4 |
5 | import itertools
6 |
7 | product = list(itertools.product(widths, heights))
8 | # [(1, 6), (1, 7), (2, 6), (2, 7), (3, 6), (3, 7)]
9 |
10 | # So we have a "list of pairs",
11 | # but what we really want is a single list for each argument, i.e. a "pair of lists".
12 | # This is exactly what the slightly weird `zip(*product)` syntax gets us:
13 |
14 | allwidths, allheights = zip(*itertools.product(widths, heights))
15 |
16 | print(" widths", allwidths)
17 | print("heights", allheights)
18 |
19 | # Now we just map our function onto those two lists, to parallelize nested for loops:
20 |
21 | ar = lview.map_async(area, allwidths, allheights)
22 |
--------------------------------------------------------------------------------
/Part-4/soln/ngrams.py:
--------------------------------------------------------------------------------
1 | def ngrams_parallel(view, fnames, n=1):
2 | """Compute ngrams in parallel
3 |
4 | view - An IPython DirectView
5 | fnames - The filenames containing the split data.
6 | """
7 |
8 | ar = view.map_async(ngrams, fnames, [n] * len(fnames))
9 | counts = {}
10 | for engine_count in ar:
11 | for gram, count in engine_count.items():
12 | if gram not in counts:
13 | counts[gram] = 0
14 | counts[gram] += count
15 | return counts
16 |
--------------------------------------------------------------------------------
/Part-4/soln/remote_iter.py:
--------------------------------------------------------------------------------
1 | import ipyparallel as parallel
2 |
3 | def remote_iterator(view, name):
4 | """Return an iterator on an object living on a remote engine."""
5 | it_name = '_%s_iter' % name
6 | view.execute('%s = iter(%s)' % (it_name,name), block=True)
7 | ref = parallel.Reference(it_name)
8 | while True:
9 | try:
10 | yield view.apply_sync(next, ref)
11 | # This causes the StopIteration exception to be raised.
12 | except parallel.RemoteError as e:
13 | if e.ename == 'StopIteration':
14 | raise StopIteration
15 | else:
16 | raise e
17 |
--------------------------------------------------------------------------------
/Part-4/soln/remote_iter_hint.py:
--------------------------------------------------------------------------------
1 | from IPython.display import display
2 |
3 | t_minus = range(10,0,-1)
4 |
5 | def lazy_iterator(name):
6 | seq = eval(name)
7 | it = iter(seq)
8 | while True:
9 | try:
10 | yield next(it)
11 | # this looks silly locally, but it will be useful for the remote version:
12 | except StopIteration:
13 | raise StopIteration
14 |
15 | lzit = lazy_iterator('t_minus')
16 | display(lzit)
17 | list(lzit)
--------------------------------------------------------------------------------
/Part-4/tutorial/myscript.py:
--------------------------------------------------------------------------------
1 | import math
2 | import numpy
3 | import sys
4 |
5 | a=5
6 |
7 | def mysquare(x):
8 | return x*x
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # IPython/Jupyter Workshop at the NGCM Summer Academy
2 |
3 | Materials for the IPython/Jupyter workshop at the Next-Generation Computational
4 | Modeling Summer Academy:
5 |
6 | - 2-day course
7 | - 27 and 28 June 2017
8 | - At Southampton University, Boldrewood campus
9 |
10 | Course URL: http://ngcm.soton.ac.uk/summer-academy/ipython.html
11 |
12 | Teaching is from 10am to 6pm, broken up by half-hour tea breaks morning and
13 | afternoon, and an hour lunch break. See
14 | [the programme](http://ngcm.soton.ac.uk/summer-academy/programme.html) for
15 | details.
16 |
17 | ## Course content
18 |
19 | Jupyter and IPython provide tools for interactive and parallel computing that are
20 | widely used in scientific computing. We will show some uses of IPython
21 | for scientific applications, focusing on exciting recent developments,
22 | web-based notebooks with code, graphics, and rich HTML.
23 |
24 | Day 1 morning: Core Jupyter and IPython
25 |
26 | - Notebook Basics
27 | - IPython - beyond plain python
28 | - Markdown Cells
29 | - Rich Display System
30 | - Beyond Python: the Jupyter architecture with Julia and R
31 |
32 | Day 1 afternoon: Working with notebook files
33 |
34 | - Converting notebooks to other formats with nbconvert
35 | - Using notebooks in version control, with git and nbdime
36 | - Sharing notebooks online using nbviewer
37 | - Notebooks in continuous integration with nbval
38 |
39 | Day 2 morning: Interactive widgets in notebooks
40 |
41 | - Using interact() to explore a function
42 | - Creating widgets manually and connecting them to Python functions
43 | - Laying out widgets on the page
44 | - The architecture of interactive widgets
45 |
46 | Day 2 afternoon: Parallel computing with IPython
47 |
48 | - Overview of the ipyparallel model
49 | - Controller and engines
50 | - Basics of remote execution
51 | - Direct vs task execution
52 | - Integration with MPI codes
53 | - Handling dependencies between tasks
54 | - Performance considerations
55 |
56 |
57 | ## Software Requirements
58 |
59 | - Python 3.x
60 | - Jupyter, including the Notebook and IPython. It should
61 | be available through the usual distribution channels, such as
62 | [Anaconda](http://continuum.io/downloads).
63 | - Your favorite text editor.
64 | - If you have trouble installing Anaconda, [this blog
65 | entry](http://www.southampton.ac.uk/~fangohr/blog/installation-of-python-spyder-numpy-sympy-scipy-pytest-matplotlib-via-anaconda.html)
66 | may help.
67 | - For the material related to `nbconvert`, the `pandoc` package, together with a `latex` installation, would be useful.
68 |
69 | To install the packages required for this course and the Pandas course
70 | in a new environment with Anaconda, run:
71 |
72 | ```bash
73 | conda create -n ngcm python=3 numpy scipy jupyter ipywidgets pandas matplotlib requests scikit-image sympy
74 | ```
75 |
76 | Then, to use this environment, enter:
77 |
78 | ```bash
79 | source activate ngcm
80 | ```
81 |
82 | On Windows, this command is just `activate ngcm`.
83 |
84 | ## Checking your installation
85 |
86 | You can download and run this
87 | [version_check.py](https://github.com/jupyter/ngcm-tutorial/raw/master/version_check.py)
88 | script, and execute it using `python version_check.py` to check
89 | you have fulfilled the installation requirements.
90 |
91 |
92 | ## Required knowledge
93 |
94 | - Basic Python,
95 | - some vague notion of html would be great.
96 |
97 |
98 | ## The trainers
99 |
100 | - [Thomas Kluyver](http://cmg.soton.ac.uk/people/tk2e15/)
101 | - [MinRK](http://github.com/minrk)
102 |
103 |
104 | ## Infrastructure
105 |
106 | - [Etherpad](https://public.etherpad-mozilla.org/p/ngcm-2017-jupyter)
107 | - [Slack channel "ipython"](https://ngcmsummeracademy2016.slack.com/messages/ipython/)
108 |
--------------------------------------------------------------------------------
/utils/list_pyfiles.ipy:
--------------------------------------------------------------------------------
1 | # A simple IPython script that provides Notebook links to .py files in the cwd
2 |
3 | from IPython.display import FileLink, display
4 | files =!ls *.py
5 | for f in files:
6 | display(FileLink(f))
--------------------------------------------------------------------------------
/utils/list_subdirs.ipy:
--------------------------------------------------------------------------------
1 | # A simple IPython script that lists files in all subdirs
2 |
3 | from IPython.display import FileLinks, display
4 | dirs =!ls -d */
5 | for d in dirs:
6 | display(FileLinks(d))
--------------------------------------------------------------------------------
/version_check.py:
--------------------------------------------------------------------------------
1 | # check Python version
2 |
3 | import sys
4 | assert sys.version_info.major >= 3, "You need Python 3."
5 | print("Python version is {} -> okay".format(sys.version.splitlines()[0]))
6 |
7 | # check IPython version
8 |
9 | import IPython
10 | assert IPython.version_info[0] >= 4, "You need IPython >= 4.0"
11 | print("IPython version is {} -> okay".format(IPython.__version__))
12 |
13 | import notebook
14 | assert notebook.version_info >= (4,2), "You need notebook >= 4.2"
15 | print("notebook version is {} -> okay".format(notebook.__version__))
16 |
17 | import ipywidgets
18 | assert 4 <= ipywidgets.version_info[0] < 6, "You need ipywidgets 4.x-5.x"
19 | print("ipywidgets version is {} -> okay".format(ipywidgets.__version__))
20 |
21 | import ipyparallel
22 | assert ipyparallel.version_info[0] > 4, "You need ipyparallel >= 4"
23 | print("ipyparallel version is {} -> okay".format(ipyparallel.__version__))
24 |
25 | import traitlets
26 | assert traitlets.version_info >= (4,2), "You need traitlets >= 4.2"
27 | print("traitlets version is {} -> okay".format(traitlets.__version__))
28 |
29 | print("You are all set for the IPython course at the NGCM Summer academy 2016.")
30 |
--------------------------------------------------------------------------------
/website_summary.rst:
--------------------------------------------------------------------------------
1 | Course content
2 | --------------
3 |
4 | Jupyter and IPython provide tools for interactive and parallel computing that are
5 | widely used in scientific computing. We will show some uses of IPython
6 | for scientific applications, focusing on exciting recent developments,
7 | web-based notebooks with code, graphics, and rich HTML.
8 |
9 | Day 1 morning: Core Jupyter and IPython
10 |
11 | - Notebook Basics
12 | - IPython - beyond plain python
13 | - Markdown Cells
14 | - Rich Display System
15 | - Beyond Python: the Jupyter architecture with Julia and R
16 |
17 | Day 1 afternoon: Working with notebook files
18 |
19 | - Converting notebooks to other formats with nbconvert
20 | - Using notebooks in version control, with git and nbdime
21 | - Sharing notebooks online using nbviewer
22 | - Notebooks in continuous integration with nbval
23 |
24 | Day 2 morning: Interactive widgets in notebooks
25 |
26 | - Using interact() to explore a function
27 | - Creating widgets manually and connecting them to Python functions
28 | - Laying out widgets on the page
29 | - The architecture of interactive widgets
30 |
31 | Day 2 afternoon: Parallel computing with IPython
32 |
33 | - Overview of the ipyparallel model
34 | - Controller and engines
35 | - Basics of remote execution
36 | - Direct vs task execution
37 | - Integration with MPI codes
38 | - Handling dependencies between tasks
39 | - Performance considerations
40 |
41 | Software Requirements
42 | ---------------------
43 |
44 | - Python 3.x
45 | - Jupyter, including the Notebook and IPython. It should
46 | be available through the usual distribution channels, such as
47 | `Anaconda `__.
48 | - Your favorite text editor.
49 | - If you have trouble installing Anaconda, `this blog
50 | entry `__
51 | may help.
52 | - For the material related to ``nbconvert``, the ``pandoc`` package, together with a ``latex`` installation, would be useful.
53 |
54 | To install the packages required for this course and the Pandas course
55 | in a new environment with Anaconda, run::
56 |
57 | conda create -n ngcm python=3 numpy scipy jupyter ipywidgets pandas matplotlib requests scikit-image sympy
58 |
59 | Then, to use this environment, enter::
60 |
61 | source activate ngcm
62 |
63 | On Windows, this command is just ``activate ngcm``.
64 |
65 | Checking your installation
66 | --------------------------
67 |
68 | You can download and run this
69 | `version_check.py `__
70 | script, and execute it using ``python version_check.py`` to check
71 | you have fulfilled the installation requirements.
72 |
73 | Required knowledge
74 | ------------------
75 |
76 | - Basic Python,
77 | - some vague notion of html would be great.
78 |
79 | The trainers
80 | ------------
81 |
82 | - `Thomas Kluyver `__
83 | - `MinRK `__
84 |
85 | Infrastructure
86 | --------------
87 |
88 | - `Etherpad `__
89 | - `Slack channel "ipython" `__
90 |
--------------------------------------------------------------------------------