##// END OF EJS Templates
Merge pull request #5897 from ellisonbg/notebook-docs...
Jonathan Frederic -
r17699:3beb4de5 merge
parent child Browse files
Show More

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

This diff has been collapsed as it changes many lines, (1613 lines changed) Show them Hide them
@@ -0,0 +1,1613 b''
1 {
2 "metadata": {
3 "name": "",
4 "signature": "sha256:31071a05d0ecd75ed72fe3f0de0ad447a6f85cffe382c26efa5e68db1fee54ee"
5 },
6 "nbformat": 3,
7 "nbformat_minor": 0,
8 "worksheets": [
9 {
10 "cells": [
11 {
12 "cell_type": "heading",
13 "level": 1,
14 "metadata": {
15 "slideshow": {
16 "slide_type": "slide"
17 }
18 },
19 "source": [
20 "IPython: beyond plain Python"
21 ]
22 },
23 {
24 "cell_type": "markdown",
25 "metadata": {},
26 "source": [
27 "When executing code in IPython, all valid Python syntax works as-is, but IPython provides a number of features designed to make the interactive experience more fluid and efficient."
28 ]
29 },
30 {
31 "cell_type": "heading",
32 "level": 2,
33 "metadata": {
34 "slideshow": {
35 "slide_type": "slide"
36 }
37 },
38 "source": [
39 "First things first: running code, getting help"
40 ]
41 },
42 {
43 "cell_type": "markdown",
44 "metadata": {},
45 "source": [
46 "In the notebook, to run a cell of code, hit `Shift-Enter`. This executes the cell and puts the cursor in the next cell below, or makes a new one if you are at the end. Alternately, you can use:\n",
47 " \n",
48 "- `Alt-Enter` to force the creation of a new cell unconditionally (useful when inserting new content in the middle of an existing notebook).\n",
49 "- `Control-Enter` executes the cell and keeps the cursor in the same cell, useful for quick experimentation of snippets that you don't need to keep permanently."
50 ]
51 },
52 {
53 "cell_type": "code",
54 "collapsed": false,
55 "input": [
56 "print \"Hi\""
57 ],
58 "language": "python",
59 "metadata": {},
60 "outputs": [
61 {
62 "output_type": "stream",
63 "stream": "stdout",
64 "text": [
65 "Hi\n"
66 ]
67 }
68 ],
69 "prompt_number": 1
70 },
71 {
72 "cell_type": "markdown",
73 "metadata": {
74 "slideshow": {
75 "slide_type": "slide"
76 }
77 },
78 "source": [
79 "Getting help:"
80 ]
81 },
82 {
83 "cell_type": "code",
84 "collapsed": false,
85 "input": [
86 "?"
87 ],
88 "language": "python",
89 "metadata": {},
90 "outputs": [],
91 "prompt_number": 2
92 },
93 {
94 "cell_type": "markdown",
95 "metadata": {
96 "slideshow": {
97 "slide_type": "slide"
98 }
99 },
100 "source": [
101 "Typing `object_name?` will print all sorts of details about any object, including docstrings, function definition lines (for call arguments) and constructor details for classes."
102 ]
103 },
104 {
105 "cell_type": "code",
106 "collapsed": false,
107 "input": [
108 "import collections\n",
109 "collections.namedtuple?"
110 ],
111 "language": "python",
112 "metadata": {},
113 "outputs": [],
114 "prompt_number": 3
115 },
116 {
117 "cell_type": "code",
118 "collapsed": false,
119 "input": [
120 "collections.Counter??"
121 ],
122 "language": "python",
123 "metadata": {},
124 "outputs": [],
125 "prompt_number": 4
126 },
127 {
128 "cell_type": "code",
129 "collapsed": false,
130 "input": [
131 "*int*?"
132 ],
133 "language": "python",
134 "metadata": {},
135 "outputs": [],
136 "prompt_number": 5
137 },
138 {
139 "cell_type": "markdown",
140 "metadata": {
141 "slideshow": {
142 "slide_type": "slide"
143 }
144 },
145 "source": [
146 "An IPython quick reference card:"
147 ]
148 },
149 {
150 "cell_type": "code",
151 "collapsed": false,
152 "input": [
153 "%quickref"
154 ],
155 "language": "python",
156 "metadata": {},
157 "outputs": [],
158 "prompt_number": 6
159 },
160 {
161 "cell_type": "heading",
162 "level": 2,
163 "metadata": {
164 "slideshow": {
165 "slide_type": "slide"
166 }
167 },
168 "source": [
169 "Tab completion"
170 ]
171 },
172 {
173 "cell_type": "markdown",
174 "metadata": {},
175 "source": [
176 "Tab completion, especially for attributes, is a convenient way to explore the structure of any object you\u2019re dealing with. Simply type `object_name.<TAB>` to view the object\u2019s attributes. Besides Python objects and keywords, tab completion also works on file and directory names."
177 ]
178 },
179 {
180 "cell_type": "code",
181 "collapsed": false,
182 "input": [
183 "collections."
184 ],
185 "language": "python",
186 "metadata": {},
187 "outputs": [],
188 "prompt_number": 8
189 },
190 {
191 "cell_type": "heading",
192 "level": 2,
193 "metadata": {
194 "slideshow": {
195 "slide_type": "slide"
196 }
197 },
198 "source": [
199 "The interactive workflow: input, output, history"
200 ]
201 },
202 {
203 "cell_type": "code",
204 "collapsed": false,
205 "input": [
206 "2+10"
207 ],
208 "language": "python",
209 "metadata": {},
210 "outputs": [
211 {
212 "metadata": {},
213 "output_type": "pyout",
214 "prompt_number": 7,
215 "text": [
216 "12"
217 ]
218 }
219 ],
220 "prompt_number": 7
221 },
222 {
223 "cell_type": "code",
224 "collapsed": false,
225 "input": [
226 "_+10"
227 ],
228 "language": "python",
229 "metadata": {},
230 "outputs": [
231 {
232 "metadata": {},
233 "output_type": "pyout",
234 "prompt_number": 8,
235 "text": [
236 "22"
237 ]
238 }
239 ],
240 "prompt_number": 8
241 },
242 {
243 "cell_type": "markdown",
244 "metadata": {
245 "slideshow": {
246 "slide_type": "slide"
247 }
248 },
249 "source": [
250 "You can suppress the storage and rendering of output if you append `;` to the last cell (this comes in handy when plotting with matplotlib, for example):"
251 ]
252 },
253 {
254 "cell_type": "code",
255 "collapsed": false,
256 "input": [
257 "10+20;"
258 ],
259 "language": "python",
260 "metadata": {},
261 "outputs": [],
262 "prompt_number": 9
263 },
264 {
265 "cell_type": "code",
266 "collapsed": false,
267 "input": [
268 "_"
269 ],
270 "language": "python",
271 "metadata": {},
272 "outputs": [
273 {
274 "metadata": {},
275 "output_type": "pyout",
276 "prompt_number": 10,
277 "text": [
278 "22"
279 ]
280 }
281 ],
282 "prompt_number": 10
283 },
284 {
285 "cell_type": "markdown",
286 "metadata": {
287 "slideshow": {
288 "slide_type": "slide"
289 }
290 },
291 "source": [
292 "The output is stored in `_N` and `Out[N]` variables:"
293 ]
294 },
295 {
296 "cell_type": "code",
297 "collapsed": false,
298 "input": [
299 "_10 == Out[10]"
300 ],
301 "language": "python",
302 "metadata": {},
303 "outputs": [
304 {
305 "metadata": {},
306 "output_type": "pyout",
307 "prompt_number": 11,
308 "text": [
309 "True"
310 ]
311 }
312 ],
313 "prompt_number": 11
314 },
315 {
316 "cell_type": "markdown",
317 "metadata": {
318 "slideshow": {
319 "slide_type": "slide"
320 }
321 },
322 "source": [
323 "And the last three have shorthands for convenience:"
324 ]
325 },
326 {
327 "cell_type": "code",
328 "collapsed": false,
329 "input": [
330 "print 'last output:', _\n",
331 "print 'next one :', __\n",
332 "print 'and next :', ___"
333 ],
334 "language": "python",
335 "metadata": {},
336 "outputs": [
337 {
338 "output_type": "stream",
339 "stream": "stdout",
340 "text": [
341 "last output: True\n",
342 "next one : 22\n",
343 "and next : 22\n"
344 ]
345 }
346 ],
347 "prompt_number": 12
348 },
349 {
350 "cell_type": "code",
351 "collapsed": false,
352 "input": [
353 "In[11]"
354 ],
355 "language": "python",
356 "metadata": {
357 "slideshow": {
358 "slide_type": "-"
359 }
360 },
361 "outputs": [
362 {
363 "metadata": {},
364 "output_type": "pyout",
365 "prompt_number": 13,
366 "text": [
367 "u'_10 == Out[10]'"
368 ]
369 }
370 ],
371 "prompt_number": 13
372 },
373 {
374 "cell_type": "code",
375 "collapsed": false,
376 "input": [
377 "_i"
378 ],
379 "language": "python",
380 "metadata": {},
381 "outputs": [
382 {
383 "metadata": {},
384 "output_type": "pyout",
385 "prompt_number": 14,
386 "text": [
387 "u'In[11]'"
388 ]
389 }
390 ],
391 "prompt_number": 14
392 },
393 {
394 "cell_type": "code",
395 "collapsed": false,
396 "input": [
397 "_ii"
398 ],
399 "language": "python",
400 "metadata": {},
401 "outputs": [
402 {
403 "metadata": {},
404 "output_type": "pyout",
405 "prompt_number": 15,
406 "text": [
407 "u'In[11]'"
408 ]
409 }
410 ],
411 "prompt_number": 15
412 },
413 {
414 "cell_type": "code",
415 "collapsed": false,
416 "input": [
417 "print 'last input:', _i\n",
418 "print 'next one :', _ii\n",
419 "print 'and next :', _iii"
420 ],
421 "language": "python",
422 "metadata": {
423 "slideshow": {
424 "slide_type": "subslide"
425 }
426 },
427 "outputs": [
428 {
429 "output_type": "stream",
430 "stream": "stdout",
431 "text": [
432 "last input: _ii\n",
433 "next one : _i\n",
434 "and next : In[11]\n"
435 ]
436 }
437 ],
438 "prompt_number": 16
439 },
440 {
441 "cell_type": "code",
442 "collapsed": false,
443 "input": [
444 "%history -n 1-5"
445 ],
446 "language": "python",
447 "metadata": {},
448 "outputs": [
449 {
450 "output_type": "stream",
451 "stream": "stdout",
452 "text": [
453 " 1: print \"Hi\"\n",
454 " 2: ?\n",
455 " 3:\n",
456 "import collections\n",
457 "collections.namedtuple?\n",
458 " 4: collections.Counter??\n",
459 " 5: *int*?\n"
460 ]
461 }
462 ],
463 "prompt_number": 17
464 },
465 {
466 "cell_type": "markdown",
467 "metadata": {
468 "slideshow": {
469 "slide_type": "subslide"
470 }
471 },
472 "source": [
473 "**Exercise**\n",
474 "\n",
475 "Write the last 10 lines of history to a file named `log.py`."
476 ]
477 },
478 {
479 "cell_type": "heading",
480 "level": 2,
481 "metadata": {
482 "slideshow": {
483 "slide_type": "slide"
484 }
485 },
486 "source": [
487 "Accessing the underlying operating system"
488 ]
489 },
490 {
491 "cell_type": "code",
492 "collapsed": false,
493 "input": [
494 "!pwd"
495 ],
496 "language": "python",
497 "metadata": {},
498 "outputs": [
499 {
500 "output_type": "stream",
501 "stream": "stdout",
502 "text": [
503 "/home/fperez/ipython/tutorial/notebooks\r\n"
504 ]
505 }
506 ],
507 "prompt_number": 18
508 },
509 {
510 "cell_type": "code",
511 "collapsed": false,
512 "input": [
513 "files = !ls\n",
514 "print \"My current directory's files:\"\n",
515 "print files"
516 ],
517 "language": "python",
518 "metadata": {},
519 "outputs": [
520 {
521 "output_type": "stream",
522 "stream": "stdout",
523 "text": [
524 "My current directory's files:\n",
525 "['BackgroundJobs.ipynb', 'Custom Display Logic.ipynb', 'Customizing IPython - Condensed.ipynb', 'Customizing IPython - Config.ipynb', 'Customizing IPython - Extensions.ipynb', 'Customizing IPython - Magics.ipynb', 'data', 'figs', 'flare.json', 'Index.ipynb', 'Interactive Widgets.ipynb', 'IPython - beyond plain Python.ipynb', 'kernel-embedding', 'Markdown Cells.ipynb', 'myscript.py', 'nbconvert_arch.png', 'NbConvert from command line.ipynb', 'NbConvert Python library.ipynb', 'Notebook and javascript extension.ipynb', 'Notebook Basics.ipynb', 'Overview of IPython.parallel.ipynb', 'parallel', 'Rich Display System.ipynb', 'Running a Secure Public Notebook.ipynb', 'Running Code.ipynb', 'Sample.ipynb', 'soln', 'Terminal usage.ipynb', 'text_analysis.py', 'Typesetting Math Using MathJax.ipynb']\n"
526 ]
527 }
528 ],
529 "prompt_number": 19
530 },
531 {
532 "cell_type": "code",
533 "collapsed": false,
534 "input": [
535 "!echo $files"
536 ],
537 "language": "python",
538 "metadata": {},
539 "outputs": [
540 {
541 "output_type": "stream",
542 "stream": "stdout",
543 "text": [
544 "[BackgroundJobs.ipynb, Custom Display Logic.ipynb, Customizing IPython - Condensed.ipynb, Customizing IPython - Config.ipynb, Customizing IPython - Extensions.ipynb, Customizing IPython - Magics.ipynb, data, figs, flare.json, Index.ipynb, Interactive Widgets.ipynb, IPython - beyond plain Python.ipynb, kernel-embedding, Markdown Cells.ipynb, myscript.py, nbconvert_arch.png, NbConvert from command line.ipynb, NbConvert Python library.ipynb, Notebook and javascript extension.ipynb, Notebook Basics.ipynb, Overview of IPython.parallel.ipynb, parallel, Rich Display System.ipynb, Running a Secure Public Notebook.ipynb, Running Code.ipynb, Sample.ipynb, soln, Terminal usage.ipynb, text_analysis.py, Typesetting Math Using MathJax.ipynb]\r\n"
545 ]
546 }
547 ],
548 "prompt_number": 20
549 },
550 {
551 "cell_type": "code",
552 "collapsed": false,
553 "input": [
554 "!echo {files[0].upper()}"
555 ],
556 "language": "python",
557 "metadata": {},
558 "outputs": [
559 {
560 "output_type": "stream",
561 "stream": "stdout",
562 "text": [
563 "BACKGROUNDJOBS.IPYNB\r\n"
564 ]
565 }
566 ],
567 "prompt_number": 21
568 },
569 {
570 "cell_type": "markdown",
571 "metadata": {},
572 "source": [
573 "Note that all this is available even in multiline blocks:"
574 ]
575 },
576 {
577 "cell_type": "code",
578 "collapsed": false,
579 "input": [
580 "import os\n",
581 "for i,f in enumerate(files):\n",
582 " if f.endswith('ipynb'):\n",
583 " !echo {\"%02d\" % i} - \"{os.path.splitext(f)[0]}\"\n",
584 " else:\n",
585 " print '--'"
586 ],
587 "language": "python",
588 "metadata": {},
589 "outputs": [
590 {
591 "output_type": "stream",
592 "stream": "stdout",
593 "text": [
594 "00 - BackgroundJobs\r\n"
595 ]
596 },
597 {
598 "output_type": "stream",
599 "stream": "stdout",
600 "text": [
601 "01 - Custom Display Logic\r\n"
602 ]
603 },
604 {
605 "output_type": "stream",
606 "stream": "stdout",
607 "text": [
608 "02 - Customizing IPython - Condensed\r\n"
609 ]
610 },
611 {
612 "output_type": "stream",
613 "stream": "stdout",
614 "text": [
615 "03 - Customizing IPython - Config\r\n"
616 ]
617 },
618 {
619 "output_type": "stream",
620 "stream": "stdout",
621 "text": [
622 "04 - Customizing IPython - Extensions\r\n"
623 ]
624 },
625 {
626 "output_type": "stream",
627 "stream": "stdout",
628 "text": [
629 "05 - Customizing IPython - Magics\r\n"
630 ]
631 },
632 {
633 "output_type": "stream",
634 "stream": "stdout",
635 "text": [
636 "--\n",
637 "--\n",
638 "--\n",
639 "09 - Index\r\n"
640 ]
641 },
642 {
643 "output_type": "stream",
644 "stream": "stdout",
645 "text": [
646 "10 - Interactive Widgets\r\n"
647 ]
648 },
649 {
650 "output_type": "stream",
651 "stream": "stdout",
652 "text": [
653 "11 - IPython - beyond plain Python\r\n"
654 ]
655 },
656 {
657 "output_type": "stream",
658 "stream": "stdout",
659 "text": [
660 "--\n",
661 "13 - Markdown Cells\r\n"
662 ]
663 },
664 {
665 "output_type": "stream",
666 "stream": "stdout",
667 "text": [
668 "--\n",
669 "--\n",
670 "16 - NbConvert from command line\r\n"
671 ]
672 },
673 {
674 "output_type": "stream",
675 "stream": "stdout",
676 "text": [
677 "17 - NbConvert Python library\r\n"
678 ]
679 },
680 {
681 "output_type": "stream",
682 "stream": "stdout",
683 "text": [
684 "18 - Notebook and javascript extension\r\n"
685 ]
686 },
687 {
688 "output_type": "stream",
689 "stream": "stdout",
690 "text": [
691 "19 - Notebook Basics\r\n"
692 ]
693 },
694 {
695 "output_type": "stream",
696 "stream": "stdout",
697 "text": [
698 "20 - Overview of IPython.parallel\r\n"
699 ]
700 },
701 {
702 "output_type": "stream",
703 "stream": "stdout",
704 "text": [
705 "--\n",
706 "22 - Rich Display System\r\n"
707 ]
708 },
709 {
710 "output_type": "stream",
711 "stream": "stdout",
712 "text": [
713 "23 - Running a Secure Public Notebook\r\n"
714 ]
715 },
716 {
717 "output_type": "stream",
718 "stream": "stdout",
719 "text": [
720 "24 - Running Code\r\n"
721 ]
722 },
723 {
724 "output_type": "stream",
725 "stream": "stdout",
726 "text": [
727 "25 - Sample\r\n"
728 ]
729 },
730 {
731 "output_type": "stream",
732 "stream": "stdout",
733 "text": [
734 "--\n",
735 "27 - Terminal usage\r\n"
736 ]
737 },
738 {
739 "output_type": "stream",
740 "stream": "stdout",
741 "text": [
742 "--\n",
743 "29 - Typesetting Math Using MathJax\r\n"
744 ]
745 }
746 ],
747 "prompt_number": 27
748 },
749 {
750 "cell_type": "heading",
751 "level": 2,
752 "metadata": {},
753 "source": [
754 "Beyond Python: magic functions"
755 ]
756 },
757 {
758 "cell_type": "markdown",
759 "metadata": {},
760 "source": [
761 "The IPyhton 'magic' functions are a set of commands, invoked by prepending one or two `%` signs to their name, that live in a namespace separate from your normal Python variables and provide a more command-like interface. They take flags with `--` and arguments without quotes, parentheses or commas. The motivation behind this system is two-fold:\n",
762 " \n",
763 "- To provide an orthogonal namespace for controlling IPython itself and exposing other system-oriented functionality.\n",
764 "\n",
765 "- To expose a calling mode that requires minimal verbosity and typing while working interactively. Thus the inspiration taken from the classic Unix shell style for commands."
766 ]
767 },
768 {
769 "cell_type": "code",
770 "collapsed": false,
771 "input": [
772 "%magic"
773 ],
774 "language": "python",
775 "metadata": {},
776 "outputs": [],
777 "prompt_number": 28
778 },
779 {
780 "cell_type": "markdown",
781 "metadata": {},
782 "source": [
783 "Line vs cell magics:"
784 ]
785 },
786 {
787 "cell_type": "code",
788 "collapsed": false,
789 "input": [
790 "%timeit range(10)"
791 ],
792 "language": "python",
793 "metadata": {},
794 "outputs": [
795 {
796 "output_type": "stream",
797 "stream": "stdout",
798 "text": [
799 "10000000 loops, best of 3: 190 ns per loop\n"
800 ]
801 }
802 ],
803 "prompt_number": 29
804 },
805 {
806 "cell_type": "code",
807 "collapsed": false,
808 "input": [
809 "%%timeit\n",
810 "range(10)\n",
811 "range(100)"
812 ],
813 "language": "python",
814 "metadata": {},
815 "outputs": [
816 {
817 "output_type": "stream",
818 "stream": "stdout",
819 "text": [
820 "1000000 loops, best of 3: 888 ns per loop\n"
821 ]
822 }
823 ],
824 "prompt_number": 30
825 },
826 {
827 "cell_type": "markdown",
828 "metadata": {},
829 "source": [
830 "Line magics can be used even inside code blocks:"
831 ]
832 },
833 {
834 "cell_type": "code",
835 "collapsed": false,
836 "input": [
837 "for i in range(5):\n",
838 " size = i*100\n",
839 " print 'size:',size, \n",
840 " %timeit range(size)"
841 ],
842 "language": "python",
843 "metadata": {},
844 "outputs": [
845 {
846 "output_type": "stream",
847 "stream": "stdout",
848 "text": [
849 "size: 010000000 loops, best of 3: 129 ns per loop"
850 ]
851 },
852 {
853 "output_type": "stream",
854 "stream": "stdout",
855 "text": [
856 "\n",
857 " size: 1001000000 loops, best of 3: 649 ns per loop"
858 ]
859 },
860 {
861 "output_type": "stream",
862 "stream": "stdout",
863 "text": [
864 "\n",
865 " size: 2001000000 loops, best of 3: 1.09 \u00b5s per loop"
866 ]
867 },
868 {
869 "output_type": "stream",
870 "stream": "stdout",
871 "text": [
872 "\n",
873 " size: 3001000000 loops, best of 3: 1.74 \u00b5s per loop"
874 ]
875 },
876 {
877 "output_type": "stream",
878 "stream": "stdout",
879 "text": [
880 "\n",
881 " size: 400100000 loops, best of 3: 2.72 \u00b5s per loop"
882 ]
883 },
884 {
885 "output_type": "stream",
886 "stream": "stdout",
887 "text": [
888 "\n",
889 "\n"
890 ]
891 }
892 ],
893 "prompt_number": 31
894 },
895 {
896 "cell_type": "markdown",
897 "metadata": {},
898 "source": [
899 "Magics can do anything they want with their input, so it doesn't have to be valid Python:"
900 ]
901 },
902 {
903 "cell_type": "code",
904 "collapsed": false,
905 "input": [
906 "%%bash\n",
907 "echo \"My shell is:\" $SHELL\n",
908 "echo \"My memory status is:\"\n",
909 "free"
910 ],
911 "language": "python",
912 "metadata": {},
913 "outputs": [
914 {
915 "output_type": "stream",
916 "stream": "stdout",
917 "text": [
918 "My shell is: /bin/bash\n",
919 "My memory status is:\n",
920 " total used free shared buffers cached\n",
921 "Mem: 7870888 6389328 1481560 0 662860 2505172\n",
922 "-/+ buffers/cache: 3221296 4649592\n",
923 "Swap: 3905532 4852 3900680\n"
924 ]
925 }
926 ],
927 "prompt_number": 32
928 },
929 {
930 "cell_type": "markdown",
931 "metadata": {},
932 "source": [
933 "Another interesting cell magic: create any file you want locally from the notebook:"
934 ]
935 },
936 {
937 "cell_type": "code",
938 "collapsed": false,
939 "input": [
940 "%%writefile test.txt\n",
941 "This is a test file!\n",
942 "It can contain anything I want...\n",
943 "\n",
944 "And more..."
945 ],
946 "language": "python",
947 "metadata": {},
948 "outputs": [
949 {
950 "output_type": "stream",
951 "stream": "stdout",
952 "text": [
953 "Writing test.txt\n"
954 ]
955 }
956 ],
957 "prompt_number": 33
958 },
959 {
960 "cell_type": "code",
961 "collapsed": false,
962 "input": [
963 "!cat test.txt"
964 ],
965 "language": "python",
966 "metadata": {},
967 "outputs": [
968 {
969 "output_type": "stream",
970 "stream": "stdout",
971 "text": [
972 "This is a test file!\r\n",
973 "It can contain anything I want...\r\n",
974 "\r\n",
975 "And more..."
976 ]
977 }
978 ],
979 "prompt_number": 34
980 },
981 {
982 "cell_type": "markdown",
983 "metadata": {},
984 "source": [
985 "Let's see what other magics are currently defined in the system:"
986 ]
987 },
988 {
989 "cell_type": "code",
990 "collapsed": false,
991 "input": [
992 "%lsmagic"
993 ],
994 "language": "python",
995 "metadata": {},
996 "outputs": [
997 {
998 "json": [
999 "{\"cell\": {\"prun\": \"ExecutionMagics\", \"file\": \"Other\", \"!\": \"OSMagics\", \"capture\": \"ExecutionMagics\", \"timeit\": \"ExecutionMagics\", \"script\": \"ScriptMagics\", \"pypy\": \"Other\", \"system\": \"OSMagics\", \"perl\": \"Other\", \"HTML\": \"Other\", \"bash\": \"Other\", \"python\": \"Other\", \"SVG\": \"Other\", \"javascript\": \"DisplayMagics\", \"writefile\": \"OSMagics\", \"ruby\": \"Other\", \"python3\": \"Other\", \"python2\": \"Other\", \"latex\": \"DisplayMagics\", \"sx\": \"OSMagics\", \"svg\": \"DisplayMagics\", \"html\": \"DisplayMagics\", \"sh\": \"Other\", \"time\": \"ExecutionMagics\", \"debug\": \"ExecutionMagics\"}, \"line\": {\"psource\": \"NamespaceMagics\", \"logstart\": \"LoggingMagics\", \"popd\": \"OSMagics\", \"loadpy\": \"CodeMagics\", \"install_ext\": \"ExtensionMagics\", \"colors\": \"BasicMagics\", \"who_ls\": \"NamespaceMagics\", \"lf\": \"Other\", \"install_profiles\": \"DeprecatedMagics\", \"clk\": \"Other\", \"ll\": \"Other\", \"pprint\": \"BasicMagics\", \"lk\": \"Other\", \"ls\": \"Other\", \"save\": \"CodeMagics\", \"tb\": \"ExecutionMagics\", \"lx\": \"Other\", \"dl\": \"Other\", \"pylab\": \"PylabMagics\", \"dd\": \"Other\", \"quickref\": \"BasicMagics\", \"dx\": \"Other\", \"d\": \"Other\", \"magic\": \"BasicMagics\", \"dhist\": \"OSMagics\", \"edit\": \"KernelMagics\", \"logstop\": \"LoggingMagics\", \"gui\": \"BasicMagics\", \"alias_magic\": \"BasicMagics\", \"debug\": \"ExecutionMagics\", \"page\": \"BasicMagics\", \"logstate\": \"LoggingMagics\", \"ed\": \"Other\", \"pushd\": \"OSMagics\", \"timeit\": \"ExecutionMagics\", \"rehashx\": \"OSMagics\", \"hist\": \"Other\", \"qtconsole\": \"KernelMagics\", \"rm\": \"Other\", \"dirs\": \"OSMagics\", \"run\": \"ExecutionMagics\", \"reset_selective\": \"NamespaceMagics\", \"rep\": \"Other\", \"pinfo2\": \"NamespaceMagics\", \"matplotlib\": \"PylabMagics\", \"automagic\": \"AutoMagics\", \"doctest_mode\": \"KernelMagics\", \"logoff\": \"LoggingMagics\", \"reload_ext\": \"ExtensionMagics\", \"pdb\": \"ExecutionMagics\", \"load\": \"CodeMagics\", \"lsmagic\": \"BasicMagics\", \"cl\": \"Other\", \"autosave\": \"KernelMagics\", \"cd\": \"OSMagics\", \"pastebin\": \"CodeMagics\", \"prun\": \"ExecutionMagics\", \"cp\": \"Other\", \"autocall\": \"AutoMagics\", \"bookmark\": \"OSMagics\", \"connect_info\": \"KernelMagics\", \"mkdir\": \"Other\", \"system\": \"OSMagics\", \"whos\": \"NamespaceMagics\", \"rmdir\": \"Other\", \"unload_ext\": \"ExtensionMagics\", \"store\": \"StoreMagics\", \"more\": \"KernelMagics\", \"pdef\": \"NamespaceMagics\", \"precision\": \"BasicMagics\", \"pinfo\": \"NamespaceMagics\", \"pwd\": \"OSMagics\", \"psearch\": \"NamespaceMagics\", \"reset\": \"NamespaceMagics\", \"recall\": \"HistoryMagics\", \"xdel\": \"NamespaceMagics\", \"xmode\": \"BasicMagics\", \"cat\": \"Other\", \"mv\": \"Other\", \"rerun\": \"HistoryMagics\", \"logon\": \"LoggingMagics\", \"history\": \"HistoryMagics\", \"pycat\": \"OSMagics\", \"unalias\": \"OSMagics\", \"install_default_config\": \"DeprecatedMagics\", \"env\": \"OSMagics\", \"load_ext\": \"ExtensionMagics\", \"config\": \"ConfigMagics\", \"killbgscripts\": \"ScriptMagics\", \"profile\": \"BasicMagics\", \"pfile\": \"NamespaceMagics\", \"less\": \"KernelMagics\", \"who\": \"NamespaceMagics\", \"notebook\": \"BasicMagics\", \"man\": \"KernelMagics\", \"sx\": \"OSMagics\", \"macro\": \"ExecutionMagics\", \"clear\": \"KernelMagics\", \"alias\": \"OSMagics\", \"time\": \"ExecutionMagics\", \"sc\": \"OSMagics\", \"ldir\": \"Other\", \"pdoc\": \"NamespaceMagics\"}}"
1000 ],
1001 "metadata": {},
1002 "output_type": "pyout",
1003 "prompt_number": 35,
1004 "text": [
1005 "Available line magics:\n",
1006 "%alias %alias_magic %autocall %automagic %autosave %bookmark %cat %cd %cl %clear %clk %colors %config %connect_info %cp %d %dd %debug %dhist %dirs %dl %doctest_mode %dx %ed %edit %env %gui %hist %history %install_default_config %install_ext %install_profiles %killbgscripts %ldir %less %lf %lk %ll %load %load_ext %loadpy %logoff %logon %logstart %logstate %logstop %ls %lsmagic %lx %macro %magic %man %matplotlib %mkdir %more %mv %notebook %page %pastebin %pdb %pdef %pdoc %pfile %pinfo %pinfo2 %popd %pprint %precision %profile %prun %psearch %psource %pushd %pwd %pycat %pylab %qtconsole %quickref %recall %rehashx %reload_ext %rep %rerun %reset %reset_selective %rm %rmdir %run %save %sc %store %sx %system %tb %time %timeit %unalias %unload_ext %who %who_ls %whos %xdel %xmode\n",
1007 "\n",
1008 "Available cell magics:\n",
1009 "%%! %%HTML %%SVG %%bash %%capture %%debug %%file %%html %%javascript %%latex %%perl %%prun %%pypy %%python %%python2 %%python3 %%ruby %%script %%sh %%svg %%sx %%system %%time %%timeit %%writefile\n",
1010 "\n",
1011 "Automagic is ON, % prefix IS NOT needed for line magics."
1012 ]
1013 }
1014 ],
1015 "prompt_number": 35
1016 },
1017 {
1018 "cell_type": "heading",
1019 "level": 2,
1020 "metadata": {},
1021 "source": [
1022 "Running normal Python code: execution and errors"
1023 ]
1024 },
1025 {
1026 "cell_type": "markdown",
1027 "metadata": {},
1028 "source": [
1029 "Not only can you input normal Python code, you can even paste straight from a Python or IPython shell session:"
1030 ]
1031 },
1032 {
1033 "cell_type": "code",
1034 "collapsed": false,
1035 "input": [
1036 ">>> # Fibonacci series:\n",
1037 "... # the sum of two elements defines the next\n",
1038 "... a, b = 0, 1\n",
1039 ">>> while b < 10:\n",
1040 "... print b\n",
1041 "... a, b = b, a+b"
1042 ],
1043 "language": "python",
1044 "metadata": {},
1045 "outputs": [
1046 {
1047 "output_type": "stream",
1048 "stream": "stdout",
1049 "text": [
1050 "1\n",
1051 "1\n",
1052 "2\n",
1053 "3\n",
1054 "5\n",
1055 "8\n"
1056 ]
1057 }
1058 ],
1059 "prompt_number": 36
1060 },
1061 {
1062 "cell_type": "code",
1063 "collapsed": false,
1064 "input": [
1065 "In [1]: for i in range(10):\n",
1066 " ...: print i,\n",
1067 " ...: "
1068 ],
1069 "language": "python",
1070 "metadata": {},
1071 "outputs": [
1072 {
1073 "output_type": "stream",
1074 "stream": "stdout",
1075 "text": [
1076 "0 1 2 3 4 5 6 7 8 9\n"
1077 ]
1078 }
1079 ],
1080 "prompt_number": 37
1081 },
1082 {
1083 "cell_type": "markdown",
1084 "metadata": {},
1085 "source": [
1086 "And when your code produces errors, you can control how they are displayed with the `%xmode` magic:"
1087 ]
1088 },
1089 {
1090 "cell_type": "code",
1091 "collapsed": false,
1092 "input": [
1093 "%%writefile mod.py\n",
1094 "\n",
1095 "def f(x):\n",
1096 " return 1.0/(x-1)\n",
1097 "\n",
1098 "def g(y):\n",
1099 " return f(y+1)"
1100 ],
1101 "language": "python",
1102 "metadata": {},
1103 "outputs": [
1104 {
1105 "output_type": "stream",
1106 "stream": "stdout",
1107 "text": [
1108 "Writing mod.py\n"
1109 ]
1110 }
1111 ],
1112 "prompt_number": 38
1113 },
1114 {
1115 "cell_type": "markdown",
1116 "metadata": {},
1117 "source": [
1118 "Now let's call the function `g` with an argument that would produce an error:"
1119 ]
1120 },
1121 {
1122 "cell_type": "code",
1123 "collapsed": false,
1124 "input": [
1125 "import mod\n",
1126 "mod.g(0)"
1127 ],
1128 "language": "python",
1129 "metadata": {},
1130 "outputs": [
1131 {
1132 "ename": "ZeroDivisionError",
1133 "evalue": "float division by zero",
1134 "output_type": "pyerr",
1135 "traceback": [
1136 "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mZeroDivisionError\u001b[0m Traceback (most recent call last)",
1137 "\u001b[1;32m<ipython-input-39-a54c5799f57e>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mmod\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mmod\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mg\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
1138 "\u001b[1;32m/home/fperez/ipython/tutorial/notebooks/mod.py\u001b[0m in \u001b[0;36mg\u001b[1;34m(y)\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mg\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 6\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mf\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m+\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
1139 "\u001b[1;32m/home/fperez/ipython/tutorial/notebooks/mod.py\u001b[0m in \u001b[0;36mf\u001b[1;34m(x)\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mf\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[1;36m1.0\u001b[0m\u001b[1;33m/\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m-\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mg\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
1140 "\u001b[1;31mZeroDivisionError\u001b[0m: float division by zero"
1141 ]
1142 }
1143 ],
1144 "prompt_number": 39
1145 },
1146 {
1147 "cell_type": "code",
1148 "collapsed": false,
1149 "input": [
1150 "%xmode plain\n",
1151 "mod.g(0)"
1152 ],
1153 "language": "python",
1154 "metadata": {},
1155 "outputs": [
1156 {
1157 "output_type": "stream",
1158 "stream": "stdout",
1159 "text": [
1160 "Exception reporting mode: Plain\n"
1161 ]
1162 },
1163 {
1164 "ename": "ZeroDivisionError",
1165 "evalue": "float division by zero",
1166 "output_type": "pyerr",
1167 "traceback": [
1168 "Traceback \u001b[1;36m(most recent call last)\u001b[0m:\n",
1169 " File \u001b[0;32m\"<ipython-input-40-5a5bcec1553f>\"\u001b[0m, line \u001b[0;32m2\u001b[0m, in \u001b[0;35m<module>\u001b[0m\n mod.g(0)\n",
1170 " File \u001b[0;32m\"mod.py\"\u001b[0m, line \u001b[0;32m6\u001b[0m, in \u001b[0;35mg\u001b[0m\n return f(y+1)\n",
1171 "\u001b[1;36m File \u001b[1;32m\"mod.py\"\u001b[1;36m, line \u001b[1;32m3\u001b[1;36m, in \u001b[1;35mf\u001b[1;36m\u001b[0m\n\u001b[1;33m return 1.0/(x-1)\u001b[0m\n",
1172 "\u001b[1;31mZeroDivisionError\u001b[0m\u001b[1;31m:\u001b[0m float division by zero\n"
1173 ]
1174 }
1175 ],
1176 "prompt_number": 40
1177 },
1178 {
1179 "cell_type": "code",
1180 "collapsed": false,
1181 "input": [
1182 "%xmode verbose\n",
1183 "mod.g(0)"
1184 ],
1185 "language": "python",
1186 "metadata": {},
1187 "outputs": [
1188 {
1189 "output_type": "stream",
1190 "stream": "stdout",
1191 "text": [
1192 "Exception reporting mode: Verbose\n"
1193 ]
1194 },
1195 {
1196 "ename": "ZeroDivisionError",
1197 "evalue": "float division by zero",
1198 "output_type": "pyerr",
1199 "traceback": [
1200 "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mZeroDivisionError\u001b[0m Traceback (most recent call last)",
1201 "\u001b[1;32m<ipython-input-41-81967cfaa0c3>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[0mget_ipython\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmagic\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34mu'xmode verbose'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mmod\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mg\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m \u001b[1;36mglobal\u001b[0m \u001b[0;36mmod.g\u001b[0m \u001b[1;34m= <function g at 0x237fc08>\u001b[0m\n",
1202 "\u001b[1;32m/home/fperez/ipython/tutorial/notebooks/mod.py\u001b[0m in \u001b[0;36mg\u001b[1;34m(y=0)\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mg\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 6\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mf\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m+\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m \u001b[1;36mglobal\u001b[0m \u001b[0;36mf\u001b[0m \u001b[1;34m= <function f at 0x2367c08>\u001b[0m\u001b[1;34m\n \u001b[0m\u001b[0;36my\u001b[0m \u001b[1;34m= 0\u001b[0m\n",
1203 "\u001b[1;32m/home/fperez/ipython/tutorial/notebooks/mod.py\u001b[0m in \u001b[0;36mf\u001b[1;34m(x=1)\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mf\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[1;36m1.0\u001b[0m\u001b[1;33m/\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m-\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m \u001b[0;36mx\u001b[0m \u001b[1;34m= 1\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mg\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
1204 "\u001b[1;31mZeroDivisionError\u001b[0m: float division by zero"
1205 ]
1206 }
1207 ],
1208 "prompt_number": 41
1209 },
1210 {
1211 "cell_type": "markdown",
1212 "metadata": {},
1213 "source": [
1214 "The default `%xmode` is \"context\", which shows additional context but not all local variables. Let's restore that one for the rest of our session."
1215 ]
1216 },
1217 {
1218 "cell_type": "code",
1219 "collapsed": false,
1220 "input": [
1221 "%xmode context"
1222 ],
1223 "language": "python",
1224 "metadata": {},
1225 "outputs": [
1226 {
1227 "output_type": "stream",
1228 "stream": "stdout",
1229 "text": [
1230 "Exception reporting mode: Context\n"
1231 ]
1232 }
1233 ],
1234 "prompt_number": 42
1235 },
1236 {
1237 "cell_type": "heading",
1238 "level": 2,
1239 "metadata": {},
1240 "source": [
1241 "Running code in other languages with special `%%` magics"
1242 ]
1243 },
1244 {
1245 "cell_type": "code",
1246 "collapsed": false,
1247 "input": [
1248 "%%perl\n",
1249 "@months = (\"July\", \"August\", \"September\");\n",
1250 "print $months[0];"
1251 ],
1252 "language": "python",
1253 "metadata": {},
1254 "outputs": [
1255 {
1256 "output_type": "stream",
1257 "stream": "stdout",
1258 "text": [
1259 "July"
1260 ]
1261 }
1262 ],
1263 "prompt_number": 43
1264 },
1265 {
1266 "cell_type": "code",
1267 "collapsed": false,
1268 "input": [
1269 "%%ruby\n",
1270 "name = \"world\"\n",
1271 "puts \"Hello #{name.capitalize}!\""
1272 ],
1273 "language": "python",
1274 "metadata": {},
1275 "outputs": [
1276 {
1277 "output_type": "stream",
1278 "stream": "stdout",
1279 "text": [
1280 "Hello World!\n"
1281 ]
1282 }
1283 ],
1284 "prompt_number": 44
1285 },
1286 {
1287 "cell_type": "heading",
1288 "level": 3,
1289 "metadata": {},
1290 "source": [
1291 "Exercise"
1292 ]
1293 },
1294 {
1295 "cell_type": "markdown",
1296 "metadata": {},
1297 "source": [
1298 "Write a cell that executes in Bash and prints your current working directory as well as the date.\n",
1299 "\n",
1300 "Apologies to Windows users who may not have Bash available, not sure how to obtain the equivalent result with `cmd.exe` or Powershell."
1301 ]
1302 },
1303 {
1304 "cell_type": "code",
1305 "collapsed": false,
1306 "input": [
1307 "%load soln/bash-script"
1308 ],
1309 "language": "python",
1310 "metadata": {},
1311 "outputs": []
1312 },
1313 {
1314 "cell_type": "heading",
1315 "level": 2,
1316 "metadata": {},
1317 "source": [
1318 "Raw Input in the notebook"
1319 ]
1320 },
1321 {
1322 "cell_type": "markdown",
1323 "metadata": {},
1324 "source": [
1325 "Since 1.0 the IPython notebook web application support `raw_input` which for example allow us to invoke the `%debug` magic in the notebook:"
1326 ]
1327 },
1328 {
1329 "cell_type": "code",
1330 "collapsed": false,
1331 "input": [
1332 "mod.g(0)"
1333 ],
1334 "language": "python",
1335 "metadata": {},
1336 "outputs": [
1337 {
1338 "ename": "ZeroDivisionError",
1339 "evalue": "float division by zero",
1340 "output_type": "pyerr",
1341 "traceback": [
1342 "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mZeroDivisionError\u001b[0m Traceback (most recent call last)",
1343 "\u001b[1;32m<ipython-input-45-5e708f13c839>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mmod\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mg\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
1344 "\u001b[1;32m/home/fperez/ipython/tutorial/notebooks/mod.py\u001b[0m in \u001b[0;36mg\u001b[1;34m(y)\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mg\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 6\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mf\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m+\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
1345 "\u001b[1;32m/home/fperez/ipython/tutorial/notebooks/mod.py\u001b[0m in \u001b[0;36mf\u001b[1;34m(x)\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mf\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[1;36m1.0\u001b[0m\u001b[1;33m/\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m-\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mg\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
1346 "\u001b[1;31mZeroDivisionError\u001b[0m: float division by zero"
1347 ]
1348 }
1349 ],
1350 "prompt_number": 45
1351 },
1352 {
1353 "cell_type": "code",
1354 "collapsed": false,
1355 "input": [
1356 "%debug"
1357 ],
1358 "language": "python",
1359 "metadata": {},
1360 "outputs": [
1361 {
1362 "output_type": "stream",
1363 "stream": "stdout",
1364 "text": [
1365 "> \u001b[0;32m/Users/bussonniermatthias/ipython-in-depth/notebooks/mod.py\u001b[0m(3)\u001b[0;36mf\u001b[0;34m()\u001b[0m\n",
1366 "\u001b[0;32m 2 \u001b[0;31m\u001b[0;32mdef\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
1367 "\u001b[0m\u001b[0;32m----> 3 \u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0;36m1.0\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
1368 "\u001b[0m\u001b[0;32m 4 \u001b[0;31m\u001b[0;34m\u001b[0m\u001b[0m\n",
1369 "\u001b[0m\n"
1370 ]
1371 },
1372 {
1373 "name": "stdout",
1374 "output_type": "stream",
1375 "stream": "stdout",
1376 "text": [
1377 "ipdb> x\n"
1378 ]
1379 },
1380 {
1381 "output_type": "stream",
1382 "stream": "stdout",
1383 "text": [
1384 "1\n"
1385 ]
1386 },
1387 {
1388 "name": "stdout",
1389 "output_type": "stream",
1390 "stream": "stdout",
1391 "text": [
1392 "ipdb> up\n"
1393 ]
1394 },
1395 {
1396 "output_type": "stream",
1397 "stream": "stdout",
1398 "text": [
1399 "> \u001b[0;32m/Users/bussonniermatthias/ipython-in-depth/notebooks/mod.py\u001b[0m(6)\u001b[0;36mg\u001b[0;34m()\u001b[0m\n",
1400 "\u001b[0;32m 4 \u001b[0;31m\u001b[0;34m\u001b[0m\u001b[0m\n",
1401 "\u001b[0m\u001b[0;32m 5 \u001b[0;31m\u001b[0;32mdef\u001b[0m \u001b[0mg\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
1402 "\u001b[0m\u001b[0;32m----> 6 \u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
1403 "\u001b[0m\n"
1404 ]
1405 },
1406 {
1407 "name": "stdout",
1408 "output_type": "stream",
1409 "stream": "stdout",
1410 "text": [
1411 "ipdb> y\n"
1412 ]
1413 },
1414 {
1415 "output_type": "stream",
1416 "stream": "stdout",
1417 "text": [
1418 "0\n"
1419 ]
1420 },
1421 {
1422 "name": "stdout",
1423 "output_type": "stream",
1424 "stream": "stdout",
1425 "text": [
1426 "ipdb> up\n"
1427 ]
1428 },
1429 {
1430 "output_type": "stream",
1431 "stream": "stdout",
1432 "text": [
1433 "> \u001b[0;32m<ipython-input-37-5e708f13c839>\u001b[0m(1)\u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n",
1434 "\u001b[0;32m----> 1 \u001b[0;31m\u001b[0mmod\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mg\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
1435 "\u001b[0m\n"
1436 ]
1437 },
1438 {
1439 "name": "stdout",
1440 "output_type": "stream",
1441 "stream": "stdout",
1442 "text": [
1443 "ipdb> exit\n"
1444 ]
1445 }
1446 ],
1447 "prompt_number": 38
1448 },
1449 {
1450 "cell_type": "markdown",
1451 "metadata": {},
1452 "source": [
1453 "Don't foget to exit your debugging session. Raw input can of course be use to ask for user input:"
1454 ]
1455 },
1456 {
1457 "cell_type": "code",
1458 "collapsed": false,
1459 "input": [
1460 "enjoy = raw_input('Are you enjoying this tutorial ?')\n",
1461 "print 'enjoy is :', enjoy"
1462 ],
1463 "language": "python",
1464 "metadata": {},
1465 "outputs": [
1466 {
1467 "name": "stdout",
1468 "output_type": "stream",
1469 "stream": "stdout",
1470 "text": [
1471 "Are you enjoying this tutorial ?Yes !\n"
1472 ]
1473 },
1474 {
1475 "output_type": "stream",
1476 "stream": "stdout",
1477 "text": [
1478 "enjoy is : Yes !\n"
1479 ]
1480 }
1481 ],
1482 "prompt_number": 39
1483 },
1484 {
1485 "cell_type": "heading",
1486 "level": 2,
1487 "metadata": {},
1488 "source": [
1489 "Plotting in the notebook"
1490 ]
1491 },
1492 {
1493 "cell_type": "markdown",
1494 "metadata": {},
1495 "source": [
1496 "This magic configures matplotlib to render its figures inline:"
1497 ]
1498 },
1499 {
1500 "cell_type": "code",
1501 "collapsed": false,
1502 "input": [
1503 "%matplotlib inline"
1504 ],
1505 "language": "python",
1506 "metadata": {},
1507 "outputs": [],
1508 "prompt_number": 46
1509 },
1510 {
1511 "cell_type": "code",
1512 "collapsed": false,
1513 "input": [
1514 "import numpy as np\n",
1515 "import matplotlib.pyplot as plt"
1516 ],
1517 "language": "python",
1518 "metadata": {},
1519 "outputs": [],
1520 "prompt_number": 47
1521 },
1522 {
1523 "cell_type": "code",
1524 "collapsed": false,
1525 "input": [
1526 "x = np.linspace(0, 2*np.pi, 300)\n",
1527 "y = np.sin(x**2)\n",
1528 "plt.plot(x, y)\n",
1529 "plt.title(\"A little chirp\")\n",
1530 "fig = plt.gcf() # let's keep the figure object around for later..."
1531 ],
1532 "language": "python",
1533 "metadata": {},
1534 "outputs": [
1535 {
1536 "metadata": {},
1537 "output_type": "display_data",
1538 "png": "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\n",
1539 "text": [
1540 "<matplotlib.figure.Figure at 0x3436950>"
1541 ]
1542 }
1543 ],
1544 "prompt_number": 48
1545 },
1546 {
1547 "cell_type": "heading",
1548 "level": 2,
1549 "metadata": {},
1550 "source": [
1551 "The IPython kernel/client model"
1552 ]
1553 },
1554 {
1555 "cell_type": "code",
1556 "collapsed": false,
1557 "input": [
1558 "%connect_info"
1559 ],
1560 "language": "python",
1561 "metadata": {},
1562 "outputs": [
1563 {
1564 "output_type": "stream",
1565 "stream": "stdout",
1566 "text": [
1567 "{\n",
1568 " \"stdin_port\": 50023, \n",
1569 " \"ip\": \"127.0.0.1\", \n",
1570 " \"control_port\": 50024, \n",
1571 " \"hb_port\": 50025, \n",
1572 " \"signature_scheme\": \"hmac-sha256\", \n",
1573 " \"key\": \"b54b8859-d64d-48bb-814a-909f9beb3316\", \n",
1574 " \"shell_port\": 50021, \n",
1575 " \"transport\": \"tcp\", \n",
1576 " \"iopub_port\": 50022\n",
1577 "}\n",
1578 "\n",
1579 "Paste the above JSON into a file, and connect with:\n",
1580 " $> ipython <app> --existing <file>\n",
1581 "or, if you are local, you can connect with just:\n",
1582 " $> ipython <app> --existing kernel-30f00f4a-230c-4e64-bea5-0e5f6a52cb40.json \n",
1583 "or even just:\n",
1584 " $> ipython <app> --existing \n",
1585 "if this is the most recent IPython session you have started.\n"
1586 ]
1587 }
1588 ],
1589 "prompt_number": 43
1590 },
1591 {
1592 "cell_type": "markdown",
1593 "metadata": {},
1594 "source": [
1595 "We can connect automatically a Qt Console to the currently running kernel with the `%qtconsole` magic, or by typing `ipython console --existing <kernel-UUID>` in any terminal:"
1596 ]
1597 },
1598 {
1599 "cell_type": "code",
1600 "collapsed": false,
1601 "input": [
1602 "%qtconsole"
1603 ],
1604 "language": "python",
1605 "metadata": {},
1606 "outputs": [],
1607 "prompt_number": 83
1608 }
1609 ],
1610 "metadata": {}
1611 }
1612 ]
1613 } No newline at end of file
@@ -0,0 +1,332 b''
1 {
2 "metadata": {
3 "name": "",
4 "signature": "sha256:df6354daf203e842bc040989d149760382d8ceec769160e4efe8cde9dfcb9107"
5 },
6 "nbformat": 3,
7 "nbformat_minor": 0,
8 "worksheets": [
9 {
10 "cells": [
11 {
12 "cell_type": "heading",
13 "level": 1,
14 "metadata": {},
15 "source": [
16 "Capturing Output With <tt>%%capture</tt>"
17 ]
18 },
19 {
20 "cell_type": "markdown",
21 "metadata": {},
22 "source": [
23 "IPython has a [cell magic](Cell Magics.ipynb), `%%capture`, which captures the stdout/stderr of a cell. With this magic you can discard these streams or store them in a variable."
24 ]
25 },
26 {
27 "cell_type": "code",
28 "collapsed": false,
29 "input": [
30 "from __future__ import print_function\n",
31 "import sys"
32 ],
33 "language": "python",
34 "metadata": {},
35 "outputs": [],
36 "prompt_number": 9
37 },
38 {
39 "cell_type": "markdown",
40 "metadata": {},
41 "source": [
42 "By default, `%%capture` discards these streams. This is a simple way to suppress unwanted output."
43 ]
44 },
45 {
46 "cell_type": "code",
47 "collapsed": false,
48 "input": [
49 "%%capture\n",
50 "print('hi, stdout')\n",
51 "print('hi, stderr', file=sys.stderr)"
52 ],
53 "language": "python",
54 "metadata": {},
55 "outputs": [],
56 "prompt_number": 10
57 },
58 {
59 "cell_type": "markdown",
60 "metadata": {},
61 "source": [
62 "If you specify a name, then stdout/stderr will be stored in an object in your namespace."
63 ]
64 },
65 {
66 "cell_type": "code",
67 "collapsed": false,
68 "input": [
69 "%%capture captured\n",
70 "print('hi, stdout')\n",
71 "print('hi, stderr', file=sys.stderr)"
72 ],
73 "language": "python",
74 "metadata": {},
75 "outputs": [],
76 "prompt_number": 11
77 },
78 {
79 "cell_type": "code",
80 "collapsed": false,
81 "input": [
82 "captured"
83 ],
84 "language": "python",
85 "metadata": {},
86 "outputs": [
87 {
88 "metadata": {},
89 "output_type": "pyout",
90 "prompt_number": 12,
91 "text": [
92 "<IPython.utils.capture.CapturedIO at 0x1076c9310>"
93 ]
94 }
95 ],
96 "prompt_number": 12
97 },
98 {
99 "cell_type": "markdown",
100 "metadata": {},
101 "source": [
102 "Calling the object writes the output to stdout/stderr as appropriate."
103 ]
104 },
105 {
106 "cell_type": "code",
107 "collapsed": false,
108 "input": [
109 "captured()"
110 ],
111 "language": "python",
112 "metadata": {},
113 "outputs": [
114 {
115 "output_type": "stream",
116 "stream": "stdout",
117 "text": [
118 "hi, stdout\n"
119 ]
120 },
121 {
122 "output_type": "stream",
123 "stream": "stderr",
124 "text": [
125 "hi, stderr\n"
126 ]
127 }
128 ],
129 "prompt_number": 13
130 },
131 {
132 "cell_type": "code",
133 "collapsed": false,
134 "input": [
135 "captured.stdout"
136 ],
137 "language": "python",
138 "metadata": {},
139 "outputs": [
140 {
141 "metadata": {},
142 "output_type": "pyout",
143 "prompt_number": 14,
144 "text": [
145 "'hi, stdout\\n'"
146 ]
147 }
148 ],
149 "prompt_number": 14
150 },
151 {
152 "cell_type": "code",
153 "collapsed": false,
154 "input": [
155 "captured.stderr"
156 ],
157 "language": "python",
158 "metadata": {},
159 "outputs": [
160 {
161 "metadata": {},
162 "output_type": "pyout",
163 "prompt_number": 15,
164 "text": [
165 "'hi, stderr\\n'"
166 ]
167 }
168 ],
169 "prompt_number": 15
170 },
171 {
172 "cell_type": "markdown",
173 "metadata": {},
174 "source": [
175 "`%%capture` grabs all output types, not just stdout/stderr, so you can do plots and use IPython's display system inside `%%capture`"
176 ]
177 },
178 {
179 "cell_type": "code",
180 "collapsed": false,
181 "input": [
182 "%matplotlib inline\n",
183 "import matplotlib.pyplot as plt\n",
184 "import numpy as np"
185 ],
186 "language": "python",
187 "metadata": {},
188 "outputs": [],
189 "prompt_number": 16
190 },
191 {
192 "cell_type": "code",
193 "collapsed": false,
194 "input": [
195 "%%capture wontshutup\n",
196 "\n",
197 "print(\"setting up X\")\n",
198 "x = np.linspace(0,5,1000)\n",
199 "print(\"step 2: constructing y-data\")\n",
200 "y = np.sin(x)\n",
201 "print(\"step 3: display info about y\")\n",
202 "plt.plot(x,y)\n",
203 "print(\"okay, I'm done now\")"
204 ],
205 "language": "python",
206 "metadata": {},
207 "outputs": [],
208 "prompt_number": 17
209 },
210 {
211 "cell_type": "code",
212 "collapsed": false,
213 "input": [
214 "wontshutup()"
215 ],
216 "language": "python",
217 "metadata": {},
218 "outputs": [
219 {
220 "output_type": "stream",
221 "stream": "stdout",
222 "text": [
223 "setting up X\n",
224 "step 2: constructing y-data\n",
225 "step 3: display info about y\n",
226 "okay, I'm done now\n"
227 ]
228 },
229 {
230 "metadata": {},
231 "output_type": "display_data",
232 "png": "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\nEfGbE9cVJiSYYxQ8HliyxByYdvCgafFceaW53aphQ3OoWlFOzNy7F/7v/8xr3TpYs8b8vm1bc2TD\no49CvXolz33OQt+lSxd27dp11j+fOHEiPXr0OO8XDwkJKXkyEREHu+giuPZa80pJgZwcU6AzMuCV\nV8yoPzcXqlUzxyzUqAEXXGA+1+uF/fvNaZp79ph/1qCBebVqZVb8tGwJF17oo7DeUkpMTPRu2LCh\nwD9bs2aNt2vXric/njhxonfSpEkFPluvXj0voJdeeumlVzFe9erVO2+d9knrxltIcyo+Pp5t27ax\nY8cOateuzdy5c0lNTS3w2e1OXL8kIuICJZ6MXbBgAZGRkWRkZNC9e3euu+46AL7//nu6d+8OQGho\nKCkpKXTt2pVGjRrRp08fYmNjfZNcRESKxDFHIIiIiH9Y3xmrDVWnDBo0iLCwMJoGyiEbfpKdnU2H\nDh1o3LgxTZo04aWXXrIdyZpff/2VNm3a0KJFCxo1asQjjzxiO5J1+fn5xMXFFWlBiJtFRUXRrFkz\n4uLiuPw8ay2tjujz8/Np2LAhK1asIDw8nNatW5Oamhq07Z1Vq1ZRuXJlbr/9djZu3Gg7jjW7du1i\n165dtGjRgl9++YVWrVqxcOHCoP3v4tChQ1SsWJFjx47Rrl07nnvuOdq1a2c7ljUvvPACGzZs4MCB\nAyxevNh2HGvq1q3Lhg0bqF69+nmftTqi14aq0yUkJFCtWjXbMayrWbMmLVq0AKBy5crExsbyfVlu\nQ3SYihUrAnDkyBHy8/OL9BfbrXJyckhLS+OOO+7QabcUvhDmTFYLfUEbqnJzcy0mEqfZsWMHWVlZ\ntGnTxnYUa44fP06LFi0ICwujQ4cONGrUyHYka+6//34mT55MuXLWu87WhYSE0LlzZ+Lj45k+ffo5\nn7X63dKGKjmXX375hZtvvpkpU6ZQuXJl23GsKVeuHJ9//jk5OTl88sknQXsUwpIlS7jsssuIi4vT\naB5IT08nKyuLpUuX8ve//51Vq1YV+qzVQh8eHk52dvbJj7Ozs4mIiLCYSJzi6NGj3HTTTdx66630\n7NnTdhxHqFKlCt27d2f9+vW2o1ixevVqFi9eTN26denXrx8fffQRt99+u+1Y1tSqVQuAP/3pT9x4\n441kZmYW+qzVQv/HDVVHjhxh7ty5JCUl2YwkDuD1ehk8eDCNGjVi5MiRtuNYtWfPHvbt2wfA4cOH\n+eCDD4iLi7Ocyo6JEyeSnZ3Nt99+y5w5c+jYsSOzZs2yHcuKQ4cOceDAAQAOHjzI8uXLz7laz2qh\n14aq0/VNJLb3AAAAlUlEQVTr14+2bduydetWIiMjmTFjhu1IVqSnpzN79mxWrlxJXFwccXFxLFu2\nzHYsK3bu3EnHjh1p0aIFbdq0oUePHnTq1Ml2LEcI5tZvXl4eCQkJJ/+7uP7667nmmmsKfV4bpkRE\nXE5T1yIiLqdCLyLicir0IiIup0IvIuJyKvQiIi6nQi8i4nIq9CIiLqdCLyLicv8PoaUAhzXYTeQA\nAAAASUVORK5CYII=\n",
233 "text": [
234 "<matplotlib.figure.Figure at 0x10866ae90>"
235 ]
236 }
237 ],
238 "prompt_number": 18
239 },
240 {
241 "cell_type": "markdown",
242 "metadata": {},
243 "source": [
244 "And you can selectively disable capturing stdout, stderr or rich display, by passing `--no-stdout`, `--no-stderr` and `--no-display`"
245 ]
246 },
247 {
248 "cell_type": "code",
249 "collapsed": false,
250 "input": [
251 "%%capture cap --no-stderr\n",
252 "print('hi, stdout')\n",
253 "print(\"hello, stderr\", file=sys.stderr)"
254 ],
255 "language": "python",
256 "metadata": {},
257 "outputs": [
258 {
259 "output_type": "stream",
260 "stream": "stderr",
261 "text": [
262 "hello, stderr\n"
263 ]
264 }
265 ],
266 "prompt_number": 19
267 },
268 {
269 "cell_type": "code",
270 "collapsed": false,
271 "input": [
272 "cap.stdout"
273 ],
274 "language": "python",
275 "metadata": {},
276 "outputs": [
277 {
278 "metadata": {},
279 "output_type": "pyout",
280 "prompt_number": 20,
281 "text": [
282 "'hi, stdout\\n'"
283 ]
284 }
285 ],
286 "prompt_number": 20
287 },
288 {
289 "cell_type": "code",
290 "collapsed": false,
291 "input": [
292 "cap.stderr"
293 ],
294 "language": "python",
295 "metadata": {},
296 "outputs": [
297 {
298 "metadata": {},
299 "output_type": "pyout",
300 "prompt_number": 21,
301 "text": [
302 "''"
303 ]
304 }
305 ],
306 "prompt_number": 21
307 },
308 {
309 "cell_type": "code",
310 "collapsed": false,
311 "input": [
312 "cap.outputs"
313 ],
314 "language": "python",
315 "metadata": {},
316 "outputs": [
317 {
318 "metadata": {},
319 "output_type": "pyout",
320 "prompt_number": 22,
321 "text": [
322 "[]"
323 ]
324 }
325 ],
326 "prompt_number": 22
327 }
328 ],
329 "metadata": {}
330 }
331 ]
332 } No newline at end of file
This diff has been collapsed as it changes many lines, (787 lines changed) Show them Hide them
@@ -0,0 +1,787 b''
1 {
2 "metadata": {
3 "name": "",
4 "signature": "sha256:86c779d5798c4a68bda7e71c8ef320cb7ba9d7e3d0f1bc4b828ee65f617a5ae3"
5 },
6 "nbformat": 3,
7 "nbformat_minor": 0,
8 "worksheets": [
9 {
10 "cells": [
11 {
12 "cell_type": "heading",
13 "level": 1,
14 "metadata": {},
15 "source": [
16 "Custom Display Logic"
17 ]
18 },
19 {
20 "cell_type": "heading",
21 "level": 2,
22 "metadata": {},
23 "source": [
24 "Overview"
25 ]
26 },
27 {
28 "cell_type": "markdown",
29 "metadata": {},
30 "source": [
31 "As described in the [Rich Output](Rich Output.ipynb) tutorial, the IPython display system can display rich representations of objects in the following formats:\n",
32 "\n",
33 "* JavaScript\n",
34 "* HTML\n",
35 "* PNG\n",
36 "* JPEG\n",
37 "* SVG\n",
38 "* LaTeX\n",
39 "* PDF\n",
40 "\n",
41 "This Notebook shows how you can add custom display logic to your own classes, so that they can be displayed using these rich representations. There are two ways of accomplishing this:\n",
42 "\n",
43 "1. Implementing special display methods such as `_repr_html_` when you define your class.\n",
44 "2. Registering a display function for a particular existing class.\n",
45 "\n",
46 "This Notebook describes and illustrates both approaches."
47 ]
48 },
49 {
50 "cell_type": "markdown",
51 "metadata": {},
52 "source": [
53 "Import the IPython display functions."
54 ]
55 },
56 {
57 "cell_type": "code",
58 "collapsed": false,
59 "input": [
60 "from IPython.display import (\n",
61 " display, display_html, display_png, display_svg\n",
62 ")"
63 ],
64 "language": "python",
65 "metadata": {},
66 "outputs": [],
67 "prompt_number": 1
68 },
69 {
70 "cell_type": "markdown",
71 "metadata": {},
72 "source": [
73 "Parts of this notebook need the matplotlib inline backend:"
74 ]
75 },
76 {
77 "cell_type": "code",
78 "collapsed": false,
79 "input": [
80 "%matplotlib inline\n",
81 "import numpy as np\n",
82 "import matplotlib.pyplot as plt"
83 ],
84 "language": "python",
85 "metadata": {},
86 "outputs": [],
87 "prompt_number": 2
88 },
89 {
90 "cell_type": "heading",
91 "level": 2,
92 "metadata": {},
93 "source": [
94 "Special display methods"
95 ]
96 },
97 {
98 "cell_type": "markdown",
99 "metadata": {},
100 "source": [
101 "The main idea of the first approach is that you have to implement special display methods when you define your class, one for each representation you want to use. Here is a list of the names of the special methods and the values they must return:\n",
102 "\n",
103 "* `_repr_html_`: return raw HTML as a string\n",
104 "* `_repr_json_`: return raw JSON as a string\n",
105 "* `_repr_jpeg_`: return raw JPEG data\n",
106 "* `_repr_png_`: return raw PNG data\n",
107 "* `_repr_svg_`: return raw SVG data as a string\n",
108 "* `_repr_latex_`: return LaTeX commands in a string surrounded by \"$\"."
109 ]
110 },
111 {
112 "cell_type": "markdown",
113 "metadata": {},
114 "source": [
115 "As an illustration, we build a class that holds data generated by sampling a Gaussian distribution with given mean and standard deviation. Here is the definition of the `Gaussian` class, which has a custom PNG and LaTeX representation."
116 ]
117 },
118 {
119 "cell_type": "code",
120 "collapsed": false,
121 "input": [
122 "from IPython.core.pylabtools import print_figure\n",
123 "from IPython.display import Image, SVG, Math\n",
124 "\n",
125 "class Gaussian(object):\n",
126 " \"\"\"A simple object holding data sampled from a Gaussian distribution.\n",
127 " \"\"\"\n",
128 " def __init__(self, mean=0.0, std=1, size=1000):\n",
129 " self.data = np.random.normal(mean, std, size)\n",
130 " self.mean = mean\n",
131 " self.std = std\n",
132 " self.size = size\n",
133 " # For caching plots that may be expensive to compute\n",
134 " self._png_data = None\n",
135 " \n",
136 " def _figure_data(self, format):\n",
137 " fig, ax = plt.subplots()\n",
138 " ax.hist(self.data, bins=50)\n",
139 " ax.set_title(self._repr_latex_())\n",
140 " ax.set_xlim(-10.0,10.0)\n",
141 " data = print_figure(fig, format)\n",
142 " # We MUST close the figure, otherwise IPython's display machinery\n",
143 " # will pick it up and send it as output, resulting in a double display\n",
144 " plt.close(fig)\n",
145 " return data\n",
146 " \n",
147 " def _repr_png_(self):\n",
148 " if self._png_data is None:\n",
149 " self._png_data = self._figure_data('png')\n",
150 " return self._png_data\n",
151 " \n",
152 " def _repr_latex_(self):\n",
153 " return r'$\\mathcal{N}(\\mu=%.2g, \\sigma=%.2g),\\ N=%d$' % (self.mean,\n",
154 " self.std, self.size)"
155 ],
156 "language": "python",
157 "metadata": {},
158 "outputs": [],
159 "prompt_number": 3
160 },
161 {
162 "cell_type": "markdown",
163 "metadata": {},
164 "source": [
165 "Create an instance of the Gaussian distribution and return it to display the default representation:"
166 ]
167 },
168 {
169 "cell_type": "code",
170 "collapsed": false,
171 "input": [
172 "x = Gaussian(2.0, 1.0)\n",
173 "x"
174 ],
175 "language": "python",
176 "metadata": {},
177 "outputs": [
178 {
179 "latex": [
180 "$\\mathcal{N}(\\mu=2, \\sigma=1),\\ N=1000$"
181 ],
182 "metadata": {},
183 "output_type": "pyout",
184 "png": "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\n",
185 "prompt_number": 4,
186 "text": [
187 "<__main__.Gaussian at 0x106e7ae10>"
188 ]
189 }
190 ],
191 "prompt_number": 4
192 },
193 {
194 "cell_type": "markdown",
195 "metadata": {},
196 "source": [
197 "You can also pass the object to the `display` function to display the default representation:"
198 ]
199 },
200 {
201 "cell_type": "code",
202 "collapsed": false,
203 "input": [
204 "display(x)"
205 ],
206 "language": "python",
207 "metadata": {},
208 "outputs": [
209 {
210 "latex": [
211 "$\\mathcal{N}(\\mu=2, \\sigma=1),\\ N=1000$"
212 ],
213 "metadata": {},
214 "output_type": "display_data",
215 "png": "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\n",
216 "text": [
217 "<__main__.Gaussian at 0x106e7ae10>"
218 ]
219 }
220 ],
221 "prompt_number": 5
222 },
223 {
224 "cell_type": "markdown",
225 "metadata": {},
226 "source": [
227 "Use `display_png` to view the PNG representation:"
228 ]
229 },
230 {
231 "cell_type": "code",
232 "collapsed": false,
233 "input": [
234 "display_png(x)"
235 ],
236 "language": "python",
237 "metadata": {},
238 "outputs": [
239 {
240 "metadata": {},
241 "output_type": "display_data",
242 "png": "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\n"
243 }
244 ],
245 "prompt_number": 6
246 },
247 {
248 "cell_type": "markdown",
249 "metadata": {},
250 "source": [
251 "<div class=\"alert alert-success\">\n",
252 "It is important to note a subtle different between <code>display</code> and <code>display_png</code>. The former computes <em>all</em> representations of the object, and lets the notebook UI decide which to display. The later only computes the PNG representation.\n",
253 "</div>"
254 ]
255 },
256 {
257 "cell_type": "markdown",
258 "metadata": {},
259 "source": [
260 "Create a new Gaussian with different parameters:"
261 ]
262 },
263 {
264 "cell_type": "code",
265 "collapsed": false,
266 "input": [
267 "x2 = Gaussian(0, 2, 2000)\n",
268 "x2"
269 ],
270 "language": "python",
271 "metadata": {},
272 "outputs": [
273 {
274 "latex": [
275 "$\\mathcal{N}(\\mu=0, \\sigma=2),\\ N=2000$"
276 ],
277 "metadata": {},
278 "output_type": "pyout",
279 "png": "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\nTkSuQmCC\n",
280 "prompt_number": 7,
281 "text": [
282 "<__main__.Gaussian at 0x106e9ce90>"
283 ]
284 }
285 ],
286 "prompt_number": 7
287 },
288 {
289 "cell_type": "markdown",
290 "metadata": {},
291 "source": [
292 "You can then compare the two Gaussians by displaying their histograms:"
293 ]
294 },
295 {
296 "cell_type": "code",
297 "collapsed": false,
298 "input": [
299 "display_png(x)\n",
300 "display_png(x2)"
301 ],
302 "language": "python",
303 "metadata": {},
304 "outputs": [
305 {
306 "metadata": {},
307 "output_type": "display_data",
308 "png": "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\n"
309 },
310 {
311 "metadata": {},
312 "output_type": "display_data",
313 "png": "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\nTkSuQmCC\n"
314 }
315 ],
316 "prompt_number": 8
317 },
318 {
319 "cell_type": "markdown",
320 "metadata": {},
321 "source": [
322 "Note that like `print`, you can call any of the `display` functions multiple times in a cell."
323 ]
324 },
325 {
326 "cell_type": "heading",
327 "level": 2,
328 "metadata": {},
329 "source": [
330 "Adding IPython display support to existing objects"
331 ]
332 },
333 {
334 "cell_type": "markdown",
335 "metadata": {},
336 "source": [
337 "When you are directly writing your own classes, you can adapt them for display in IPython by following the above approach. But in practice, you often need to work with existing classes that you can't easily modify. We now illustrate how to add rich output capabilities to existing objects. We will use the NumPy polynomials and change their default representation to be a formatted LaTeX expression."
338 ]
339 },
340 {
341 "cell_type": "markdown",
342 "metadata": {},
343 "source": [
344 "First, consider how a NumPy polynomial object renders by default:"
345 ]
346 },
347 {
348 "cell_type": "code",
349 "collapsed": false,
350 "input": [
351 "p = np.polynomial.Polynomial([1,2,3], [-10, 10])\n",
352 "p"
353 ],
354 "language": "python",
355 "metadata": {},
356 "outputs": [
357 {
358 "metadata": {},
359 "output_type": "pyout",
360 "prompt_number": 9,
361 "text": [
362 "Polynomial([ 1., 2., 3.], [-10., 10.], [-1., 1.])"
363 ]
364 }
365 ],
366 "prompt_number": 9
367 },
368 {
369 "cell_type": "markdown",
370 "metadata": {},
371 "source": [
372 "Next, define a function that pretty-prints a polynomial as a LaTeX string:"
373 ]
374 },
375 {
376 "cell_type": "code",
377 "collapsed": false,
378 "input": [
379 "def poly_to_latex(p):\n",
380 " terms = ['%.2g' % p.coef[0]]\n",
381 " if len(p) > 1:\n",
382 " term = 'x'\n",
383 " c = p.coef[1]\n",
384 " if c!=1:\n",
385 " term = ('%.2g ' % c) + term\n",
386 " terms.append(term)\n",
387 " if len(p) > 2:\n",
388 " for i in range(2, len(p)):\n",
389 " term = 'x^%d' % i\n",
390 " c = p.coef[i]\n",
391 " if c!=1:\n",
392 " term = ('%.2g ' % c) + term\n",
393 " terms.append(term)\n",
394 " px = '$P(x)=%s$' % '+'.join(terms)\n",
395 " dom = r', $x \\in [%.2g,\\ %.2g]$' % tuple(p.domain)\n",
396 " return px+dom"
397 ],
398 "language": "python",
399 "metadata": {},
400 "outputs": [],
401 "prompt_number": 10
402 },
403 {
404 "cell_type": "markdown",
405 "metadata": {},
406 "source": [
407 "This produces, on our polynomial ``p``, the following:"
408 ]
409 },
410 {
411 "cell_type": "code",
412 "collapsed": false,
413 "input": [
414 "poly_to_latex(p)"
415 ],
416 "language": "python",
417 "metadata": {},
418 "outputs": [
419 {
420 "metadata": {},
421 "output_type": "pyout",
422 "prompt_number": 11,
423 "text": [
424 "'$P(x)=1+2 x+3 x^2$, $x \\\\in [-10,\\\\ 10]$'"
425 ]
426 }
427 ],
428 "prompt_number": 11
429 },
430 {
431 "cell_type": "markdown",
432 "metadata": {},
433 "source": [
434 "You can render this string using the `Latex` class:"
435 ]
436 },
437 {
438 "cell_type": "code",
439 "collapsed": false,
440 "input": [
441 "from IPython.display import Latex\n",
442 "Latex(poly_to_latex(p))"
443 ],
444 "language": "python",
445 "metadata": {},
446 "outputs": [
447 {
448 "latex": [
449 "$P(x)=1+2 x+3 x^2$, $x \\in [-10,\\ 10]$"
450 ],
451 "metadata": {},
452 "output_type": "pyout",
453 "prompt_number": 12,
454 "text": [
455 "<IPython.core.display.Latex object>"
456 ]
457 }
458 ],
459 "prompt_number": 12
460 },
461 {
462 "cell_type": "markdown",
463 "metadata": {},
464 "source": [
465 "However, you can configure IPython to do this automatically by registering the `Polynomial` class and the `plot_to_latex` function with an IPython display formatter. Let's look at the default formatters provided by IPython:"
466 ]
467 },
468 {
469 "cell_type": "code",
470 "collapsed": false,
471 "input": [
472 "ip = get_ipython()\n",
473 "for mime, formatter in ip.display_formatter.formatters.items():\n",
474 " print '%24s : %s' % (mime, formatter.__class__.__name__)"
475 ],
476 "language": "python",
477 "metadata": {},
478 "outputs": [
479 {
480 "output_type": "stream",
481 "stream": "stdout",
482 "text": [
483 " text/plain : PlainTextFormatter\n",
484 " image/jpeg : JPEGFormatter\n",
485 " text/html : HTMLFormatter\n",
486 " image/svg+xml : SVGFormatter\n",
487 " image/png : PNGFormatter\n",
488 " application/javascript : JavascriptFormatter\n",
489 " text/markdown : MarkdownFormatter\n",
490 " text/latex : LatexFormatter\n",
491 " application/json : JSONFormatter\n",
492 " application/pdf : PDFFormatter\n"
493 ]
494 }
495 ],
496 "prompt_number": 13
497 },
498 {
499 "cell_type": "markdown",
500 "metadata": {},
501 "source": [
502 "The `formatters` attribute is a dictionary keyed by MIME types. To define a custom LaTeX display function, you want a handle on the `text/latex` formatter:"
503 ]
504 },
505 {
506 "cell_type": "code",
507 "collapsed": false,
508 "input": [
509 "ip = get_ipython()\n",
510 "latex_f = ip.display_formatter.formatters['text/latex']"
511 ],
512 "language": "python",
513 "metadata": {},
514 "outputs": [],
515 "prompt_number": 14
516 },
517 {
518 "cell_type": "markdown",
519 "metadata": {},
520 "source": [
521 "The formatter object has a couple of methods for registering custom display functions for existing types."
522 ]
523 },
524 {
525 "cell_type": "code",
526 "collapsed": false,
527 "input": [
528 "help(latex_f.for_type)"
529 ],
530 "language": "python",
531 "metadata": {},
532 "outputs": [
533 {
534 "output_type": "stream",
535 "stream": "stdout",
536 "text": [
537 "Help on method for_type in module IPython.core.formatters:\n",
538 "\n",
539 "for_type(self, typ, func=None) method of IPython.core.formatters.LatexFormatter instance\n",
540 " Add a format function for a given type.\n",
541 " \n",
542 " Parameters\n",
543 " -----------\n",
544 " typ : type or '__module__.__name__' string for a type\n",
545 " The class of the object that will be formatted using `func`.\n",
546 " func : callable\n",
547 " A callable for computing the format data.\n",
548 " `func` will be called with the object to be formatted,\n",
549 " and will return the raw data in this formatter's format.\n",
550 " Subclasses may use a different call signature for the\n",
551 " `func` argument.\n",
552 " \n",
553 " If `func` is None or not specified, there will be no change,\n",
554 " only returning the current value.\n",
555 " \n",
556 " Returns\n",
557 " -------\n",
558 " oldfunc : callable\n",
559 " The currently registered callable.\n",
560 " If you are registering a new formatter,\n",
561 " this will be the previous value (to enable restoring later).\n",
562 "\n"
563 ]
564 }
565 ],
566 "prompt_number": 15
567 },
568 {
569 "cell_type": "code",
570 "collapsed": false,
571 "input": [
572 "help(latex_f.for_type_by_name)"
573 ],
574 "language": "python",
575 "metadata": {},
576 "outputs": [
577 {
578 "output_type": "stream",
579 "stream": "stdout",
580 "text": [
581 "Help on method for_type_by_name in module IPython.core.formatters:\n",
582 "\n",
583 "for_type_by_name(self, type_module, type_name, func=None) method of IPython.core.formatters.LatexFormatter instance\n",
584 " Add a format function for a type specified by the full dotted\n",
585 " module and name of the type, rather than the type of the object.\n",
586 " \n",
587 " Parameters\n",
588 " ----------\n",
589 " type_module : str\n",
590 " The full dotted name of the module the type is defined in, like\n",
591 " ``numpy``.\n",
592 " type_name : str\n",
593 " The name of the type (the class name), like ``dtype``\n",
594 " func : callable\n",
595 " A callable for computing the format data.\n",
596 " `func` will be called with the object to be formatted,\n",
597 " and will return the raw data in this formatter's format.\n",
598 " Subclasses may use a different call signature for the\n",
599 " `func` argument.\n",
600 " \n",
601 " If `func` is None or unspecified, there will be no change,\n",
602 " only returning the current value.\n",
603 " \n",
604 " Returns\n",
605 " -------\n",
606 " oldfunc : callable\n",
607 " The currently registered callable.\n",
608 " If you are registering a new formatter,\n",
609 " this will be the previous value (to enable restoring later).\n",
610 "\n"
611 ]
612 }
613 ],
614 "prompt_number": 16
615 },
616 {
617 "cell_type": "markdown",
618 "metadata": {},
619 "source": [
620 "In this case, we will use `for_type_by_name` to register `poly_to_latex` as the display function for the `Polynomial` type:"
621 ]
622 },
623 {
624 "cell_type": "code",
625 "collapsed": false,
626 "input": [
627 "latex_f.for_type_by_name('numpy.polynomial.polynomial',\n",
628 " 'Polynomial', poly_to_latex)"
629 ],
630 "language": "python",
631 "metadata": {},
632 "outputs": [],
633 "prompt_number": 18
634 },
635 {
636 "cell_type": "markdown",
637 "metadata": {},
638 "source": [
639 "Once the custom display function has been registered, all NumPy `Polynomial` instances will be represented by their LaTeX form instead:"
640 ]
641 },
642 {
643 "cell_type": "code",
644 "collapsed": false,
645 "input": [
646 "p"
647 ],
648 "language": "python",
649 "metadata": {},
650 "outputs": [
651 {
652 "latex": [
653 "$P(x)=1+2 x+3 x^2$, $x \\in [-10,\\ 10]$"
654 ],
655 "metadata": {},
656 "output_type": "pyout",
657 "prompt_number": 19,
658 "text": [
659 "Polynomial([ 1., 2., 3.], [-10., 10.], [-1., 1.])"
660 ]
661 }
662 ],
663 "prompt_number": 19
664 },
665 {
666 "cell_type": "code",
667 "collapsed": false,
668 "input": [
669 "p2 = np.polynomial.Polynomial([-20, 71, -15, 1])\n",
670 "p2"
671 ],
672 "language": "python",
673 "metadata": {},
674 "outputs": [
675 {
676 "latex": [
677 "$P(x)=-20+71 x+-15 x^2+x^3$, $x \\in [-1,\\ 1]$"
678 ],
679 "metadata": {},
680 "output_type": "pyout",
681 "prompt_number": 20,
682 "text": [
683 "Polynomial([-20., 71., -15., 1.], [-1., 1.], [-1., 1.])"
684 ]
685 }
686 ],
687 "prompt_number": 20
688 },
689 {
690 "cell_type": "heading",
691 "level": 2,
692 "metadata": {},
693 "source": [
694 "More complex display with `_ipython_display_`"
695 ]
696 },
697 {
698 "cell_type": "markdown",
699 "metadata": {},
700 "source": [
701 "Rich output special methods and functions can only display one object or MIME type at a time. Sometimes this is not enough if you want to display multiple objects or MIME types at once. An example of this would be to use an HTML representation to put some HTML elements in the DOM and then use a JavaScript representation to add events to those elements.\n",
702 "\n",
703 "**IPython 2.0** recognizes another display method, `_ipython_display_`, which allows your objects to take complete control of displaying themselves. If this method is defined, IPython will call it, and make no effort to display the object using the above described `_repr_*_` methods for custom display functions. It's a way for you to say \"Back off, IPython, I can display this myself.\" Most importantly, your `_ipython_display_` method can make multiple calls to the top-level `display` functions to accomplish its goals.\n",
704 "\n",
705 "Here is an object that uses `display_html` and `display_javascript` to make a plot using the [Flot](http://www.flotcharts.org/) JavaScript plotting library:"
706 ]
707 },
708 {
709 "cell_type": "code",
710 "collapsed": false,
711 "input": [
712 "import json\n",
713 "import uuid\n",
714 "from IPython.display import display_javascript, display_html, display\n",
715 "\n",
716 "class FlotPlot(object):\n",
717 " def __init__(self, x, y):\n",
718 " self.x = x\n",
719 " self.y = y\n",
720 " self.uuid = str(uuid.uuid4())\n",
721 " \n",
722 " def _ipython_display_(self):\n",
723 " json_data = json.dumps(zip(self.x, self.y))\n",
724 " display_html('<div id=\"{}\" style=\"height: 300px; width:80%;\"></div>'.format(self.uuid),\n",
725 " raw=True\n",
726 " )\n",
727 " display_javascript(\"\"\"\n",
728 " require([\"//cdnjs.cloudflare.com/ajax/libs/flot/0.8.2/jquery.flot.min.js\"], function() {\n",
729 " var line = JSON.parse(\"%s\");\n",
730 " console.log(line);\n",
731 " $.plot(\"#%s\", [line]);\n",
732 " });\n",
733 " \"\"\" % (json_data, self.uuid), raw=True)\n"
734 ],
735 "language": "python",
736 "metadata": {},
737 "outputs": [],
738 "prompt_number": 21
739 },
740 {
741 "cell_type": "code",
742 "collapsed": false,
743 "input": [
744 "import numpy as np\n",
745 "x = np.linspace(0,10)\n",
746 "y = np.sin(x)\n",
747 "FlotPlot(x, np.sin(x))"
748 ],
749 "language": "python",
750 "metadata": {},
751 "outputs": [
752 {
753 "html": [
754 "<div id=\"e75b8189-92cb-4cbb-9996-bb8ad5ff1b4e\" style=\"height: 300px; width:80%;\"></div>"
755 ],
756 "metadata": {},
757 "output_type": "display_data"
758 },
759 {
760 "javascript": [
761 "\n",
762 " require([\"//cdnjs.cloudflare.com/ajax/libs/flot/0.8.2/jquery.flot.min.js\"], function() {\n",
763 " var line = JSON.parse(\"[[0.0, 0.0], [0.20408163265306123, 0.20266793654820095], [0.40816326530612246, 0.39692414892492234], [0.61224489795918369, 0.57470604121617908], [0.81632653061224492, 0.72863478346935029], [1.0204081632653061, 0.85232156971961837], [1.2244897959183674, 0.94063278511248671], [1.4285714285714286, 0.98990307637212394], [1.6326530612244898, 0.99808748213471832], [1.8367346938775511, 0.96484630898376322], [2.0408163265306123, 0.89155923041100371], [2.2448979591836737, 0.7812680235262639], [2.4489795918367347, 0.63855032022660208], [2.6530612244897958, 0.46932961277720098], [2.8571428571428572, 0.28062939951435684], [3.0612244897959187, 0.080281674842813497], [3.2653061224489797, -0.12339813736217871], [3.4693877551020407, -0.32195631507261868], [3.6734693877551021, -0.50715170948451438], [3.8775510204081636, -0.67129779355193209], [4.0816326530612246, -0.80758169096833643], [4.2857142857142856, -0.91034694431078278], [4.4897959183673475, -0.97532828606704558], [4.6938775510204085, -0.99982866838408957], [4.8979591836734695, -0.98283120392563061], [5.1020408163265305, -0.92504137173820289], [5.3061224489795915, -0.82885773637304272], [5.5102040816326534, -0.69827239556539955], [5.7142857142857144, -0.53870528838615628], [5.9183673469387754, -0.35677924089893803], [6.1224489795918373, -0.16004508604325057], [6.3265306122448983, 0.043331733368683463], [6.5306122448979593, 0.24491007101197931], [6.7346938775510203, 0.43632342647181932], [6.9387755102040813, 0.6096271964908323], [7.1428571428571432, 0.75762841539272019], [7.3469387755102042, 0.87418429881973347], [7.5510204081632653, 0.95445719973875187], [7.7551020408163271, 0.99511539477766364], [7.9591836734693882, 0.99447136726361685], [8.1632653061224492, 0.95255184753146038], [8.3673469387755102, 0.87109670348232071], [8.5714285714285712, 0.75348672743963763], [8.7755102040816322, 0.60460331650615429], [8.979591836734695, 0.43062587038273736], [9.183673469387756, 0.23877531564403087], [9.387755102040817, 0.037014401485062368], [9.591836734693878, -0.16628279384875641], [9.795918367346939, -0.36267842882654883], [10.0, -0.54402111088936989]]\");\n",
764 " console.log(line);\n",
765 " $.plot(\"#e75b8189-92cb-4cbb-9996-bb8ad5ff1b4e\", [line]);\n",
766 " });\n",
767 " "
768 ],
769 "metadata": {},
770 "output_type": "display_data"
771 }
772 ],
773 "prompt_number": 22
774 },
775 {
776 "cell_type": "code",
777 "collapsed": false,
778 "input": [],
779 "language": "python",
780 "metadata": {},
781 "outputs": []
782 }
783 ],
784 "metadata": {}
785 }
786 ]
787 } No newline at end of file
This diff has been collapsed as it changes many lines, (944 lines changed) Show them Hide them
@@ -0,0 +1,944 b''
1 {
2 "metadata": {
3 "name": ""
4 },
5 "nbformat": 3,
6 "nbformat_minor": 0,
7 "worksheets": [
8 {
9 "cells": [
10 {
11 "cell_type": "heading",
12 "level": 1,
13 "metadata": {},
14 "source": [
15 "Defining Custom Display Logic for Your Own Objects"
16 ]
17 },
18 {
19 "cell_type": "heading",
20 "level": 2,
21 "metadata": {},
22 "source": [
23 "Overview"
24 ]
25 },
26 {
27 "cell_type": "markdown",
28 "metadata": {},
29 "source": [
30 "In Python, objects can declare their textual representation using the `__repr__` method. IPython expands on this idea and allows objects to declare other, richer representations including:\n",
31 "\n",
32 "* HTML\n",
33 "* JSON\n",
34 "* PNG\n",
35 "* JPEG\n",
36 "* SVG\n",
37 "* LaTeX\n",
38 "\n",
39 "This Notebook shows how you can add custom display logic to your own classes, so that they can be displayed using these rich representations. There are two ways of accomplishing this:\n",
40 "\n",
41 "1. Implementing special display methods such as `_repr_html_`.\n",
42 "2. Registering a display function for a particular type.\n",
43 "\n",
44 "In this Notebook we show how both approaches work."
45 ]
46 },
47 {
48 "cell_type": "markdown",
49 "metadata": {},
50 "source": [
51 "Before we get started, we will import the various display functions for displaying the different formats we will create."
52 ]
53 },
54 {
55 "cell_type": "code",
56 "collapsed": false,
57 "input": [
58 "from IPython.display import display\n",
59 "from IPython.display import (\n",
60 " display_html, display_jpeg, display_png,\n",
61 " display_javascript, display_svg, display_latex\n",
62 ")"
63 ],
64 "language": "python",
65 "metadata": {},
66 "outputs": [],
67 "prompt_number": 1
68 },
69 {
70 "cell_type": "heading",
71 "level": 2,
72 "metadata": {},
73 "source": [
74 "Implementing special display methods"
75 ]
76 },
77 {
78 "cell_type": "markdown",
79 "metadata": {},
80 "source": [
81 "The main idea of the first approach is that you have to implement special display methods, one for each representation you want to use. Here is a list of the names of the special methods and the values they must return:\n",
82 "\n",
83 "* `_repr_html_`: return raw HTML as a string\n",
84 "* `_repr_json_`: return raw JSON as a string\n",
85 "* `_repr_jpeg_`: return raw JPEG data\n",
86 "* `_repr_png_`: return raw PNG data\n",
87 "* `_repr_svg_`: return raw SVG data as a string\n",
88 "* `_repr_latex_`: return LaTeX commands in a string surrounded by \"$\"."
89 ]
90 },
91 {
92 "cell_type": "heading",
93 "level": 3,
94 "metadata": {},
95 "source": [
96 "Model Citizen: pandas"
97 ]
98 },
99 {
100 "cell_type": "markdown",
101 "metadata": {},
102 "source": [
103 "A prominent example of a package that has IPython-aware rich representations of its objects is [pandas](http://pandas.pydata.org/).\n",
104 "\n",
105 "A pandas DataFrame has a rich HTML table representation,\n",
106 "using `_repr_html_`.\n"
107 ]
108 },
109 {
110 "cell_type": "code",
111 "collapsed": false,
112 "input": [
113 "import io\n",
114 "import pandas"
115 ],
116 "language": "python",
117 "metadata": {},
118 "outputs": [],
119 "prompt_number": 2
120 },
121 {
122 "cell_type": "code",
123 "collapsed": false,
124 "input": [
125 "%%writefile data.csv\n",
126 "Date,Open,High,Low,Close,Volume,Adj Close\n",
127 "2012-06-01,569.16,590.00,548.50,584.00,14077000,581.50\n",
128 "2012-05-01,584.90,596.76,522.18,577.73,18827900,575.26\n",
129 "2012-04-02,601.83,644.00,555.00,583.98,28759100,581.48\n",
130 "2012-03-01,548.17,621.45,516.22,599.55,26486000,596.99\n",
131 "2012-02-01,458.41,547.61,453.98,542.44,22001000,540.12\n",
132 "2012-01-03,409.40,458.24,409.00,456.48,12949100,454.53\n"
133 ],
134 "language": "python",
135 "metadata": {},
136 "outputs": [
137 {
138 "output_type": "stream",
139 "stream": "stdout",
140 "text": [
141 "Writing data.csv\n"
142 ]
143 }
144 ],
145 "prompt_number": 3
146 },
147 {
148 "cell_type": "code",
149 "collapsed": false,
150 "input": [
151 "df = pandas.read_csv(\"data.csv\")\n",
152 "pandas.set_option('display.notebook_repr_html', False)\n",
153 "df"
154 ],
155 "language": "python",
156 "metadata": {},
157 "outputs": [
158 {
159 "metadata": {},
160 "output_type": "pyout",
161 "prompt_number": 4,
162 "text": [
163 " Date Open High Low Close Volume Adj Close\n",
164 "0 2012-06-01 569.16 590.00 548.50 584.00 14077000 581.50\n",
165 "1 2012-05-01 584.90 596.76 522.18 577.73 18827900 575.26\n",
166 "2 2012-04-02 601.83 644.00 555.00 583.98 28759100 581.48\n",
167 "3 2012-03-01 548.17 621.45 516.22 599.55 26486000 596.99\n",
168 "4 2012-02-01 458.41 547.61 453.98 542.44 22001000 540.12\n",
169 "5 2012-01-03 409.40 458.24 409.00 456.48 12949100 454.53"
170 ]
171 }
172 ],
173 "prompt_number": 4
174 },
175 {
176 "cell_type": "markdown",
177 "metadata": {},
178 "source": [
179 "rich HTML can be activated via `pandas.set_option`."
180 ]
181 },
182 {
183 "cell_type": "code",
184 "collapsed": false,
185 "input": [
186 "pandas.set_option('display.notebook_repr_html', True)\n",
187 "df"
188 ],
189 "language": "python",
190 "metadata": {},
191 "outputs": [
192 {
193 "html": [
194 "<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
195 "<table border=\"1\" class=\"dataframe\">\n",
196 " <thead>\n",
197 " <tr style=\"text-align: right;\">\n",
198 " <th></th>\n",
199 " <th>Date</th>\n",
200 " <th>Open</th>\n",
201 " <th>High</th>\n",
202 " <th>Low</th>\n",
203 " <th>Close</th>\n",
204 " <th>Volume</th>\n",
205 " <th>Adj Close</th>\n",
206 " </tr>\n",
207 " </thead>\n",
208 " <tbody>\n",
209 " <tr>\n",
210 " <th>0</th>\n",
211 " <td> 2012-06-01</td>\n",
212 " <td> 569.16</td>\n",
213 " <td> 590.00</td>\n",
214 " <td> 548.50</td>\n",
215 " <td> 584.00</td>\n",
216 " <td> 14077000</td>\n",
217 " <td> 581.50</td>\n",
218 " </tr>\n",
219 " <tr>\n",
220 " <th>1</th>\n",
221 " <td> 2012-05-01</td>\n",
222 " <td> 584.90</td>\n",
223 " <td> 596.76</td>\n",
224 " <td> 522.18</td>\n",
225 " <td> 577.73</td>\n",
226 " <td> 18827900</td>\n",
227 " <td> 575.26</td>\n",
228 " </tr>\n",
229 " <tr>\n",
230 " <th>2</th>\n",
231 " <td> 2012-04-02</td>\n",
232 " <td> 601.83</td>\n",
233 " <td> 644.00</td>\n",
234 " <td> 555.00</td>\n",
235 " <td> 583.98</td>\n",
236 " <td> 28759100</td>\n",
237 " <td> 581.48</td>\n",
238 " </tr>\n",
239 " <tr>\n",
240 " <th>3</th>\n",
241 " <td> 2012-03-01</td>\n",
242 " <td> 548.17</td>\n",
243 " <td> 621.45</td>\n",
244 " <td> 516.22</td>\n",
245 " <td> 599.55</td>\n",
246 " <td> 26486000</td>\n",
247 " <td> 596.99</td>\n",
248 " </tr>\n",
249 " <tr>\n",
250 " <th>4</th>\n",
251 " <td> 2012-02-01</td>\n",
252 " <td> 458.41</td>\n",
253 " <td> 547.61</td>\n",
254 " <td> 453.98</td>\n",
255 " <td> 542.44</td>\n",
256 " <td> 22001000</td>\n",
257 " <td> 540.12</td>\n",
258 " </tr>\n",
259 " <tr>\n",
260 " <th>5</th>\n",
261 " <td> 2012-01-03</td>\n",
262 " <td> 409.40</td>\n",
263 " <td> 458.24</td>\n",
264 " <td> 409.00</td>\n",
265 " <td> 456.48</td>\n",
266 " <td> 12949100</td>\n",
267 " <td> 454.53</td>\n",
268 " </tr>\n",
269 " </tbody>\n",
270 "</table>\n",
271 "</div>"
272 ],
273 "metadata": {},
274 "output_type": "pyout",
275 "prompt_number": 5,
276 "text": [
277 " Date Open High Low Close Volume Adj Close\n",
278 "0 2012-06-01 569.16 590.00 548.50 584.00 14077000 581.50\n",
279 "1 2012-05-01 584.90 596.76 522.18 577.73 18827900 575.26\n",
280 "2 2012-04-02 601.83 644.00 555.00 583.98 28759100 581.48\n",
281 "3 2012-03-01 548.17 621.45 516.22 599.55 26486000 596.99\n",
282 "4 2012-02-01 458.41 547.61 453.98 542.44 22001000 540.12\n",
283 "5 2012-01-03 409.40 458.24 409.00 456.48 12949100 454.53"
284 ]
285 }
286 ],
287 "prompt_number": 5
288 },
289 {
290 "cell_type": "code",
291 "collapsed": false,
292 "input": [
293 "lines = df._repr_html_().splitlines()\n",
294 "print \"\\n\".join(lines[:20])"
295 ],
296 "language": "python",
297 "metadata": {},
298 "outputs": [
299 {
300 "output_type": "stream",
301 "stream": "stdout",
302 "text": [
303 "<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
304 "<table border=\"1\" class=\"dataframe\">\n",
305 " <thead>\n",
306 " <tr style=\"text-align: right;\">\n",
307 " <th></th>\n",
308 " <th>Date</th>\n",
309 " <th>Open</th>\n",
310 " <th>High</th>\n",
311 " <th>Low</th>\n",
312 " <th>Close</th>\n",
313 " <th>Volume</th>\n",
314 " <th>Adj Close</th>\n",
315 " </tr>\n",
316 " </thead>\n",
317 " <tbody>\n",
318 " <tr>\n",
319 " <th>0</th>\n",
320 " <td> 2012-06-01</td>\n",
321 " <td> 569.16</td>\n",
322 " <td> 590.00</td>\n"
323 ]
324 }
325 ],
326 "prompt_number": 6
327 },
328 {
329 "cell_type": "heading",
330 "level": 3,
331 "metadata": {},
332 "source": [
333 "Exercise"
334 ]
335 },
336 {
337 "cell_type": "markdown",
338 "metadata": {},
339 "source": [
340 "Write a simple `Circle` Python class. Don't even worry about properties such as radius, position, colors, etc. To help you out use the following representations (remember to wrap them in Python strings):\n",
341 "\n",
342 "For HTML:\n",
343 "\n",
344 " &#x25CB;\n",
345 "\n",
346 "For SVG:\n",
347 "\n",
348 " <svg width=\"100px\" height=\"100px\">\n",
349 " <circle cx=\"50\" cy=\"50\" r=\"20\" stroke=\"black\" stroke-width=\"1\" fill=\"white\"/>\n",
350 " </svg>\n",
351 "\n",
352 "For LaTeX (wrap with `$` and use a raw Python string):\n",
353 "\n",
354 " \\bigcirc\n",
355 "\n",
356 "After you write the class, create an instance and then use `display_html`, `display_svg` and `display_latex` to display those representations.\n",
357 "\n",
358 "Tips : you can slightly tweek the representation to know from which `_repr_*_` method it came from. \n",
359 "For example in my solution the svg representation is blue, and the HTML one show \"`HTML`\" between brackets."
360 ]
361 },
362 {
363 "cell_type": "heading",
364 "level": 3,
365 "metadata": {},
366 "source": [
367 "Solution"
368 ]
369 },
370 {
371 "cell_type": "markdown",
372 "metadata": {},
373 "source": [
374 "Here is my simple `MyCircle` class:"
375 ]
376 },
377 {
378 "cell_type": "code",
379 "collapsed": false,
380 "input": [
381 "%load soln/mycircle.py"
382 ],
383 "language": "python",
384 "metadata": {},
385 "outputs": [],
386 "prompt_number": 8
387 },
388 {
389 "cell_type": "markdown",
390 "metadata": {},
391 "source": [
392 "Now create an instance and use the display methods:"
393 ]
394 },
395 {
396 "cell_type": "code",
397 "collapsed": false,
398 "input": [
399 "c = MyCircle()"
400 ],
401 "language": "python",
402 "metadata": {},
403 "outputs": [],
404 "prompt_number": 11
405 },
406 {
407 "cell_type": "code",
408 "collapsed": false,
409 "input": [
410 "display_html(c)"
411 ],
412 "language": "python",
413 "metadata": {},
414 "outputs": [
415 {
416 "html": [
417 "&#x25CB; (<b>html</b>)"
418 ],
419 "metadata": {},
420 "output_type": "display_data"
421 }
422 ],
423 "prompt_number": 12
424 },
425 {
426 "cell_type": "code",
427 "collapsed": false,
428 "input": [
429 "display_svg(c)"
430 ],
431 "language": "python",
432 "metadata": {},
433 "outputs": [
434 {
435 "metadata": {},
436 "output_type": "display_data",
437 "svg": [
438 "<svg width=\"100px\" height=\"100px\">\n",
439 " <circle cx=\"50\" cy=\"50\" r=\"20\" stroke=\"black\" stroke-width=\"1\" fill=\"blue\"/>\n",
440 " </svg>"
441 ]
442 }
443 ],
444 "prompt_number": 13
445 },
446 {
447 "cell_type": "code",
448 "collapsed": false,
449 "input": [
450 "display_latex(c)"
451 ],
452 "language": "python",
453 "metadata": {},
454 "outputs": [
455 {
456 "latex": [
457 "$\\bigcirc \\LaTeX$"
458 ],
459 "metadata": {},
460 "output_type": "display_data"
461 }
462 ],
463 "prompt_number": 14
464 },
465 {
466 "cell_type": "code",
467 "collapsed": false,
468 "input": [
469 "display_javascript(c)"
470 ],
471 "language": "python",
472 "metadata": {},
473 "outputs": [
474 {
475 "javascript": [
476 "alert('I am a circle!');"
477 ],
478 "metadata": {},
479 "output_type": "display_data"
480 }
481 ],
482 "prompt_number": 15
483 },
484 {
485 "cell_type": "heading",
486 "level": 2,
487 "metadata": {},
488 "source": [
489 "Adding IPython display support to existing objects"
490 ]
491 },
492 {
493 "cell_type": "markdown",
494 "metadata": {},
495 "source": [
496 "When you are directly writing your own classes, you can adapt them for display in IPython by following the above example. But in practice, we often need to work with existing code we can't modify. We now illustrate how to add these kinds of extended display capabilities to existing objects. To continue with our example above, we will add a PNG representation to our `Circle` class using Matplotlib."
497 ]
498 },
499 {
500 "cell_type": "heading",
501 "level": 3,
502 "metadata": {},
503 "source": [
504 "Model citizen: sympy"
505 ]
506 },
507 {
508 "cell_type": "markdown",
509 "metadata": {},
510 "source": [
511 "[SymPy](http://sympy.org) is another model citizen that defines rich representations of its object.\n",
512 "Unlike pandas above, sympy registers display formatters via IPython's display formatter API, rather than declaring `_repr_mime_` methods."
513 ]
514 },
515 {
516 "cell_type": "code",
517 "collapsed": false,
518 "input": [
519 "from sympy import Rational, pi, exp, I, symbols\n",
520 "x, y, z = symbols(\"x y z\")"
521 ],
522 "language": "python",
523 "metadata": {},
524 "outputs": [],
525 "prompt_number": 16
526 },
527 {
528 "cell_type": "code",
529 "collapsed": false,
530 "input": [
531 "r = Rational(3,2)*pi + exp(I*x) / (x**2 + y)\n",
532 "r"
533 ],
534 "language": "python",
535 "metadata": {},
536 "outputs": [
537 {
538 "metadata": {},
539 "output_type": "pyout",
540 "prompt_number": 17,
541 "text": [
542 "3*pi/2 + exp(I*x)/(x**2 + y)"
543 ]
544 }
545 ],
546 "prompt_number": 17
547 },
548 {
549 "cell_type": "markdown",
550 "metadata": {},
551 "source": [
552 "SymPy provides an `init_printing` function that sets up advanced $\\LaTeX$\n",
553 "representations of its objects."
554 ]
555 },
556 {
557 "cell_type": "code",
558 "collapsed": false,
559 "input": [
560 "from sympy.interactive.printing import init_printing\n",
561 "init_printing()\n",
562 "r"
563 ],
564 "language": "python",
565 "metadata": {},
566 "outputs": [
567 {
568 "latex": [
569 "$$\\frac{3}{2} \\pi + \\frac{e^{\\mathbf{\\imath} x}}{x^{2} + y}$$"
570 ],
571 "metadata": {},
572 "output_type": "pyout",
573 "png": "iVBORw0KGgoAAAANSUhEUgAAAFAAAAAlCAYAAADV/m7fAAAABHNCSVQICAgIfAhkiAAAA9xJREFU\naIHt2l2IVVUUwPHfzDQ4hc1UFpaVTvoiKNoHaTCmU/lQaERR9mGUZBSkUVEQvcR9CSKIoCgoom5F\nBX2T+RD6EBQVZI1BBoVSFA0JUkNiiX1MD+uc5szkOPfjnHvvyP3DwF4z96y1Zp+91l577Uubuuho\ntgMNYikG8TU+wwosxs9YjTvwWy2Kj8mMV2IeZiTGythem78txwjmYitOxHs4G7vwthonbyL7cHMy\nvga/4/g8FLcAx+FVnIVesXDeRScW1KM4uwIH8V0yHkV3PYpbjFnifzsDt2J3Il+Mg9hTq+LJcuAr\nYnk/VKviJtKJe3AIv2I2Hi3SWJZzcR8O4LGijBbM0yKynsCbOKkZTtyGzzGzAbaWGJ9K6mEh/hC5\nfD1uETmvcC7AXpFkU0dGcXUDbJfRn5Oua7EjJ10VkYbwXyLnDSfyfPyJnY10Jge+FZtCSofYNAqr\nd9PQ2YHnsBn/iEJzrditsvTiGVyBnkl0jmIVPszb2QoYEnnvLvyCY7El8akQqnkzHaLoHMKnuEpU\n9d/jbjwldr6D+Fi8iEooo5ToOaq5CZdl5NfRlYy31KG3LL8c2HCq2f1ezIxPSJ79W1T5p+Tp1HSi\n1vJhPT5JxgvFRE7FC+JQP5G5WCbCfyIbRTnV8oxO8TORnTg/Ga/BN3XYLqsshKfysSk/6QqsZjNJ\nuzZfJHKvWEU9xpcQeTOVj53YJHZeeKRAX8YZrZZ7sc1Y2A6LyVudl1M1sgbviIlbjvMaYTQ7gcvF\nIbwkJmjlJM8sxbMZeQg/qO1l5MkCXJ+M9+DMRhqfiYcz8jrRDzy9AbbL8iljZhjrX76POTnorJgl\novBNm4u9Ikmua4Dtx3FqjvouxAM56quIDhHCaaJeJCbwnEY7Uid9eLDZTsBLCmxCFsgm0UnvVt2m\ntjlPJzaKnWy63djdIC6H9olO9OIqni3l5cRaMYFEadKfl+KcGMAG0S2/EbfjLdF+q4fSJL/vElee\nz4vTEpwsczrKlh6rxP3BVpHUL8VpdTqWJ73i2FjGB7hTtO/3i4qhCK4UTZPsYroIP6YfSMN0Pr70\n/xZ+n5zuTHOgR1QKh0TJNWJ86VUps0X7LZuiVuCjjLxfXKj1JfJuMYEH8GQiT9c7I0QIpWfxviN9\nsEJKR/jbdXgjI+8Sl29o/umhGi4XJ6V+sUEMiVW0oWC7c4zdG/cn8n9XHV2HeaBVGRD16SxxXbBM\n1KmvidCqh0GRVw/HXvFNjW7xAofxcp32jjrur/Bz20St2aZCFuEnkSoG8JWxdhmmVwg3g04xefNw\nifjCwUhTPWrTpk2bFuJflVvSLV1580UAAAAASUVORK5CYII=\n",
574 "prompt_number": 18,
575 "text": [
576 " \u2148\u22c5x \n",
577 "3\u22c5\u03c0 \u212f \n",
578 "\u2500\u2500\u2500 + \u2500\u2500\u2500\u2500\u2500\u2500\n",
579 " 2 2 \n",
580 " x + y"
581 ]
582 }
583 ],
584 "prompt_number": 18
585 },
586 {
587 "cell_type": "markdown",
588 "metadata": {},
589 "source": [
590 "To add a display method to an existing class, we must use IPython's display formatter API. Here we show all of the available formatters:"
591 ]
592 },
593 {
594 "cell_type": "code",
595 "collapsed": false,
596 "input": [
597 "ip = get_ipython()\n",
598 "for mime, formatter in ip.display_formatter.formatters.items():\n",
599 " print '%24s : %s' % (mime, formatter.__class__.__name__)\n"
600 ],
601 "language": "python",
602 "metadata": {},
603 "outputs": [
604 {
605 "output_type": "stream",
606 "stream": "stdout",
607 "text": [
608 " text/html : HTMLFormatter\n",
609 " image/jpeg : JPEGFormatter\n",
610 " image/svg+xml : SVGFormatter\n",
611 " image/png : PNGFormatter\n",
612 " application/javascript : JavascriptFormatter\n",
613 " text/latex : LatexFormatter\n",
614 " application/json : JSONFormatter\n",
615 " text/plain : PlainTextFormatter\n"
616 ]
617 }
618 ],
619 "prompt_number": 6
620 },
621 {
622 "cell_type": "markdown",
623 "metadata": {},
624 "source": [
625 "Let's grab the PNG formatter:"
626 ]
627 },
628 {
629 "cell_type": "code",
630 "collapsed": false,
631 "input": [
632 "png_f = ip.display_formatter.formatters['image/png']"
633 ],
634 "language": "python",
635 "metadata": {},
636 "outputs": [],
637 "prompt_number": 20
638 },
639 {
640 "cell_type": "markdown",
641 "metadata": {},
642 "source": [
643 "We will use the `for_type` method to register our display function."
644 ]
645 },
646 {
647 "cell_type": "code",
648 "collapsed": false,
649 "input": [
650 "png_f.for_type?"
651 ],
652 "language": "python",
653 "metadata": {},
654 "outputs": [],
655 "prompt_number": 21
656 },
657 {
658 "cell_type": "markdown",
659 "metadata": {},
660 "source": [
661 "As the docstring describes, we need to define a function the takes the object as a parameter and returns the raw PNG data."
662 ]
663 },
664 {
665 "cell_type": "code",
666 "collapsed": false,
667 "input": [
668 "%matplotlib inline\n",
669 "import matplotlib.pyplot as plt"
670 ],
671 "language": "python",
672 "metadata": {},
673 "outputs": [],
674 "prompt_number": 22
675 },
676 {
677 "cell_type": "code",
678 "collapsed": false,
679 "input": [
680 "class AnotherCircle(object):\n",
681 " def __init__(self, radius=1, center=(0,0), color='r'):\n",
682 " self.radius = radius\n",
683 " self.center = center\n",
684 " self.color = color\n",
685 " \n",
686 " def __repr__(self):\n",
687 " return \"<%s Circle with r=%s at %s>\" % (\n",
688 " self.color,\n",
689 " self.radius,\n",
690 " self.center,\n",
691 " )\n",
692 " \n",
693 "c = AnotherCircle()\n",
694 "c"
695 ],
696 "language": "python",
697 "metadata": {},
698 "outputs": [
699 {
700 "metadata": {},
701 "output_type": "pyout",
702 "prompt_number": 23,
703 "text": [
704 "<r Circle with r=1 at (0, 0)>"
705 ]
706 }
707 ],
708 "prompt_number": 23
709 },
710 {
711 "cell_type": "code",
712 "collapsed": false,
713 "input": [
714 "from IPython.core.pylabtools import print_figure\n",
715 "\n",
716 "def png_circle(circle):\n",
717 " \"\"\"Render AnotherCircle to png data using matplotlib\"\"\"\n",
718 " fig, ax = plt.subplots()\n",
719 " patch = plt.Circle(circle.center,\n",
720 " radius=circle.radius,\n",
721 " fc=circle.color,\n",
722 " )\n",
723 " ax.add_patch(patch)\n",
724 " plt.axis('scaled')\n",
725 " data = print_figure(fig, 'png')\n",
726 " # We MUST close the figure, otherwise IPython's display machinery\n",
727 " # will pick it up and send it as output, resulting in a double display\n",
728 " plt.close(fig)\n",
729 " return data"
730 ],
731 "language": "python",
732 "metadata": {},
733 "outputs": [],
734 "prompt_number": 24
735 },
736 {
737 "cell_type": "code",
738 "collapsed": false,
739 "input": [
740 "c = AnotherCircle()\n",
741 "print repr(png_circle(c)[:10])"
742 ],
743 "language": "python",
744 "metadata": {},
745 "outputs": [
746 {
747 "output_type": "stream",
748 "stream": "stdout",
749 "text": [
750 "'\\x89PNG\\r\\n\\x1a\\n\\x00\\x00'\n"
751 ]
752 }
753 ],
754 "prompt_number": 27
755 },
756 {
757 "cell_type": "markdown",
758 "metadata": {},
759 "source": [
760 "Now we register the display function for the type:"
761 ]
762 },
763 {
764 "cell_type": "code",
765 "collapsed": false,
766 "input": [
767 "png_f.for_type(AnotherCircle, png_circle)"
768 ],
769 "language": "python",
770 "metadata": {},
771 "outputs": [],
772 "prompt_number": 28
773 },
774 {
775 "cell_type": "markdown",
776 "metadata": {},
777 "source": [
778 "Now all `Circle` instances have PNG representations!"
779 ]
780 },
781 {
782 "cell_type": "code",
783 "collapsed": false,
784 "input": [
785 "c2 = AnotherCircle(radius=2, center=(1,0), color='g')\n",
786 "c2"
787 ],
788 "language": "python",
789 "metadata": {},
790 "outputs": [
791 {
792 "metadata": {},
793 "output_type": "pyout",
794 "png": "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\nTkSuQmCC\n",
795 "prompt_number": 29,
796 "text": [
797 "<g Circle with r=2 at (1, 0)>"
798 ]
799 }
800 ],
801 "prompt_number": 29
802 },
803 {
804 "cell_type": "code",
805 "collapsed": false,
806 "input": [
807 "display_png(c2)"
808 ],
809 "language": "python",
810 "metadata": {},
811 "outputs": [
812 {
813 "metadata": {},
814 "output_type": "display_data",
815 "png": "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\nTkSuQmCC\n"
816 }
817 ],
818 "prompt_number": 30
819 },
820 {
821 "cell_type": "heading",
822 "level": 2,
823 "metadata": {},
824 "source": [
825 "return the object"
826 ]
827 },
828 {
829 "cell_type": "code",
830 "collapsed": false,
831 "input": [
832 "# for demonstration purpose, I do the same with a circle that has no _repr_javascript method\n",
833 "class MyNoJSCircle(MyCircle):\n",
834 " \n",
835 " def _repr_javascript_(self):\n",
836 " return\n",
837 "\n",
838 "cNoJS = MyNoJSCircle()"
839 ],
840 "language": "python",
841 "metadata": {},
842 "outputs": []
843 },
844 {
845 "cell_type": "markdown",
846 "metadata": {},
847 "source": [
848 "Of course you can now still return the object, and this will use compute all the representations, store them in the notebook and show you the appropriate one."
849 ]
850 },
851 {
852 "cell_type": "code",
853 "collapsed": false,
854 "input": [
855 "cNoJS"
856 ],
857 "language": "python",
858 "metadata": {},
859 "outputs": []
860 },
861 {
862 "cell_type": "markdown",
863 "metadata": {},
864 "source": [
865 "Or just use `display(object)` if you are in a middle of a loop"
866 ]
867 },
868 {
869 "cell_type": "code",
870 "collapsed": false,
871 "input": [
872 "for i in range(3):\n",
873 " display(cNoJS)"
874 ],
875 "language": "python",
876 "metadata": {},
877 "outputs": []
878 },
879 {
880 "cell_type": "markdown",
881 "metadata": {},
882 "source": [
883 "Advantage of using `display()` versus `display_*()` is that all representation will be stored in the notebook document and notebook file, they are then availlable for other frontends or post-processing tool like `nbconvert`."
884 ]
885 },
886 {
887 "cell_type": "markdown",
888 "metadata": {},
889 "source": [
890 "Let's compare `display()` vs `display_html()` for our circle in the Notebook Web-app and we'll see later the difference in nbconvert."
891 ]
892 },
893 {
894 "cell_type": "code",
895 "collapsed": false,
896 "input": [
897 "print \"I should see a nice html circle in web-app, but\"\n",
898 "print \"nothing if the format I'm viewing the notebook in\"\n",
899 "print \"does not support html\"\n",
900 "display_html(cNoJS)"
901 ],
902 "language": "python",
903 "metadata": {},
904 "outputs": []
905 },
906 {
907 "cell_type": "code",
908 "collapsed": false,
909 "input": [
910 "print \"Whatever the format I will see a representation\"\n",
911 "print \"of my circle\"\n",
912 "display(cNoJS)"
913 ],
914 "language": "python",
915 "metadata": {},
916 "outputs": []
917 },
918 {
919 "cell_type": "code",
920 "collapsed": false,
921 "input": [
922 "print \"Same if I return the object\"\n",
923 "cNoJS"
924 ],
925 "language": "python",
926 "metadata": {},
927 "outputs": []
928 },
929 {
930 "cell_type": "code",
931 "collapsed": false,
932 "input": [
933 "print \"But not if I print it\"\n",
934 "print cNoJS"
935 ],
936 "language": "python",
937 "metadata": {},
938 "outputs": []
939 }
940 ],
941 "metadata": {}
942 }
943 ]
944 } No newline at end of file
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: file renamed from examples/Notebook/Animations Using clear_output.ipynb to examples/IPython Kernel/Animations Using clear_output.ipynb
@@ -1,358 +1,406 b''
1 1 {
2 2 "metadata": {
3 "name": "",
4 "signature": "sha256:481e128e553ec13e039f3e3f5e567cc3caffe391b78b9821ee883fb8770ebc82"
3 "name": "BackgroundJobs"
5 4 },
6 5 "nbformat": 3,
7 6 "nbformat_minor": 0,
8 7 "worksheets": [
9 8 {
10 9 "cells": [
11 10 {
12 "cell_type": "heading",
13 "level": 1,
14 "metadata": {},
15 "source": [
16 "Background Jobs"
17 ]
18 },
19 {
20 11 "cell_type": "markdown",
21 12 "metadata": {},
22 13 "source": [
14 "# Simple interactive bacgkround jobs with IPython\n",
15 "\n",
23 16 "We start by loading the `backgroundjobs` library and defining a few trivial functions to illustrate things with."
24 17 ]
25 18 },
26 19 {
27 20 "cell_type": "code",
28 21 "collapsed": false,
29 22 "input": [
30 "from __future__ import print_function\n",
31 23 "from IPython.lib import backgroundjobs as bg\n",
32 24 "\n",
33 25 "import sys\n",
34 26 "import time\n",
35 27 "\n",
36 28 "def sleepfunc(interval=2, *a, **kw):\n",
37 29 " args = dict(interval=interval,\n",
38 30 " args=a,\n",
39 31 " kwargs=kw)\n",
40 32 " time.sleep(interval)\n",
41 33 " return args\n",
42 34 "\n",
43 35 "def diefunc(interval=2, *a, **kw):\n",
44 36 " time.sleep(interval)\n",
45 37 " raise Exception(\"Dead job with interval %s\" % interval)\n",
46 38 "\n",
47 39 "def printfunc(interval=1, reps=5):\n",
48 40 " for n in range(reps):\n",
49 41 " time.sleep(interval)\n",
50 " print('In the background...', n)\n",
42 " print 'In the background...', n\n",
51 43 " sys.stdout.flush()\n",
52 " print('All done!')\n",
44 " print 'All done!'\n",
53 45 " sys.stdout.flush()"
54 46 ],
55 47 "language": "python",
56 48 "metadata": {},
57 49 "outputs": [],
58 50 "prompt_number": 1
59 51 },
60 52 {
61 53 "cell_type": "markdown",
62 54 "metadata": {},
63 55 "source": [
64 56 "Now, we can create a job manager (called simply `jobs`) and use it to submit new jobs.\n",
65 "<br>\n",
66 "Run the cell below and wait a few seconds for the whole thing to finish, until you see the \"All done!\" printout."
57 "\n",
58 "Run the cell below, it will show when the jobs start. Wait a few seconds until you see the 'all done' completion message:"
67 59 ]
68 60 },
69 61 {
70 62 "cell_type": "code",
71 63 "collapsed": false,
72 64 "input": [
73 65 "jobs = bg.BackgroundJobManager()\n",
74 66 "\n",
75 67 "# Start a few jobs, the first one will have ID # 0\n",
76 68 "jobs.new(sleepfunc, 4)\n",
77 69 "jobs.new(sleepfunc, kw={'reps':2})\n",
78 "jobs.new('printfunc(1,3)')\n",
79 "\n",
80 "# This makes a couple of jobs which will die. Let's keep a reference to\n",
81 "# them for easier traceback reporting later\n",
82 "diejob1 = jobs.new(diefunc, 1)\n",
83 "diejob2 = jobs.new(diefunc, 2)"
70 "jobs.new('printfunc(1,3)')"
84 71 ],
85 72 "language": "python",
86 73 "metadata": {},
87 74 "outputs": [
88 75 {
89 76 "output_type": "stream",
90 77 "stream": "stdout",
91 78 "text": [
92 79 "Starting job # 0 in a separate thread.\n",
93 80 "Starting job # 2 in a separate thread.\n",
94 "Starting job # 3 in a separate thread.\n",
95 "Starting job # 4 in a separate thread.\n",
96 "Starting job # 5 in a separate thread.\n"
81 "Starting job # 3 in a separate thread.\n"
82 ]
83 },
84 {
85 "output_type": "pyout",
86 "prompt_number": 10,
87 "text": [
88 "<BackgroundJob #3: printfunc(1,3)>"
89 ]
90 },
91 {
92 "output_type": "stream",
93 "stream": "stdout",
94 "text": [
95 "In the background... 0\n"
96 ]
97 },
98 {
99 "output_type": "stream",
100 "stream": "stdout",
101 "text": [
102 "In the background... 1\n"
103 ]
104 },
105 {
106 "output_type": "stream",
107 "stream": "stdout",
108 "text": [
109 "In the background... 2\n"
110 ]
111 },
112 {
113 "output_type": "stream",
114 "stream": "stdout",
115 "text": [
116 "All done!\n"
97 117 ]
98 118 }
99 119 ],
100 "prompt_number": 2
120 "prompt_number": 10
101 121 },
102 122 {
103 123 "cell_type": "markdown",
104 124 "metadata": {},
105 125 "source": [
106 126 "You can check the status of your jobs at any time:"
107 127 ]
108 128 },
109 129 {
110 130 "cell_type": "code",
111 131 "collapsed": false,
112 132 "input": [
113 133 "jobs.status()"
114 134 ],
115 135 "language": "python",
116 136 "metadata": {},
117 137 "outputs": [
118 138 {
119 139 "output_type": "stream",
120 140 "stream": "stdout",
121 141 "text": [
122 "In the background... 0\n",
123 "Running jobs:"
142 "Completed jobs:\n",
143 "0 : <function sleepfunc at 0x314f848>\n",
144 "2 : <function sleepfunc at 0x314f848>\n",
145 "3 : printfunc(1,3)\n",
146 "\n"
124 147 ]
148 }
149 ],
150 "prompt_number": 11
125 151 },
126 152 {
127 "output_type": "stream",
128 "stream": "stdout",
153 "cell_type": "markdown",
154 "metadata": {},
155 "source": [
156 "For any completed job, you can get its result easily:"
157 ]
158 },
159 {
160 "cell_type": "code",
161 "collapsed": false,
162 "input": [
163 "jobs[0].result"
164 ],
165 "language": "python",
166 "metadata": {},
167 "outputs": [
168 {
169 "output_type": "pyout",
170 "prompt_number": 12,
129 171 "text": [
130 "\n",
131 "0 : <function sleepfunc at 0x102cc6848>\n",
132 "2 : <function sleepfunc at 0x102cc6848>\n",
133 "3 : printfunc(1,3)\n",
134 "5 : <function diefunc at 0x102cc68c0>\n",
135 "\n",
136 "Dead jobs:\n",
137 "4 : <function diefunc at 0x102cc68c0>\n",
138 "\n"
172 "{'args': (), 'interval': 4, 'kwargs': {}}"
139 173 ]
140 174 }
141 175 ],
142 "prompt_number": 3
176 "prompt_number": 12
177 },
178 {
179 "cell_type": "heading",
180 "level": 2,
181 "metadata": {},
182 "source": [
183 "Errors and tracebacks"
184 ]
143 185 },
144 186 {
145 187 "cell_type": "markdown",
146 188 "metadata": {},
147 189 "source": [
148 "For any completed job, you can get its result easily:"
190 "The jobs manager tries to help you with debugging:"
149 191 ]
150 192 },
151 193 {
152 194 "cell_type": "code",
153 195 "collapsed": false,
154 196 "input": [
155 "jobs[0].result\n",
156 "j0 = jobs[0]\n",
157 "j0.join?"
197 "# This makes a couple of jobs which will die. Let's keep a reference to\n",
198 "# them for easier traceback reporting later\n",
199 "diejob1 = jobs.new(diefunc, 1)\n",
200 "diejob2 = jobs.new(diefunc, 2)"
158 201 ],
159 202 "language": "python",
160 203 "metadata": {},
161 "outputs": [],
162 "prompt_number": 4
204 "outputs": [
205 {
206 "output_type": "stream",
207 "stream": "stdout",
208 "text": [
209 "Starting job # 4 in a separate thread.\n",
210 "Starting job # 5 in a separate thread.\n"
211 ]
212 }
213 ],
214 "prompt_number": 13
163 215 },
164 216 {
165 217 "cell_type": "markdown",
166 218 "metadata": {},
167 219 "source": [
168 220 "You can get the traceback of any dead job. Run the line\n",
169 221 "below again interactively until it prints a traceback (check the status\n",
170 222 "of the job):\n"
171 223 ]
172 224 },
173 225 {
174 226 "cell_type": "code",
175 227 "collapsed": false,
176 228 "input": [
177 229 "print \"Status of diejob1:\", diejob1.status\n",
178 230 "diejob1.traceback() # jobs.traceback(4) would also work here, with the job number"
179 231 ],
180 232 "language": "python",
181 233 "metadata": {},
182 234 "outputs": [
183 235 {
184 236 "output_type": "stream",
185 237 "stream": "stdout",
186 238 "text": [
187 "In the background... 1\n",
188 "In the background... 2\n",
189 "All done!\n"
190 ]
191 },
192 {
193 "ename": "SyntaxError",
194 "evalue": "invalid syntax (<ipython-input-5-a90bd59af669>, line 1)",
195 "output_type": "pyerr",
196 "traceback": [
197 "\u001b[0;36m File \u001b[0;32m\"<ipython-input-5-a90bd59af669>\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m print \"Status of diejob1:\", diejob1.status\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
239 "Status of diejob1: Dead (Exception), call jobs.traceback() for details\n",
240 "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n",
241 "\u001b[1;31mException\u001b[0m Traceback (most recent call last)\n",
242 "\u001b[1;32m/home/fperez/usr/opt/virtualenv/ipython-0.13.2/lib/python2.7/site-packages/IPython/lib/backgroundjobs.pyc\u001b[0m in \u001b[0;36mcall\u001b[1;34m(self)\u001b[0m\n",
243 "\u001b[0;32m 482\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
244 "\u001b[0;32m 483\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mcall\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
245 "\u001b[1;32m--> 484\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfunc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
246 "\u001b[0m\n",
247 "\u001b[1;32m<ipython-input-1-fbbbd0d2a1c3>\u001b[0m in \u001b[0;36mdiefunc\u001b[1;34m(interval, *a, **kw)\u001b[0m\n",
248 "\u001b[0;32m 13\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mdiefunc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0minterval\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m*\u001b[0m\u001b[0ma\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkw\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
249 "\u001b[0;32m 14\u001b[0m \u001b[0mtime\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msleep\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0minterval\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
250 "\u001b[1;32m---> 15\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mException\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Dead job with interval %s\"\u001b[0m \u001b[1;33m%\u001b[0m \u001b[0minterval\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
251 "\u001b[0m\u001b[0;32m 16\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
252 "\u001b[0;32m 17\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mprintfunc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0minterval\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mreps\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m5\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
253 "\n",
254 "\u001b[1;31mException\u001b[0m: Dead job with interval 1\n"
198 255 ]
199 256 }
200 257 ],
201 "prompt_number": 5
258 "prompt_number": 14
202 259 },
203 260 {
204 261 "cell_type": "markdown",
205 262 "metadata": {},
206 263 "source": [
207 264 "This will print all tracebacks for all dead jobs:"
208 265 ]
209 266 },
210 267 {
211 268 "cell_type": "code",
212 269 "collapsed": false,
213 270 "input": [
214 271 "jobs.traceback()"
215 272 ],
216 273 "language": "python",
217 274 "metadata": {},
218 275 "outputs": [
219 276 {
220 277 "output_type": "stream",
221 278 "stream": "stdout",
222 279 "text": [
223 "Traceback for: <BackgroundJob #4: <function diefunc at 0x102cc68c0>>\n",
224 "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n",
225 "\u001b[0;31mException\u001b[0m Traceback (most recent call last)\n",
226 "\u001b[0;32m/Users/bgranger/Documents/Computing/IPython/code/ipython/IPython/lib/backgroundjobs.pyc\u001b[0m in \u001b[0;36mcall\u001b[0;34m(self)\u001b[0m\n",
227 "\u001b[1;32m 489\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
228 "\u001b[1;32m 490\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mcall\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
229 "\u001b[0;32m--> 491\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
280 "Traceback for: <BackgroundJob #4: <function diefunc at 0x314f668>>\n",
281 "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n",
282 "\u001b[1;31mException\u001b[0m Traceback (most recent call last)\n",
283 "\u001b[1;32m/home/fperez/usr/opt/virtualenv/ipython-0.13.2/lib/python2.7/site-packages/IPython/lib/backgroundjobs.pyc\u001b[0m in \u001b[0;36mcall\u001b[1;34m(self)\u001b[0m\n",
284 "\u001b[0;32m 482\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
285 "\u001b[0;32m 483\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mcall\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
286 "\u001b[1;32m--> 484\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfunc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
230 287 "\u001b[0m\n",
231 "\u001b[0;32m<ipython-input-1-7391f8ae281b>\u001b[0m in \u001b[0;36mdiefunc\u001b[0;34m(interval, *a, **kw)\u001b[0m\n",
232 "\u001b[1;32m 14\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mdiefunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minterval\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkw\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
233 "\u001b[1;32m 15\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msleep\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minterval\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
234 "\u001b[0;32m---> 16\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mException\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Dead job with interval %s\"\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0minterval\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
235 "\u001b[0m\u001b[1;32m 17\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
236 "\u001b[1;32m 18\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mprintfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minterval\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mreps\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
288 "\u001b[1;32m<ipython-input-1-fbbbd0d2a1c3>\u001b[0m in \u001b[0;36mdiefunc\u001b[1;34m(interval, *a, **kw)\u001b[0m\n",
289 "\u001b[0;32m 13\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mdiefunc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0minterval\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m*\u001b[0m\u001b[0ma\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkw\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
290 "\u001b[0;32m 14\u001b[0m \u001b[0mtime\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msleep\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0minterval\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
291 "\u001b[1;32m---> 15\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mException\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Dead job with interval %s\"\u001b[0m \u001b[1;33m%\u001b[0m \u001b[0minterval\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
292 "\u001b[0m\u001b[0;32m 16\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
293 "\u001b[0;32m 17\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mprintfunc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0minterval\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mreps\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m5\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
237 294 "\n",
238 "\u001b[0;31mException\u001b[0m: Dead job with interval 1\n",
295 "\u001b[1;31mException\u001b[0m: Dead job with interval 1\n",
239 296 "\n",
240 "Traceback for: <BackgroundJob #5: <function diefunc at 0x102cc68c0>>\n",
241 "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n",
242 "\u001b[0;31mException\u001b[0m Traceback (most recent call last)\n",
243 "\u001b[0;32m/Users/bgranger/Documents/Computing/IPython/code/ipython/IPython/lib/backgroundjobs.pyc\u001b[0m in \u001b[0;36mcall\u001b[0;34m(self)\u001b[0m\n",
244 "\u001b[1;32m 489\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
245 "\u001b[1;32m 490\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mcall\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
246 "\u001b[0;32m--> 491\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
297 "Traceback for: <BackgroundJob #5: <function diefunc at 0x314f668>>\n",
298 "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n",
299 "\u001b[1;31mException\u001b[0m Traceback (most recent call last)\n",
300 "\u001b[1;32m/home/fperez/usr/opt/virtualenv/ipython-0.13.2/lib/python2.7/site-packages/IPython/lib/backgroundjobs.pyc\u001b[0m in \u001b[0;36mcall\u001b[1;34m(self)\u001b[0m\n",
301 "\u001b[0;32m 482\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
302 "\u001b[0;32m 483\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mcall\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
303 "\u001b[1;32m--> 484\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfunc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
247 304 "\u001b[0m\n",
248 "\u001b[0;32m<ipython-input-1-7391f8ae281b>\u001b[0m in \u001b[0;36mdiefunc\u001b[0;34m(interval, *a, **kw)\u001b[0m\n",
249 "\u001b[1;32m 14\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mdiefunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minterval\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkw\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
250 "\u001b[1;32m 15\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msleep\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minterval\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
251 "\u001b[0;32m---> 16\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mException\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Dead job with interval %s\"\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0minterval\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
252 "\u001b[0m\u001b[1;32m 17\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
253 "\u001b[1;32m 18\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mprintfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minterval\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mreps\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
305 "\u001b[1;32m<ipython-input-1-fbbbd0d2a1c3>\u001b[0m in \u001b[0;36mdiefunc\u001b[1;34m(interval, *a, **kw)\u001b[0m\n",
306 "\u001b[0;32m 13\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mdiefunc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0minterval\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m*\u001b[0m\u001b[0ma\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkw\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
307 "\u001b[0;32m 14\u001b[0m \u001b[0mtime\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msleep\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0minterval\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
308 "\u001b[1;32m---> 15\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mException\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Dead job with interval %s\"\u001b[0m \u001b[1;33m%\u001b[0m \u001b[0minterval\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
309 "\u001b[0m\u001b[0;32m 16\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
310 "\u001b[0;32m 17\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mprintfunc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0minterval\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mreps\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m5\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
254 311 "\n",
255 "\u001b[0;31mException\u001b[0m: Dead job with interval 2\n",
312 "\u001b[1;31mException\u001b[0m: Dead job with interval 2\n",
256 313 "\n"
257 314 ]
258 315 }
259 316 ],
260 "prompt_number": 6
317 "prompt_number": 15
261 318 },
262 319 {
263 320 "cell_type": "markdown",
264 321 "metadata": {},
265 322 "source": [
266 323 "The job manager can be flushed of all completed jobs at any time:"
267 324 ]
268 325 },
269 326 {
270 327 "cell_type": "code",
271 328 "collapsed": false,
272 329 "input": [
273 330 "jobs.flush()"
274 331 ],
275 332 "language": "python",
276 333 "metadata": {},
277 334 "outputs": [
278 335 {
279 336 "output_type": "stream",
280 337 "stream": "stdout",
281 338 "text": [
282 339 "Flushing 3 Completed jobs.\n",
283 340 "Flushing 2 Dead jobs.\n"
284 341 ]
285 342 }
286 343 ],
287 "prompt_number": 7
344 "prompt_number": 16
288 345 },
289 346 {
290 347 "cell_type": "markdown",
291 348 "metadata": {},
292 349 "source": [
293 350 "After that, the status is simply empty:"
294 351 ]
295 352 },
296 353 {
297 354 "cell_type": "code",
298 355 "collapsed": true,
299 356 "input": [
300 357 "jobs.status()"
301 358 ],
302 359 "language": "python",
303 360 "metadata": {},
304 361 "outputs": [],
305 "prompt_number": 8
362 "prompt_number": 17
306 363 },
307 364 {
308 365 "cell_type": "markdown",
309 366 "metadata": {},
310 367 "source": [
311 "It's easy to wait on a job:"
368 "Jobs have a `.join` method that lets you wait on their thread for completion:"
312 369 ]
313 370 },
314 371 {
315 372 "cell_type": "code",
316 373 "collapsed": false,
317 374 "input": [
318 375 "j = jobs.new(sleepfunc, 2)\n",
319 "print(\"Will wait for j now...\")\n",
320 "sys.stdout.flush()\n",
321 "j.join()\n",
322 "print(\"Result from j:\")\n",
323 "j.result"
376 "j.join?"
324 377 ],
325 378 "language": "python",
326 379 "metadata": {},
327 380 "outputs": [
328 381 {
329 382 "output_type": "stream",
330 383 "stream": "stdout",
331 384 "text": [
332 "Starting job # 0 in a separate thread.\n",
333 "Will wait for j now...\n"
334 ]
335 },
336 {
337 "output_type": "stream",
338 "stream": "stdout",
339 "text": [
340 "Result from j:\n"
385 "Starting job # 0 in a separate thread.\n"
341 386 ]
387 }
388 ],
389 "prompt_number": 18
342 390 },
343 391 {
392 "cell_type": "markdown",
344 393 "metadata": {},
345 "output_type": "pyout",
346 "prompt_number": 9,
347 "text": [
348 "{'args': (), 'interval': 2, 'kwargs': {}}"
394 "source": [
395 "## Exercise\n",
396 "\n",
397 "1. Start a new job that calls `sleepfunc` with a 5-second wait\n",
398 "2. Print a short message that indicates you are waiting (note: you'll need to flush stdout to see that print output appear).\n",
399 "3. Wait on the job and then print its result."
349 400 ]
350 401 }
351 402 ],
352 "prompt_number": 9
353 }
354 ],
355 403 "metadata": {}
356 404 }
357 405 ]
358 406 } No newline at end of file
@@ -1,165 +1,172 b''
1 1 {
2 2 "metadata": {
3 3 "name": "",
4 "signature": "sha256:b0cbc510e3a2cd2333bc169f96a4e2e29d892cef880222c00f53b067f2d4f257"
4 "signature": "sha256:ee769d05a7e195e4b8546ef9a866ef03e59bff2f0fcba499d168c06b516aa79a"
5 5 },
6 6 "nbformat": 3,
7 7 "nbformat_minor": 0,
8 8 "worksheets": [
9 9 {
10 10 "cells": [
11 11 {
12 12 "cell_type": "markdown",
13 13 "metadata": {},
14 14 "source": [
15 15 "<img src=\"../images/ipython_logo.png\">"
16 16 ]
17 17 },
18 18 {
19 19 "cell_type": "markdown",
20 20 "metadata": {},
21 21 "source": [
22 22 "Back to the main [Index](../Index.ipynb)"
23 23 ]
24 24 },
25 25 {
26 26 "cell_type": "heading",
27 27 "level": 1,
28 28 "metadata": {},
29 29 "source": [
30 30 "IPython Kernel"
31 31 ]
32 32 },
33 33 {
34 34 "cell_type": "markdown",
35 35 "metadata": {},
36 36 "source": [
37 37 "IPython provides extensions to the Python programming language that make working interactively convenient and efficient. These extensions are implemented in the IPython Kernel and are available in all of the IPython Frontends (Notebook, Terminal, Console and Qt Console) when running this kernel."
38 38 ]
39 39 },
40 40 {
41 41 "cell_type": "heading",
42 42 "level": 2,
43 43 "metadata": {},
44 44 "source": [
45 45 "Tutorials"
46 46 ]
47 47 },
48 48 {
49 49 "cell_type": "markdown",
50 50 "metadata": {},
51 51 "source": [
52 52 "* [Cell Magics](Cell Magics.ipynb)\n",
53 "* [Script Magics](Script Magics.ipynb)"
53 "* [Script Magics](Script Magics.ipynb)\n",
54 "* [Rich Output](Rich Output.ipynb)\n",
55 "* [Custom Display Logic](Custom Display Logic.ipynb)\n",
56 "* [Plotting in the Notebook](Plotting in the Notebook.ipynb)\n",
57 "* [Capturing Output](Capturing Output.ipynb)"
54 58 ]
55 59 },
56 60 {
57 61 "cell_type": "heading",
58 62 "level": 2,
59 63 "metadata": {},
60 64 "source": [
61 65 "Examples"
62 66 ]
63 67 },
64 68 {
65 69 "cell_type": "markdown",
66 70 "metadata": {},
67 71 "source": [
68 "* [Background Jobs](Background Jobs.ipynb)"
72 "* [Background Jobs](Background Jobs.ipynb)\n",
73 "* [Trapezoid Rule](Trapezoid Rule.ipynb)\n",
74 "* [SymPy](SymPy.ipynb)\n",
75 "* [Raw Input in the Notebook](Raw Input in the Notebook.ipynb)"
69 76 ]
70 77 },
71 78 {
72 79 "cell_type": "heading",
73 80 "level": 2,
74 81 "metadata": {},
75 82 "source": [
76 83 "Non-notebook examples"
77 84 ]
78 85 },
79 86 {
80 87 "cell_type": "markdown",
81 88 "metadata": {},
82 89 "source": [
83 90 "This directory also contains examples that are regular Python (`.py`) files."
84 91 ]
85 92 },
86 93 {
87 94 "cell_type": "code",
88 95 "collapsed": false,
89 96 "input": [
90 97 "%run ../utils/list_pyfiles.ipy"
91 98 ],
92 99 "language": "python",
93 100 "metadata": {},
94 101 "outputs": [
95 102 {
96 103 "html": [
97 104 "<a href='example-demo.py' target='_blank'>example-demo.py</a><br>"
98 105 ],
99 106 "metadata": {},
100 107 "output_type": "display_data",
101 108 "text": [
102 109 "/Users/bgranger/Documents/Computing/IPython/code/ipython/examples/IPython Kernel/example-demo.py"
103 110 ]
104 111 },
105 112 {
106 113 "html": [
107 114 "<a href='ipython-get-history.py' target='_blank'>ipython-get-history.py</a><br>"
108 115 ],
109 116 "metadata": {},
110 117 "output_type": "display_data",
111 118 "text": [
112 119 "/Users/bgranger/Documents/Computing/IPython/code/ipython/examples/IPython Kernel/ipython-get-history.py"
113 120 ]
114 121 }
115 122 ],
116 123 "prompt_number": 1
117 124 },
118 125 {
119 126 "cell_type": "markdown",
120 127 "metadata": {},
121 128 "source": [
122 129 "There are also a set of examples that show how to integrate IPython with different GUI event loops:"
123 130 ]
124 131 },
125 132 {
126 133 "cell_type": "code",
127 134 "collapsed": false,
128 135 "input": [
129 136 "%run ../utils/list_subdirs.ipy"
130 137 ],
131 138 "language": "python",
132 139 "metadata": {},
133 140 "outputs": [
134 141 {
135 142 "html": [
136 143 "gui/<br>\n",
137 144 "&nbsp;&nbsp;<a href='gui/gui-glut.py' target='_blank'>gui-glut.py</a><br>\n",
138 145 "&nbsp;&nbsp;<a href='gui/gui-gtk.py' target='_blank'>gui-gtk.py</a><br>\n",
139 146 "&nbsp;&nbsp;<a href='gui/gui-gtk3.py' target='_blank'>gui-gtk3.py</a><br>\n",
140 147 "&nbsp;&nbsp;<a href='gui/gui-pyglet.py' target='_blank'>gui-pyglet.py</a><br>\n",
141 148 "&nbsp;&nbsp;<a href='gui/gui-qt.py' target='_blank'>gui-qt.py</a><br>\n",
142 149 "&nbsp;&nbsp;<a href='gui/gui-tk.py' target='_blank'>gui-tk.py</a><br>\n",
143 150 "&nbsp;&nbsp;<a href='gui/gui-wx.py' target='_blank'>gui-wx.py</a><br>"
144 151 ],
145 152 "metadata": {},
146 153 "output_type": "display_data",
147 154 "text": [
148 155 "gui/\n",
149 156 " gui-glut.py\n",
150 157 " gui-gtk.py\n",
151 158 " gui-gtk3.py\n",
152 159 " gui-pyglet.py\n",
153 160 " gui-qt.py\n",
154 161 " gui-tk.py\n",
155 162 " gui-wx.py"
156 163 ]
157 164 }
158 165 ],
159 166 "prompt_number": 2
160 167 }
161 168 ],
162 169 "metadata": {}
163 170 }
164 171 ]
165 172 } No newline at end of file
1 NO CONTENT: file renamed from examples/Notebook/Plotting with Matplotlib.ipynb to examples/IPython Kernel/Plotting in the Notebook.ipynb
1 NO CONTENT: file renamed from examples/Notebook/Raw Input.ipynb to examples/IPython Kernel/Raw Input in the Notebook.ipynb
1 NO CONTENT: file renamed from examples/Notebook/Display System.ipynb to examples/IPython Kernel/Rich Output.ipynb
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from examples/Notebook/SymPy.ipynb to examples/IPython Kernel/SymPy.ipynb
1 NO CONTENT: file renamed from examples/Interactive Widgets/Widget Styles.ipynb to examples/IPython Kernel/Terminal Usage.ipynb
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from examples/Notebook/Trapezoid Rule.ipynb to examples/IPython Kernel/Trapezoid Rule.ipynb
1 NO CONTENT: file renamed from examples/Interactive Widgets/Custom Widgets.ipynb to examples/Interactive Widgets/Date Picker Widget.ipynb
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from examples/Notebook/User Interface.ipynb to examples/Notebook/Running the Notebook Server.ipynb
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from examples/Notebook/Typesetting Math Using MathJax.ipynb to examples/Notebook/Typesetting Equations.ipynb
1 NO CONTENT: file renamed from examples/Notebook/Markdown Cells.ipynb to examples/Notebook/Working With Markdown Cells.ipynb
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from examples/Notebook/images/animation.m4v to examples/images/animation.m4v
1 NO CONTENT: file renamed from examples/Notebook/images/python_logo.svg to examples/images/python_logo.svg
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 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