##// END OF EJS Templates
rebuild example notebooks...
MinRK -
Show More

The requested changes are too big and content was truncated. Show full diff

1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
This diff has been collapsed as it changes many lines, (708 lines changed) Show them Hide them
@@ -3,480 +3,600 b''
3 "name": "01_notebook_introduction"
3 "name": "01_notebook_introduction"
4 },
4 },
5 "nbformat": 3,
5 "nbformat": 3,
6 "nbformat_minor": 0,
6 "worksheets": [
7 "worksheets": [
7 {
8 {
8 "cells": [
9 "cells": [
9 {
10 {
11 "cell_type": "heading",
12 "level": 1,
13 "metadata": {},
14 "source": [
15 "An introduction to the IPython notebook"
16 ]
17 },
18 {
10 "cell_type": "markdown",
19 "cell_type": "markdown",
20 "metadata": {},
11 "source": [
21 "source": [
12 "# An introduction to the IPython notebook",
22 "\n",
13 "",
23 "The IPython web notebook is a frontend that allows for new modes\n",
14 "The IPython web notebook is a frontend that allows for new modes",
24 "of interaction with IPython: this web-based interface allows you to execute Python and IPython\n",
15 "of interaction with IPython: this web-based interface allows you to execute Python and IPython",
25 "commands in each input cell just like you would at the IPython terminal or Qt console, but you can\n",
16 "commands in each input cell just like you would at the IPython terminal or Qt console, but you can",
26 "also save an entire session as a document in a file with the `.ipynb` extension.\n",
17 "also save an entire session as a document in a file with the `.ipynb` extension.",
27 "\n",
18 "",
28 "The document you are reading now is precisely an example of one such notebook, and we will show you\n",
19 "The document you are reading now is precisely an example of one such notebook, and we will show you",
29 "here how to best use this new interface.\n",
20 "here how to best use this new interface.",
30 "\n",
21 "",
31 "The first thing to understand is that a notebook consists of a sequence of 'cells' that can contain \n",
22 "The first thing to understand is that a notebook consists of a sequence of 'cells' that can contain ",
32 "either text (such as this one) or code meant for execution (such as the next one):\n",
23 "either text (such as this one) or code meant for execution (such as the next one):",
33 "\n",
24 "",
34 "* Text cells can be written using [Markdown syntax](http://daringfireball.net/projects/markdown/syntax) \n",
25 "* Text cells can be written using [Markdown syntax](http://daringfireball.net/projects/markdown/syntax) ",
35 "(in a future release we will also provide support for reStructuredText and Sphinx integration, and we \n",
26 "(in a future release we will also provide support for reStructuredText and Sphinx integration, and we ",
36 "welcome help from interested contributors to make that happen).\n",
27 "welcome help from interested contributors to make that happen).",
37 "\n",
28 "",
38 "* Code cells take IPython input (i.e. Python code, `%magics`, `!system calls`, etc) like IPython at\n",
29 "* Code cells take IPython input (i.e. Python code, `%magics`, `!system calls`, etc) like IPython at",
39 "the terminal or at the Qt Console. The only difference is that in order to execute a cell, you *must*\n",
30 "the terminal or at the Qt Console. The only difference is that in order to execute a cell, you *must*",
40 "use `Shift-Enter`, as pressing `Enter` will add a new line of text to the cell. When you type \n",
31 "use `Shift-Enter`, as pressing `Enter` will add a new line of text to the cell. When you type ",
41 "`Shift-Enter`, the cell content is executed, output displayed and a new cell is created below. Try\n",
32 "`Shift-Enter`, the cell content is executed, output displayed and a new cell is created below. Try",
33 "it now by putting your cursor on the next cell and typing `Shift-Enter`:"
42 "it now by putting your cursor on the next cell and typing `Shift-Enter`:"
34 ]
43 ]
35 },
44 },
36 {
45 {
37 "cell_type": "code",
46 "cell_type": "code",
47 "collapsed": false,
38 "input": [
48 "input": [
39 "\"This is the new IPython notebook\""
49 "\"This is the new IPython notebook\""
40 ],
50 ],
41 "language": "python",
51 "language": "python",
52 "metadata": {},
42 "outputs": [
53 "outputs": [
43 {
54 {
44 "output_type": "pyout",
55 "output_type": "pyout",
45 "prompt_number": 1,
56 "prompt_number": 2,
46 "text": [
57 "text": [
47 "'This is the new IPython notebook'"
58 "'This is the new IPython notebook'"
48 ]
59 ]
49 }
60 }
50 ],
61 ],
51 "prompt_number": 1
62 "prompt_number": 2
52 },
63 },
53 {
64 {
54 "cell_type": "markdown",
65 "cell_type": "markdown",
66 "metadata": {},
55 "source": [
67 "source": [
56 "You can re-execute the same cell over and over as many times as you want. Simply put your",
68 "You can re-execute the same cell over and over as many times as you want. Simply put your\n",
57 "cursor in the cell again, edit at will, and type `Shift-Enter` to execute. ",
69 "cursor in the cell again, edit at will, and type `Shift-Enter` to execute. \n",
58 "",
70 "\n",
59 "**Tip:** A cell can also be executed",
71 "**Tip:** A cell can also be executed\n",
60 "*in-place*, where IPython executes its content but leaves the cursor in the same cell. This is done by",
72 "*in-place*, where IPython executes its content but leaves the cursor in the same cell. This is done by\n",
61 "typing `Ctrl-Enter` instead, and is useful if you want to quickly run a command to check something ",
73 "typing `Ctrl-Enter` instead, and is useful if you want to quickly run a command to check something \n",
62 "before tping the real content you want to leave in the cell. For example, in the next cell, try issuing",
74 "before tping the real content you want to leave in the cell. For example, in the next cell, try issuing\n",
63 "several system commands in-place with `Ctrl-Enter`, such as `pwd` and then `ls`:"
75 "several system commands in-place with `Ctrl-Enter`, such as `pwd` and then `ls`:"
64 ]
76 ]
65 },
77 },
66 {
78 {
67 "cell_type": "code",
79 "cell_type": "code",
80 "collapsed": false,
68 "input": [
81 "input": [
69 "ls"
82 "ls"
70 ],
83 ],
71 "language": "python",
84 "language": "python",
85 "metadata": {},
72 "outputs": [
86 "outputs": [
73 {
87 {
74 "output_type": "stream",
88 "output_type": "stream",
75 "stream": "stdout",
89 "stream": "stdout",
76 "text": [
90 "text": [
77 "00_notebook_tour.ipynb formatting.ipynb sympy_quantum_computing.ipynb",
91 "00_notebook_tour.ipynb callbacks.ipynb python-logo.svg\r\n",
78 "01_notebook_introduction.ipynb python-logo.svg trapezoid_rule.ipynb",
92 "01_notebook_introduction.ipynb cython_extension.ipynb rmagic_extension.ipynb\r\n",
79 "display_protocol.ipynb sympy.ipynb"
93 "Animations_and_Progress.ipynb display_protocol.ipynb sympy.ipynb\r\n",
94 "Capturing Output.ipynb formatting.ipynb sympy_quantum_computing.ipynb\r\n",
95 "Script Magics.ipynb octavemagic_extension.ipynb trapezoid_rule.ipynb\r\n",
96 "animation.m4v progbar.ipynb\r\n"
80 ]
97 ]
81 }
98 }
82 ],
99 ],
83 "prompt_number": 2
100 "prompt_number": 3
84 },
101 },
85 {
102 {
86 "cell_type": "markdown",
103 "cell_type": "markdown",
104 "metadata": {},
87 "source": [
105 "source": [
88 "In a cell, you can type anything from a single python expression to an arbitrarily long amount of code ",
106 "In a cell, you can type anything from a single python expression to an arbitrarily long amount of code \n",
89 "(although for reasons of readability, you should probably limit this to a few dozen lines):"
107 "(although for reasons of readability, you should probably limit this to a few dozen lines):"
90 ]
108 ]
91 },
109 },
92 {
110 {
93 "cell_type": "code",
111 "cell_type": "code",
112 "collapsed": false,
94 "input": [
113 "input": [
95 "def f(x):",
114 "def f(x):\n",
96 " \"\"\"My function",
115 " \"\"\"My function\n",
97 " x : parameter\"\"\"",
116 " x : parameter\"\"\"\n",
98 " ",
117 " \n",
99 " return x+1",
118 " return x+1\n",
100 "",
119 "\n",
101 "print \"f(3) = \", f(3)"
120 "print \"f(3) = \", f(3)"
102 ],
121 ],
103 "language": "python",
122 "language": "python",
123 "metadata": {},
104 "outputs": [
124 "outputs": [
105 {
125 {
106 "output_type": "stream",
126 "output_type": "stream",
107 "stream": "stdout",
127 "stream": "stdout",
108 "text": [
128 "text": [
109 "f(3) = 4"
129 "f(3) = 4\n"
110 ]
130 ]
111 }
131 }
112 ],
132 ],
113 "prompt_number": 3
133 "prompt_number": 4
134 },
135 {
136 "cell_type": "heading",
137 "level": 2,
138 "metadata": {},
139 "source": [
140 "User interface"
141 ]
114 },
142 },
115 {
143 {
116 "cell_type": "markdown",
144 "cell_type": "markdown",
145 "metadata": {},
117 "source": [
146 "source": [
118 "## User interface",
147 "When you start a new notebook server with `ipython notebook`, your\n",
119 "",
148 "browser should open into the *Dashboard*, a page listing all notebooks\n",
120 "When you start a new notebook server with `ipython notebook`, your",
149 "available in the current directory as well as letting you create new\n",
121 "browser should open into the *Dashboard*, a page listing all notebooks",
150 "notebooks. In this page, you can also drag and drop existing `.py` files\n",
122 "available in the current directory as well as letting you create new",
151 "over the file list to import them as notebooks (see the manual for \n",
123 "notebooks. In this page, you can also drag and drop existing `.py` files",
152 "[further details on how these files are \n",
124 "over the file list to import them as notebooks (see the manual for ",
153 "interpreted](http://ipython.org/ipython-doc/stable/interactive/htmlnotebook.html)).\n",
125 "[further details on how these files are ",
154 "\n",
126 "interpreted](http://ipython.org/ipython-doc/stable/interactive/htmlnotebook.html)).",
155 "Once you open an existing notebook (like this one) or create a new one,\n",
127 "",
156 "you are in the main notebook interface, which consists of a main editing\n",
128 "Once you open an existing notebook (like this one) or create a new one,",
157 "area (where these cells are contained) as well as a menu and \n",
129 "you are in the main notebook interface, which consists of a main editing",
158 "permanent header area at the top, and a pager that rises from the\n",
130 "area (where these cells are contained) as well as a collapsible left panel, ",
131 "a permanent header area at the top, and a pager that rises from the",
132 "bottom when needed and can be collapsed again."
159 "bottom when needed and can be collapsed again."
133 ]
160 ]
134 },
161 },
135 {
162 {
163 "cell_type": "heading",
164 "level": 3,
165 "metadata": {},
166 "source": [
167 "Main editing area"
168 ]
169 },
170 {
136 "cell_type": "markdown",
171 "cell_type": "markdown",
172 "metadata": {},
137 "source": [
173 "source": [
138 "### Main editing area",
174 "Here, you can move with the arrow keys or using the \n",
139 "",
175 "scroll bars. The cursor enters code cells immediately, but only selects\n",
140 "Here, you can move with the arrow keys or using the ",
176 "text (markdown) cells without entering in them; to enter a text cell,\n",
141 "scroll bars. The cursor enters code cells immediately, but only selects",
177 "use `Enter` (or double-click), and `Shift-Enter` to exit it again (just like to execute a \n",
142 "text (markdown) cells without entering in them; to enter a text cell,",
143 "use `Enter`, and `Shift-Enter` to exit it again (just like to execute a ",
144 "code cell)."
178 "code cell)."
145 ]
179 ]
146 },
180 },
147 {
181 {
182 "cell_type": "heading",
183 "level": 3,
184 "metadata": {},
185 "source": [
186 "Menu"
187 ]
188 },
189 {
148 "cell_type": "markdown",
190 "cell_type": "markdown",
191 "metadata": {},
192 "source": [
193 "The menu bar conains all the commands you can use to manipulate the notebook.\n",
194 "\n",
195 "The *File* menu has the usual open/save file operations, as well as Export,\n",
196 "for downloading the notebook to your computer.\n",
197 "\n",
198 "*Edit* has controls for cut/copy/paste, and moving cells around.\n",
199 "\n",
200 "*View* lets you toggle visibility of the header elements,\n",
201 "to recover precious screen real estate.\n",
202 "\n",
203 "The *Cell* menu lets you manipulate individual cells,\n",
204 "and the names should be fairly self-explanatory.\n",
205 "\n",
206 "The *Kernel* menu lets you signal the kernel executing your code. \n",
207 "`Interrupt` does the equivalent of hitting `Ctrl-C` at a terminal, and\n",
208 "`Restart` fully kills the kernel process and starts a fresh one. Obviously\n",
209 "this means that all your previous variables are destroyed, but it also\n",
210 "makes it easy to get a fresh kernel in which to re-execute a notebook, perhaps\n",
211 "after changing an extension module for which Python's `reload` mechanism\n",
212 "does not work.\n",
213 "\n",
214 "The *Help* menu contains links to the documentation of some projects\n",
215 "closely related to IPython as well as the minimal keybindings you need to\n",
216 "know. But you should use `Ctrl-m h` (or click the `QuickHelp` button at\n",
217 "the top) and learn some of the other keybindings, as it will make your \n",
218 "workflow much more fluid and efficient.\n",
219 "\n",
220 "You will also see a few buttons there for common actions,\n",
221 "and hovering over each button will tell you which command they correspond to,\n",
222 "if the icons are not clear enough."
223 ]
224 },
225 {
226 "cell_type": "heading",
227 "level": 3,
228 "metadata": {},
149 "source": [
229 "source": [
150 "### Left panel",
230 "Header bar"
151 "",
152 "This panel contains a number of panes that can be",
153 "collapsed vertically by clicking on their title bar, and the whole panel",
154 "can also be collapsed by clicking on the vertical divider (note that you",
155 "can not *drag* the divider, for now you can only click on it).",
156 "",
157 "The *Notebook* section contains actions that pertain to the whole notebook,",
158 "such as downloading the current notebook either in its original format",
159 "or as a `.py` script, and printing it. When you click the `Print` button,",
160 "a new HTML page opens with a static copy of the notebook; you can then",
161 "use your web browser's mechanisms to save or print this file.",
162 "",
163 "The *Cell* section lets you manipulate individual cells, and the names should ",
164 "be fairly self-explanatory.",
165 "",
166 "The *Kernel* section lets you signal the kernel executing your code. ",
167 "`Interrupt` does the equivalent of hitting `Ctrl-C` at a terminal, and",
168 "`Restart` fully kills the kernel process and starts a fresh one. Obviously",
169 "this means that all your previous variables are destroyed, but it also",
170 "makes it easy to get a fresh kernel in which to re-execute a notebook, perhaps",
171 "after changing an extension module for which Python's `reload` mechanism",
172 "does not work. If you check the 'Kill kernel upon exit' box, when you ",
173 "close the page IPython will automatically shut down the running kernel;",
174 "otherwise the kernels won't close until you stop the whole ",
175 "",
176 "The *Help* section contains links to the documentation of some projects",
177 "closely related to IPython as well as the minimal keybindings you need to",
178 "know. But you should use `Ctrl-m h` (or click the `QuickHelp` button at",
179 "the top) and learn some of the other keybindings, as it will make your ",
180 "workflow much more fluid and efficient."
181 ]
231 ]
182 },
232 },
183 {
233 {
184 "cell_type": "markdown",
234 "cell_type": "markdown",
235 "metadata": {},
185 "source": [
236 "source": [
186 "### Header bar",
237 "The header area at the top allows you to rename an existing \n",
187 "",
238 "notebook and open up a short help tooltip. This area also indicates\n",
188 "The header area at the top allows you to rename an existing ",
239 "with a red **Busy** mark on the right whenever the kernel is busy executing\n",
189 "notebook and open up a short help tooltip. This area also indicates",
190 "with a red **Busy** mark on the right whenever the kernel is busy executing",
191 "code."
240 "code."
192 ]
241 ]
193 },
242 },
194 {
243 {
244 "cell_type": "heading",
245 "level": 3,
246 "metadata": {},
247 "source": [
248 "The pager at the bottom"
249 ]
250 },
251 {
195 "cell_type": "markdown",
252 "cell_type": "markdown",
253 "metadata": {},
196 "source": [
254 "source": [
197 "### The pager at the bottom",
255 "Whenever IPython needs to display additional \n",
198 "",
256 "information, such as when you type `somefunction?` in a cell, the notebook\n",
199 "Whenever IPython needs to display additional ",
257 "opens a pane at the bottom where this information is shown. You can keep\n",
200 "information, such as when you type `somefunction?` in a cell, the notebook",
258 "this pager pane open for reference (it doesn't block input in the main area)\n",
201 "opens a pane at the bottom where this information is shown. You can keep",
202 "this pager pane open for reference (it doesn't block input in the main area)",
203 "or dismiss it by clicking on its divider bar."
259 "or dismiss it by clicking on its divider bar."
204 ]
260 ]
205 },
261 },
206 {
262 {
263 "cell_type": "heading",
264 "level": 3,
265 "metadata": {},
266 "source": [
267 "Tab completion and tooltips"
268 ]
269 },
270 {
207 "cell_type": "markdown",
271 "cell_type": "markdown",
272 "metadata": {},
208 "source": [
273 "source": [
209 "### Tab completion and tooltips",
274 "The notebook uses the same underlying machinery for tab completion that \n",
210 "",
275 "IPython uses at the terminal, but displays the information differently.\n",
211 "The notebook uses the same underlying machinery for tab completion that ",
276 "Whey you complete with the `Tab` key, IPython shows a drop list with all\n",
212 "IPython uses at the terminal, but displays the information differently.",
277 "available completions. If you type more characters while this list is open,\n",
213 "Whey you complete with the `Tab` key, IPython shows a drop list with all",
278 "IPython automatically eliminates from the list options that don't match the\n",
214 "available completions. If you type more characters while this list is open,",
279 "new characters; once there is only one option left you can hit `Tab` once\n",
215 "IPython automatically eliminates from the list options that don't match the",
280 "more (or `Enter`) to complete. You can also select the completion you\n",
216 "new characters; once there is only one option left you can hit `Tab` once",
281 "want with the arrow keys or the mouse, and then hit `Enter`.\n",
217 "more (or `Enter`) to complete. You can also select the completion you",
282 "\n",
218 "want with the arrow keys or the mouse, and then hit `Enter`.",
283 "In addition, if you hit `Tab` inside of open parentheses, IPython will \n",
219 "",
284 "search for the docstring of the last object left of the parens and will\n",
220 "In addition, if you hit `Tab` inside of open parentheses, IPython will ",
285 "display it on a tooltip. For example, type `list(<TAB>` and you will\n",
221 "search for the docstring of the last object left of the parens and will",
222 "display it on a tooltip. For example, type `list(<TAB>` and you will",
223 "see the docstring for the builtin `list` constructor:"
286 "see the docstring for the builtin `list` constructor:"
224 ]
287 ]
225 },
288 },
226 {
289 {
227 "cell_type": "code",
290 "cell_type": "code",
291 "collapsed": false,
228 "input": [
292 "input": [
229 "# Position your cursor after the ( and hit the Tab key:",
293 "# Position your cursor after the ( and hit the Tab key:\n",
230 "range("
294 "range("
231 ],
295 ],
232 "language": "python",
296 "language": "python",
297 "metadata": {},
233 "outputs": []
298 "outputs": []
234 },
299 },
235 {
300 {
236 "cell_type": "markdown",
301 "cell_type": "markdown",
302 "metadata": {},
237 "source": [
303 "source": [
238 "More over pressing tab several time in a row allows you change the behaviour of the tooltip.",
304 "Moreover, pressing tab several time in a row allows you change the behaviour of the tooltip.\n",
239 "",
305 "\n",
240 "* firt `tab` press, you get a classical tooltip",
306 "* first `tab` press, you get a classical tooltip\n",
241 "* second time, the tooltip grow vertically, and allow you to scroll the docstring",
307 "* second tab, the tooltip grow vertically, and allow you to scroll the docstring\n",
242 "* third tab press, tooltip, will be made sticky for 10 seconds, allowing you to carry on typing while it stays open.",
308 "* third tab, tooltip will be made sticky for 10 seconds, allowing you to carry on typing while it stays open.\n",
243 "* forth time press, the tooltip help is sent to the pager at the bottom of the screen , and is dismiss.",
309 "* forth tab, the tooltip help is sent to the pager at the bottom of the screen.\n",
244 "<script>",
310 "<script>\n",
245 " IPython.tooltip.tabs_functions = [ function(cell,text){",
311 " IPython.tooltip.tabs_functions = [ function(cell,text){\n",
246 " IPython.tooltip._request_tooltip(cell,text);",
312 " IPython.tooltip._request_tooltip(cell,text);\n",
247 " IPython.notification_widget.set_message('tab again to expand pager',2500);",
313 " IPython.notification_widget.set_message('tab again to expand pager',2500);\n",
248 " setTimeout(function(){",
314 " setTimeout(function(){\n",
249 " $('.tooltiptext pre').text(\"function signture : You've invoked a tooltip !\\n\\nWell done! Here usualy lies the current function *call signature* and it's *docstring*. You can now expand the tooltip pressing <tab> a second time...\")},400);",
315 " $('.tooltiptext pre').text(\"function signture : You've invoked a tooltip !\\n\\nWell done! Here usualy lies the current function *call signature* and it's *docstring*. You can now expand the tooltip pressing <tab> a second time...\")},400);\n",
250 " },",
316 " },\n",
251 " function(){",
317 " function(){\n",
252 " IPython.tooltip.expand();",
318 " IPython.tooltip.expand();\n",
253 " IPython.notification_widget.set_message('tab again to make pager sticky for 10s',2500);",
319 " IPython.notification_widget.set_message('tab again to make pager sticky for 10s',2500);\n",
254 " setTimeout(function(){",
320 " setTimeout(function(){\n",
255 " $('.tooltiptext pre').text(\"Now the tooltip is expanded !\\",
321 " $('.tooltiptext pre').text(\"Now the tooltip is expanded !\\\n",
256 " \\n\\nThis is really usefull if you have long docstring and if you want to be able to scroll them. \\",
322 " \\n\\nThis is really usefull if you have long docstring and if you want to be able to scroll them. \\\n",
257 "For example, I can give you many information about the tooltip:\\n - The tooltip is smart, and \\",
323 "For example, I can give you many information about the tooltip:\\n - The tooltip is smart, and \\\n",
258 "you don't always need to press tab to invoke it, if you press an opening bracket `(` then nothing \\",
324 "you don't always need to press tab to invoke it, if you press an opening bracket `(` then nothing \\\n",
259 "for some time, tooltip will be invoked by itself.\\",
325 "for some time, tooltip will be invoked by itself.\\\n",
260 "\\n - Also you can hoover over the icon on the top right to know what they are dooing...\\",
326 "\\n - Also you can hoover over the icon on the top right to know what they are dooing...\\\n",
261 "\\n\\nBack to the next lesson.\\n\\nSometime you need to the tooltip to stay on screen while\\",
327 "\\n\\nBack to the next lesson.\\n\\nSometime you need to the tooltip to stay on screen while\\\n",
262 "you type. That's the reason for the sticky mode (indicated by a small clock on the top left of the tooltip),\\",
328 "you type. That's the reason for the sticky mode (indicated by a small clock on the top left of the tooltip),\\\n",
263 "\\n\\nNow press <tab> a 3rd time and continue typing some text to test it...\")",
329 "\\n\\nNow press <tab> a 3rd time and continue typing some text to test it...\")\n",
264 " },400);",
330 " },400);\n",
265 " },",
331 " },\n",
266 " function(){",
332 " function(){\n",
267 " var time = 35;",
333 " var time = 35;\n",
268 " IPython.tooltip.stick(time);",
334 " IPython.tooltip.stick(time);\n",
269 " $('.tooltiptext pre').text(\"Type more text !...\\n\\n range(7,125,3)\\n\\n The tooltip is in sticky mode, it won't be dismissed for at least 10 secondes \",400);",
335 " $('.tooltiptext pre').text(\"Type more text !...\\n\\n range(7,125,3)\\n\\n The tooltip is in sticky mode, it won't be dismissed for at least 10 secondes \",400);\n",
270 " setTimeout(function(){",
336 " setTimeout(function(){\n",
271 " $('.tooltiptext pre').text(\"That was sticky mode...\\nI'll keep it on 15 more seconds just for you.\\n\\nLast thing you can do is send the current help displayed in the tooltip to the pager at the bottom of the screen. To do that, press tab 4 time in a row after a parenthesis. \\n\\n Now I'll stop bothering you and let you Play with the tooltip !\");",
337 " $('.tooltiptext pre').text(\"That was sticky mode...\\nI'll keep it on 15 more seconds just for you.\\n\\nLast thing you can do is send the current help displayed in the tooltip to the pager at the bottom of the screen. To do that, press tab 4 time in a row after a parenthesis. \\n\\n Now I'll stop bothering you and let you Play with the tooltip !\");\n",
272 " reset_tooltip()",
338 " reset_tooltip()\n",
273 " },15000);",
339 " },15000);\n",
274 " },",
340 " },\n",
275 " function(cell){",
341 " function(cell){\n",
276 " IPython.tooltip.cancel_stick();",
342 " IPython.tooltip.cancel_stick();\n",
277 " reset_tooltip()",
343 " reset_tooltip()\n",
278 " IPython.tooltip.showInPager(cell);",
344 " IPython.tooltip.showInPager(cell);\n",
279 " IPython.tooltip._cmfocus();",
345 " IPython.tooltip._cmfocus();\n",
280 " }",
346 " }\n",
281 " ];",
347 " ];\n",
282 " ",
348 " \n",
283 " reset_tooltip = function(){",
349 " reset_tooltip = function(){\n",
284 " IPython.tooltip.tabs_functions = [ function(cell,text){",
350 " IPython.tooltip.tabs_functions = [ function(cell,text){\n",
285 " IPython.tooltip._request_tooltip(cell,text);",
351 " IPython.tooltip._request_tooltip(cell,text);\n",
286 " IPython.notification_widget.set_message('tab again to expand pager',2500);",
352 " IPython.notification_widget.set_message('tab again to expand pager',2500);\n",
287 " },",
353 " },\n",
288 " function(){",
354 " function(){\n",
289 " IPython.tooltip.expand();",
355 " IPython.tooltip.expand();\n",
290 " IPython.notification_widget.set_message('tab again to make pager sticky for 10s',2500);",
356 " IPython.notification_widget.set_message('tab again to make pager sticky for 10s',2500);\n",
291 " },",
357 " },\n",
292 " function(){",
358 " function(){\n",
293 " IPython.tooltip.stick();",
359 " IPython.tooltip.stick();\n",
294 " IPython.notification_widget.set_message('tab again to open help in pager',2500);",
360 " IPython.notification_widget.set_message('tab again to open help in pager',2500);\n",
295 " },",
361 " },\n",
296 " function(cell){",
362 " function(cell){\n",
297 " IPython.tooltip.cancel_stick();",
363 " IPython.tooltip.cancel_stick();\n",
298 " IPython.tooltip.showInPager(cell);",
364 " IPython.tooltip.showInPager(cell);\n",
299 " IPython.tooltip._cmfocus();",
365 " IPython.tooltip._cmfocus();\n",
300 " }",
366 " }\n",
301 " ];",
367 " ];\n",
302 " }",
368 " }\n",
303 "</script>"
369 "</script>"
304 ]
370 ]
305 },
371 },
306 {
372 {
373 "cell_type": "heading",
374 "level": 2,
375 "metadata": {},
376 "source": [
377 "The frontend/kernel model"
378 ]
379 },
380 {
307 "cell_type": "markdown",
381 "cell_type": "markdown",
382 "metadata": {},
308 "source": [
383 "source": [
309 "## The frontend/kernel model",
384 "The IPython notebook works on a client/server model where an *IPython kernel*\n",
310 "",
385 "starts in a separate process and acts as a server to executes the code you type,\n",
311 "The IPython notebook works on a client/server model where an *IPython kernel*",
386 "while the web browser provides acts as a client, providing a front end environment\n",
312 "starts in a separate process and acts as a server to executes the code you type,",
387 "for you to type. But one kernel is capable of simultaneously talking to more than\n",
313 "while the web browser provides acts as a client, providing a front end environment",
388 "one client, and they do not all need to be of the same kind. All IPython frontends\n",
314 "for you to type. But one kernel is capable of simultaneously talking to more than",
389 "are capable of communicating with a kernel, and any number of them can be active\n",
315 "one client, and they do not all need to be of the same kind. All IPython frontends",
390 "at the same time. In addition to allowing you to have, for example, more than one\n",
316 "are capable of communicating with a kernel, and any number of them can be active",
391 "browser session active, this lets you connect clients with different user interface features.\n",
317 "at the same time. In addition to allowing you to have, for example, more than one",
392 "\n",
318 "browser session active, this lets you connect clients with different user interface features.",
393 "For example, you may want to connect a Qt console to your kernel and use it as a help\n",
319 "",
394 "browser, calling `??` on objects in the Qt console (whose pager is more flexible than the\n",
320 "For example, you may want to connect a Qt console to your kernel and use it as a help",
395 "one in the notebook). You can start a new Qt console connected to your current kernel by \n",
321 "browser, calling `??` on objects in the Qt console (whose pager is more flexible than the",
396 "using the `%qtconsole` magic, this will automatically detect the necessary connection\n",
322 "one in the notebook). You can start a new Qt console connected to your current kernel by ",
397 "information.\n",
323 "using the `%qtconsole` magic, this will automatically detect the necessary connection",
398 "\n",
324 "information.",
399 "If you want to open one manually, or want to open a text console from a terminal, you can \n",
325 "",
326 "If you want to open one manually, or want to open a text console from a terminal, you can ",
327 "get your kernel's connection information with the `%connect_info` magic:"
400 "get your kernel's connection information with the `%connect_info` magic:"
328 ]
401 ]
329 },
402 },
330 {
403 {
331 "cell_type": "code",
404 "cell_type": "code",
405 "collapsed": false,
332 "input": [
406 "input": [
333 "%connect_info"
407 "%connect_info"
334 ],
408 ],
335 "language": "python",
409 "language": "python",
410 "metadata": {},
336 "outputs": [
411 "outputs": [
337 {
412 {
338 "output_type": "stream",
413 "output_type": "stream",
339 "stream": "stdout",
414 "stream": "stdout",
340 "text": [
415 "text": [
341 "{",
416 "{\n",
342 " \"stdin_port\": 53970, ",
417 " \"stdin_port\": 52858, \n",
343 " \"ip\": \"127.0.0.1\", ",
418 " \"ip\": \"127.0.0.1\", \n",
344 " \"hb_port\": 53971, ",
419 " \"hb_port\": 52859, \n",
345 " \"key\": \"30daac61-6b73-4bae-a7d9-9dca538794d5\", ",
420 " \"key\": \"7efd45ca-d8a2-41b0-9cea-d9116d0fb883\", \n",
346 " \"shell_port\": 53968, ",
421 " \"shell_port\": 52856, \n",
347 " \"iopub_port\": 53969",
422 " \"iopub_port\": 52857\n",
348 "}",
423 "}\n",
349 "",
424 "\n",
350 "Paste the above JSON into a file, and connect with:",
425 "Paste the above JSON into a file, and connect with:\n",
351 " $> ipython <app> --existing <file>",
426 " $> ipython <app> --existing <file>\n",
352 "or, if you are local, you can connect with just:",
427 "or, if you are local, you can connect with just:\n",
353 " $> ipython <app> --existing kernel-dd85d1cc-c335-44f4-bed8-f1a2173a819a.json ",
428 " $> ipython <app> --existing kernel-b3bac7c1-8b2c-4536-8082-8d1df24f99ac.json \n",
354 "or even just:",
429 "or even just:\n",
355 " $> ipython <app> --existing ",
430 " $> ipython <app> --existing \n",
356 "if this is the most recent IPython session you have started."
431 "if this is the most recent IPython session you have started.\n"
357 ]
432 ]
358 }
433 }
359 ],
434 ],
360 "prompt_number": 4
435 "prompt_number": 6
436 },
437 {
438 "cell_type": "heading",
439 "level": 2,
440 "metadata": {},
441 "source": [
442 "The kernel's `raw_input` and `%debug`"
443 ]
361 },
444 },
362 {
445 {
363 "cell_type": "markdown",
446 "cell_type": "markdown",
447 "metadata": {},
364 "source": [
448 "source": [
365 "## The kernel's `raw_input` and `%debug`",
449 "The one feature the notebook currently doesn't support as a client is the ability to send data to the kernel's\n",
366 "",
450 "standard input socket. That is, if the kernel requires information to be typed interactively by calling the\n",
367 "The one feature the notebook currently doesn't support as a client is the ability to send data to the kernel's",
451 "builtin `raw_input` function, the notebook will be blocked. This happens for example if you run a script\n",
368 "standard input socket. That is, if the kernel requires information to be typed interactively by calling the",
452 "that queries interactively for parameters, and very importantly, is how the interactive IPython debugger that \n",
369 "builtin `raw_input` function, the notebook will be blocked. This happens for example if you run a script",
453 "activates when you type `%debug` works.\n",
370 "that queries interactively for parameters, and very importantly, is how the interactive IPython debugger that ",
454 "\n",
371 "activates when you type `%debug` works.",
455 "So, in order to be able to use `%debug` or anything else that requires `raw_input`, you can either use a Qt \n",
372 "",
456 "console or a terminal console:\n",
373 "So, in order to be able to use `%debug` or anything else that requires `raw_input`, you can either use a Qt ",
457 "\n",
374 "console or a terminal console:",
458 "- From the notebook, typing `%qtconsole` finds all the necessary connection data for you.\n",
375 "",
459 "- From the terminal, first type `%connect_info` while still in the notebook, and then copy and paste the \n",
376 "- From the notebook, typing `%qtconsole` finds all the necessary connection data for you.",
377 "- From the terminal, first type `%connect_info` while still in the notebook, and then copy and paste the ",
378 "resulting information, using `qtconsole` or `console` depending on which type of client you want."
460 "resulting information, using `qtconsole` or `console` depending on which type of client you want."
379 ]
461 ]
380 },
462 },
381 {
463 {
464 "cell_type": "heading",
465 "level": 2,
466 "metadata": {},
467 "source": [
468 "Display of complex objects"
469 ]
470 },
471 {
382 "cell_type": "markdown",
472 "cell_type": "markdown",
473 "metadata": {},
383 "source": [
474 "source": [
384 "## Display of complex objects",
475 "As the 'tour' notebook shows, the IPython notebook has fairly sophisticated display capabilities. In addition\n",
385 "",
476 "to the examples there, you can study the `display_protocol` notebook in this same examples folder, to \n",
386 "As the 'tour' notebook shows, the IPython notebook has fairly sophisticated display capabilities. In addition",
477 "learn how to customize arbitrary objects (in your own code or external libraries) to display in the notebook\n",
387 "to the examples there, you can study the `display_protocol` notebook in this same examples folder, to ",
388 "learn how to customize arbitrary objects (in your own code or external libraries) to display in the notebook",
389 "in any way you want, including graphical forms or mathematical expressions."
478 "in any way you want, including graphical forms or mathematical expressions."
390 ]
479 ]
391 },
480 },
392 {
481 {
482 "cell_type": "heading",
483 "level": 2,
484 "metadata": {},
485 "source": [
486 "Plotting support"
487 ]
488 },
489 {
393 "cell_type": "markdown",
490 "cell_type": "markdown",
491 "metadata": {},
394 "source": [
492 "source": [
395 "## Plotting support",
493 "As we've explained already, the notebook is just another frontend talking to the same IPython kernel that\n",
396 "",
494 "you're familiar with, so the same options for plotting support apply.\n",
397 "As we've explained already, the notebook is just another frontend talking to the same IPython kernel that",
495 "\n",
398 "you're already familiar with, so the same options for plotting support apply.",
496 "You can enable inline plotting with `%pylab inline`:"
399 "",
400 "If you start the notebook with `--pylab`, you will get matplotlib's floating, interactive windows and you",
401 "can call the `display` function to paste figures into the notebook document. If you start it with ",
402 "`--pylab inline`, all plots will appear inline automatically. In this regard, the notebook works identically",
403 "to the Qt console.",
404 "",
405 "Note that if you start the notebook server with pylab support, *all* kernels are automatically started in",
406 "pylab mode and with the same choice of backend (i.e. floating windows or inline figures). But you can also",
407 "start the notebook server simply by typing `ipython notebook`, and then selectively turn on pylab support ",
408 "only for the notebooks you want by using the `%pylab` magic (see its docstring for details)."
409 ]
497 ]
410 },
498 },
411 {
499 {
412 "cell_type": "code",
500 "cell_type": "code",
501 "collapsed": false,
413 "input": [
502 "input": [
414 "%pylab inline",
503 "%pylab inline"
415 "plot(rand(100))"
416 ],
504 ],
417 "language": "python",
505 "language": "python",
506 "metadata": {},
418 "outputs": [
507 "outputs": [
419 {
508 {
420 "output_type": "stream",
509 "output_type": "stream",
421 "stream": "stdout",
510 "stream": "stdout",
422 "text": [
511 "text": [
423 "",
512 "\n",
424 "Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.zmq.pylab.backend_inline].",
513 "Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.zmq.pylab.backend_inline].\n",
425 "For more information, type 'help(pylab)'."
514 "For more information, type 'help(pylab)'.\n"
426 ]
515 ]
427 },
516 }
517 ],
518 "prompt_number": 7
519 },
520 {
521 "cell_type": "markdown",
522 "metadata": {},
523 "source": [
524 "If you start the notebook server itself with `--pylab`, you will get matplotlib's floating, interactive windows and you\n",
525 "can call the `display` function to paste figures into the notebook document. If you start it with \n",
526 "`--pylab inline`, all plots will appear inline automatically. In this regard, the notebook works identically\n",
527 "to the Qt console.\n",
528 "\n",
529 "Note that if you start the notebook server with pylab support, *all* kernels are automatically started in\n",
530 "pylab mode and with the same choice of backend (i.e. floating windows or inline figures).\n",
531 "For this reason, it is recommended that you\n",
532 "start the notebook server simply by typing `ipython notebook`, and then selectively turn on pylab support \n",
533 "only for the notebooks you want by using the `%pylab` magic (see its docstring for details)."
534 ]
535 },
536 {
537 "cell_type": "code",
538 "collapsed": false,
539 "input": [
540 "plot(rand(100))"
541 ],
542 "language": "python",
543 "metadata": {},
544 "outputs": [
428 {
545 {
429 "output_type": "pyout",
546 "output_type": "pyout",
430 "prompt_number": 5,
547 "prompt_number": 8,
431 "text": [
548 "text": [
432 "[<matplotlib.lines.Line2D at 0x11165bcd0>]"
549 "[<matplotlib.lines.Line2D at 0x1124ba350>]"
433 ]
550 ]
434 },
551 },
435 {
552 {
436 "output_type": "display_data",
553 "output_type": "display_data",
437 "png": "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\n"
554 "png": "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\nDVi7dm3cTUgMSqkvvv/9cPdfSn0RNmxfBIeS4OfMmYPOzs5Tnzs7O9HISRh+m66uLswRSAD+IWBh\nYWFhES6UFs3SpUuxe/dudHR0YHh4GJs3b8aqVasKtlm1ahXuu+8+AMC2bdswadIkzJw5M7wWW1hY\nWFhoQangs9ksNmzYgBUrVmB0dBTXXXcdFixYgI0bNwIA1qxZg8suuwyPPfYYmpubUV9fj3vuuSeS\nhltYWFhYuMAJGY8//rgzf/58p7m52bntttvCPlyi8P777zvLly93Fi5c6Jx11lnOnXfe6TiO4xw+\nfNi5+OKLnZaWFueSSy5xjh49GnNLo8PIyIizZMkS57Of/azjOOnti6NHjzpXXnml09ra6ixYsMDZ\ntm1bavti3bp1zsKFC51FixY511xzjTM4OJiavrj22mudGTNmOIsWLTr1nerc161b5zQ3Nzvz5893\nfve737nuP9R5ajp59OWMqqoq3HHHHXjjjTewbds2/PjHP8auXbtw22234ZJLLsHbb7+Niy66CLfd\ndlvcTY0Md955JxYuXHgq4J7WvvjGN76Byy67DLt27cJrr72G1tbWVPZFR0cHfvrTn2LHjh14/fXX\nMTo6ivvvvz81fXHttdeira2t4DvZue/cuRObN2/Gzp070dbWhq997WsYGxtTHyCUx9IHeO6555wV\nK1ac+vz973/f+f73vx/mIRONyy+/3HniiSec+fPnO/v373ccx3H27dvnzJ8/P+aWRYPOzk7noosu\ncv74xz+eUvBp7Ive3l7njDPOKPo+jX1x+PBhZ968ec6RI0ecXC7nfPazn3V+//vfp6ov9uzZU6Dg\nZee+bt26AhdkxYoVzp///GflvkNV8Dp59GlBR0cHXn75ZSxbtgwHDhw4FYieOXNmaiaGffOb38QP\nfvADVDAFTtLYF3v27MH06dNx7bXX4qMf/Siuv/56nDhxIpV9MWXKFNxyyy04/fTT0dDQgEmTJuGS\nSy5JZV9QyM597969BVmMOnwaKsHbvHeC/v5+XHnllbjzzjsxfvz4gv/LZDKp6KdHH30UM2bMwDnn\nnCNNmU1LX4yMjGDHjh342te+hh07dqC+vr7IgkhLX7z77rv44Q9/iI6ODuzduxf9/f345S9/WbBN\nWvpCBLdzd+uXUAleJ4++3JHL5XDllVfii1/8Ij7/+c8DIE/l/fv3AwD27duHGSlYbv65557Dww8/\njDPOOAPXXHMN/vjHP+KLX/xiKvuisbERjY2NOPfccwEAV111FXbs2IFZs2alri9efPFFfPzjH8fU\nqVORzWZxxRVX4M9//nMq+4JCdk/ozjliESrB6+TRlzMcx8F1112HhQsX4uabbz71/apVq3DvvfcC\nAO69995TxF/OWLduHTo7O7Fnzx7cf//9uPDCC/GLX/wilX0xa9YsNDU14e233wYAbN26FWeddRY+\n97nPpa4vWltbsW3bNgwMDMBxHGzduhULFy5MZV9QyO6JVatW4f7778fw8DD27NmD3bt347zzzlPv\nzHTAgMdjjz3mzJs3zznzzDOddevWhX24ROGZZ55xMpmMs3jxYmfJkiXOkiVLnMcff9w5fPiwc9FF\nF5V9CpgM7e3tzuc+9znHcZzU9sUrr7ziLF261Dn77LOdL3zhC05vb29q+2L9+vWn0iS/9KUvOcPD\nw6npi9WrVzuzZ892qqqqnMbGRudnP/uZ8ty/973vOWeeeaYzf/58p62tzXX/GcexNQQsLCwsyhF2\nvRYLCwuLMoUleAsLC4syhSV4CwsLizKFJXgLCwuLMoUleAsLC4syhSV4CwsLizLF/weSDoopnVla\nxAAAAABJRU5ErkJggg==\n"
438 }
555 }
439 ],
556 ],
440 "prompt_number": 5
557 "prompt_number": 8
441 },
558 },
442 {
559 {
443 "cell_type": "markdown",
560 "cell_type": "heading",
561 "level": 2,
562 "metadata": {},
444 "source": [
563 "source": [
445 "## Security",
564 "Security"
446 "",
447 "By default the notebook only listens on localhost, so it does not expose your computer to attacks coming from",
448 "the internet. By default the notebook does not require any authentication, but you can configure it to",
449 "ask for a password before allowing access to the files. ",
450 "",
451 "Furthermore, you can require the notebook to encrypt all communications by using SSL and making all connections",
452 "using the https protocol instead of plain http. This is a good idea if you decide to run your notebook on",
453 "addresses that are visible from the internet. For further details on how to configure this, see the",
454 "[security section](http://ipython.org/ipython-doc/stable/interactive/htmlnotebook.html#security) of the ",
455 "manual.",
456 "",
457 "Finally, note that you can also run a notebook with the `--read-only` flag, which lets you provide access",
458 "to your notebook documents to others without letting them execute code (which can be useful to broadcast",
459 "a computation to colleagues or students, for example). The read-only flag behaves differently depending",
460 "on whether the server has a password or not:",
461 "",
462 "- Passwordless server: users directly see all notebooks in read-only mode.",
463 "- Password-protected server: users can see all notebooks in read-only mode, but a login button is available",
464 "and once a user authenticates, he or she obtains write/execute privileges.",
465 "",
466 "The first case above makes it easy to broadcast on the fly an existing notebook by simply starting a *second* ",
467 "notebook server in the same directory as the first, but in read-only mode. This can be done without having",
468 "to configure a password first (which requires calling a hashing function and editing a configuration file)."
469 ]
565 ]
470 },
566 },
471 {
567 {
472 "cell_type": "code",
568 "cell_type": "markdown",
473 "input": [
569 "metadata": {},
474 ""
570 "source": [
475 ],
571 "By default the notebook only listens on localhost, so it does not expose your computer to attacks coming from\n",
476 "language": "python",
572 "the internet. By default the notebook does not require any authentication, but you can configure it to\n",
477 "outputs": []
573 "ask for a password before allowing access to the files. \n",
574 "\n",
575 "Furthermore, you can require the notebook to encrypt all communications by using SSL and making all connections\n",
576 "using the https protocol instead of plain http. This is a good idea if you decide to run your notebook on\n",
577 "addresses that are visible from the internet. For further details on how to configure this, see the\n",
578 "[security section](http://ipython.org/ipython-doc/stable/interactive/htmlnotebook.html#security) of the \n",
579 "manual.\n",
580 "\n",
581 "Finally, note that you can also run a notebook with the `--read-only` flag, which lets you provide access\n",
582 "to your notebook documents to others without letting them execute code (which can be useful to broadcast\n",
583 "a computation to colleagues or students, for example). The read-only flag behaves differently depending\n",
584 "on whether the server has a password or not:\n",
585 "\n",
586 "- Passwordless server: users directly see all notebooks in read-only mode.\n",
587 "- Password-protected server: users can see all notebooks in read-only mode, but a login button is available\n",
588 "and once a user authenticates, he or she obtains write/execute privileges.\n",
589 "\n",
590 "The first case above makes it easy to broadcast on the fly an existing notebook by simply starting a *second* \n",
591 "notebook server in the same directory as the first, but in read-only mode. This can be done without having\n",
592 "to configure a password first (which requires calling a hashing function and editing a configuration file).\n",
593 "\n",
594 "**NOTE:** IPython 0.13's javascript rewrite did not include read-only UI, so it does not work well.\n",
595 "Code/notebooks are still protected from unauthorized access, but the UI is not appropriately restricted."
596 ]
478 }
597 }
479 ]
598 ],
599 "metadata": {}
480 }
600 }
481 ]
601 ]
482 } No newline at end of file
602 }
@@ -3,30 +3,34 b''
3 "name": "Animations_and_Progress"
3 "name": "Animations_and_Progress"
4 },
4 },
5 "nbformat": 3,
5 "nbformat": 3,
6 "nbformat_minor": 0,
6 "worksheets": [
7 "worksheets": [
7 {
8 {
8 "cells": [
9 "cells": [
9 {
10 {
10 "cell_type": "heading",
11 "cell_type": "heading",
11 "level": 1,
12 "level": 1,
13 "metadata": {},
12 "source": [
14 "source": [
13 "Simple animations, progress bars, and clearing output"
15 "Simple animations, progress bars, and clearing output"
14 ]
16 ]
15 },
17 },
16 {
18 {
17 "cell_type": "markdown",
19 "cell_type": "markdown",
20 "metadata": {},
18 "source": [
21 "source": [
19 "Sometimes you want to print progress in-place, but don't want",
22 "Sometimes you want to print progress in-place, but don't want\n",
20 "to keep growing the output area. In terminals, there is the carriage-return",
23 "to keep growing the output area. In terminals, there is the carriage-return\n",
21 "(`'\\r'`) for overwriting a single line, but the notebook frontend does not support this",
24 "(`'\\r'`) for overwriting a single line, but the notebook frontend does not support this\n",
22 "behavior (yet).",
25 "behavior (yet).\n",
23 "",
26 "\n",
24 "What the notebook *does* support is explicit `clear_output`, and you can use this to replace previous",
27 "What the notebook *does* support is explicit `clear_output`, and you can use this to replace previous\n",
25 "output (specifying stdout/stderr or the special IPython display outputs)."
28 "output (specifying stdout/stderr or the special IPython display outputs)."
26 ]
29 ]
27 },
30 },
28 {
31 {
29 "cell_type": "markdown",
32 "cell_type": "markdown",
33 "metadata": {},
30 "source": [
34 "source": [
31 "A simple example printing our progress iterating through a list:"
35 "A simple example printing our progress iterating through a list:"
32 ]
36 ]
@@ -35,34 +39,35 b''
35 "cell_type": "code",
39 "cell_type": "code",
36 "collapsed": true,
40 "collapsed": true,
37 "input": [
41 "input": [
38 "import sys",
42 "import sys\n",
39 "import time"
43 "import time"
40 ],
44 ],
41 "language": "python",
45 "language": "python",
42 "outputs": [],
46 "metadata": {},
43 "prompt_number": 16
47 "outputs": []
44 },
48 },
45 {
49 {
46 "cell_type": "code",
50 "cell_type": "code",
47 "collapsed": false,
51 "collapsed": false,
48 "input": [
52 "input": [
49 "from IPython.core.display import clear_output",
53 "from IPython.core.display import clear_output\n",
50 "for i in range(10):",
54 "for i in range(10):\n",
51 " time.sleep(0.25)",
55 " time.sleep(0.25)\n",
52 " clear_output()",
56 " clear_output()\n",
53 " print i",
57 " print i\n",
54 " sys.stdout.flush()"
58 " sys.stdout.flush()"
55 ],
59 ],
56 "language": "python",
60 "language": "python",
57 "outputs": [],
61 "metadata": {},
58 "prompt_number": 12
62 "outputs": []
59 },
63 },
60 {
64 {
61 "cell_type": "markdown",
65 "cell_type": "markdown",
66 "metadata": {},
62 "source": [
67 "source": [
63 "The AsyncResult object has a special `wait_interactive()` method, which prints its progress interactively,",
68 "The AsyncResult object has a special `wait_interactive()` method, which prints its progress interactively,\n",
64 "so you can watch as your parallel computation completes.",
69 "so you can watch as your parallel computation completes.\n",
65 "",
70 "\n",
66 "**This example assumes you have an IPython cluster running, which you can start from the [cluster panel](/#tab2)**"
71 "**This example assumes you have an IPython cluster running, which you can start from the [cluster panel](/#tab2)**"
67 ]
72 ]
68 },
73 },
@@ -70,23 +75,24 b''
70 "cell_type": "code",
75 "cell_type": "code",
71 "collapsed": false,
76 "collapsed": false,
72 "input": [
77 "input": [
73 "from IPython import parallel",
78 "from IPython import parallel\n",
74 "rc = parallel.Client()",
79 "rc = parallel.Client()\n",
75 "view = rc.load_balanced_view()",
80 "view = rc.load_balanced_view()\n",
76 "",
81 "\n",
77 "amr = view.map_async(time.sleep, [0.5]*100)",
82 "amr = view.map_async(time.sleep, [0.5]*100)\n",
78 "",
83 "\n",
79 "amr.wait_interactive()"
84 "amr.wait_interactive()"
80 ],
85 ],
81 "language": "python",
86 "language": "python",
82 "outputs": [],
87 "metadata": {},
83 "prompt_number": 13
88 "outputs": []
84 },
89 },
85 {
90 {
86 "cell_type": "markdown",
91 "cell_type": "markdown",
92 "metadata": {},
87 "source": [
93 "source": [
88 "You can also use `clear_output()` to clear figures and plots.",
94 "You can also use `clear_output()` to clear figures and plots.\n",
89 "",
95 "\n",
90 "This time, we need to make sure we are using inline pylab (**requires matplotlib**)"
96 "This time, we need to make sure we are using inline pylab (**requires matplotlib**)"
91 ]
97 ]
92 },
98 },
@@ -97,63 +103,47 b''
97 "%pylab inline"
103 "%pylab inline"
98 ],
104 ],
99 "language": "python",
105 "language": "python",
100 "outputs": [
106 "metadata": {},
101 {
107 "outputs": []
102 "output_type": "stream",
103 "stream": "stdout",
104 "text": [
105 "",
106 "Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.zmq.pylab.backend_inline].",
107 "For more information, type 'help(pylab)'."
108 ]
109 }
110 ],
111 "prompt_number": 17
112 },
108 },
113 {
109 {
114 "cell_type": "code",
110 "cell_type": "code",
115 "collapsed": false,
111 "collapsed": false,
116 "input": [
112 "input": [
117 "from scipy.special import jn",
113 "from scipy.special import jn\n",
118 "x = np.linspace(0,5)",
114 "x = np.linspace(0,5)\n",
119 "f, ax = plt.subplots()",
115 "f, ax = plt.subplots()\n",
120 "ax.set_title(\"Bessel functions\")",
116 "ax.set_title(\"Bessel functions\")\n",
121 "",
117 "\n",
122 "for n in range(1,10):",
118 "for n in range(1,10):\n",
123 " time.sleep(1)",
119 " time.sleep(1)\n",
124 " ax.plot(x, jn(x,n))",
120 " ax.plot(x, jn(x,n))\n",
125 " clear_output()",
121 " clear_output()\n",
126 " display(f)",
122 " display(f)\n",
127 "",
123 "\n",
128 "# close the figure at the end, so we don't get a duplicate",
124 "# close the figure at the end, so we don't get a duplicate\n",
129 "# of the last plot",
125 "# of the last plot\n",
130 "plt.close()"
126 "plt.close()"
131 ],
127 ],
132 "language": "python",
128 "language": "python",
133 "outputs": [
129 "metadata": {},
134 {
130 "outputs": []
135 "output_type": "display_data",
136 "png": "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\nYII=\n",
137 "text": [
138 "<matplotlib.figure.Figure at 0x1083272d0>"
139 ]
140 }
141 ],
142 "prompt_number": 20
143 },
131 },
144 {
132 {
145 "cell_type": "heading",
133 "cell_type": "heading",
146 "level": 2,
134 "level": 2,
135 "metadata": {},
147 "source": [
136 "source": [
148 "A Javascript Progress Bar"
137 "A Javascript Progress Bar"
149 ]
138 ]
150 },
139 },
151 {
140 {
152 "cell_type": "markdown",
141 "cell_type": "markdown",
142 "metadata": {},
153 "source": [
143 "source": [
154 "`clear_output()` is still something of a hack, and if you want to do a progress bar in the notebook",
144 "`clear_output()` is still something of a hack, and if you want to do a progress bar in the notebook\n",
155 "it is better to just use Javascript/HTML if you can.",
145 "it is better to just use Javascript/HTML if you can.\n",
156 "",
146 "\n",
157 "Here is a simple progress bar using HTML/Javascript:"
147 "Here is a simple progress bar using HTML/Javascript:"
158 ]
148 ]
159 },
149 },
@@ -161,47 +151,50 b''
161 "cell_type": "code",
151 "cell_type": "code",
162 "collapsed": false,
152 "collapsed": false,
163 "input": [
153 "input": [
164 "import uuid",
154 "import uuid\n",
165 "from IPython.core.display import HTML, Javascript, display",
155 "from IPython.core.display import HTML, Javascript, display\n",
166 "",
156 "\n",
167 "divid = str(uuid.uuid4())",
157 "divid = str(uuid.uuid4())\n",
168 "",
158 "\n",
169 "pb = HTML(",
159 "pb = HTML(\n",
170 "\"\"\"",
160 "\"\"\"\n",
171 "<div style=\"border: 1px solid black; width:500px\">",
161 "<div style=\"border: 1px solid black; width:500px\">\n",
172 " <div id=\"%s\" style=\"background-color:blue; width:0%%\">&nbsp;</div>",
162 " <div id=\"%s\" style=\"background-color:blue; width:0%%\">&nbsp;</div>\n",
173 "</div> ",
163 "</div> \n",
174 "\"\"\" % divid)",
164 "\"\"\" % divid)\n",
175 "display(pb)",
165 "display(pb)\n",
176 "for i in range(1,101):",
166 "for i in range(1,101):\n",
177 " time.sleep(0.1)",
167 " time.sleep(0.1)\n",
178 " ",
168 " \n",
179 " display(Javascript(\"$('div#%s').width('%i%%')\" % (divid, i)))"
169 " display(Javascript(\"$('div#%s').width('%i%%')\" % (divid, i)))"
180 ],
170 ],
181 "language": "python",
171 "language": "python",
182 "outputs": [],
172 "metadata": {},
183 "prompt_number": 15
173 "outputs": []
184 },
174 },
185 {
175 {
186 "cell_type": "markdown",
176 "cell_type": "markdown",
177 "metadata": {},
187 "source": [
178 "source": [
188 "The above simply makes a div that is a box, and a blue div inside it with a unique ID ",
179 "The above simply makes a div that is a box, and a blue div inside it with a unique ID \n",
189 "(so that the javascript won't collide with other similar progress bars on the same page). ",
180 "(so that the javascript won't collide with other similar progress bars on the same page). \n",
190 "",
181 "\n",
191 "Then, at every progress point, we run a simple jQuery call to resize the blue box to",
182 "Then, at every progress point, we run a simple jQuery call to resize the blue box to\n",
192 "the appropriate fraction of the width of its containing box, and voil\u00e0 a nice",
183 "the appropriate fraction of the width of its containing box, and voil\u00e0 a nice\n",
193 "HTML/Javascript progress bar!"
184 "HTML/Javascript progress bar!"
194 ]
185 ]
195 },
186 },
196 {
187 {
197 "cell_type": "heading",
188 "cell_type": "heading",
198 "level": 2,
189 "level": 2,
190 "metadata": {},
199 "source": [
191 "source": [
200 "ProgressBar class"
192 "ProgressBar class"
201 ]
193 ]
202 },
194 },
203 {
195 {
204 "cell_type": "markdown",
196 "cell_type": "markdown",
197 "metadata": {},
205 "source": [
198 "source": [
206 "And finally, here is a progress bar *class* extracted from [PyMC](http://code.google.com/p/pymc/), which will work in regular Python as well as in the IPython Notebook"
199 "And finally, here is a progress bar *class* extracted from [PyMC](http://code.google.com/p/pymc/), which will work in regular Python as well as in the IPython Notebook"
207 ]
200 ]
@@ -210,65 +203,73 b''
210 "cell_type": "code",
203 "cell_type": "code",
211 "collapsed": true,
204 "collapsed": true,
212 "input": [
205 "input": [
213 "import sys, time",
206 "import sys, time\n",
214 "try:",
207 "try:\n",
215 " from IPython.core.display import clear_output",
208 " from IPython.core.display import clear_output\n",
216 " have_ipython = True",
209 " have_ipython = True\n",
217 "except ImportError:",
210 "except ImportError:\n",
218 " have_ipython = False",
211 " have_ipython = False\n",
219 "",
212 "\n",
220 "class ProgressBar:",
213 "class ProgressBar:\n",
221 " def __init__(self, iterations):",
214 " def __init__(self, iterations):\n",
222 " self.iterations = iterations",
215 " self.iterations = iterations\n",
223 " self.prog_bar = '[]'",
216 " self.prog_bar = '[]'\n",
224 " self.fill_char = '*'",
217 " self.fill_char = '*'\n",
225 " self.width = 40",
218 " self.width = 40\n",
226 " self.__update_amount(0)",
219 " self.__update_amount(0)\n",
227 " if have_ipython:",
220 " if have_ipython:\n",
228 " self.animate = self.animate_ipython",
221 " self.animate = self.animate_ipython\n",
229 " else:",
222 " else:\n",
230 " self.animate = self.animate_noipython",
223 " self.animate = self.animate_noipython\n",
231 "",
224 "\n",
232 " def animate_ipython(self, iter):",
225 " def animate_ipython(self, iter):\n",
233 " clear_output()",
226 " print '\\r', self,\n",
234 " print '\\r', self,",
227 " sys.stdout.flush()\n",
235 " sys.stdout.flush()",
228 " self.update_iteration(iter + 1)\n",
236 " self.update_iteration(iter + 1)",
229 "\n",
237 "",
230 " def update_iteration(self, elapsed_iter):\n",
238 " def update_iteration(self, elapsed_iter):",
231 " self.__update_amount((elapsed_iter / float(self.iterations)) * 100.0)\n",
239 " self.__update_amount((elapsed_iter / float(self.iterations)) * 100.0)",
232 " self.prog_bar += ' %d of %s complete' % (elapsed_iter, self.iterations)\n",
240 " self.prog_bar += ' %d of %s complete' % (elapsed_iter, self.iterations)",
233 "\n",
241 "",
234 " def __update_amount(self, new_amount):\n",
242 " def __update_amount(self, new_amount):",
235 " percent_done = int(round((new_amount / 100.0) * 100.0))\n",
243 " percent_done = int(round((new_amount / 100.0) * 100.0))",
236 " all_full = self.width - 2\n",
244 " all_full = self.width - 2",
237 " num_hashes = int(round((percent_done / 100.0) * all_full))\n",
245 " num_hashes = int(round((percent_done / 100.0) * all_full))",
238 " self.prog_bar = '[' + self.fill_char * num_hashes + ' ' * (all_full - num_hashes) + ']'\n",
246 " self.prog_bar = '[' + self.fill_char * num_hashes + ' ' * (all_full - num_hashes) + ']'",
239 " pct_place = (len(self.prog_bar) // 2) - len(str(percent_done))\n",
247 " pct_place = (len(self.prog_bar) // 2) - len(str(percent_done))",
240 " pct_string = '%d%%' % percent_done\n",
248 " pct_string = '%d%%' % percent_done",
241 " self.prog_bar = self.prog_bar[0:pct_place] + \\\n",
249 " self.prog_bar = self.prog_bar[0:pct_place] + \\",
242 " (pct_string + self.prog_bar[pct_place + len(pct_string):])\n",
250 " (pct_string + self.prog_bar[pct_place + len(pct_string):])",
243 "\n",
251 "",
244 " def __str__(self):\n",
252 " def __str__(self):",
253 " return str(self.prog_bar)"
245 " return str(self.prog_bar)"
254 ],
246 ],
255 "language": "python",
247 "language": "python",
256 "outputs": [],
248 "metadata": {},
257 "prompt_number": 10
249 "outputs": []
258 },
250 },
259 {
251 {
260 "cell_type": "code",
252 "cell_type": "code",
261 "collapsed": false,
253 "collapsed": false,
262 "input": [
254 "input": [
263 "p = ProgressBar(1000)",
255 "p = ProgressBar(1000)\n",
264 "for i in range(1001):",
256 "for i in range(1001):\n",
265 " p.animate(i)"
257 " p.animate(i)"
266 ],
258 ],
267 "language": "python",
259 "language": "python",
268 "outputs": [],
260 "metadata": {},
269 "prompt_number": 11
261 "outputs": []
262 },
263 {
264 "cell_type": "code",
265 "collapsed": false,
266 "input": [],
267 "language": "python",
268 "metadata": {},
269 "outputs": []
270 }
270 }
271 ]
271 ],
272 "metadata": {}
272 }
273 }
273 ]
274 ]
274 } No newline at end of file
275 }
@@ -3,180 +3,207 b''
3 "name": "Capturing Output"
3 "name": "Capturing Output"
4 },
4 },
5 "nbformat": 3,
5 "nbformat": 3,
6 "nbformat_minor": 0,
6 "worksheets": [
7 "worksheets": [
7 {
8 {
8 "cells": [
9 "cells": [
9 {
10 {
10 "cell_type": "heading",
11 "cell_type": "heading",
11 "level": 1,
12 "level": 1,
13 "metadata": {},
12 "source": [
14 "source": [
13 "Capturing Output with <tt>%%capture</tt>"
15 "Capturing Output with <tt>%%capture</tt>"
14 ]
16 ]
15 },
17 },
16 {
18 {
17 "cell_type": "markdown",
19 "cell_type": "markdown",
20 "metadata": {},
18 "source": [
21 "source": [
19 "One of IPython's new cell magics is `%%capture`, which captures stdout/err for a cell,",
22 "One of IPython's new cell magics is `%%capture`, which captures stdout/err for a cell,\n",
20 "and discards them or stores them in variables in your namespace."
23 "and discards them or stores them in variables in your namespace."
21 ]
24 ]
22 },
25 },
23 {
26 {
24 "cell_type": "code",
27 "cell_type": "code",
28 "collapsed": false,
25 "input": [
29 "input": [
26 "import sys"
30 "import sys"
27 ],
31 ],
28 "language": "python",
32 "language": "python",
33 "metadata": {},
29 "outputs": []
34 "outputs": []
30 },
35 },
31 {
36 {
32 "cell_type": "markdown",
37 "cell_type": "markdown",
38 "metadata": {},
33 "source": [
39 "source": [
34 "By default, it just swallows it up. This is a simple way to suppress unwanted output."
40 "By default, it just swallows it up. This is a simple way to suppress unwanted output."
35 ]
41 ]
36 },
42 },
37 {
43 {
38 "cell_type": "code",
44 "cell_type": "code",
45 "collapsed": false,
39 "input": [
46 "input": [
40 "%%capture",
47 "%%capture\n",
41 "print 'hi, stdout'",
48 "print 'hi, stdout'\n",
42 "print >> sys.stderr, 'hi, stderr'"
49 "print >> sys.stderr, 'hi, stderr'"
43 ],
50 ],
44 "language": "python",
51 "language": "python",
52 "metadata": {},
45 "outputs": []
53 "outputs": []
46 },
54 },
47 {
55 {
48 "cell_type": "markdown",
56 "cell_type": "markdown",
57 "metadata": {},
49 "source": [
58 "source": [
50 "If you specify a name, then stdout and stderr will be stored in an object in your namespace."
59 "If you specify a name, then stdout and stderr will be stored in an object in your namespace."
51 ]
60 ]
52 },
61 },
53 {
62 {
54 "cell_type": "code",
63 "cell_type": "code",
64 "collapsed": false,
55 "input": [
65 "input": [
56 "%%capture captured",
66 "%%capture captured\n",
57 "print 'hi, stdout'",
67 "print 'hi, stdout'\n",
58 "print >> sys.stderr, 'hi, stderr'"
68 "print >> sys.stderr, 'hi, stderr'"
59 ],
69 ],
60 "language": "python",
70 "language": "python",
71 "metadata": {},
61 "outputs": []
72 "outputs": []
62 },
73 },
63 {
74 {
64 "cell_type": "code",
75 "cell_type": "code",
76 "collapsed": false,
65 "input": [
77 "input": [
66 "captured"
78 "captured"
67 ],
79 ],
68 "language": "python",
80 "language": "python",
81 "metadata": {},
69 "outputs": []
82 "outputs": []
70 },
83 },
71 {
84 {
72 "cell_type": "markdown",
85 "cell_type": "markdown",
86 "metadata": {},
73 "source": [
87 "source": [
74 "Calling the object writes the output to stdout/err as appropriate."
88 "Calling the object writes the output to stdout/err as appropriate."
75 ]
89 ]
76 },
90 },
77 {
91 {
78 "cell_type": "code",
92 "cell_type": "code",
93 "collapsed": false,
79 "input": [
94 "input": [
80 "captured()"
95 "captured()"
81 ],
96 ],
82 "language": "python",
97 "language": "python",
98 "metadata": {},
83 "outputs": []
99 "outputs": []
84 },
100 },
85 {
101 {
86 "cell_type": "code",
102 "cell_type": "code",
103 "collapsed": false,
87 "input": [
104 "input": [
88 "captured.stdout"
105 "captured.stdout"
89 ],
106 ],
90 "language": "python",
107 "language": "python",
108 "metadata": {},
91 "outputs": []
109 "outputs": []
92 },
110 },
93 {
111 {
94 "cell_type": "code",
112 "cell_type": "code",
113 "collapsed": false,
95 "input": [
114 "input": [
96 "captured.stderr"
115 "captured.stderr"
97 ],
116 ],
98 "language": "python",
117 "language": "python",
118 "metadata": {},
99 "outputs": []
119 "outputs": []
100 },
120 },
101 {
121 {
102 "cell_type": "markdown",
122 "cell_type": "markdown",
123 "metadata": {},
103 "source": [
124 "source": [
104 "`%%capture` only captures stdout/err, not displaypub, so you can still do plots and use the display protocol inside %%capture"
125 "`%%capture` only captures stdout/err, not displaypub, so you can still do plots and use the display protocol inside %%capture"
105 ]
126 ]
106 },
127 },
107 {
128 {
108 "cell_type": "code",
129 "cell_type": "code",
130 "collapsed": false,
109 "input": [
131 "input": [
110 "%pylab inline"
132 "%pylab inline"
111 ],
133 ],
112 "language": "python",
134 "language": "python",
135 "metadata": {},
113 "outputs": []
136 "outputs": []
114 },
137 },
115 {
138 {
116 "cell_type": "code",
139 "cell_type": "code",
140 "collapsed": false,
117 "input": [
141 "input": [
118 "%%capture wontshutup",
142 "%%capture wontshutup\n",
119 "",
143 "\n",
120 "print \"setting up X\"",
144 "print \"setting up X\"\n",
121 "x = np.linspace(0,5,1000)",
145 "x = np.linspace(0,5,1000)\n",
122 "print \"step 2: constructing y-data\"",
146 "print \"step 2: constructing y-data\"\n",
123 "y = np.sin(x)",
147 "y = np.sin(x)\n",
124 "print \"step 3: display info about y\"",
148 "print \"step 3: display info about y\"\n",
125 "plt.plot(x,y)",
149 "plt.plot(x,y)\n",
126 "print \"okay, I'm done now\""
150 "print \"okay, I'm done now\""
127 ],
151 ],
128 "language": "python",
152 "language": "python",
153 "metadata": {},
129 "outputs": []
154 "outputs": []
130 },
155 },
131 {
156 {
132 "cell_type": "code",
157 "cell_type": "code",
158 "collapsed": false,
133 "input": [
159 "input": [
134 "wontshutup()"
160 "wontshutup()"
135 ],
161 ],
136 "language": "python",
162 "language": "python",
163 "metadata": {},
137 "outputs": []
164 "outputs": []
138 },
165 },
139 {
166 {
140 "cell_type": "markdown",
167 "cell_type": "markdown",
168 "metadata": {},
141 "source": [
169 "source": [
142 "And you can selectively disable capturing stdout or stderr by passing `--no-stdout/err`."
170 "And you can selectively disable capturing stdout or stderr by passing `--no-stdout/err`."
143 ]
171 ]
144 },
172 },
145 {
173 {
146 "cell_type": "code",
174 "cell_type": "code",
175 "collapsed": false,
147 "input": [
176 "input": [
148 "%%capture cap --no-stderr",
177 "%%capture cap --no-stderr\n",
149 "print 'hi, stdout'",
178 "print 'hi, stdout'\n",
150 "print >> sys.stderr, \"hello, stderr\""
179 "print >> sys.stderr, \"hello, stderr\""
151 ],
180 ],
152 "language": "python",
181 "language": "python",
182 "metadata": {},
153 "outputs": []
183 "outputs": []
154 },
184 },
155 {
185 {
156 "cell_type": "code",
186 "cell_type": "code",
187 "collapsed": false,
157 "input": [
188 "input": [
158 "cap.stdout"
189 "cap.stdout"
159 ],
190 ],
160 "language": "python",
191 "language": "python",
192 "metadata": {},
161 "outputs": []
193 "outputs": []
162 },
194 },
163 {
195 {
164 "cell_type": "code",
196 "cell_type": "code",
197 "collapsed": false,
165 "input": [
198 "input": [
166 "cap.stderr"
199 "cap.stderr"
167 ],
200 ],
168 "language": "python",
201 "language": "python",
169 "outputs": []
202 "metadata": {},
170 },
171 {
172 "cell_type": "code",
173 "input": [
174 ""
175 ],
176 "language": "python",
177 "outputs": []
203 "outputs": []
178 }
204 }
179 ]
205 ],
206 "metadata": {}
180 }
207 }
181 ]
208 ]
182 } No newline at end of file
209 }
@@ -3,57 +3,64 b''
3 "name": "Script Magics"
3 "name": "Script Magics"
4 },
4 },
5 "nbformat": 3,
5 "nbformat": 3,
6 "nbformat_minor": 0,
6 "worksheets": [
7 "worksheets": [
7 {
8 {
8 "cells": [
9 "cells": [
9 {
10 {
10 "cell_type": "heading",
11 "cell_type": "heading",
11 "level": 1,
12 "level": 1,
13 "metadata": {},
12 "source": [
14 "source": [
13 "Running Scripts from IPython"
15 "Running Scripts from IPython"
14 ]
16 ]
15 },
17 },
16 {
18 {
17 "cell_type": "markdown",
19 "cell_type": "markdown",
20 "metadata": {},
18 "source": [
21 "source": [
19 "IPython has a `%%script` cell magic, which lets you run a cell in",
22 "IPython has a `%%script` cell magic, which lets you run a cell in\n",
20 "a subprocess of any interpreter on your system, such as: bash, ruby, perl, zsh, R, etc.",
23 "a subprocess of any interpreter on your system, such as: bash, ruby, perl, zsh, R, etc.\n",
21 "",
24 "\n",
22 "It can even be a script of your own, which expects input on stdin."
25 "It can even be a script of your own, which expects input on stdin."
23 ]
26 ]
24 },
27 },
25 {
28 {
26 "cell_type": "code",
29 "cell_type": "code",
30 "collapsed": false,
27 "input": [
31 "input": [
28 "import sys"
32 "import sys"
29 ],
33 ],
30 "language": "python",
34 "language": "python",
35 "metadata": {},
31 "outputs": [],
36 "outputs": [],
32 "prompt_number": 1
37 "prompt_number": 1
33 },
38 },
34 {
39 {
35 "cell_type": "markdown",
40 "cell_type": "markdown",
41 "metadata": {},
36 "source": [
42 "source": [
37 "To use it, simply pass a path or shell command to the program you want to run on the `%%script` line,",
43 "To use it, simply pass a path or shell command to the program you want to run on the `%%script` line,\n",
38 "and the rest of the cell will be run by that script, and stdout/err from the subprocess are captured and displayed."
44 "and the rest of the cell will be run by that script, and stdout/err from the subprocess are captured and displayed."
39 ]
45 ]
40 },
46 },
41 {
47 {
42 "cell_type": "code",
48 "cell_type": "code",
49 "collapsed": false,
43 "input": [
50 "input": [
44 "%%script python",
51 "%%script python\n",
45 "import sys",
52 "import sys\n",
46 "print 'hello from Python %s' % sys.version"
53 "print 'hello from Python %s' % sys.version"
47 ],
54 ],
48 "language": "python",
55 "language": "python",
56 "metadata": {},
49 "outputs": [
57 "outputs": [
50 {
58 {
51 "output_type": "stream",
59 "output_type": "stream",
52 "stream": "stdout",
60 "stream": "stdout",
53 "text": [
61 "text": [
54 "hello from Python 2.7.1 (r271:86832, Jul 31 2011, 19:30:53) ",
62 "hello from Python 2.7.1 (r271:86832, Jul 31 2011, 19:30:53) \n",
55 "[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)]",
63 "[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)]\n"
56 ""
57 ]
64 ]
58 }
65 }
59 ],
66 ],
@@ -61,20 +68,21 b''
61 },
68 },
62 {
69 {
63 "cell_type": "code",
70 "cell_type": "code",
71 "collapsed": false,
64 "input": [
72 "input": [
65 "%%script python3",
73 "%%script python3\n",
66 "import sys",
74 "import sys\n",
67 "print('hello from Python: %s' % sys.version)"
75 "print('hello from Python: %s' % sys.version)"
68 ],
76 ],
69 "language": "python",
77 "language": "python",
78 "metadata": {},
70 "outputs": [
79 "outputs": [
71 {
80 {
72 "output_type": "stream",
81 "output_type": "stream",
73 "stream": "stdout",
82 "stream": "stdout",
74 "text": [
83 "text": [
75 "hello from Python: 3.2.3 (v3.2.3:3d0686d90f55, Apr 10 2012, 11:25:50) ",
84 "hello from Python: 3.2.3 (v3.2.3:3d0686d90f55, Apr 10 2012, 11:25:50) \n",
76 "[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)]",
85 "[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)]\n"
77 ""
78 ]
86 ]
79 }
87 }
80 ],
88 ],
@@ -82,26 +90,28 b''
82 },
90 },
83 {
91 {
84 "cell_type": "markdown",
92 "cell_type": "markdown",
93 "metadata": {},
85 "source": [
94 "source": [
86 "IPython also creates aliases for a few common interpreters, such as bash, ruby, perl, etc.",
95 "IPython also creates aliases for a few common interpreters, such as bash, ruby, perl, etc.\n",
87 "",
96 "\n",
88 "These are all equivalent to `%%script <name>`"
97 "These are all equivalent to `%%script <name>`"
89 ]
98 ]
90 },
99 },
91 {
100 {
92 "cell_type": "code",
101 "cell_type": "code",
102 "collapsed": false,
93 "input": [
103 "input": [
94 "%%ruby",
104 "%%ruby\n",
95 "puts \"Hello from Ruby #{RUBY_VERSION}\""
105 "puts \"Hello from Ruby #{RUBY_VERSION}\""
96 ],
106 ],
97 "language": "python",
107 "language": "python",
108 "metadata": {},
98 "outputs": [
109 "outputs": [
99 {
110 {
100 "output_type": "stream",
111 "output_type": "stream",
101 "stream": "stdout",
112 "stream": "stdout",
102 "text": [
113 "text": [
103 "Hello from Ruby 1.8.7",
114 "Hello from Ruby 1.8.7\n"
104 ""
105 ]
115 ]
106 }
116 }
107 ],
117 ],
@@ -109,18 +119,19 b''
109 },
119 },
110 {
120 {
111 "cell_type": "code",
121 "cell_type": "code",
122 "collapsed": false,
112 "input": [
123 "input": [
113 "%%bash",
124 "%%bash\n",
114 "echo \"hello from $BASH\""
125 "echo \"hello from $BASH\""
115 ],
126 ],
116 "language": "python",
127 "language": "python",
128 "metadata": {},
117 "outputs": [
129 "outputs": [
118 {
130 {
119 "output_type": "stream",
131 "output_type": "stream",
120 "stream": "stdout",
132 "stream": "stdout",
121 "text": [
133 "text": [
122 "hello from /usr/local/bin/bash",
134 "hello from /usr/local/bin/bash\n"
123 ""
124 ]
135 ]
125 }
136 }
126 ],
137 ],
@@ -129,40 +140,41 b''
129 {
140 {
130 "cell_type": "heading",
141 "cell_type": "heading",
131 "level": 2,
142 "level": 2,
143 "metadata": {},
132 "source": [
144 "source": [
133 "Capturing output"
145 "Capturing output"
134 ]
146 ]
135 },
147 },
136 {
148 {
137 "cell_type": "markdown",
149 "cell_type": "markdown",
150 "metadata": {},
138 "source": [
151 "source": [
139 "You can also capture stdout/err from these subprocesses into Python variables, instead of letting them go directly to stdout/err"
152 "You can also capture stdout/err from these subprocesses into Python variables, instead of letting them go directly to stdout/err"
140 ]
153 ]
141 },
154 },
142 {
155 {
143 "cell_type": "code",
156 "cell_type": "code",
157 "collapsed": false,
144 "input": [
158 "input": [
145 "%%bash",
159 "%%bash\n",
146 "echo \"hi, stdout\"",
160 "echo \"hi, stdout\"\n",
147 "echo \"hello, stderr\" >&2",
161 "echo \"hello, stderr\" >&2\n"
148 ""
149 ],
162 ],
150 "language": "python",
163 "language": "python",
164 "metadata": {},
151 "outputs": [
165 "outputs": [
152 {
166 {
153 "output_type": "stream",
167 "output_type": "stream",
154 "stream": "stdout",
168 "stream": "stdout",
155 "text": [
169 "text": [
156 "hi, stdout",
170 "hi, stdout\n"
157 ""
158 ]
171 ]
159 },
172 },
160 {
173 {
161 "output_type": "stream",
174 "output_type": "stream",
162 "stream": "stderr",
175 "stream": "stderr",
163 "text": [
176 "text": [
164 "hello, stderr",
177 "hello, stderr\n"
165 ""
166 ]
178 ]
167 }
179 }
168 ],
180 ],
@@ -170,32 +182,35 b''
170 },
182 },
171 {
183 {
172 "cell_type": "code",
184 "cell_type": "code",
185 "collapsed": false,
173 "input": [
186 "input": [
174 "%%bash --out output --err error",
187 "%%bash --out output --err error\n",
175 "echo \"hi, stdout\"",
188 "echo \"hi, stdout\"\n",
176 "echo \"hello, stderr\" >&2"
189 "echo \"hello, stderr\" >&2"
177 ],
190 ],
178 "language": "python",
191 "language": "python",
192 "metadata": {},
179 "outputs": [],
193 "outputs": [],
180 "prompt_number": 7
194 "prompt_number": 7
181 },
195 },
182 {
196 {
183 "cell_type": "code",
197 "cell_type": "code",
198 "collapsed": false,
184 "input": [
199 "input": [
185 "print error",
200 "print error\n",
186 "print output"
201 "print output"
187 ],
202 ],
188 "language": "python",
203 "language": "python",
204 "metadata": {},
189 "outputs": [
205 "outputs": [
190 {
206 {
191 "output_type": "stream",
207 "output_type": "stream",
192 "stream": "stdout",
208 "stream": "stdout",
193 "text": [
209 "text": [
194 "hello, stderr",
210 "hello, stderr\n",
195 "",
211 "\n",
196 "hi, stdout",
212 "hi, stdout\n",
197 "",
213 "\n"
198 ""
199 ]
214 ]
200 }
215 }
201 ],
216 ],
@@ -204,37 +219,40 b''
204 {
219 {
205 "cell_type": "heading",
220 "cell_type": "heading",
206 "level": 2,
221 "level": 2,
222 "metadata": {},
207 "source": [
223 "source": [
208 "Background Scripts"
224 "Background Scripts"
209 ]
225 ]
210 },
226 },
211 {
227 {
212 "cell_type": "markdown",
228 "cell_type": "markdown",
229 "metadata": {},
213 "source": [
230 "source": [
214 "These scripts can be run in the background, by adding the `--bg` flag.",
231 "These scripts can be run in the background, by adding the `--bg` flag.\n",
215 "",
232 "\n",
216 "When you do this, output is discarded unless you use the `--out/err`",
233 "When you do this, output is discarded unless you use the `--out/err`\n",
217 "flags to store output as above."
234 "flags to store output as above."
218 ]
235 ]
219 },
236 },
220 {
237 {
221 "cell_type": "code",
238 "cell_type": "code",
239 "collapsed": false,
222 "input": [
240 "input": [
223 "%%ruby --bg --out ruby_lines",
241 "%%ruby --bg --out ruby_lines\n",
224 "for n in 1...10",
242 "for n in 1...10\n",
225 " sleep 1",
243 " sleep 1\n",
226 " puts \"line #{n}\"",
244 " puts \"line #{n}\"\n",
227 " STDOUT.flush",
245 " STDOUT.flush\n",
228 "end"
246 "end"
229 ],
247 ],
230 "language": "python",
248 "language": "python",
249 "metadata": {},
231 "outputs": [
250 "outputs": [
232 {
251 {
233 "output_type": "stream",
252 "output_type": "stream",
234 "stream": "stdout",
253 "stream": "stdout",
235 "text": [
254 "text": [
236 "Starting job # 0 in a separate thread.",
255 "Starting job # 0 in a separate thread.\n"
237 ""
238 ]
256 ]
239 }
257 }
240 ],
258 ],
@@ -242,23 +260,26 b''
242 },
260 },
243 {
261 {
244 "cell_type": "markdown",
262 "cell_type": "markdown",
263 "metadata": {},
245 "source": [
264 "source": [
246 "When you do store output of a background thread, these are the stdout/err *pipes*,",
265 "When you do store output of a background thread, these are the stdout/err *pipes*,\n",
247 "rather than the text of the output."
266 "rather than the text of the output."
248 ]
267 ]
249 },
268 },
250 {
269 {
251 "cell_type": "code",
270 "cell_type": "code",
271 "collapsed": false,
252 "input": [
272 "input": [
253 "ruby_lines"
273 "ruby_lines"
254 ],
274 ],
255 "language": "python",
275 "language": "python",
276 "metadata": {},
256 "outputs": [
277 "outputs": [
257 {
278 {
258 "output_type": "pyout",
279 "output_type": "pyout",
259 "prompt_number": 10,
280 "prompt_number": 10,
260 "text": [
281 "text": [
261 "<open file '<fdopen>', mode 'rb' at 0x10dc651e0>"
282 "<open file '<fdopen>', mode 'rb' at 0x10a4be660>"
262 ]
283 ]
263 }
284 }
264 ],
285 ],
@@ -266,26 +287,27 b''
266 },
287 },
267 {
288 {
268 "cell_type": "code",
289 "cell_type": "code",
290 "collapsed": false,
269 "input": [
291 "input": [
270 "print ruby_lines.read()"
292 "print ruby_lines.read()"
271 ],
293 ],
272 "language": "python",
294 "language": "python",
295 "metadata": {},
273 "outputs": [
296 "outputs": [
274 {
297 {
275 "output_type": "stream",
298 "output_type": "stream",
276 "stream": "stdout",
299 "stream": "stdout",
277 "text": [
300 "text": [
278 "line 1",
301 "line 1\n",
279 "line 2",
302 "line 2\n",
280 "line 3",
303 "line 3\n",
281 "line 4",
304 "line 4\n",
282 "line 5",
305 "line 5\n",
283 "line 6",
306 "line 6\n",
284 "line 7",
307 "line 7\n",
285 "line 8",
308 "line 8\n",
286 "line 9",
309 "line 9\n",
287 "",
310 "\n"
288 ""
289 ]
311 ]
290 }
312 }
291 ],
313 ],
@@ -294,31 +316,34 b''
294 {
316 {
295 "cell_type": "heading",
317 "cell_type": "heading",
296 "level": 2,
318 "level": 2,
319 "metadata": {},
297 "source": [
320 "source": [
298 "Arguments to subcommand"
321 "Arguments to subcommand"
299 ]
322 ]
300 },
323 },
301 {
324 {
302 "cell_type": "markdown",
325 "cell_type": "markdown",
326 "metadata": {},
303 "source": [
327 "source": [
304 "You can pass arguments the subcommand as well,",
328 "You can pass arguments the subcommand as well,\n",
305 "such as this example instructing Python to use integer division from Python 3:"
329 "such as this example instructing Python to use integer division from Python 3:"
306 ]
330 ]
307 },
331 },
308 {
332 {
309 "cell_type": "code",
333 "cell_type": "code",
334 "collapsed": false,
310 "input": [
335 "input": [
311 "%%script python -Qnew",
336 "%%script python -Qnew\n",
312 "print 1/3"
337 "print 1/3"
313 ],
338 ],
314 "language": "python",
339 "language": "python",
340 "metadata": {},
315 "outputs": [
341 "outputs": [
316 {
342 {
317 "output_type": "stream",
343 "output_type": "stream",
318 "stream": "stdout",
344 "stream": "stdout",
319 "text": [
345 "text": [
320 "0.333333333333",
346 "0.333333333333\n"
321 ""
322 ]
347 ]
323 }
348 }
324 ],
349 ],
@@ -326,30 +351,31 b''
326 },
351 },
327 {
352 {
328 "cell_type": "markdown",
353 "cell_type": "markdown",
354 "metadata": {},
329 "source": [
355 "source": [
330 "You can really specify *any* program for `%%script`,",
356 "You can really specify *any* program for `%%script`,\n",
331 "for instance here is a 'program' that echos the lines of stdin, with delays between each line."
357 "for instance here is a 'program' that echos the lines of stdin, with delays between each line."
332 ]
358 ]
333 },
359 },
334 {
360 {
335 "cell_type": "code",
361 "cell_type": "code",
362 "collapsed": false,
336 "input": [
363 "input": [
337 "%%script --bg --out bashout bash -c \"while read line; do echo $line; sleep 1; done\"",
364 "%%script --bg --out bashout bash -c \"while read line; do echo $line; sleep 1; done\"\n",
338 "line 1",
365 "line 1\n",
339 "line 2",
366 "line 2\n",
340 "line 3",
367 "line 3\n",
341 "line 4",
368 "line 4\n",
342 "line 5",
369 "line 5\n"
343 ""
344 ],
370 ],
345 "language": "python",
371 "language": "python",
372 "metadata": {},
346 "outputs": [
373 "outputs": [
347 {
374 {
348 "output_type": "stream",
375 "output_type": "stream",
349 "stream": "stdout",
376 "stream": "stdout",
350 "text": [
377 "text": [
351 "Starting job # 2 in a separate thread.",
378 "Starting job # 2 in a separate thread.\n"
352 ""
353 ]
379 ]
354 }
380 }
355 ],
381 ],
@@ -357,65 +383,62 b''
357 },
383 },
358 {
384 {
359 "cell_type": "markdown",
385 "cell_type": "markdown",
386 "metadata": {},
360 "source": [
387 "source": [
361 "Remember, since the output of a background script is just the stdout pipe,",
388 "Remember, since the output of a background script is just the stdout pipe,\n",
362 "you can read it as lines become available:"
389 "you can read it as lines become available:"
363 ]
390 ]
364 },
391 },
365 {
392 {
366 "cell_type": "code",
393 "cell_type": "code",
394 "collapsed": false,
367 "input": [
395 "input": [
368 "import time",
396 "import time\n",
369 "tic = time.time()",
397 "tic = time.time()\n",
370 "line = True",
398 "line = True\n",
371 "while True:",
399 "while True:\n",
372 " line = bashout.readline()",
400 " line = bashout.readline()\n",
373 " if not line:",
401 " if not line:\n",
374 " break",
402 " break\n",
375 " sys.stdout.write(\"%.1fs: %s\" %(time.time()-tic, line))",
403 " sys.stdout.write(\"%.1fs: %s\" %(time.time()-tic, line))\n",
376 " sys.stdout.flush()",
404 " sys.stdout.flush()\n"
377 ""
378 ],
405 ],
379 "language": "python",
406 "language": "python",
407 "metadata": {},
380 "outputs": [
408 "outputs": [
381 {
409 {
382 "output_type": "stream",
410 "output_type": "stream",
383 "stream": "stdout",
411 "stream": "stdout",
384 "text": [
412 "text": [
385 "0.0s: line 1",
413 "0.0s: line 1\n"
386 ""
387 ]
414 ]
388 },
415 },
389 {
416 {
390 "output_type": "stream",
417 "output_type": "stream",
391 "stream": "stdout",
418 "stream": "stdout",
392 "text": [
419 "text": [
393 "1.0s: line 2",
420 "1.0s: line 2\n"
394 ""
395 ]
421 ]
396 },
422 },
397 {
423 {
398 "output_type": "stream",
424 "output_type": "stream",
399 "stream": "stdout",
425 "stream": "stdout",
400 "text": [
426 "text": [
401 "2.0s: line 3",
427 "2.0s: line 3\n"
402 ""
403 ]
428 ]
404 },
429 },
405 {
430 {
406 "output_type": "stream",
431 "output_type": "stream",
407 "stream": "stdout",
432 "stream": "stdout",
408 "text": [
433 "text": [
409 "3.0s: line 4",
434 "3.0s: line 4\n"
410 ""
411 ]
435 ]
412 },
436 },
413 {
437 {
414 "output_type": "stream",
438 "output_type": "stream",
415 "stream": "stdout",
439 "stream": "stdout",
416 "text": [
440 "text": [
417 "4.0s: line 5",
441 "4.0s: line 5\n"
418 ""
419 ]
442 ]
420 }
443 }
421 ],
444 ],
@@ -424,25 +447,28 b''
424 {
447 {
425 "cell_type": "heading",
448 "cell_type": "heading",
426 "level": 2,
449 "level": 2,
450 "metadata": {},
427 "source": [
451 "source": [
428 "Configuring the default ScriptMagics"
452 "Configuring the default ScriptMagics"
429 ]
453 ]
430 },
454 },
431 {
455 {
432 "cell_type": "markdown",
456 "cell_type": "markdown",
457 "metadata": {},
433 "source": [
458 "source": [
434 "The list of aliased script magics is configurable.",
459 "The list of aliased script magics is configurable.\n",
435 "",
460 "\n",
436 "The default is to pick from a few common interpreters, and use them if found, but you can specify your own in ipython_config.py:",
461 "The default is to pick from a few common interpreters, and use them if found, but you can specify your own in ipython_config.py:\n",
437 "",
462 "\n",
438 " c.ScriptMagics.scripts = ['R', 'pypy', 'myprogram']",
463 " c.ScriptMagics.scripts = ['R', 'pypy', 'myprogram']\n",
439 "",
464 "\n",
440 "And if any of these programs do not apear on your default PATH, then you would also need to specify their location with:",
465 "And if any of these programs do not apear on your default PATH, then you would also need to specify their location with:\n",
441 "",
466 "\n",
442 " c.ScriptMagics.script_paths = {'myprogram': '/opt/path/to/myprogram'}"
467 " c.ScriptMagics.script_paths = {'myprogram': '/opt/path/to/myprogram'}"
443 ]
468 ]
444 }
469 }
445 ]
470 ],
471 "metadata": {}
446 }
472 }
447 ]
473 ]
448 } No newline at end of file
474 }
@@ -3,12 +3,14 b''
3 "name": "cython_extension"
3 "name": "cython_extension"
4 },
4 },
5 "nbformat": 3,
5 "nbformat": 3,
6 "nbformat_minor": 0,
6 "worksheets": [
7 "worksheets": [
7 {
8 {
8 "cells": [
9 "cells": [
9 {
10 {
10 "cell_type": "heading",
11 "cell_type": "heading",
11 "level": 1,
12 "level": 1,
13 "metadata": {},
12 "source": [
14 "source": [
13 "Cython Magic Functions Extension"
15 "Cython Magic Functions Extension"
14 ]
16 ]
@@ -16,116 +18,134 b''
16 {
18 {
17 "cell_type": "heading",
19 "cell_type": "heading",
18 "level": 2,
20 "level": 2,
21 "metadata": {},
19 "source": [
22 "source": [
20 "Loading the extension"
23 "Loading the extension"
21 ]
24 ]
22 },
25 },
23 {
26 {
24 "cell_type": "markdown",
27 "cell_type": "markdown",
28 "metadata": {},
25 "source": [
29 "source": [
26 "IPtyhon has a `cythonmagic` extension that contains a number of magic functions for working with Cython code. This extension can be loaded using the `%load_ext` magic as follows:"
30 "IPtyhon has a `cythonmagic` extension that contains a number of magic functions for working with Cython code. This extension can be loaded using the `%load_ext` magic as follows:"
27 ]
31 ]
28 },
32 },
29 {
33 {
30 "cell_type": "code",
34 "cell_type": "code",
35 "collapsed": false,
31 "input": [
36 "input": [
32 "%load_ext cythonmagic"
37 "%load_ext cythonmagic"
33 ],
38 ],
34 "language": "python",
39 "language": "python",
40 "metadata": {},
35 "outputs": [],
41 "outputs": [],
36 "prompt_number": 1
42 "prompt_number": 1
37 },
43 },
38 {
44 {
39 "cell_type": "heading",
45 "cell_type": "heading",
40 "level": 2,
46 "level": 2,
47 "metadata": {},
41 "source": [
48 "source": [
42 "The %cython_inline magic"
49 "The %cython_inline magic"
43 ]
50 ]
44 },
51 },
45 {
52 {
46 "cell_type": "markdown",
53 "cell_type": "markdown",
54 "metadata": {},
47 "source": [
55 "source": [
48 "The `%%cython_inline` magic uses `Cython.inline` to compile a Cython expression. This allows you to enter and run a function body with Cython code. Use a bare `return` statement to return values. "
56 "The `%%cython_inline` magic uses `Cython.inline` to compile a Cython expression. This allows you to enter and run a function body with Cython code. Use a bare `return` statement to return values. "
49 ]
57 ]
50 },
58 },
51 {
59 {
52 "cell_type": "code",
60 "cell_type": "code",
61 "collapsed": false,
53 "input": [
62 "input": [
54 "a = 10\n",
63 "a = 10\n",
55 "b = 20"
64 "b = 20"
56 ],
65 ],
57 "language": "python",
66 "language": "python",
67 "metadata": {},
58 "outputs": [],
68 "outputs": [],
59 "prompt_number": 8
69 "prompt_number": 2
60 },
70 },
61 {
71 {
62 "cell_type": "code",
72 "cell_type": "code",
73 "collapsed": false,
63 "input": [
74 "input": [
64 "%%cython_inline\n",
75 "%%cython_inline\n",
65 "return a+b"
76 "return a+b"
66 ],
77 ],
67 "language": "python",
78 "language": "python",
79 "metadata": {},
68 "outputs": [
80 "outputs": [
69 {
81 {
70 "output_type": "pyout",
82 "output_type": "pyout",
71 "prompt_number": 9,
83 "prompt_number": 3,
72 "text": [
84 "text": [
73 "30"
85 "30"
74 ]
86 ]
75 }
87 }
76 ],
88 ],
77 "prompt_number": 9
89 "prompt_number": 3
78 },
90 },
79 {
91 {
80 "cell_type": "heading",
92 "cell_type": "heading",
81 "level": 2,
93 "level": 2,
94 "metadata": {},
82 "source": [
95 "source": [
83 "The %cython_pyximport magic"
96 "The %cython_pyximport magic"
84 ]
97 ]
85 },
98 },
86 {
99 {
87 "cell_type": "markdown",
100 "cell_type": "markdown",
101 "metadata": {},
88 "source": [
102 "source": [
89 "The `%%cython_pyximport` magic allows you to enter arbitrary Cython code into a cell. That Cython code is written as a `.pyx` file in the current working directory and then imported using `pyximport`. You have the specify the name of the module that the Code will appear in. All symbols from the module are imported automatically by the magic function."
103 "The `%%cython_pyximport` magic allows you to enter arbitrary Cython code into a cell. That Cython code is written as a `.pyx` file in the current working directory and then imported using `pyximport`. You have the specify the name of the module that the Code will appear in. All symbols from the module are imported automatically by the magic function."
90 ]
104 ]
91 },
105 },
92 {
106 {
93 "cell_type": "code",
107 "cell_type": "code",
108 "collapsed": false,
94 "input": [
109 "input": [
95 "%%cython_pyximport foo\n",
110 "%%cython_pyximport foo\n",
96 "def f(x):\n",
111 "def f(x):\n",
97 " return 4.0*x"
112 " return 4.0*x"
98 ],
113 ],
99 "language": "python",
114 "language": "python",
115 "metadata": {},
100 "outputs": [],
116 "outputs": [],
101 "prompt_number": 18
117 "prompt_number": 4
102 },
118 },
103 {
119 {
104 "cell_type": "code",
120 "cell_type": "code",
121 "collapsed": false,
105 "input": [
122 "input": [
106 "f(10)"
123 "f(10)"
107 ],
124 ],
108 "language": "python",
125 "language": "python",
126 "metadata": {},
109 "outputs": [
127 "outputs": [
110 {
128 {
111 "output_type": "pyout",
129 "output_type": "pyout",
112 "prompt_number": 19,
130 "prompt_number": 5,
113 "text": [
131 "text": [
114 "40.0"
132 "40.0"
115 ]
133 ]
116 }
134 }
117 ],
135 ],
118 "prompt_number": 19
136 "prompt_number": 5
119 },
137 },
120 {
138 {
121 "cell_type": "heading",
139 "cell_type": "heading",
122 "level": 2,
140 "level": 2,
141 "metadata": {},
123 "source": [
142 "source": [
124 "The %cython magic"
143 "The %cython magic"
125 ]
144 ]
126 },
145 },
127 {
146 {
128 "cell_type": "markdown",
147 "cell_type": "markdown",
148 "metadata": {},
129 "source": [
149 "source": [
130 "Probably the most important magic is the `%cython` magic. This is similar to the `%%cython_pyximport` magic, but doesn't require you to specify a module name. Instead, the `%%cython` magic uses manages everything using temporary files in the `~/.cython/magic` directory. All of the symbols in the Cython module are imported automatically by the magic.\n",
150 "Probably the most important magic is the `%cython` magic. This is similar to the `%%cython_pyximport` magic, but doesn't require you to specify a module name. Instead, the `%%cython` magic uses manages everything using temporary files in the `~/.cython/magic` directory. All of the symbols in the Cython module are imported automatically by the magic.\n",
131 "\n",
151 "\n",
@@ -134,6 +154,7 b''
134 },
154 },
135 {
155 {
136 "cell_type": "code",
156 "cell_type": "code",
157 "collapsed": false,
137 "input": [
158 "input": [
138 "%%cython\n",
159 "%%cython\n",
139 "cimport cython\n",
160 "cimport cython\n",
@@ -165,15 +186,18 b''
165 " return optprice"
186 " return optprice"
166 ],
187 ],
167 "language": "python",
188 "language": "python",
189 "metadata": {},
168 "outputs": [],
190 "outputs": [],
169 "prompt_number": 6
191 "prompt_number": 6
170 },
192 },
171 {
193 {
172 "cell_type": "code",
194 "cell_type": "code",
195 "collapsed": false,
173 "input": [
196 "input": [
174 "black_scholes(100.0, 100.0, 1.0, 0.3, 0.03, 0.0, -1)"
197 "black_scholes(100.0, 100.0, 1.0, 0.3, 0.03, 0.0, -1)"
175 ],
198 ],
176 "language": "python",
199 "language": "python",
200 "metadata": {},
177 "outputs": [
201 "outputs": [
178 {
202 {
179 "output_type": "pyout",
203 "output_type": "pyout",
@@ -187,35 +211,40 b''
187 },
211 },
188 {
212 {
189 "cell_type": "code",
213 "cell_type": "code",
214 "collapsed": false,
190 "input": [
215 "input": [
191 "%timeit black_scholes(100.0, 100.0, 1.0, 0.3, 0.03, 0.0, -1)"
216 "%timeit black_scholes(100.0, 100.0, 1.0, 0.3, 0.03, 0.0, -1)"
192 ],
217 ],
193 "language": "python",
218 "language": "python",
219 "metadata": {},
194 "outputs": [
220 "outputs": [
195 {
221 {
196 "output_type": "stream",
222 "output_type": "stream",
197 "stream": "stdout",
223 "stream": "stdout",
198 "text": [
224 "text": [
199 "1000000 loops, best of 3: 621 ns per loop\n"
225 "1000000 loops, best of 3: 821 ns per loop\n"
200 ]
226 ]
201 }
227 }
202 ],
228 ],
203 "prompt_number": 14
229 "prompt_number": 8
204 },
230 },
205 {
231 {
206 "cell_type": "markdown",
232 "cell_type": "markdown",
233 "metadata": {},
207 "source": [
234 "source": [
208 "Cython allows you to specify additional libraries to be linked with your extension, you can do so with the `-l` flag (also spelled `--lib`). Note that this flag can be passed more than once to specify multiple libraries, such as `-lm -llib2 --lib lib3`. Here's a simple example of how to access the system math library:"
235 "Cython allows you to specify additional libraries to be linked with your extension, you can do so with the `-l` flag (also spelled `--lib`). Note that this flag can be passed more than once to specify multiple libraries, such as `-lm -llib2 --lib lib3`. Here's a simple example of how to access the system math library:"
209 ]
236 ]
210 },
237 },
211 {
238 {
212 "cell_type": "code",
239 "cell_type": "code",
240 "collapsed": false,
213 "input": [
241 "input": [
214 "%%cython -lm\n",
242 "%%cython -lm\n",
215 "from libc.math cimport sin\n",
243 "from libc.math cimport sin\n",
216 "print 'sin(1)=', sin(1)"
244 "print 'sin(1)=', sin(1)"
217 ],
245 ],
218 "language": "python",
246 "language": "python",
247 "metadata": {},
219 "outputs": [
248 "outputs": [
220 {
249 {
221 "output_type": "stream",
250 "output_type": "stream",
@@ -225,15 +254,17 b''
225 ]
254 ]
226 }
255 }
227 ],
256 ],
228 "prompt_number": 2
257 "prompt_number": 9
229 },
258 },
230 {
259 {
231 "cell_type": "markdown",
260 "cell_type": "markdown",
261 "metadata": {},
232 "source": [
262 "source": [
233 "You can similarly use the `-I/--include` flag to add include directories to the search path, and `-c/--compile-args` to add extra flags that are passed to Cython via the `extra_compile_args` of the distutils `Extension` class. Please see [the Cython docs on C library usage](http://docs.cython.org/src/tutorial/clibraries.html) for more details on the use of these flags."
263 "You can similarly use the `-I/--include` flag to add include directories to the search path, and `-c/--compile-args` to add extra flags that are passed to Cython via the `extra_compile_args` of the distutils `Extension` class. Please see [the Cython docs on C library usage](http://docs.cython.org/src/tutorial/clibraries.html) for more details on the use of these flags."
234 ]
264 ]
235 }
265 }
236 ]
266 ],
267 "metadata": {}
237 }
268 }
238 ]
269 ]
239 } No newline at end of file
270 }
@@ -3,42 +3,73 b''
3 "name": "display_protocol"
3 "name": "display_protocol"
4 },
4 },
5 "nbformat": 3,
5 "nbformat": 3,
6 "nbformat_minor": 0,
6 "worksheets": [
7 "worksheets": [
7 {
8 {
8 "cells": [
9 "cells": [
9 {
10 {
11 "cell_type": "heading",
12 "level": 1,
13 "metadata": {},
14 "source": [
15 "Using the IPython display protocol for your own objects"
16 ]
17 },
18 {
19 "cell_type": "markdown",
20 "metadata": {},
21 "source": [
22 "IPython extends the idea of the ``__repr__`` method in Python to support multiple representations for a given\n",
23 "object, which clients can use to display the object according to their capabilities. An object can return multiple\n",
24 "representations of itself by implementing special methods, and you can also define at runtime custom display \n",
25 "functions for existing objects whose methods you can't or won't modify. In this notebook, we show how both approaches work.\n",
26 "\n",
27 "<br/>\n",
28 "**Note:** this notebook has had all output cells stripped out so we can include it in the IPython documentation with \n",
29 "a minimal file size. You'll need to manually execute the cells to see the output (you can run all of them with the \n",
30 "\"Run All\" button, or execute each individually)."
31 ]
32 },
33 {
34 "cell_type": "markdown",
35 "metadata": {},
36 "source": [
37 "Parts of this notebook need the inline matplotlib backend:"
38 ]
39 },
40 {
41 "cell_type": "code",
42 "collapsed": false,
43 "input": [
44 "%pylab inline"
45 ],
46 "language": "python",
47 "metadata": {},
48 "outputs": []
49 },
50 {
51 "cell_type": "heading",
52 "level": 2,
53 "metadata": {},
54 "source": [
55 "Custom-built classes with dedicated ``_repr_*_`` methods"
56 ]
57 },
58 {
10 "cell_type": "markdown",
59 "cell_type": "markdown",
60 "metadata": {},
11 "source": [
61 "source": [
12 "# Using the IPython display protocol for your own objects",
62 "In our first example, we illustrate how objects can expose directly to IPython special representations of\n",
13 "",
63 "themselves, by providing methods such as ``_repr_svg_``, ``_repr_png_``, ``_repr_latex_``, etc. For a full\n",
14 "IPython extends the idea of the ``__repr__`` method in Python to support multiple representations for a given",
64 "list of the special ``_repr_*_`` methods supported, see the code in ``IPython.core.displaypub``.\n",
15 "object, which clients can use to display the object according to their capabilities. An object can return multiple",
65 "\n",
16 "representations of itself by implementing special methods, and you can also define at runtime custom display ",
66 "As an illustration, we build a class that holds data generated by sampling a Gaussian distribution with given mean \n",
17 "functions for existing objects whose methods you can't or won't modify. In this notebook, we show how both approaches work.",
67 "and variance. The class can display itself in a variety of ways: as a LaTeX expression or as an image in PNG or SVG \n",
18 "",
68 "format. Each frontend can then decide which representation it can handle.\n",
19 "<br/>",
69 "Further, we illustrate how to expose directly to the user the ability to directly access the various alternate \n",
20 "**Note:** this notebook has had all output cells stripped out so we can include it in the IPython documentation with ",
70 "representations (since by default displaying the object itself will only show one, and which is shown will depend on the \n",
21 "a minimal file size. You'll need to manually execute the cells to see the output (you can run all of them with the ",
71 "required representations that even cache necessary data in cases where it may be expensive to compute.\n",
22 "\"Run All\" button, or execute each individually). You must start this notebook with",
72 "\n",
23 "<pre>",
24 "ipython notebook --pylab inline",
25 "</pre>",
26 "",
27 "to ensure pylab support is available for plots.",
28 "",
29 "## Custom-built classes with dedicated ``_repr_*_`` methods",
30 "",
31 "In our first example, we illustrate how objects can expose directly to IPython special representations of",
32 "themselves, by providing methods such as ``_repr_svg_``, ``_repr_png_``, ``_repr_latex_``, etc. For a full",
33 "list of the special ``_repr_*_`` methods supported, see the code in ``IPython.core.displaypub``.",
34 "",
35 "As an illustration, we build a class that holds data generated by sampling a Gaussian distribution with given mean ",
36 "and variance. The class can display itself in a variety of ways: as a LaTeX expression or as an image in PNG or SVG ",
37 "format. Each frontend can then decide which representation it can handle.",
38 "Further, we illustrate how to expose directly to the user the ability to directly access the various alternate ",
39 "representations (since by default displaying the object itself will only show one, and which is shown will depend on the ",
40 "required representations that even cache necessary data in cases where it may be expensive to compute.",
41 "",
42 "The next cell defines the Gaussian class:"
73 "The next cell defines the Gaussian class:"
43 ]
74 ]
44 },
75 },
@@ -46,81 +77,82 b''
46 "cell_type": "code",
77 "cell_type": "code",
47 "collapsed": false,
78 "collapsed": false,
48 "input": [
79 "input": [
49 "from IPython.core.pylabtools import print_figure",
80 "from IPython.core.pylabtools import print_figure\n",
50 "from IPython.core.display import Image, SVG, Math",
81 "from IPython.display import Image, SVG, Math\n",
51 "",
82 "\n",
52 "class Gaussian(object):",
83 "class Gaussian(object):\n",
53 " \"\"\"A simple object holding data sampled from a Gaussian distribution.",
84 " \"\"\"A simple object holding data sampled from a Gaussian distribution.\n",
54 " \"\"\"",
85 " \"\"\"\n",
55 " def __init__(self, mean=0, std=1, size=1000):",
86 " def __init__(self, mean=0, std=1, size=1000):\n",
56 " self.data = np.random.normal(mean, std, size)",
87 " self.data = np.random.normal(mean, std, size)\n",
57 " self.mean = mean",
88 " self.mean = mean\n",
58 " self.std = std",
89 " self.std = std\n",
59 " self.size = size",
90 " self.size = size\n",
60 " # For caching plots that may be expensive to compute",
91 " # For caching plots that may be expensive to compute\n",
61 " self._png_data = None",
92 " self._png_data = None\n",
62 " self._svg_data = None",
93 " self._svg_data = None\n",
63 " ",
94 " \n",
64 " def _figure_data(self, format):",
95 " def _figure_data(self, format):\n",
65 " fig, ax = plt.subplots()",
96 " fig, ax = plt.subplots()\n",
66 " ax.plot(self.data, 'o')",
97 " ax.plot(self.data, 'o')\n",
67 " ax.set_title(self._repr_latex_())",
98 " ax.set_title(self._repr_latex_())\n",
68 " data = print_figure(fig, format)",
99 " data = print_figure(fig, format)\n",
69 " # We MUST close the figure, otherwise IPython's display machinery",
100 " # We MUST close the figure, otherwise IPython's display machinery\n",
70 " # will pick it up and send it as output, resulting in a double display",
101 " # will pick it up and send it as output, resulting in a double display\n",
71 " plt.close(fig)",
102 " plt.close(fig)\n",
72 " return data",
103 " return data\n",
73 " ",
104 " \n",
74 " # Here we define the special repr methods that provide the IPython display protocol",
105 " # Here we define the special repr methods that provide the IPython display protocol\n",
75 " # Note that for the two figures, we cache the figure data once computed.",
106 " # Note that for the two figures, we cache the figure data once computed.\n",
76 " ",
107 " \n",
77 " def _repr_png_(self):",
108 " def _repr_png_(self):\n",
78 " if self._png_data is None:",
109 " if self._png_data is None:\n",
79 " self._png_data = self._figure_data('png')",
110 " self._png_data = self._figure_data('png')\n",
80 " return self._png_data",
111 " return self._png_data\n",
81 "",
112 "\n",
82 "",
113 "\n",
83 " def _repr_svg_(self):",
114 " def _repr_svg_(self):\n",
84 " if self._svg_data is None:",
115 " if self._svg_data is None:\n",
85 " self._svg_data = self._figure_data('svg')",
116 " self._svg_data = self._figure_data('svg')\n",
86 " return self._svg_data",
117 " return self._svg_data\n",
87 " ",
118 " \n",
88 " def _repr_latex_(self):",
119 " def _repr_latex_(self):\n",
89 " return r'$\\mathcal{N}(\\mu=%.2g, \\sigma=%.2g),\\ N=%d$' % (self.mean,",
120 " return r'$\\mathcal{N}(\\mu=%.2g, \\sigma=%.2g),\\ N=%d$' % (self.mean,\n",
90 " self.std, self.size)",
121 " self.std, self.size)\n",
91 " ",
122 " \n",
92 " # We expose as properties some of the above reprs, so that the user can see them",
123 " # We expose as properties some of the above reprs, so that the user can see them\n",
93 " # directly (since otherwise the client dictates which one it shows by default)",
124 " # directly (since otherwise the client dictates which one it shows by default)\n",
94 " @property",
125 " @property\n",
95 " def png(self):",
126 " def png(self):\n",
96 " return Image(self._repr_png_(), embed=True)",
127 " return Image(self._repr_png_(), embed=True)\n",
97 " ",
128 " \n",
98 " @property",
129 " @property\n",
99 " def svg(self):",
130 " def svg(self):\n",
100 " return SVG(self._repr_svg_())",
131 " return SVG(self._repr_svg_())\n",
101 " ",
132 " \n",
102 " @property",
133 " @property\n",
103 " def latex(self):",
134 " def latex(self):\n",
104 " return Math(self._repr_svg_())",
135 " return Math(self._repr_svg_())\n",
105 " ",
136 " \n",
106 " # An example of using a property to display rich information, in this case",
137 " # An example of using a property to display rich information, in this case\n",
107 " # the histogram of the distribution. We've hardcoded the format to be png",
138 " # the histogram of the distribution. We've hardcoded the format to be png\n",
108 " # in this case, but in production code it would be trivial to make it an option",
139 " # in this case, but in production code it would be trivial to make it an option\n",
109 " @property",
140 " @property\n",
110 " def hist(self):",
141 " def hist(self):\n",
111 " fig, ax = plt.subplots()",
142 " fig, ax = plt.subplots()\n",
112 " ax.hist(self.data, bins=100)",
143 " ax.hist(self.data, bins=100)\n",
113 " ax.set_title(self._repr_latex_())",
144 " ax.set_title(self._repr_latex_())\n",
114 " data = print_figure(fig, 'png')",
145 " data = print_figure(fig, 'png')\n",
115 " plt.close(fig)",
146 " plt.close(fig)\n",
116 " return Image(data, embed=True)"
147 " return Image(data, embed=True)"
117 ],
148 ],
118 "language": "python",
149 "language": "python",
119 "outputs": [],
150 "metadata": {},
120 "prompt_number": 1
151 "outputs": []
121 },
152 },
122 {
153 {
123 "cell_type": "markdown",
154 "cell_type": "markdown",
155 "metadata": {},
124 "source": [
156 "source": [
125 "Now, we create an instance of the Gaussian distribution, whose default representation will be its LaTeX form:"
157 "Now, we create an instance of the Gaussian distribution, whose default representation will be its LaTeX form:"
126 ]
158 ]
@@ -129,15 +161,16 b''
129 "cell_type": "code",
161 "cell_type": "code",
130 "collapsed": false,
162 "collapsed": false,
131 "input": [
163 "input": [
132 "x = Gaussian()",
164 "x = Gaussian()\n",
133 "x"
165 "x"
134 ],
166 ],
135 "language": "python",
167 "language": "python",
136 "outputs": [],
168 "metadata": {},
137 "prompt_number": 2
169 "outputs": []
138 },
170 },
139 {
171 {
140 "cell_type": "markdown",
172 "cell_type": "markdown",
173 "metadata": {},
141 "source": [
174 "source": [
142 "We can view the data in png or svg formats:"
175 "We can view the data in png or svg formats:"
143 ]
176 ]
@@ -149,8 +182,8 b''
149 "x.png"
182 "x.png"
150 ],
183 ],
151 "language": "python",
184 "language": "python",
152 "outputs": [],
185 "metadata": {},
153 "prompt_number": 3
186 "outputs": []
154 },
187 },
155 {
188 {
156 "cell_type": "code",
189 "cell_type": "code",
@@ -159,13 +192,14 b''
159 "x.svg"
192 "x.svg"
160 ],
193 ],
161 "language": "python",
194 "language": "python",
162 "outputs": [],
195 "metadata": {},
163 "prompt_number": 4
196 "outputs": []
164 },
197 },
165 {
198 {
166 "cell_type": "markdown",
199 "cell_type": "markdown",
200 "metadata": {},
167 "source": [
201 "source": [
168 "Since IPython only displays by default as an ``Out[]`` cell the result of the last computation, we can use the",
202 "Since IPython only displays by default as an ``Out[]`` cell the result of the last computation, we can use the\n",
169 "``display()`` function to show more than one representation in a single cell:"
203 "``display()`` function to show more than one representation in a single cell:"
170 ]
204 ]
171 },
205 },
@@ -173,15 +207,16 b''
173 "cell_type": "code",
207 "cell_type": "code",
174 "collapsed": false,
208 "collapsed": false,
175 "input": [
209 "input": [
176 "display(x.png)",
210 "display(x.png)\n",
177 "display(x.svg)"
211 "display(x.svg)"
178 ],
212 ],
179 "language": "python",
213 "language": "python",
180 "outputs": [],
214 "metadata": {},
181 "prompt_number": 5
215 "outputs": []
182 },
216 },
183 {
217 {
184 "cell_type": "markdown",
218 "cell_type": "markdown",
219 "metadata": {},
185 "source": [
220 "source": [
186 "Now let's create a new Gaussian with different parameters"
221 "Now let's create a new Gaussian with different parameters"
187 ]
222 ]
@@ -190,15 +225,16 b''
190 "cell_type": "code",
225 "cell_type": "code",
191 "collapsed": false,
226 "collapsed": false,
192 "input": [
227 "input": [
193 "x2 = Gaussian(0.5, 0.2, 2000)",
228 "x2 = Gaussian(0.5, 0.2, 2000)\n",
194 "x2"
229 "x2"
195 ],
230 ],
196 "language": "python",
231 "language": "python",
197 "outputs": [],
232 "metadata": {},
198 "prompt_number": 6
233 "outputs": []
199 },
234 },
200 {
235 {
201 "cell_type": "markdown",
236 "cell_type": "markdown",
237 "metadata": {},
202 "source": [
238 "source": [
203 "We can easily compare them by displaying their histograms"
239 "We can easily compare them by displaying their histograms"
204 ]
240 ]
@@ -207,26 +243,27 b''
207 "cell_type": "code",
243 "cell_type": "code",
208 "collapsed": false,
244 "collapsed": false,
209 "input": [
245 "input": [
210 "display(x.hist)",
246 "display(x.hist)\n",
211 "display(x2.hist)"
247 "display(x2.hist)"
212 ],
248 ],
213 "language": "python",
249 "language": "python",
214 "outputs": [],
250 "metadata": {},
215 "prompt_number": 7
251 "outputs": []
216 },
252 },
217 {
253 {
218 "cell_type": "markdown",
254 "cell_type": "markdown",
255 "metadata": {},
219 "source": [
256 "source": [
220 "## Adding IPython display support to existing objects",
257 "## Adding IPython display support to existing objects\n",
221 "",
258 "\n",
222 "When you are directly writing your own classes, you can adapt them for display in IPython by ",
259 "When you are directly writing your own classes, you can adapt them for display in IPython by \n",
223 "following the above example. But in practice, we often need to work with existing code we",
260 "following the above example. But in practice, we often need to work with existing code we\n",
224 "can't modify. ",
261 "can't modify. \n",
225 "",
262 "\n",
226 "We now illustrate how to add these kinds of extended display capabilities to existing objects.",
263 "We now illustrate how to add these kinds of extended display capabilities to existing objects.\n",
227 "We will use the numpy polynomials and change their default representation to be a formatted",
264 "We will use the numpy polynomials and change their default representation to be a formatted\n",
228 "LaTeX expression.",
265 "LaTeX expression.\n",
229 "",
266 "\n",
230 "First, consider how a numpy polynomial object renders by default:"
267 "First, consider how a numpy polynomial object renders by default:"
231 ]
268 ]
232 },
269 },
@@ -234,48 +271,50 b''
234 "cell_type": "code",
271 "cell_type": "code",
235 "collapsed": false,
272 "collapsed": false,
236 "input": [
273 "input": [
237 "p = np.polynomial.Polynomial([1,2,3], [-10, 10])",
274 "p = np.polynomial.Polynomial([1,2,3], [-10, 10])\n",
238 "p"
275 "p"
239 ],
276 ],
240 "language": "python",
277 "language": "python",
241 "outputs": [],
278 "metadata": {},
242 "prompt_number": 8
279 "outputs": []
243 },
280 },
244 {
281 {
245 "cell_type": "markdown",
282 "cell_type": "markdown",
283 "metadata": {},
246 "source": [
284 "source": [
247 "Next, we define a function that pretty-prints a polynomial as a LaTeX string:"
285 "Next, we define a function that pretty-prints a polynomial as a LaTeX string:"
248 ]
286 ]
249 },
287 },
250 {
288 {
251 "cell_type": "code",
289 "cell_type": "code",
252 "collapsed": true,
290 "collapsed": false,
253 "input": [
291 "input": [
254 "def poly2latex(p):",
292 "def poly2latex(p):\n",
255 " terms = ['%.2g' % p.coef[0]]",
293 " terms = ['%.2g' % p.coef[0]]\n",
256 " if len(p) > 1:",
294 " if len(p) > 1:\n",
257 " term = 'x'",
295 " term = 'x'\n",
258 " c = p.coef[1]",
296 " c = p.coef[1]\n",
259 " if c!=1:",
297 " if c!=1:\n",
260 " term = ('%.2g ' % c) + term",
298 " term = ('%.2g ' % c) + term\n",
261 " terms.append(term)",
299 " terms.append(term)\n",
262 " if len(p) > 2:",
300 " if len(p) > 2:\n",
263 " for i in range(2, len(p)):",
301 " for i in range(2, len(p)):\n",
264 " term = 'x^%d' % i",
302 " term = 'x^%d' % i\n",
265 " c = p.coef[i]",
303 " c = p.coef[i]\n",
266 " if c!=1:",
304 " if c!=1:\n",
267 " term = ('%.2g ' % c) + term",
305 " term = ('%.2g ' % c) + term\n",
268 " terms.append(term)",
306 " terms.append(term)\n",
269 " px = '$P(x)=%s$' % '+'.join(terms)",
307 " px = '$P(x)=%s$' % '+'.join(terms)\n",
270 " dom = r', domain: $[%.2g,\\ %.2g]$' % tuple(p.domain)",
308 " dom = r', domain: $[%.2g,\\ %.2g]$' % tuple(p.domain)\n",
271 " return px+dom"
309 " return px+dom"
272 ],
310 ],
273 "language": "python",
311 "language": "python",
274 "outputs": [],
312 "metadata": {},
275 "prompt_number": 9
313 "outputs": []
276 },
314 },
277 {
315 {
278 "cell_type": "markdown",
316 "cell_type": "markdown",
317 "metadata": {},
279 "source": [
318 "source": [
280 "This produces, on our polynomial ``p``, the following:"
319 "This produces, on our polynomial ``p``, the following:"
281 ]
320 ]
@@ -287,59 +326,53 b''
287 "poly2latex(p)"
326 "poly2latex(p)"
288 ],
327 ],
289 "language": "python",
328 "language": "python",
290 "outputs": [],
329 "metadata": {},
291 "prompt_number": 10
330 "outputs": []
292 },
293 {
294 "cell_type": "markdown",
295 "source": [
296 "Note that this did *not* produce a formated LaTeX object, because it is simply a string ",
297 "with LaTeX code. In order for this to be interpreted as a mathematical expression, it",
298 "must be properly wrapped into a Math object:"
299 ]
300 },
331 },
301 {
332 {
302 "cell_type": "code",
333 "cell_type": "code",
303 "collapsed": false,
334 "collapsed": false,
304 "input": [
335 "input": [
305 "from IPython.core.display import Math",
336 "from IPython.display import Latex\n",
306 "Math(poly2latex(p))"
337 "Latex(poly2latex(p))"
307 ],
338 ],
308 "language": "python",
339 "language": "python",
309 "outputs": [],
340 "metadata": {},
310 "prompt_number": 11
341 "outputs": []
311 },
342 },
312 {
343 {
313 "cell_type": "markdown",
344 "cell_type": "markdown",
345 "metadata": {},
314 "source": [
346 "source": [
315 "But we can configure IPython to do this automatically for us as follows. We hook into the",
347 "But we can configure IPython to do this automatically for us as follows. We hook into the\n",
316 "IPython display system and instruct it to use ``poly2latex`` for the latex mimetype, when",
348 "IPython display system and instruct it to use ``poly2latex`` for the latex mimetype, when\n",
317 "encountering objects of the ``Polynomial`` type defined in the",
349 "encountering objects of the ``Polynomial`` type defined in the\n",
318 "``numpy.polynomial.polynomial`` module:"
350 "``numpy.polynomial.polynomial`` module:"
319 ]
351 ]
320 },
352 },
321 {
353 {
322 "cell_type": "code",
354 "cell_type": "code",
323 "collapsed": true,
355 "collapsed": false,
324 "input": [
356 "input": [
325 "ip = get_ipython()",
357 "ip = get_ipython()\n",
326 "latex_formatter = ip.display_formatter.formatters['text/latex']",
358 "latex_formatter = ip.display_formatter.formatters['text/latex']\n",
327 "latex_formatter.for_type_by_name('numpy.polynomial.polynomial',",
359 "latex_formatter.for_type_by_name('numpy.polynomial.polynomial',\n",
328 " 'Polynomial', poly2latex)"
360 " 'Polynomial', poly2latex)"
329 ],
361 ],
330 "language": "python",
362 "language": "python",
331 "outputs": [],
363 "metadata": {},
332 "prompt_number": 12
364 "outputs": []
333 },
365 },
334 {
366 {
335 "cell_type": "markdown",
367 "cell_type": "markdown",
368 "metadata": {},
336 "source": [
369 "source": [
337 "For more examples on how to use the above system, and how to bundle similar print functions",
370 "For more examples on how to use the above system, and how to bundle similar print functions\n",
338 "into a convenient IPython extension, see the ``IPython/extensions/sympyprinting.py`` file. ",
371 "into a convenient IPython extension, see the ``IPython/extensions/sympyprinting.py`` file. \n",
339 "The machinery that defines the display system is in the ``display.py`` and ``displaypub.py`` ",
372 "The machinery that defines the display system is in the ``display.py`` and ``displaypub.py`` \n",
340 "files in ``IPython/core``.",
373 "files in ``IPython/core``.\n",
341 "",
374 "\n",
342 "Once our special printer has been loaded, all polynomials will be represented by their ",
375 "Once our special printer has been loaded, all polynomials will be represented by their \n",
343 "mathematical form instead:"
376 "mathematical form instead:"
344 ]
377 ]
345 },
378 },
@@ -350,29 +383,22 b''
350 "p"
383 "p"
351 ],
384 ],
352 "language": "python",
385 "language": "python",
353 "outputs": [],
386 "metadata": {},
354 "prompt_number": 13
387 "outputs": []
355 },
388 },
356 {
389 {
357 "cell_type": "code",
390 "cell_type": "code",
358 "collapsed": false,
391 "collapsed": false,
359 "input": [
392 "input": [
360 "p2 = np.polynomial.Polynomial([-20, 71, -15, 1])",
393 "p2 = np.polynomial.Polynomial([-20, 71, -15, 1])\n",
361 "p2"
394 "p2"
362 ],
395 ],
363 "language": "python",
396 "language": "python",
364 "outputs": [],
397 "metadata": {},
365 "prompt_number": 14
398 "outputs": []
366 },
367 {
368 "cell_type": "code",
369 "collapsed": true,
370 "input": [],
371 "language": "python",
372 "outputs": [],
373 "prompt_number": 14
374 }
399 }
375 ]
400 ],
401 "metadata": {}
376 }
402 }
377 ]
403 ]
378 } No newline at end of file
404 }
@@ -3,124 +3,137 b''
3 "name": "formatting"
3 "name": "formatting"
4 },
4 },
5 "nbformat": 3,
5 "nbformat": 3,
6 "nbformat_minor": 0,
6 "worksheets": [
7 "worksheets": [
7 {
8 {
8 "cells": [
9 "cells": [
9 {
10 {
10 "cell_type": "markdown",
11 "cell_type": "markdown",
12 "metadata": {},
11 "source": [
13 "source": [
12 "# Examples of basic formatting in the notebook",
14 "# Examples of basic formatting in the notebook\n",
13 "",
15 "\n",
14 "Normal and formatted text cells such as this one use the ",
16 "Normal and formatted text cells such as this one use the \n",
15 "[Markdown](http://daringfireball.net/projects/markdown/basics) syntax.",
17 "[Markdown](http://daringfireball.net/projects/markdown/basics) syntax.\n",
16 "",
18 "\n",
17 "",
19 "\n",
18 "# Title (h1)",
20 "# Title (h1)\n",
19 "",
21 "\n",
20 "## Heading (h2)",
22 "## Heading (h2)\n",
21 "",
23 "\n",
22 "### Heading (h3)",
24 "### Heading (h3)\n",
23 "",
25 "\n",
24 "Here is a paragraph of text.",
26 "Here is a paragraph of text.\n",
25 "",
27 "\n",
26 "* One.",
28 "* One.\n",
27 " - Sublist",
29 " - Sublist\n",
28 " - Here we go",
30 " - Here we go\n",
29 " - Sublist",
31 " - Sublist\n",
30 " - Here we go",
32 " - Here we go\n",
31 " - Here we go",
33 " - Here we go\n",
32 "* Two.",
34 "* Two.\n",
33 " - Sublist",
35 " - Sublist\n",
34 "* Three.",
36 "* Three.\n",
35 " - Sublist",
37 " - Sublist\n",
36 "",
38 "\n",
37 "Now another list:",
39 "Now another list:\n",
38 "",
40 "\n",
39 "---",
41 "---\n",
40 "",
42 "\n",
41 "1. Here we go",
43 "1. Here we go\n",
42 " 1. Sublist",
44 " 1. Sublist\n",
43 " 2. Sublist",
45 " 2. Sublist\n",
44 "2. There we go",
46 "2. There we go\n",
45 "3. Now this",
47 "3. Now this\n",
46 "",
48 "\n",
47 "And another paragraph.",
49 "And another paragraph.\n",
48 "",
50 "\n",
49 "### Heading (h3)",
51 "### Heading (h3)\n",
50 "",
52 "\n",
51 "#### Heading (h4)",
53 "#### Heading (h4)\n",
52 "",
54 "\n",
53 "##### Heading (h5)",
55 "##### Heading (h5)\n",
54 "",
56 "\n",
55 "###### Heading (h6)",
57 "###### Heading (h6)\n",
56 "",
58 "\n",
57 "## Heading (h2)"
59 "## Heading (h2)"
58 ]
60 ]
59 },
61 },
60 {
62 {
61 "cell_type": "markdown",
63 "cell_type": "markdown",
64 "metadata": {},
62 "source": [
65 "source": [
63 "# Heading (h1)",
66 "# Heading (h1)\n",
64 "",
67 "\n",
65 "## Heading (h2)",
68 "## Heading (h2)\n",
66 "",
69 "\n",
67 "### Heading (h3)",
70 "### Heading (h3)\n",
68 "",
71 "\n",
69 "#### Heading (h4)",
72 "#### Heading (h4)\n",
70 "",
73 "\n",
71 "##### Heading (h5)",
74 "##### Heading (h5)\n",
72 "",
75 "\n",
73 "###### Heading (h6)",
76 "###### Heading (h6)\n",
74 "",
77 "\n",
75 "Now for a simple code example:",
78 "Now for a simple code example:\n",
76 "",
79 "\n",
77 " for i in range(10):",
80 " for i in range(10):\n",
78 " print i",
81 " print i\n",
79 "",
82 "\n",
80 "Now more text"
83 "Now more text"
81 ]
84 ]
82 },
85 },
83 {
86 {
84 "cell_type": "markdown",
87 "cell_type": "heading",
88 "level": 1,
89 "metadata": {},
85 "source": [
90 "source": [
86 "## Heading (h2)",
91 "This is a Heading Cell (level 1)"
87 "",
92 ]
88 "Here is text.",
93 },
89 "",
94 {
90 "> This is a *block* quote. This is a block quote. This is a block quote. ",
95 "cell_type": "heading",
91 "> This is a **block** quote. This is a block quote. This is a block quote. ",
96 "level": 4,
92 "> This is a `block` quote. This is a block quote. This is a block quote. ",
97 "metadata": {},
93 "> This is a block quote. This is a block quote. This is a block quote. ",
98 "source": [
94 "> This is a block quote. This is a block quote. This is a block quote. ",
99 "This is a Heading Cell (level 4)"
95 "> This is a block quote. This is a block quote. This is a block quote. ",
96 "",
97 "Here is text",
98 "",
99 "<table>",
100 "<tr>",
101 "<th>Header 1</th>",
102 "<th>Header 2</th>",
103 "</tr>",
104 "<tr>",
105 "<td>row 1, cell 1</td>",
106 "<td>row 1, cell 2</td>",
107 "</tr>",
108 "<tr>",
109 "<td>row 2, cell 1</td>",
110 "<td>row 2, cell 2</td>",
111 "</tr>",
112 "</table>"
113 ]
100 ]
114 },
101 },
115 {
102 {
116 "cell_type": "code",
103 "cell_type": "markdown",
117 "collapsed": true,
104 "metadata": {},
118 "input": [],
105 "source": [
119 "language": "python",
106 "## Heading (h2)\n",
120 "outputs": [],
107 "\n",
121 "prompt_number": "&nbsp;"
108 "Here is text.\n",
109 "\n",
110 "> This is a *block* quote. This is a block quote. This is a block quote. \n",
111 "> This is a **block** quote. This is a block quote. This is a block quote. \n",
112 "> This is a `block` quote. This is a block quote. This is a block quote. \n",
113 "> This is a block quote. This is a block quote. This is a block quote. \n",
114 "> This is a block quote. This is a block quote. This is a block quote. \n",
115 "> This is a block quote. This is a block quote. This is a block quote. \n",
116 "\n",
117 "Here is text\n",
118 "\n",
119 "<table>\n",
120 "<tr>\n",
121 "<th>Header 1</th>\n",
122 "<th>Header 2</th>\n",
123 "</tr>\n",
124 "<tr>\n",
125 "<td>row 1, cell 1</td>\n",
126 "<td>row 1, cell 2</td>\n",
127 "</tr>\n",
128 "<tr>\n",
129 "<td>row 2, cell 1</td>\n",
130 "<td>row 2, cell 2</td>\n",
131 "</tr>\n",
132 "</table>"
133 ]
122 }
134 }
123 ]
135 ],
136 "metadata": {}
124 }
137 }
125 ]
138 ]
126 } No newline at end of file
139 }
@@ -3,12 +3,14 b''
3 "name": "octavemagic_extension"
3 "name": "octavemagic_extension"
4 },
4 },
5 "nbformat": 3,
5 "nbformat": 3,
6 "nbformat_minor": 0,
6 "worksheets": [
7 "worksheets": [
7 {
8 {
8 "cells": [
9 "cells": [
9 {
10 {
10 "cell_type": "heading",
11 "cell_type": "heading",
11 "level": 1,
12 "level": 1,
13 "metadata": {},
12 "source": [
14 "source": [
13 "octavemagic: Octave inside IPython"
15 "octavemagic: Octave inside IPython"
14 ]
16 ]
@@ -16,57 +18,65 b''
16 {
18 {
17 "cell_type": "heading",
19 "cell_type": "heading",
18 "level": 2,
20 "level": 2,
21 "metadata": {},
19 "source": [
22 "source": [
20 "Installation"
23 "Installation"
21 ]
24 ]
22 },
25 },
23 {
26 {
24 "cell_type": "markdown",
27 "cell_type": "markdown",
28 "metadata": {},
25 "source": [
29 "source": [
26 "The `octavemagic` extension provides the ability to interact with Octave. It depends on the `oct2py` and `h5py` packages,",
30 "The `octavemagic` extension provides the ability to interact with Octave. It depends on the `oct2py` and `h5py` packages,\n",
27 "which may be installed using `easy_install`.",
31 "which may be installed using `easy_install`.\n",
28 "",
32 "\n",
29 "To enable the extension, load it as follows:"
33 "To enable the extension, load it as follows:"
30 ]
34 ]
31 },
35 },
32 {
36 {
33 "cell_type": "code",
37 "cell_type": "code",
38 "collapsed": false,
34 "input": [
39 "input": [
35 "%load_ext octavemagic"
40 "%load_ext octavemagic"
36 ],
41 ],
37 "language": "python",
42 "language": "python",
43 "metadata": {},
38 "outputs": [],
44 "outputs": [],
39 "prompt_number": 18
45 "prompt_number": 18
40 },
46 },
41 {
47 {
42 "cell_type": "heading",
48 "cell_type": "heading",
43 "level": 2,
49 "level": 2,
50 "metadata": {},
44 "source": [
51 "source": [
45 "Overview"
52 "Overview"
46 ]
53 ]
47 },
54 },
48 {
55 {
49 "cell_type": "markdown",
56 "cell_type": "markdown",
57 "metadata": {},
50 "source": [
58 "source": [
51 "Loading the extension enables three magic functions: `%octave`, `%octave_push`, and `%octave_pull`.",
59 "Loading the extension enables three magic functions: `%octave`, `%octave_push`, and `%octave_pull`.\n",
52 "",
60 "\n",
53 "The first is for executing one or more lines of Octave, while the latter allow moving variables between the Octave and Python workspace.",
61 "The first is for executing one or more lines of Octave, while the latter allow moving variables between the Octave and Python workspace.\n",
54 "Here you see an example of how to execute a single line of Octave, and how to transfer the generated value back to Python:"
62 "Here you see an example of how to execute a single line of Octave, and how to transfer the generated value back to Python:"
55 ]
63 ]
56 },
64 },
57 {
65 {
58 "cell_type": "code",
66 "cell_type": "code",
67 "collapsed": false,
59 "input": [
68 "input": [
60 "x = %octave [1 2; 3 4];",
69 "x = %octave [1 2; 3 4];\n",
61 "x"
70 "x"
62 ],
71 ],
63 "language": "python",
72 "language": "python",
73 "metadata": {},
64 "outputs": [
74 "outputs": [
65 {
75 {
66 "output_type": "pyout",
76 "output_type": "pyout",
67 "prompt_number": 19,
77 "prompt_number": 19,
68 "text": [
78 "text": [
69 "array([[ 1., 2.],",
79 "array([[ 1., 2.],\n",
70 " [ 3., 4.]])"
80 " [ 3., 4.]])"
71 ]
81 ]
72 }
82 }
@@ -75,15 +85,17 b''
75 },
85 },
76 {
86 {
77 "cell_type": "code",
87 "cell_type": "code",
88 "collapsed": false,
78 "input": [
89 "input": [
79 "a = [1, 2, 3]",
90 "a = [1, 2, 3]\n",
80 "",
91 "\n",
81 "%octave_push a",
92 "%octave_push a\n",
82 "%octave a = a * 2;",
93 "%octave a = a * 2;\n",
83 "%octave_pull a",
94 "%octave_pull a\n",
84 "a"
95 "a"
85 ],
96 ],
86 "language": "python",
97 "language": "python",
98 "metadata": {},
87 "outputs": [
99 "outputs": [
88 {
100 {
89 "output_type": "pyout",
101 "output_type": "pyout",
@@ -97,33 +109,38 b''
97 },
109 },
98 {
110 {
99 "cell_type": "markdown",
111 "cell_type": "markdown",
112 "metadata": {},
100 "source": [
113 "source": [
101 "When using the cell magic, `%%octave` (note the double `%`), multiple lines of Octave can be executed together. Unlike",
114 "When using the cell magic, `%%octave` (note the double `%`), multiple lines of Octave can be executed together. Unlike\n",
102 "with the single cell magic, no value is returned, so we use the `-i` and `-o` flags to specify input and output variables."
115 "with the single cell magic, no value is returned, so we use the `-i` and `-o` flags to specify input and output variables."
103 ]
116 ]
104 },
117 },
105 {
118 {
106 "cell_type": "code",
119 "cell_type": "code",
120 "collapsed": false,
107 "input": [
121 "input": [
108 "%%octave -i x -o y",
122 "%%octave -i x -o y\n",
109 "y = x + 3;"
123 "y = x + 3;"
110 ],
124 ],
111 "language": "python",
125 "language": "python",
126 "metadata": {},
112 "outputs": [],
127 "outputs": [],
113 "prompt_number": 21
128 "prompt_number": 21
114 },
129 },
115 {
130 {
116 "cell_type": "code",
131 "cell_type": "code",
132 "collapsed": false,
117 "input": [
133 "input": [
118 "y"
134 "y"
119 ],
135 ],
120 "language": "python",
136 "language": "python",
137 "metadata": {},
121 "outputs": [
138 "outputs": [
122 {
139 {
123 "output_type": "pyout",
140 "output_type": "pyout",
124 "prompt_number": 22,
141 "prompt_number": 22,
125 "text": [
142 "text": [
126 "array([[ 4., 5.],",
143 "array([[ 4., 5.],\n",
127 " [ 6., 7.]])"
144 " [ 6., 7.]])"
128 ]
145 ]
129 }
146 }
@@ -133,28 +150,32 b''
133 {
150 {
134 "cell_type": "heading",
151 "cell_type": "heading",
135 "level": 2,
152 "level": 2,
153 "metadata": {},
136 "source": [
154 "source": [
137 "Plotting"
155 "Plotting"
138 ]
156 ]
139 },
157 },
140 {
158 {
141 "cell_type": "markdown",
159 "cell_type": "markdown",
160 "metadata": {},
142 "source": [
161 "source": [
143 "Plot output is automatically captured and displayed, and using the `-f` flag you may choose its format (currently, `png` and `svg` are supported)."
162 "Plot output is automatically captured and displayed, and using the `-f` flag you may choose its format (currently, `png` and `svg` are supported)."
144 ]
163 ]
145 },
164 },
146 {
165 {
147 "cell_type": "code",
166 "cell_type": "code",
167 "collapsed": false,
148 "input": [
168 "input": [
149 "%%octave -f svg",
169 "%%octave -f svg\n",
150 "",
170 "\n",
151 "p = [12 -2.5 -8 -0.1 8];",
171 "p = [12 -2.5 -8 -0.1 8];\n",
152 "x = 0:0.01:1;",
172 "x = 0:0.01:1;\n",
153 "",
173 "\n",
154 "polyout(p, 'x')",
174 "polyout(p, 'x')\n",
155 "plot(x, polyval(p, x));"
175 "plot(x, polyval(p, x));"
156 ],
176 ],
157 "language": "python",
177 "language": "python",
178 "metadata": {},
158 "outputs": [
179 "outputs": [
159 {
180 {
160 "output_type": "display_data",
181 "output_type": "display_data",
@@ -165,111 +186,111 b''
165 {
186 {
166 "output_type": "display_data",
187 "output_type": "display_data",
167 "svg": [
188 "svg": [
168 "<svg height=\"240px\" viewBox=\"0 0 192 115\" width=\"400px\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">",
189 "<svg height=\"240px\" viewBox=\"0 0 192 115\" width=\"400px\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
169 "",
190 "\n",
170 "<desc>Produced by GNUPLOT 4.4 patchlevel 0 </desc>",
191 "<desc>Produced by GNUPLOT 4.4 patchlevel 0 </desc>\n",
171 "",
192 "\n",
172 "<defs>",
193 "<defs>\n",
173 "",
194 "\n",
174 "\t<circle id=\"gpDot\" r=\"0.5\" stroke-width=\"0.5\"/>",
195 "\t<circle id=\"gpDot\" r=\"0.5\" stroke-width=\"0.5\"/>\n",
175 "\t<path d=\"M-1,0 h2 M0,-1 v2\" id=\"gpPt0\" stroke=\"currentColor\" stroke-width=\"0.333\"/>",
196 "\t<path d=\"M-1,0 h2 M0,-1 v2\" id=\"gpPt0\" stroke=\"currentColor\" stroke-width=\"0.333\"/>\n",
176 "\t<path d=\"M-1,-1 L1,1 M1,-1 L-1,1\" id=\"gpPt1\" stroke=\"currentColor\" stroke-width=\"0.333\"/>",
197 "\t<path d=\"M-1,-1 L1,1 M1,-1 L-1,1\" id=\"gpPt1\" stroke=\"currentColor\" stroke-width=\"0.333\"/>\n",
177 "\t<path d=\"M-1,0 L1,0 M0,-1 L0,1 M-1,-1 L1,1 M-1,1 L1,-1\" id=\"gpPt2\" stroke=\"currentColor\" stroke-width=\"0.333\"/>",
198 "\t<path d=\"M-1,0 L1,0 M0,-1 L0,1 M-1,-1 L1,1 M-1,1 L1,-1\" id=\"gpPt2\" stroke=\"currentColor\" stroke-width=\"0.333\"/>\n",
178 "\t<rect height=\"2\" id=\"gpPt3\" stroke=\"currentColor\" stroke-width=\"0.333\" width=\"2\" x=\"-1\" y=\"-1\"/>",
199 "\t<rect height=\"2\" id=\"gpPt3\" stroke=\"currentColor\" stroke-width=\"0.333\" width=\"2\" x=\"-1\" y=\"-1\"/>\n",
179 "\t<rect fill=\"currentColor\" height=\"2\" id=\"gpPt4\" stroke=\"currentColor\" stroke-width=\"0.333\" width=\"2\" x=\"-1\" y=\"-1\"/>",
200 "\t<rect fill=\"currentColor\" height=\"2\" id=\"gpPt4\" stroke=\"currentColor\" stroke-width=\"0.333\" width=\"2\" x=\"-1\" y=\"-1\"/>\n",
180 "\t<circle cx=\"0\" cy=\"0\" id=\"gpPt5\" r=\"1\" stroke=\"currentColor\" stroke-width=\"0.333\"/>",
201 "\t<circle cx=\"0\" cy=\"0\" id=\"gpPt5\" r=\"1\" stroke=\"currentColor\" stroke-width=\"0.333\"/>\n",
181 "\t<use fill=\"currentColor\" id=\"gpPt6\" stroke=\"none\" xlink:href=\"#gpPt5\"/>",
202 "\t<use fill=\"currentColor\" id=\"gpPt6\" stroke=\"none\" xlink:href=\"#gpPt5\"/>\n",
182 "\t<path d=\"M0,-1.33 L-1.33,0.67 L1.33,0.67 z\" id=\"gpPt7\" stroke=\"currentColor\" stroke-width=\"0.333\"/>",
203 "\t<path d=\"M0,-1.33 L-1.33,0.67 L1.33,0.67 z\" id=\"gpPt7\" stroke=\"currentColor\" stroke-width=\"0.333\"/>\n",
183 "\t<use fill=\"currentColor\" id=\"gpPt8\" stroke=\"none\" xlink:href=\"#gpPt7\"/>",
204 "\t<use fill=\"currentColor\" id=\"gpPt8\" stroke=\"none\" xlink:href=\"#gpPt7\"/>\n",
184 "\t<use id=\"gpPt9\" stroke=\"currentColor\" transform=\"rotate(180)\" xlink:href=\"#gpPt7\"/>",
205 "\t<use id=\"gpPt9\" stroke=\"currentColor\" transform=\"rotate(180)\" xlink:href=\"#gpPt7\"/>\n",
185 "\t<use fill=\"currentColor\" id=\"gpPt10\" stroke=\"none\" xlink:href=\"#gpPt9\"/>",
206 "\t<use fill=\"currentColor\" id=\"gpPt10\" stroke=\"none\" xlink:href=\"#gpPt9\"/>\n",
186 "\t<use id=\"gpPt11\" stroke=\"currentColor\" transform=\"rotate(45)\" xlink:href=\"#gpPt3\"/>",
207 "\t<use id=\"gpPt11\" stroke=\"currentColor\" transform=\"rotate(45)\" xlink:href=\"#gpPt3\"/>\n",
187 "\t<use fill=\"currentColor\" id=\"gpPt12\" stroke=\"none\" xlink:href=\"#gpPt11\"/>",
208 "\t<use fill=\"currentColor\" id=\"gpPt12\" stroke=\"none\" xlink:href=\"#gpPt11\"/>\n",
188 "</defs>",
209 "</defs>\n",
189 "<g style=\"fill:none; color:white; stroke:currentColor; stroke-width:1.00; stroke-linecap:butt; stroke-linejoin:miter\">",
210 "<g style=\"fill:none; color:white; stroke:currentColor; stroke-width:1.00; stroke-linecap:butt; stroke-linejoin:miter\">\n",
190 "</g>",
211 "</g>\n",
191 "<g style=\"fill:none; color:white; stroke:currentColor; stroke-width:0.50; stroke-linecap:butt; stroke-linejoin:miter\">",
212 "<g style=\"fill:none; color:white; stroke:currentColor; stroke-width:0.50; stroke-linecap:butt; stroke-linejoin:miter\">\n",
192 "</g>",
213 "</g>\n",
193 "<g style=\"fill:none; color:black; stroke:currentColor; stroke-width:0.50; stroke-linecap:butt; stroke-linejoin:miter\">",
214 "<g style=\"fill:none; color:black; stroke:currentColor; stroke-width:0.50; stroke-linecap:butt; stroke-linejoin:miter\">\n",
194 "\t<path d=\"M36.4,91.2 L44.8,91.2 M177.9,91.2 L169.5,91.2 \"/>",
215 "\t<path d=\"M36.4,91.2 L44.8,91.2 M177.9,91.2 L169.5,91.2 \"/>\n",
195 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:end\" transform=\"translate(30.8,94.2)\">",
216 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:end\" transform=\"translate(30.8,94.2)\">\n",
196 "\t\t<text><tspan>6</tspan>",
217 "\t\t<text><tspan>6</tspan>\n",
197 "\t\t</text>",
218 "\t\t</text>\n",
198 "\t</g>",
219 "\t</g>\n",
199 "\t<path d=\"M36.4,79.8 L44.8,79.8 M177.9,79.8 L169.5,79.8 \"/>",
220 "\t<path d=\"M36.4,79.8 L44.8,79.8 M177.9,79.8 L169.5,79.8 \"/>\n",
200 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:end\" transform=\"translate(30.8,82.8)\">",
221 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:end\" transform=\"translate(30.8,82.8)\">\n",
201 "\t\t<text><tspan>6.5</tspan>",
222 "\t\t<text><tspan>6.5</tspan>\n",
202 "\t\t</text>",
223 "\t\t</text>\n",
203 "\t</g>",
224 "\t</g>\n",
204 "\t<path d=\"M36.4,68.4 L44.8,68.4 M177.9,68.4 L169.5,68.4 \"/>",
225 "\t<path d=\"M36.4,68.4 L44.8,68.4 M177.9,68.4 L169.5,68.4 \"/>\n",
205 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:end\" transform=\"translate(30.8,71.4)\">",
226 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:end\" transform=\"translate(30.8,71.4)\">\n",
206 "\t\t<text><tspan>7</tspan>",
227 "\t\t<text><tspan>7</tspan>\n",
207 "\t\t</text>",
228 "\t\t</text>\n",
208 "\t</g>",
229 "\t</g>\n",
209 "\t<path d=\"M36.4,57.0 L44.8,57.0 M177.9,57.0 L169.5,57.0 \"/>",
230 "\t<path d=\"M36.4,57.0 L44.8,57.0 M177.9,57.0 L169.5,57.0 \"/>\n",
210 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:end\" transform=\"translate(30.8,60.0)\">",
231 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:end\" transform=\"translate(30.8,60.0)\">\n",
211 "\t\t<text><tspan>7.5</tspan>",
232 "\t\t<text><tspan>7.5</tspan>\n",
212 "\t\t</text>",
233 "\t\t</text>\n",
213 "\t</g>",
234 "\t</g>\n",
214 "\t<path d=\"M36.4,45.5 L44.8,45.5 M177.9,45.5 L169.5,45.5 \"/>",
235 "\t<path d=\"M36.4,45.5 L44.8,45.5 M177.9,45.5 L169.5,45.5 \"/>\n",
215 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:end\" transform=\"translate(30.8,48.5)\">",
236 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:end\" transform=\"translate(30.8,48.5)\">\n",
216 "\t\t<text><tspan>8</tspan>",
237 "\t\t<text><tspan>8</tspan>\n",
217 "\t\t</text>",
238 "\t\t</text>\n",
218 "\t</g>",
239 "\t</g>\n",
219 "\t<path d=\"M36.4,34.1 L44.8,34.1 M177.9,34.1 L169.5,34.1 \"/>",
240 "\t<path d=\"M36.4,34.1 L44.8,34.1 M177.9,34.1 L169.5,34.1 \"/>\n",
220 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:end\" transform=\"translate(30.8,37.1)\">",
241 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:end\" transform=\"translate(30.8,37.1)\">\n",
221 "\t\t<text><tspan>8.5</tspan>",
242 "\t\t<text><tspan>8.5</tspan>\n",
222 "\t\t</text>",
243 "\t\t</text>\n",
223 "\t</g>",
244 "\t</g>\n",
224 "\t<path d=\"M36.4,22.7 L44.8,22.7 M177.9,22.7 L169.5,22.7 \"/>",
245 "\t<path d=\"M36.4,22.7 L44.8,22.7 M177.9,22.7 L169.5,22.7 \"/>\n",
225 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:end\" transform=\"translate(30.8,25.7)\">",
246 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:end\" transform=\"translate(30.8,25.7)\">\n",
226 "\t\t<text><tspan>9</tspan>",
247 "\t\t<text><tspan>9</tspan>\n",
227 "\t\t</text>",
248 "\t\t</text>\n",
228 "\t</g>",
249 "\t</g>\n",
229 "\t<path d=\"M36.4,11.3 L44.8,11.3 M177.9,11.3 L169.5,11.3 \"/>",
250 "\t<path d=\"M36.4,11.3 L44.8,11.3 M177.9,11.3 L169.5,11.3 \"/>\n",
230 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:end\" transform=\"translate(30.8,14.3)\">",
251 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:end\" transform=\"translate(30.8,14.3)\">\n",
231 "\t\t<text><tspan>9.5</tspan>",
252 "\t\t<text><tspan>9.5</tspan>\n",
232 "\t\t</text>",
253 "\t\t</text>\n",
233 "\t</g>",
254 "\t</g>\n",
234 "\t<path d=\"M36.4,91.2 L36.4,82.8 M36.4,11.3 L36.4,19.7 \"/>",
255 "\t<path d=\"M36.4,91.2 L36.4,82.8 M36.4,11.3 L36.4,19.7 \"/>\n",
235 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:middle\" transform=\"translate(36.4,106.2)\">",
256 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:middle\" transform=\"translate(36.4,106.2)\">\n",
236 "\t\t<text><tspan>0</tspan>",
257 "\t\t<text><tspan>0</tspan>\n",
237 "\t\t</text>",
258 "\t\t</text>\n",
238 "\t</g>",
259 "\t</g>\n",
239 "\t<path d=\"M64.7,91.2 L64.7,82.8 M64.7,11.3 L64.7,19.7 \"/>",
260 "\t<path d=\"M64.7,91.2 L64.7,82.8 M64.7,11.3 L64.7,19.7 \"/>\n",
240 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:middle\" transform=\"translate(64.7,106.2)\">",
261 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:middle\" transform=\"translate(64.7,106.2)\">\n",
241 "\t\t<text><tspan>0.2</tspan>",
262 "\t\t<text><tspan>0.2</tspan>\n",
242 "\t\t</text>",
263 "\t\t</text>\n",
243 "\t</g>",
264 "\t</g>\n",
244 "\t<path d=\"M93.0,91.2 L93.0,82.8 M93.0,11.3 L93.0,19.7 \"/>",
265 "\t<path d=\"M93.0,91.2 L93.0,82.8 M93.0,11.3 L93.0,19.7 \"/>\n",
245 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:middle\" transform=\"translate(93.0,106.2)\">",
266 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:middle\" transform=\"translate(93.0,106.2)\">\n",
246 "\t\t<text><tspan>0.4</tspan>",
267 "\t\t<text><tspan>0.4</tspan>\n",
247 "\t\t</text>",
268 "\t\t</text>\n",
248 "\t</g>",
269 "\t</g>\n",
249 "\t<path d=\"M121.3,91.2 L121.3,82.8 M121.3,11.3 L121.3,19.7 \"/>",
270 "\t<path d=\"M121.3,91.2 L121.3,82.8 M121.3,11.3 L121.3,19.7 \"/>\n",
250 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:middle\" transform=\"translate(121.3,106.2)\">",
271 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:middle\" transform=\"translate(121.3,106.2)\">\n",
251 "\t\t<text><tspan>0.6</tspan>",
272 "\t\t<text><tspan>0.6</tspan>\n",
252 "\t\t</text>",
273 "\t\t</text>\n",
253 "\t</g>",
274 "\t</g>\n",
254 "\t<path d=\"M149.6,91.2 L149.6,82.8 M149.6,11.3 L149.6,19.7 \"/>",
275 "\t<path d=\"M149.6,91.2 L149.6,82.8 M149.6,11.3 L149.6,19.7 \"/>\n",
255 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:middle\" transform=\"translate(149.6,106.2)\">",
276 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:middle\" transform=\"translate(149.6,106.2)\">\n",
256 "\t\t<text><tspan>0.8</tspan>",
277 "\t\t<text><tspan>0.8</tspan>\n",
257 "\t\t</text>",
278 "\t\t</text>\n",
258 "\t</g>",
279 "\t</g>\n",
259 "\t<path d=\"M177.9,91.2 L177.9,82.8 M177.9,11.3 L177.9,19.7 \"/>",
280 "\t<path d=\"M177.9,91.2 L177.9,82.8 M177.9,11.3 L177.9,19.7 \"/>\n",
260 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:middle\" transform=\"translate(177.9,106.2)\">",
281 "\t<g style=\"stroke:none; fill:rgb(0,0,0); font-family:{}; font-size:10.00pt; text-anchor:middle\" transform=\"translate(177.9,106.2)\">\n",
261 "\t\t<text><tspan>1</tspan>",
282 "\t\t<text><tspan>1</tspan>\n",
262 "\t\t</text>",
283 "\t\t</text>\n",
263 "\t</g>",
284 "\t</g>\n",
264 "\t<path d=\"M36.4,11.3 L36.4,91.2 L177.9,91.2 L177.9,11.3 L36.4,11.3 Z \"/>",
285 "\t<path d=\"M36.4,11.3 L36.4,91.2 L177.9,91.2 L177.9,11.3 L36.4,11.3 Z \"/>\n",
265 "</g>",
286 "</g>\n",
266 "\t<a xlink:title=\"Plot #1\">",
287 "\t<a xlink:title=\"Plot #1\">\n",
267 "<g style=\"fill:none; color:red; stroke:currentColor; stroke-width:0.50; stroke-linecap:butt; stroke-linejoin:miter\">",
288 "<g style=\"fill:none; color:red; stroke:currentColor; stroke-width:0.50; stroke-linecap:butt; stroke-linejoin:miter\">\n",
268 "\t<path d=\"M36.4,45.5 L37.8,45.6 L39.2,45.7 L40.6,45.8 L42.1,45.9 L43.5,46.1 L44.9,46.3 L46.3,46.6 L47.7,46.9 L49.1,47.3 L50.6,47.6 L52.0,48.0 L53.4,48.5 L54.8,49.0 L56.2,49.5 L57.6,50.0 L59.0,50.6 L60.5,51.3 L61.9,51.9 L63.3,52.6 L64.7,53.3 L66.1,54.1 L67.5,54.9 L68.9,55.7 L70.4,56.5 L71.8,57.3 L73.2,58.2 L74.6,59.1 L76.0,60.1 L77.4,61.0 L78.9,62.0 L80.3,63.0 L81.7,64.0 L83.1,65.0 L84.5,66.0 L85.9,67.0 L87.3,68.1 L88.8,69.1 L90.2,70.2 L91.6,71.3 L93.0,72.3 L94.4,73.4 L95.8,74.4 L97.2,75.5 L98.7,76.5 L100.1,77.5 L101.5,78.5 L102.9,79.5 L104.3,80.5 L105.7,81.4 L107.2,82.4 L108.6,83.2 L110.0,84.1 L111.4,84.9 L112.8,85.7 L114.2,86.5 L115.6,87.2 L117.1,87.8 L118.5,88.4 L119.9,89.0 L121.3,89.5 L122.7,89.9 L124.1,90.3 L125.5,90.6 L127.0,90.8 L128.4,91.0 L129.8,91.0 L131.2,91.0 L132.6,90.9 L134.0,90.7 L135.5,90.4 L136.9,90.0 L138.3,89.5 L139.7,88.9 L141.1,88.2 L142.5,87.4 L143.9,86.4 L145.4,85.3 L146.8,84.1 L148.2,82.8 L149.6,81.3 L151.0,79.6 L152.4,77.8 L153.8,75.9 L155.3,73.8 L156.7,71.5 L158.1,69.0 L159.5,66.4 L160.9,63.6 L162.3,60.6 L163.8,57.4 L165.2,54.0 L166.6,50.4 L168.0,46.6 L169.4,42.6 L170.8,38.3 L172.2,33.9 L173.7,29.2 L175.1,24.2 L176.5,19.0 L177.9,13.6 \" stroke=\"rgb( 0, 0, 255)\"/>",
289 "\t<path d=\"M36.4,45.5 L37.8,45.6 L39.2,45.7 L40.6,45.8 L42.1,45.9 L43.5,46.1 L44.9,46.3 L46.3,46.6 L47.7,46.9 L49.1,47.3 L50.6,47.6 L52.0,48.0 L53.4,48.5 L54.8,49.0 L56.2,49.5 L57.6,50.0 L59.0,50.6 L60.5,51.3 L61.9,51.9 L63.3,52.6 L64.7,53.3 L66.1,54.1 L67.5,54.9 L68.9,55.7 L70.4,56.5 L71.8,57.3 L73.2,58.2 L74.6,59.1 L76.0,60.1 L77.4,61.0 L78.9,62.0 L80.3,63.0 L81.7,64.0 L83.1,65.0 L84.5,66.0 L85.9,67.0 L87.3,68.1 L88.8,69.1 L90.2,70.2 L91.6,71.3 L93.0,72.3 L94.4,73.4 L95.8,74.4 L97.2,75.5 L98.7,76.5 L100.1,77.5 L101.5,78.5 L102.9,79.5 L104.3,80.5 L105.7,81.4 L107.2,82.4 L108.6,83.2 L110.0,84.1 L111.4,84.9 L112.8,85.7 L114.2,86.5 L115.6,87.2 L117.1,87.8 L118.5,88.4 L119.9,89.0 L121.3,89.5 L122.7,89.9 L124.1,90.3 L125.5,90.6 L127.0,90.8 L128.4,91.0 L129.8,91.0 L131.2,91.0 L132.6,90.9 L134.0,90.7 L135.5,90.4 L136.9,90.0 L138.3,89.5 L139.7,88.9 L141.1,88.2 L142.5,87.4 L143.9,86.4 L145.4,85.3 L146.8,84.1 L148.2,82.8 L149.6,81.3 L151.0,79.6 L152.4,77.8 L153.8,75.9 L155.3,73.8 L156.7,71.5 L158.1,69.0 L159.5,66.4 L160.9,63.6 L162.3,60.6 L163.8,57.4 L165.2,54.0 L166.6,50.4 L168.0,46.6 L169.4,42.6 L170.8,38.3 L172.2,33.9 L173.7,29.2 L175.1,24.2 L176.5,19.0 L177.9,13.6 \" stroke=\"rgb( 0, 0, 255)\"/>\n",
269 "</g>",
290 "</g>\n",
270 "\t</a>",
291 "\t</a>\n",
271 "<g style=\"fill:none; color:black; stroke:currentColor; stroke-width:0.50; stroke-linecap:butt; stroke-linejoin:miter\">",
292 "<g style=\"fill:none; color:black; stroke:currentColor; stroke-width:0.50; stroke-linecap:butt; stroke-linejoin:miter\">\n",
272 "</g>",
293 "</g>\n",
273 "</svg>"
294 "</svg>"
274 ]
295 ]
275 }
296 }
@@ -278,21 +299,24 b''
278 },
299 },
279 {
300 {
280 "cell_type": "markdown",
301 "cell_type": "markdown",
302 "metadata": {},
281 "source": [
303 "source": [
282 "The plot size is adjusted using the `-s` flag:"
304 "The plot size is adjusted using the `-s` flag:"
283 ]
305 ]
284 },
306 },
285 {
307 {
286 "cell_type": "code",
308 "cell_type": "code",
309 "collapsed": false,
287 "input": [
310 "input": [
288 "%%octave -s 500,500",
311 "%%octave -s 500,500\n",
289 "",
312 "\n",
290 "# butterworth filter, order 2, cutoff pi/2 radians",
313 "# butterworth filter, order 2, cutoff pi/2 radians\n",
291 "b = [0.292893218813452 0.585786437626905 0.292893218813452];",
314 "b = [0.292893218813452 0.585786437626905 0.292893218813452];\n",
292 "a = [1 0 0.171572875253810];",
315 "a = [1 0 0.171572875253810];\n",
293 "freqz(b, a, 32);"
316 "freqz(b, a, 32);"
294 ],
317 ],
295 "language": "python",
318 "language": "python",
319 "metadata": {},
296 "outputs": [
320 "outputs": [
297 {
321 {
298 "output_type": "display_data",
322 "output_type": "display_data",
@@ -303,18 +327,20 b''
303 },
327 },
304 {
328 {
305 "cell_type": "code",
329 "cell_type": "code",
330 "collapsed": false,
306 "input": [
331 "input": [
307 "%%octave -s 600,200 -f png",
332 "%%octave -s 600,200 -f png\n",
308 "",
333 "\n",
309 "subplot(121);",
334 "subplot(121);\n",
310 "[x, y] = meshgrid(0:0.1:3);",
335 "[x, y] = meshgrid(0:0.1:3);\n",
311 "r = sin(x - 0.5).^2 + cos(y - 0.5).^2;",
336 "r = sin(x - 0.5).^2 + cos(y - 0.5).^2;\n",
312 "surf(x, y, r);",
337 "surf(x, y, r);\n",
313 "",
338 "\n",
314 "subplot(122);",
339 "subplot(122);\n",
315 "sombrero()"
340 "sombrero()"
316 ],
341 ],
317 "language": "python",
342 "language": "python",
343 "metadata": {},
318 "outputs": [
344 "outputs": [
319 {
345 {
320 "output_type": "display_data",
346 "output_type": "display_data",
@@ -326,17 +352,20 b''
326 {
352 {
327 "cell_type": "heading",
353 "cell_type": "heading",
328 "level": 2,
354 "level": 2,
355 "metadata": {},
329 "source": [
356 "source": [
330 "Future work"
357 "Future work"
331 ]
358 ]
332 },
359 },
333 {
360 {
334 "cell_type": "markdown",
361 "cell_type": "markdown",
362 "metadata": {},
335 "source": [
363 "source": [
336 "After the next release of `oct2py`, we'll add the ability to interrupt/kill the current Octave session without restarting the Python kernel."
364 "After the next release of `oct2py`, we'll add the ability to interrupt/kill the current Octave session without restarting the Python kernel."
337 ]
365 ]
338 }
366 }
339 ]
367 ],
368 "metadata": {}
340 }
369 }
341 ]
370 ]
342 } No newline at end of file
371 }
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now