##// END OF EJS Templates
Merge pull request #7244 from minrk/rm-signature...
Min RK -
r19680:d4983156 merge
parent child Browse files
Show More

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

@@ -1,434 +1,436
1 1 # coding: utf-8
2 2 """Tests for the notebook manager."""
3 3 from __future__ import print_function
4 4
5 5 import os
6 import time
6 7
7 8 from tornado.web import HTTPError
8 9 from unittest import TestCase
9 10 from tempfile import NamedTemporaryFile
10 11
11 12 from IPython.nbformat import v4 as nbformat
12 13
13 14 from IPython.utils.tempdir import TemporaryDirectory
14 15 from IPython.utils.traitlets import TraitError
15 16 from IPython.html.utils import url_path_join
16 17 from IPython.testing import decorators as dec
17 18
18 19 from ..filemanager import FileContentsManager
19 20
20 21
21 22 def _make_dir(contents_manager, api_path):
22 23 """
23 24 Make a directory.
24 25 """
25 26 os_path = contents_manager._get_os_path(api_path)
26 27 try:
27 28 os.makedirs(os_path)
28 29 except OSError:
29 30 print("Directory already exists: %r" % os_path)
30 31
31 32
32 33 class TestFileContentsManager(TestCase):
33 34
34 35 def symlink(self, contents_manager, src, dst):
35 36 """Make a symlink to src from dst
36 37
37 38 src and dst are api_paths
38 39 """
39 40 src_os_path = contents_manager._get_os_path(src)
40 41 dst_os_path = contents_manager._get_os_path(dst)
41 42 print(src_os_path, dst_os_path, os.path.isfile(src_os_path))
42 43 os.symlink(src_os_path, dst_os_path)
43 44
44 45 def test_root_dir(self):
45 46 with TemporaryDirectory() as td:
46 47 fm = FileContentsManager(root_dir=td)
47 48 self.assertEqual(fm.root_dir, td)
48 49
49 50 def test_missing_root_dir(self):
50 51 with TemporaryDirectory() as td:
51 52 root = os.path.join(td, 'notebook', 'dir', 'is', 'missing')
52 53 self.assertRaises(TraitError, FileContentsManager, root_dir=root)
53 54
54 55 def test_invalid_root_dir(self):
55 56 with NamedTemporaryFile() as tf:
56 57 self.assertRaises(TraitError, FileContentsManager, root_dir=tf.name)
57 58
58 59 def test_get_os_path(self):
59 60 # full filesystem path should be returned with correct operating system
60 61 # separators.
61 62 with TemporaryDirectory() as td:
62 63 root = td
63 64 fm = FileContentsManager(root_dir=root)
64 65 path = fm._get_os_path('/path/to/notebook/test.ipynb')
65 66 rel_path_list = '/path/to/notebook/test.ipynb'.split('/')
66 67 fs_path = os.path.join(fm.root_dir, *rel_path_list)
67 68 self.assertEqual(path, fs_path)
68 69
69 70 fm = FileContentsManager(root_dir=root)
70 71 path = fm._get_os_path('test.ipynb')
71 72 fs_path = os.path.join(fm.root_dir, 'test.ipynb')
72 73 self.assertEqual(path, fs_path)
73 74
74 75 fm = FileContentsManager(root_dir=root)
75 76 path = fm._get_os_path('////test.ipynb')
76 77 fs_path = os.path.join(fm.root_dir, 'test.ipynb')
77 78 self.assertEqual(path, fs_path)
78 79
79 80 def test_checkpoint_subdir(self):
80 81 subd = u'sub ∂ir'
81 82 cp_name = 'test-cp.ipynb'
82 83 with TemporaryDirectory() as td:
83 84 root = td
84 85 os.mkdir(os.path.join(td, subd))
85 86 fm = FileContentsManager(root_dir=root)
86 87 cp_dir = fm.get_checkpoint_path('cp', 'test.ipynb')
87 88 cp_subdir = fm.get_checkpoint_path('cp', '/%s/test.ipynb' % subd)
88 89 self.assertNotEqual(cp_dir, cp_subdir)
89 90 self.assertEqual(cp_dir, os.path.join(root, fm.checkpoint_dir, cp_name))
90 91 self.assertEqual(cp_subdir, os.path.join(root, subd, fm.checkpoint_dir, cp_name))
91 92
92 93 @dec.skip_win32
93 94 def test_bad_symlink(self):
94 95 with TemporaryDirectory() as td:
95 96 cm = FileContentsManager(root_dir=td)
96 97 path = 'test bad symlink'
97 98 _make_dir(cm, path)
98 99
99 100 file_model = cm.new_untitled(path=path, ext='.txt')
100 101
101 102 # create a broken symlink
102 103 self.symlink(cm, "target", '%s/%s' % (path, 'bad symlink'))
103 104 model = cm.get(path)
104 105 self.assertEqual(model['content'], [file_model])
105 106
106 107 @dec.skip_win32
107 108 def test_good_symlink(self):
108 109 with TemporaryDirectory() as td:
109 110 cm = FileContentsManager(root_dir=td)
110 111 parent = 'test good symlink'
111 112 name = 'good symlink'
112 113 path = '{0}/{1}'.format(parent, name)
113 114 _make_dir(cm, parent)
114 115
115 116 file_model = cm.new(path=parent + '/zfoo.txt')
116 117
117 118 # create a good symlink
118 119 self.symlink(cm, file_model['path'], path)
119 120 symlink_model = cm.get(path, content=False)
120 121 dir_model = cm.get(parent)
121 122 self.assertEqual(
122 123 sorted(dir_model['content'], key=lambda x: x['name']),
123 124 [symlink_model, file_model],
124 125 )
125 126
126 127
127 128 class TestContentsManager(TestCase):
128 129
129 130 def setUp(self):
130 131 self._temp_dir = TemporaryDirectory()
131 132 self.td = self._temp_dir.name
132 133 self.contents_manager = FileContentsManager(
133 134 root_dir=self.td,
134 135 )
135 136
136 137 def tearDown(self):
137 138 self._temp_dir.cleanup()
138 139
139 140 def make_dir(self, api_path):
140 141 """make a subdirectory at api_path
141 142
142 143 override in subclasses if contents are not on the filesystem.
143 144 """
144 145 _make_dir(self.contents_manager, api_path)
145 146
146 147 def add_code_cell(self, nb):
147 148 output = nbformat.new_output("display_data", {'application/javascript': "alert('hi');"})
148 149 cell = nbformat.new_code_cell("print('hi')", outputs=[output])
149 150 nb.cells.append(cell)
150 151
151 152 def new_notebook(self):
152 153 cm = self.contents_manager
153 154 model = cm.new_untitled(type='notebook')
154 155 name = model['name']
155 156 path = model['path']
156 157
157 158 full_model = cm.get(path)
158 159 nb = full_model['content']
160 nb['metadata']['counter'] = int(1e6 * time.time())
159 161 self.add_code_cell(nb)
160 162
161 163 cm.save(full_model, path)
162 164 return nb, name, path
163 165
164 166 def test_new_untitled(self):
165 167 cm = self.contents_manager
166 168 # Test in root directory
167 169 model = cm.new_untitled(type='notebook')
168 170 assert isinstance(model, dict)
169 171 self.assertIn('name', model)
170 172 self.assertIn('path', model)
171 173 self.assertIn('type', model)
172 174 self.assertEqual(model['type'], 'notebook')
173 175 self.assertEqual(model['name'], 'Untitled.ipynb')
174 176 self.assertEqual(model['path'], 'Untitled.ipynb')
175 177
176 178 # Test in sub-directory
177 179 model = cm.new_untitled(type='directory')
178 180 assert isinstance(model, dict)
179 181 self.assertIn('name', model)
180 182 self.assertIn('path', model)
181 183 self.assertIn('type', model)
182 184 self.assertEqual(model['type'], 'directory')
183 185 self.assertEqual(model['name'], 'Untitled Folder')
184 186 self.assertEqual(model['path'], 'Untitled Folder')
185 187 sub_dir = model['path']
186 188
187 189 model = cm.new_untitled(path=sub_dir)
188 190 assert isinstance(model, dict)
189 191 self.assertIn('name', model)
190 192 self.assertIn('path', model)
191 193 self.assertIn('type', model)
192 194 self.assertEqual(model['type'], 'file')
193 195 self.assertEqual(model['name'], 'untitled')
194 196 self.assertEqual(model['path'], '%s/untitled' % sub_dir)
195 197
196 198 def test_get(self):
197 199 cm = self.contents_manager
198 200 # Create a notebook
199 201 model = cm.new_untitled(type='notebook')
200 202 name = model['name']
201 203 path = model['path']
202 204
203 205 # Check that we 'get' on the notebook we just created
204 206 model2 = cm.get(path)
205 207 assert isinstance(model2, dict)
206 208 self.assertIn('name', model2)
207 209 self.assertIn('path', model2)
208 210 self.assertEqual(model['name'], name)
209 211 self.assertEqual(model['path'], path)
210 212
211 213 nb_as_file = cm.get(path, content=True, type='file')
212 214 self.assertEqual(nb_as_file['path'], path)
213 215 self.assertEqual(nb_as_file['type'], 'file')
214 216 self.assertEqual(nb_as_file['format'], 'text')
215 217 self.assertNotIsInstance(nb_as_file['content'], dict)
216 218
217 219 nb_as_bin_file = cm.get(path, content=True, type='file', format='base64')
218 220 self.assertEqual(nb_as_bin_file['format'], 'base64')
219 221
220 222 # Test in sub-directory
221 223 sub_dir = '/foo/'
222 224 self.make_dir('foo')
223 225 model = cm.new_untitled(path=sub_dir, ext='.ipynb')
224 226 model2 = cm.get(sub_dir + name)
225 227 assert isinstance(model2, dict)
226 228 self.assertIn('name', model2)
227 229 self.assertIn('path', model2)
228 230 self.assertIn('content', model2)
229 231 self.assertEqual(model2['name'], 'Untitled.ipynb')
230 232 self.assertEqual(model2['path'], '{0}/{1}'.format(sub_dir.strip('/'), name))
231 233
232 234 # Test with a regular file.
233 235 file_model_path = cm.new_untitled(path=sub_dir, ext='.txt')['path']
234 236 file_model = cm.get(file_model_path)
235 237 self.assertDictContainsSubset(
236 238 {
237 239 'content': u'',
238 240 'format': u'text',
239 241 'mimetype': u'text/plain',
240 242 'name': u'untitled.txt',
241 243 'path': u'foo/untitled.txt',
242 244 'type': u'file',
243 245 'writable': True,
244 246 },
245 247 file_model,
246 248 )
247 249 self.assertIn('created', file_model)
248 250 self.assertIn('last_modified', file_model)
249 251
250 252 # Test getting directory model
251 253
252 254 # Create a sub-sub directory to test getting directory contents with a
253 255 # subdir.
254 256 self.make_dir('foo/bar')
255 257 dirmodel = cm.get('foo')
256 258 self.assertEqual(dirmodel['type'], 'directory')
257 259 self.assertIsInstance(dirmodel['content'], list)
258 260 self.assertEqual(len(dirmodel['content']), 3)
259 261 self.assertEqual(dirmodel['path'], 'foo')
260 262 self.assertEqual(dirmodel['name'], 'foo')
261 263
262 264 # Directory contents should match the contents of each individual entry
263 265 # when requested with content=False.
264 266 model2_no_content = cm.get(sub_dir + name, content=False)
265 267 file_model_no_content = cm.get(u'foo/untitled.txt', content=False)
266 268 sub_sub_dir_no_content = cm.get('foo/bar', content=False)
267 269 self.assertEqual(sub_sub_dir_no_content['path'], 'foo/bar')
268 270 self.assertEqual(sub_sub_dir_no_content['name'], 'bar')
269 271
270 272 for entry in dirmodel['content']:
271 273 # Order isn't guaranteed by the spec, so this is a hacky way of
272 274 # verifying that all entries are matched.
273 275 if entry['path'] == sub_sub_dir_no_content['path']:
274 276 self.assertEqual(entry, sub_sub_dir_no_content)
275 277 elif entry['path'] == model2_no_content['path']:
276 278 self.assertEqual(entry, model2_no_content)
277 279 elif entry['path'] == file_model_no_content['path']:
278 280 self.assertEqual(entry, file_model_no_content)
279 281 else:
280 282 self.fail("Unexpected directory entry: %s" % entry())
281 283
282 284 with self.assertRaises(HTTPError):
283 285 cm.get('foo', type='file')
284 286
285 287 def test_update(self):
286 288 cm = self.contents_manager
287 289 # Create a notebook
288 290 model = cm.new_untitled(type='notebook')
289 291 name = model['name']
290 292 path = model['path']
291 293
292 294 # Change the name in the model for rename
293 295 model['path'] = 'test.ipynb'
294 296 model = cm.update(model, path)
295 297 assert isinstance(model, dict)
296 298 self.assertIn('name', model)
297 299 self.assertIn('path', model)
298 300 self.assertEqual(model['name'], 'test.ipynb')
299 301
300 302 # Make sure the old name is gone
301 303 self.assertRaises(HTTPError, cm.get, path)
302 304
303 305 # Test in sub-directory
304 306 # Create a directory and notebook in that directory
305 307 sub_dir = '/foo/'
306 308 self.make_dir('foo')
307 309 model = cm.new_untitled(path=sub_dir, type='notebook')
308 310 path = model['path']
309 311
310 312 # Change the name in the model for rename
311 313 d = path.rsplit('/', 1)[0]
312 314 new_path = model['path'] = d + '/test_in_sub.ipynb'
313 315 model = cm.update(model, path)
314 316 assert isinstance(model, dict)
315 317 self.assertIn('name', model)
316 318 self.assertIn('path', model)
317 319 self.assertEqual(model['name'], 'test_in_sub.ipynb')
318 320 self.assertEqual(model['path'], new_path)
319 321
320 322 # Make sure the old name is gone
321 323 self.assertRaises(HTTPError, cm.get, path)
322 324
323 325 def test_save(self):
324 326 cm = self.contents_manager
325 327 # Create a notebook
326 328 model = cm.new_untitled(type='notebook')
327 329 name = model['name']
328 330 path = model['path']
329 331
330 332 # Get the model with 'content'
331 333 full_model = cm.get(path)
332 334
333 335 # Save the notebook
334 336 model = cm.save(full_model, path)
335 337 assert isinstance(model, dict)
336 338 self.assertIn('name', model)
337 339 self.assertIn('path', model)
338 340 self.assertEqual(model['name'], name)
339 341 self.assertEqual(model['path'], path)
340 342
341 343 # Test in sub-directory
342 344 # Create a directory and notebook in that directory
343 345 sub_dir = '/foo/'
344 346 self.make_dir('foo')
345 347 model = cm.new_untitled(path=sub_dir, type='notebook')
346 348 name = model['name']
347 349 path = model['path']
348 350 model = cm.get(path)
349 351
350 352 # Change the name in the model for rename
351 353 model = cm.save(model, path)
352 354 assert isinstance(model, dict)
353 355 self.assertIn('name', model)
354 356 self.assertIn('path', model)
355 357 self.assertEqual(model['name'], 'Untitled.ipynb')
356 358 self.assertEqual(model['path'], 'foo/Untitled.ipynb')
357 359
358 360 def test_delete(self):
359 361 cm = self.contents_manager
360 362 # Create a notebook
361 363 nb, name, path = self.new_notebook()
362 364
363 365 # Delete the notebook
364 366 cm.delete(path)
365 367
366 368 # Check that deleting a non-existent path raises an error.
367 369 self.assertRaises(HTTPError, cm.delete, path)
368 370
369 371 # Check that a 'get' on the deleted notebook raises and error
370 372 self.assertRaises(HTTPError, cm.get, path)
371 373
372 374 def test_copy(self):
373 375 cm = self.contents_manager
374 376 parent = u'å b'
375 377 name = u'nb √.ipynb'
376 378 path = u'{0}/{1}'.format(parent, name)
377 379 self.make_dir(parent)
378 380
379 381 orig = cm.new(path=path)
380 382 # copy with unspecified name
381 383 copy = cm.copy(path)
382 384 self.assertEqual(copy['name'], orig['name'].replace('.ipynb', '-Copy1.ipynb'))
383 385
384 386 # copy with specified name
385 387 copy2 = cm.copy(path, u'å b/copy 2.ipynb')
386 388 self.assertEqual(copy2['name'], u'copy 2.ipynb')
387 389 self.assertEqual(copy2['path'], u'å b/copy 2.ipynb')
388 390 # copy with specified path
389 391 copy2 = cm.copy(path, u'/')
390 392 self.assertEqual(copy2['name'], name)
391 393 self.assertEqual(copy2['path'], name)
392 394
393 395 def test_trust_notebook(self):
394 396 cm = self.contents_manager
395 397 nb, name, path = self.new_notebook()
396 398
397 399 untrusted = cm.get(path)['content']
398 400 assert not cm.notary.check_cells(untrusted)
399 401
400 402 # print(untrusted)
401 403 cm.trust_notebook(path)
402 404 trusted = cm.get(path)['content']
403 405 # print(trusted)
404 406 assert cm.notary.check_cells(trusted)
405 407
406 408 def test_mark_trusted_cells(self):
407 409 cm = self.contents_manager
408 410 nb, name, path = self.new_notebook()
409 411
410 412 cm.mark_trusted_cells(nb, path)
411 413 for cell in nb.cells:
412 414 if cell.cell_type == 'code':
413 415 assert not cell.metadata.trusted
414 416
415 417 cm.trust_notebook(path)
416 418 nb = cm.get(path)['content']
417 419 for cell in nb.cells:
418 420 if cell.cell_type == 'code':
419 421 assert cell.metadata.trusted
420 422
421 423 def test_check_and_sign(self):
422 424 cm = self.contents_manager
423 425 nb, name, path = self.new_notebook()
424 426
425 427 cm.mark_trusted_cells(nb, path)
426 428 cm.check_and_sign(nb, path)
427 429 assert not cm.notary.check_signature(nb)
428 430
429 431 cm.trust_notebook(path)
430 432 nb = cm.get(path)['content']
431 433 cm.mark_trusted_cells(nb, path)
432 434 cm.check_and_sign(nb, path)
433 435 assert cm.notary.check_signature(nb)
434 436
@@ -1,331 +1,427
1 """Functions for signing notebooks"""
1 """Utilities for signing notebooks"""
2 2
3 3 # Copyright (c) IPython Development Team.
4 4 # Distributed under the terms of the Modified BSD License.
5 5
6 6 import base64
7 7 from contextlib import contextmanager
8 from datetime import datetime
8 9 import hashlib
9 10 from hmac import HMAC
10 11 import io
11 12 import os
12 13
14 try:
15 import sqlite3
16 except ImportError:
17 try:
18 from pysqlite2 import dbapi2 as sqlite3
19 except ImportError:
20 sqlite3 = None
21
13 22 from IPython.utils.io import atomic_writing
14 from IPython.utils.py3compat import string_types, unicode_type, cast_bytes
15 from IPython.utils.traitlets import Instance, Bytes, Enum, Any, Unicode, Bool
23 from IPython.utils.py3compat import unicode_type, cast_bytes
24 from IPython.utils.traitlets import Instance, Bytes, Enum, Any, Unicode, Bool, Integer
16 25 from IPython.config import LoggingConfigurable, MultipleInstanceError
17 26 from IPython.core.application import BaseIPythonApplication, base_flags
18 27
19 28 from . import read, write, NO_CONVERT
20 29
21 30 try:
22 31 # Python 3
23 32 algorithms = hashlib.algorithms_guaranteed
24 33 except AttributeError:
25 34 algorithms = hashlib.algorithms
26 35
27 36
28 37 def yield_everything(obj):
29 38 """Yield every item in a container as bytes
30 39
31 40 Allows any JSONable object to be passed to an HMAC digester
32 41 without having to serialize the whole thing.
33 42 """
34 43 if isinstance(obj, dict):
35 44 for key in sorted(obj):
36 45 value = obj[key]
37 46 yield cast_bytes(key)
38 47 for b in yield_everything(value):
39 48 yield b
40 49 elif isinstance(obj, (list, tuple)):
41 50 for element in obj:
42 51 for b in yield_everything(element):
43 52 yield b
44 53 elif isinstance(obj, unicode_type):
45 54 yield obj.encode('utf8')
46 55 else:
47 56 yield unicode_type(obj).encode('utf8')
48 57
49 58 def yield_code_cells(nb):
50 59 """Iterator that yields all cells in a notebook
51 60
52 61 nbformat version independent
53 62 """
54 63 if nb.nbformat >= 4:
55 64 for cell in nb['cells']:
56 65 if cell['cell_type'] == 'code':
57 66 yield cell
58 67 elif nb.nbformat == 3:
59 68 for ws in nb['worksheets']:
60 69 for cell in ws['cells']:
61 70 if cell['cell_type'] == 'code':
62 71 yield cell
63 72
64 73 @contextmanager
65 74 def signature_removed(nb):
66 75 """Context manager for operating on a notebook with its signature removed
67 76
68 77 Used for excluding the previous signature when computing a notebook's signature.
69 78 """
70 79 save_signature = nb['metadata'].pop('signature', None)
71 80 try:
72 81 yield
73 82 finally:
74 83 if save_signature is not None:
75 84 nb['metadata']['signature'] = save_signature
76 85
77 86
78 87 class NotebookNotary(LoggingConfigurable):
79 88 """A class for computing and verifying notebook signatures."""
80 89
81 90 profile_dir = Instance("IPython.core.profiledir.ProfileDir")
82 91 def _profile_dir_default(self):
83 92 from IPython.core.application import BaseIPythonApplication
84 93 app = None
85 94 try:
86 95 if BaseIPythonApplication.initialized():
87 96 app = BaseIPythonApplication.instance()
88 97 except MultipleInstanceError:
89 98 pass
90 99 if app is None:
91 100 # create an app, without the global instance
92 101 app = BaseIPythonApplication()
93 102 app.initialize(argv=[])
94 103 return app.profile_dir
95 104
105 db_file = Unicode(config=True,
106 help="""The sqlite file in which to store notebook signatures.
107 By default, this will be in your IPython profile.
108 You can set it to ':memory:' to disable sqlite writing to the filesystem.
109 """)
110 def _db_file_default(self):
111 if self.profile_dir is None:
112 return ':memory:'
113 return os.path.join(self.profile_dir.security_dir, u'nbsignatures.db')
114
115 # 64k entries ~ 12MB
116 cache_size = Integer(65535, config=True,
117 help="""The number of notebook signatures to cache.
118 When the number of signatures exceeds this value,
119 the oldest 25% of signatures will be culled.
120 """
121 )
122 db = Any()
123 def _db_default(self):
124 if sqlite3 is None:
125 self.log.warn("Missing SQLite3, all notebooks will be untrusted!")
126 return
127 kwargs = dict(detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
128 db = sqlite3.connect(self.db_file, **kwargs)
129 self.init_db(db)
130 return db
131
132 def init_db(self, db):
133 db.execute("""
134 CREATE TABLE IF NOT EXISTS nbsignatures
135 (
136 id integer PRIMARY KEY AUTOINCREMENT,
137 algorithm text,
138 signature text,
139 path text,
140 last_seen timestamp
141 )""")
142 db.execute("""
143 CREATE INDEX IF NOT EXISTS algosig ON nbsignatures(algorithm, signature)
144 """)
145 db.commit()
146
96 147 algorithm = Enum(algorithms, default_value='sha256', config=True,
97 148 help="""The hashing algorithm used to sign notebooks."""
98 149 )
99 150 def _algorithm_changed(self, name, old, new):
100 151 self.digestmod = getattr(hashlib, self.algorithm)
101 152
102 153 digestmod = Any()
103 154 def _digestmod_default(self):
104 155 return getattr(hashlib, self.algorithm)
105 156
106 157 secret_file = Unicode(config=True,
107 158 help="""The file where the secret key is stored."""
108 159 )
109 160 def _secret_file_default(self):
110 161 if self.profile_dir is None:
111 162 return ''
112 163 return os.path.join(self.profile_dir.security_dir, 'notebook_secret')
113 164
114 165 secret = Bytes(config=True,
115 166 help="""The secret key with which notebooks are signed."""
116 167 )
117 168 def _secret_default(self):
118 169 # note : this assumes an Application is running
119 170 if os.path.exists(self.secret_file):
120 171 with io.open(self.secret_file, 'rb') as f:
121 172 return f.read()
122 173 else:
123 174 secret = base64.encodestring(os.urandom(1024))
124 175 self._write_secret_file(secret)
125 176 return secret
126 177
127 178 def _write_secret_file(self, secret):
128 179 """write my secret to my secret_file"""
129 180 self.log.info("Writing notebook-signing key to %s", self.secret_file)
130 181 with io.open(self.secret_file, 'wb') as f:
131 182 f.write(secret)
132 183 try:
133 184 os.chmod(self.secret_file, 0o600)
134 185 except OSError:
135 186 self.log.warn(
136 187 "Could not set permissions on %s",
137 188 self.secret_file
138 189 )
139 190 return secret
140 191
141 192 def compute_signature(self, nb):
142 193 """Compute a notebook's signature
143 194
144 195 by hashing the entire contents of the notebook via HMAC digest.
145 196 """
146 197 hmac = HMAC(self.secret, digestmod=self.digestmod)
147 198 # don't include the previous hash in the content to hash
148 199 with signature_removed(nb):
149 200 # sign the whole thing
150 201 for b in yield_everything(nb):
151 202 hmac.update(b)
152 203
153 204 return hmac.hexdigest()
154 205
155 206 def check_signature(self, nb):
156 207 """Check a notebook's stored signature
157 208
158 209 If a signature is stored in the notebook's metadata,
159 210 a new signature is computed and compared with the stored value.
160 211
161 212 Returns True if the signature is found and matches, False otherwise.
162 213
163 214 The following conditions must all be met for a notebook to be trusted:
164 215 - a signature is stored in the form 'scheme:hexdigest'
165 216 - the stored scheme matches the requested scheme
166 217 - the requested scheme is available from hashlib
167 218 - the computed hash from notebook_signature matches the stored hash
168 219 """
169 220 if nb.nbformat < 3:
170 221 return False
171 stored_signature = nb['metadata'].get('signature', None)
172 if not stored_signature \
173 or not isinstance(stored_signature, string_types) \
174 or ':' not in stored_signature:
222 if self.db is None:
175 223 return False
176 stored_algo, sig = stored_signature.split(':', 1)
177 if self.algorithm != stored_algo:
224 signature = self.compute_signature(nb)
225 r = self.db.execute("""SELECT id FROM nbsignatures WHERE
226 algorithm = ? AND
227 signature = ?;
228 """, (self.algorithm, signature)).fetchone()
229 if r is None:
178 230 return False
179 my_signature = self.compute_signature(nb)
180 return my_signature == sig
231 self.db.execute("""UPDATE nbsignatures SET last_seen = ? WHERE
232 algorithm = ? AND
233 signature = ?;
234 """,
235 (datetime.utcnow(), self.algorithm, signature),
236 )
237 self.db.commit()
238 return True
181 239
182 240 def sign(self, nb):
183 """Sign a notebook, indicating that its output is trusted
241 """Sign a notebook, indicating that its output is trusted on this machine
184 242
185 stores 'algo:hmac-hexdigest' in notebook.metadata.signature
186
187 e.g. 'sha256:deadbeef123...'
243 Stores hash algorithm and hmac digest in a local database of trusted notebooks.
188 244 """
189 245 if nb.nbformat < 3:
190 246 return
191 247 signature = self.compute_signature(nb)
192 nb['metadata']['signature'] = "%s:%s" % (self.algorithm, signature)
248 self.store_signature(signature, nb)
249
250 def store_signature(self, signature, nb):
251 if self.db is None:
252 return
253 self.db.execute("""INSERT OR IGNORE INTO nbsignatures
254 (algorithm, signature, last_seen) VALUES (?, ?, ?)""",
255 (self.algorithm, signature, datetime.utcnow())
256 )
257 self.db.execute("""UPDATE nbsignatures SET last_seen = ? WHERE
258 algorithm = ? AND
259 signature = ?;
260 """,
261 (datetime.utcnow(), self.algorithm, signature),
262 )
263 self.db.commit()
264 n, = self.db.execute("SELECT Count(*) FROM nbsignatures").fetchone()
265 if n > self.cache_size:
266 self.cull_db()
267
268 def unsign(self, nb):
269 """Ensure that a notebook is untrusted
270
271 by removing its signature from the trusted database, if present.
272 """
273 signature = self.compute_signature(nb)
274 self.db.execute("""DELETE FROM nbsignatures WHERE
275 algorithm = ? AND
276 signature = ?;
277 """,
278 (self.algorithm, signature)
279 )
280 self.db.commit()
281
282 def cull_db(self):
283 """Cull oldest 25% of the trusted signatures when the size limit is reached"""
284 self.db.execute("""DELETE FROM nbsignatures WHERE id IN (
285 SELECT id FROM nbsignatures ORDER BY last_seen DESC LIMIT -1 OFFSET ?
286 );
287 """, (max(int(0.75 * self.cache_size), 1),))
193 288
194 289 def mark_cells(self, nb, trusted):
195 290 """Mark cells as trusted if the notebook's signature can be verified
196 291
197 292 Sets ``cell.metadata.trusted = True | False`` on all code cells,
198 293 depending on whether the stored signature can be verified.
199 294
200 295 This function is the inverse of check_cells
201 296 """
202 297 if nb.nbformat < 3:
203 298 return
204 299
205 300 for cell in yield_code_cells(nb):
206 301 cell['metadata']['trusted'] = trusted
207 302
208 303 def _check_cell(self, cell, nbformat_version):
209 304 """Do we trust an individual cell?
210 305
211 306 Return True if:
212 307
213 308 - cell is explicitly trusted
214 309 - cell has no potentially unsafe rich output
215 310
216 311 If a cell has no output, or only simple print statements,
217 312 it will always be trusted.
218 313 """
219 314 # explicitly trusted
220 315 if cell['metadata'].pop("trusted", False):
221 316 return True
222 317
223 318 # explicitly safe output
224 319 if nbformat_version >= 4:
225 safe = {'text/plain', 'image/png', 'image/jpeg'}
226 320 unsafe_output_types = ['execute_result', 'display_data']
227 321 safe_keys = {"output_type", "execution_count", "metadata"}
228 322 else: # v3
229 safe = {'text', 'png', 'jpeg'}
230 323 unsafe_output_types = ['pyout', 'display_data']
231 324 safe_keys = {"output_type", "prompt_number", "metadata"}
232 325
233 326 for output in cell['outputs']:
234 327 output_type = output['output_type']
235 328 if output_type in unsafe_output_types:
236 329 # if there are any data keys not in the safe whitelist
237 330 output_keys = set(output)
238 331 if output_keys.difference(safe_keys):
239 332 return False
240 333
241 334 return True
242 335
243 336 def check_cells(self, nb):
244 337 """Return whether all code cells are trusted
245 338
246 339 If there are no code cells, return True.
247 340
248 341 This function is the inverse of mark_cells.
249 342 """
250 343 if nb.nbformat < 3:
251 344 return False
252 345 trusted = True
253 346 for cell in yield_code_cells(nb):
254 347 # only distrust a cell if it actually has some output to distrust
255 348 if not self._check_cell(cell, nb.nbformat):
256 349 trusted = False
257 350
258 351 return trusted
259 352
260 353
261 354 trust_flags = {
262 355 'reset' : (
263 356 {'TrustNotebookApp' : { 'reset' : True}},
264 """Generate a new key for notebook signature.
357 """Delete the trusted notebook cache.
265 358 All previously signed notebooks will become untrusted.
266 359 """
267 360 ),
268 361 }
269 362 trust_flags.update(base_flags)
270 363 trust_flags.pop('init')
271 364
272 365
273 366 class TrustNotebookApp(BaseIPythonApplication):
274 367
275 368 description="""Sign one or more IPython notebooks with your key,
276 369 to trust their dynamic (HTML, Javascript) output.
277 370
278 371 Trusting a notebook only applies to the current IPython profile.
279 372 To trust a notebook for use with a profile other than default,
280 373 add `--profile [profile name]`.
281 374
282 375 Otherwise, you will have to re-execute the notebook to see output.
283 376 """
284 377
285 378 examples = """
286 379 ipython trust mynotebook.ipynb and_this_one.ipynb
287 380 ipython trust --profile myprofile mynotebook.ipynb
288 381 """
289 382
290 383 flags = trust_flags
291 384
292 385 reset = Bool(False, config=True,
293 help="""If True, generate a new key for notebook signature.
386 help="""If True, delete the trusted signature cache.
294 387 After reset, all previously signed notebooks will become untrusted.
295 388 """
296 389 )
297 390
298 391 notary = Instance(NotebookNotary)
299 392 def _notary_default(self):
300 393 return NotebookNotary(parent=self, profile_dir=self.profile_dir)
301 394
302 395 def sign_notebook(self, notebook_path):
303 396 if not os.path.exists(notebook_path):
304 397 self.log.error("Notebook missing: %s" % notebook_path)
305 398 self.exit(1)
306 399 with io.open(notebook_path, encoding='utf8') as f:
307 400 nb = read(f, NO_CONVERT)
308 401 if self.notary.check_signature(nb):
309 402 print("Notebook already signed: %s" % notebook_path)
310 403 else:
311 404 print("Signing notebook: %s" % notebook_path)
312 405 self.notary.sign(nb)
313 406 with atomic_writing(notebook_path) as f:
314 407 write(nb, f, NO_CONVERT)
315 408
316 409 def generate_new_key(self):
317 410 """Generate a new notebook signature key"""
318 411 print("Generating new notebook key: %s" % self.notary.secret_file)
319 412 self.notary._write_secret_file(os.urandom(1024))
320 413
321 414 def start(self):
322 415 if self.reset:
416 if os.path.exists(self.notary.db_file):
417 print("Removing trusted signature cache: %s" % self.notary.db_file)
418 os.remove(self.notary.db_file)
323 419 self.generate_new_key()
324 420 return
325 421 if not self.extra_args:
326 422 self.log.critical("Specify at least one notebook to sign.")
327 423 self.exit(1)
328 424
329 425 for notebook_path in self.extra_args:
330 426 self.sign_notebook(notebook_path)
331 427
@@ -1,150 +1,191
1 1 """Test Notebook signing"""
2 2
3 3 # Copyright (c) IPython Development Team.
4 4 # Distributed under the terms of the Modified BSD License.
5 5
6 import copy
7 import time
8
6 9 from .base import TestsBase
7 10
8 11 from IPython.nbformat import read, sign
9 12 from IPython.core.getipython import get_ipython
10 13
11 14
12 15 class TestNotary(TestsBase):
13 16
14 17 def setUp(self):
15 18 self.notary = sign.NotebookNotary(
19 db_file=':memory:',
16 20 secret=b'secret',
17 profile_dir=get_ipython().profile_dir
21 profile_dir=get_ipython().profile_dir,
18 22 )
19 23 with self.fopen(u'test3.ipynb', u'r') as f:
20 24 self.nb = read(f, as_version=4)
21 25 with self.fopen(u'test3.ipynb', u'r') as f:
22 26 self.nb3 = read(f, as_version=3)
23 27
24 28 def test_algorithms(self):
25 29 last_sig = ''
26 30 for algo in sign.algorithms:
27 31 self.notary.algorithm = algo
28 self.notary.sign(self.nb)
29 sig = self.nb.metadata.signature
30 print(sig)
31 self.assertEqual(sig[:len(self.notary.algorithm)+1], '%s:' % self.notary.algorithm)
32 sig = self.notary.compute_signature(self.nb)
32 33 self.assertNotEqual(last_sig, sig)
33 34 last_sig = sig
34 35
35 36 def test_sign_same(self):
36 37 """Multiple signatures of the same notebook are the same"""
37 38 sig1 = self.notary.compute_signature(self.nb)
38 39 sig2 = self.notary.compute_signature(self.nb)
39 40 self.assertEqual(sig1, sig2)
40 41
41 42 def test_change_secret(self):
42 43 """Changing the secret changes the signature"""
43 44 sig1 = self.notary.compute_signature(self.nb)
44 45 self.notary.secret = b'different'
45 46 sig2 = self.notary.compute_signature(self.nb)
46 47 self.assertNotEqual(sig1, sig2)
47 48
48 49 def test_sign(self):
50 self.assertFalse(self.notary.check_signature(self.nb))
51 self.notary.sign(self.nb)
52 self.assertTrue(self.notary.check_signature(self.nb))
53
54 def test_unsign(self):
49 55 self.notary.sign(self.nb)
50 sig = self.nb.metadata.signature
51 self.assertEqual(sig[:len(self.notary.algorithm)+1], '%s:' % self.notary.algorithm)
56 self.assertTrue(self.notary.check_signature(self.nb))
57 self.notary.unsign(self.nb)
58 self.assertFalse(self.notary.check_signature(self.nb))
59 self.notary.unsign(self.nb)
60 self.assertFalse(self.notary.check_signature(self.nb))
61
62 def test_cull_db(self):
63 # this test has various sleeps of 2ms
64 # to ensure low resolution timestamps compare as expected
65 dt = 2e-3
66 nbs = [
67 copy.deepcopy(self.nb) for i in range(10)
68 ]
69 for row in self.notary.db.execute("SELECT * FROM nbsignatures"):
70 print(row)
71 self.notary.cache_size = 8
72 for i, nb in enumerate(nbs[:8]):
73 nb.metadata.dirty = i
74 self.notary.sign(nb)
75
76 for i, nb in enumerate(nbs[:8]):
77 time.sleep(dt)
78 self.assertTrue(self.notary.check_signature(nb), 'nb %i is trusted' % i)
79
80 # signing the 9th triggers culling of first 3
81 # (75% of 8 = 6, 9 - 6 = 3 culled)
82 self.notary.sign(nbs[8])
83 self.assertFalse(self.notary.check_signature(nbs[0]))
84 self.assertFalse(self.notary.check_signature(nbs[1]))
85 self.assertFalse(self.notary.check_signature(nbs[2]))
86 self.assertTrue(self.notary.check_signature(nbs[3]))
87 # checking nb3 should keep it from being culled:
88 self.notary.sign(nbs[0])
89 self.notary.sign(nbs[1])
90 self.notary.sign(nbs[2])
91 self.assertTrue(self.notary.check_signature(nbs[3]))
92 self.assertFalse(self.notary.check_signature(nbs[4]))
52 93
53 94 def test_check_signature(self):
54 95 nb = self.nb
55 96 md = nb.metadata
56 97 notary = self.notary
57 98 check_signature = notary.check_signature
58 99 # no signature:
59 100 md.pop('signature', None)
60 101 self.assertFalse(check_signature(nb))
61 102 # hash only, no algo
62 103 md.signature = notary.compute_signature(nb)
63 104 self.assertFalse(check_signature(nb))
64 105 # proper signature, algo mismatch
65 106 notary.algorithm = 'sha224'
66 107 notary.sign(nb)
67 108 notary.algorithm = 'sha256'
68 109 self.assertFalse(check_signature(nb))
69 110 # check correctly signed notebook
70 111 notary.sign(nb)
71 112 self.assertTrue(check_signature(nb))
72 113
73 114 def test_mark_cells_untrusted(self):
74 115 cells = self.nb.cells
75 116 self.notary.mark_cells(self.nb, False)
76 117 for cell in cells:
77 118 self.assertNotIn('trusted', cell)
78 119 if cell.cell_type == 'code':
79 120 self.assertIn('trusted', cell.metadata)
80 121 self.assertFalse(cell.metadata.trusted)
81 122 else:
82 123 self.assertNotIn('trusted', cell.metadata)
83 124
84 125 def test_mark_cells_trusted(self):
85 126 cells = self.nb.cells
86 127 self.notary.mark_cells(self.nb, True)
87 128 for cell in cells:
88 129 self.assertNotIn('trusted', cell)
89 130 if cell.cell_type == 'code':
90 131 self.assertIn('trusted', cell.metadata)
91 132 self.assertTrue(cell.metadata.trusted)
92 133 else:
93 134 self.assertNotIn('trusted', cell.metadata)
94 135
95 136 def test_check_cells(self):
96 137 nb = self.nb
97 138 self.notary.mark_cells(nb, True)
98 139 self.assertTrue(self.notary.check_cells(nb))
99 140 for cell in nb.cells:
100 141 self.assertNotIn('trusted', cell)
101 142 self.notary.mark_cells(nb, False)
102 143 self.assertFalse(self.notary.check_cells(nb))
103 144 for cell in nb.cells:
104 145 self.assertNotIn('trusted', cell)
105 146
106 147 def test_trust_no_output(self):
107 148 nb = self.nb
108 149 self.notary.mark_cells(nb, False)
109 150 for cell in nb.cells:
110 151 if cell.cell_type == 'code':
111 152 cell.outputs = []
112 153 self.assertTrue(self.notary.check_cells(nb))
113 154
114 155 def test_mark_cells_untrusted_v3(self):
115 156 nb = self.nb3
116 157 cells = nb.worksheets[0].cells
117 158 self.notary.mark_cells(nb, False)
118 159 for cell in cells:
119 160 self.assertNotIn('trusted', cell)
120 161 if cell.cell_type == 'code':
121 162 self.assertIn('trusted', cell.metadata)
122 163 self.assertFalse(cell.metadata.trusted)
123 164 else:
124 165 self.assertNotIn('trusted', cell.metadata)
125 166
126 167 def test_mark_cells_trusted_v3(self):
127 168 nb = self.nb3
128 169 cells = nb.worksheets[0].cells
129 170 self.notary.mark_cells(nb, True)
130 171 for cell in cells:
131 172 self.assertNotIn('trusted', cell)
132 173 if cell.cell_type == 'code':
133 174 self.assertIn('trusted', cell.metadata)
134 175 self.assertTrue(cell.metadata.trusted)
135 176 else:
136 177 self.assertNotIn('trusted', cell.metadata)
137 178
138 179 def test_check_cells_v3(self):
139 180 nb = self.nb3
140 181 cells = nb.worksheets[0].cells
141 182 self.notary.mark_cells(nb, True)
142 183 self.assertTrue(self.notary.check_cells(nb))
143 184 for cell in cells:
144 185 self.assertNotIn('trusted', cell)
145 186 self.notary.mark_cells(nb, False)
146 187 self.assertFalse(self.notary.check_cells(nb))
147 188 for cell in cells:
148 189 self.assertNotIn('trusted', cell)
149 190
150 191
@@ -1,252 +1,253
1 1 """Code for converting notebooks to and from v3."""
2 2
3 3 # Copyright (c) IPython Development Team.
4 4 # Distributed under the terms of the Modified BSD License.
5 5
6 6 import json
7 7 import re
8 8
9 9 from .nbbase import (
10 10 nbformat, nbformat_minor,
11 11 NotebookNode,
12 12 )
13 13
14 14 from IPython.nbformat import v3
15 15 from IPython.utils.log import get_logger
16 16
17 17 def _warn_if_invalid(nb, version):
18 18 """Log validation errors, if there are any."""
19 19 from IPython.nbformat import validate, ValidationError
20 20 try:
21 21 validate(nb, version=version)
22 22 except ValidationError as e:
23 23 get_logger().error("Notebook JSON is not valid v%i: %s", version, e)
24 24
25 25 def upgrade(nb, from_version=3, from_minor=0):
26 26 """Convert a notebook to v4.
27 27
28 28 Parameters
29 29 ----------
30 30 nb : NotebookNode
31 31 The Python representation of the notebook to convert.
32 32 from_version : int
33 33 The original version of the notebook to convert.
34 34 from_minor : int
35 35 The original minor version of the notebook to convert (only relevant for v >= 3).
36 36 """
37 37 if from_version == 3:
38 38 # Validate the notebook before conversion
39 39 _warn_if_invalid(nb, from_version)
40 40
41 41 # Mark the original nbformat so consumers know it has been converted
42 42 orig_nbformat = nb.pop('orig_nbformat', None)
43 43 nb.metadata.orig_nbformat = orig_nbformat or 3
44 44
45 45 # Mark the new format
46 46 nb.nbformat = nbformat
47 47 nb.nbformat_minor = nbformat_minor
48 48
49 49 # remove worksheet(s)
50 50 nb['cells'] = cells = []
51 51 # In the unlikely event of multiple worksheets,
52 52 # they will be flattened
53 53 for ws in nb.pop('worksheets', []):
54 54 # upgrade each cell
55 55 for cell in ws['cells']:
56 56 cells.append(upgrade_cell(cell))
57 57 # upgrade metadata
58 58 nb.metadata.pop('name', '')
59 nb.metadata.pop('signature', '')
59 60 # Validate the converted notebook before returning it
60 61 _warn_if_invalid(nb, nbformat)
61 62 return nb
62 63 elif from_version == 4:
63 64 # nothing to do
64 65 if from_minor != nbformat_minor:
65 66 nb.metadata.orig_nbformat_minor = from_minor
66 67 nb.nbformat_minor = nbformat_minor
67 68
68 69 return nb
69 70 else:
70 71 raise ValueError('Cannot convert a notebook directly from v%s to v4. ' \
71 72 'Try using the IPython.nbformat.convert module.' % from_version)
72 73
73 74 def upgrade_cell(cell):
74 75 """upgrade a cell from v3 to v4
75 76
76 77 heading cell:
77 78 - -> markdown heading
78 79 code cell:
79 80 - remove language metadata
80 81 - cell.input -> cell.source
81 82 - cell.prompt_number -> cell.execution_count
82 83 - update outputs
83 84 """
84 85 cell.setdefault('metadata', NotebookNode())
85 86 if cell.cell_type == 'code':
86 87 cell.pop('language', '')
87 88 if 'collapsed' in cell:
88 89 cell.metadata['collapsed'] = cell.pop('collapsed')
89 90 cell.source = cell.pop('input', '')
90 91 cell.execution_count = cell.pop('prompt_number', None)
91 92 cell.outputs = upgrade_outputs(cell.outputs)
92 93 elif cell.cell_type == 'heading':
93 94 cell.cell_type = 'markdown'
94 95 level = cell.pop('level', 1)
95 96 cell.source = u'{hashes} {single_line}'.format(
96 97 hashes='#' * level,
97 98 single_line = ' '.join(cell.get('source', '').splitlines()),
98 99 )
99 100 elif cell.cell_type == 'html':
100 101 # Technically, this exists. It will never happen in practice.
101 102 cell.cell_type = 'markdown'
102 103 return cell
103 104
104 105 def downgrade_cell(cell):
105 106 """downgrade a cell from v4 to v3
106 107
107 108 code cell:
108 109 - set cell.language
109 110 - cell.input <- cell.source
110 111 - cell.prompt_number <- cell.execution_count
111 112 - update outputs
112 113 markdown cell:
113 114 - single-line heading -> heading cell
114 115 """
115 116 if cell.cell_type == 'code':
116 117 cell.language = 'python'
117 118 cell.input = cell.pop('source', '')
118 119 cell.prompt_number = cell.pop('execution_count', None)
119 120 cell.collapsed = cell.metadata.pop('collapsed', False)
120 121 cell.outputs = downgrade_outputs(cell.outputs)
121 122 elif cell.cell_type == 'markdown':
122 123 source = cell.get('source', '')
123 124 if '\n' not in source and source.startswith('#'):
124 125 prefix, text = re.match(r'(#+)\s*(.*)', source).groups()
125 126 cell.cell_type = 'heading'
126 127 cell.source = text
127 128 cell.level = len(prefix)
128 129 return cell
129 130
130 131 _mime_map = {
131 132 "text" : "text/plain",
132 133 "html" : "text/html",
133 134 "svg" : "image/svg+xml",
134 135 "png" : "image/png",
135 136 "jpeg" : "image/jpeg",
136 137 "latex" : "text/latex",
137 138 "json" : "application/json",
138 139 "javascript" : "application/javascript",
139 140 };
140 141
141 142 def to_mime_key(d):
142 143 """convert dict with v3 aliases to plain mime-type keys"""
143 144 for alias, mime in _mime_map.items():
144 145 if alias in d:
145 146 d[mime] = d.pop(alias)
146 147 return d
147 148
148 149 def from_mime_key(d):
149 150 """convert dict with mime-type keys to v3 aliases"""
150 151 for alias, mime in _mime_map.items():
151 152 if mime in d:
152 153 d[alias] = d.pop(mime)
153 154 return d
154 155
155 156 def upgrade_output(output):
156 157 """upgrade a single code cell output from v3 to v4
157 158
158 159 - pyout -> execute_result
159 160 - pyerr -> error
160 161 - output.type -> output.data.mime/type
161 162 - mime-type keys
162 163 - stream.stream -> stream.name
163 164 """
164 165 if output['output_type'] in {'pyout', 'display_data'}:
165 166 output.setdefault('metadata', NotebookNode())
166 167 if output['output_type'] == 'pyout':
167 168 output['output_type'] = 'execute_result'
168 169 output['execution_count'] = output.pop('prompt_number', None)
169 170
170 171 # move output data into data sub-dict
171 172 data = {}
172 173 for key in list(output):
173 174 if key in {'output_type', 'execution_count', 'metadata'}:
174 175 continue
175 176 data[key] = output.pop(key)
176 177 to_mime_key(data)
177 178 output['data'] = data
178 179 to_mime_key(output.metadata)
179 180 if 'application/json' in data:
180 181 data['application/json'] = json.loads(data['application/json'])
181 182 # promote ascii bytes (from v2) to unicode
182 183 for key in ('image/png', 'image/jpeg'):
183 184 if key in data and isinstance(data[key], bytes):
184 185 data[key] = data[key].decode('ascii')
185 186 elif output['output_type'] == 'pyerr':
186 187 output['output_type'] = 'error'
187 188 elif output['output_type'] == 'stream':
188 189 output['name'] = output.pop('stream')
189 190 return output
190 191
191 192 def downgrade_output(output):
192 193 """downgrade a single code cell output to v3 from v4
193 194
194 195 - pyout <- execute_result
195 196 - pyerr <- error
196 197 - output.data.mime/type -> output.type
197 198 - un-mime-type keys
198 199 - stream.stream <- stream.name
199 200 """
200 201 if output['output_type'] in {'execute_result', 'display_data'}:
201 202 if output['output_type'] == 'execute_result':
202 203 output['output_type'] = 'pyout'
203 204 output['prompt_number'] = output.pop('execution_count', None)
204 205
205 206 # promote data dict to top-level output namespace
206 207 data = output.pop('data', {})
207 208 if 'application/json' in data:
208 209 data['application/json'] = json.dumps(data['application/json'])
209 210 from_mime_key(data)
210 211 output.update(data)
211 212 from_mime_key(output.get('metadata', {}))
212 213 elif output['output_type'] == 'error':
213 214 output['output_type'] = 'pyerr'
214 215 elif output['output_type'] == 'stream':
215 216 output['stream'] = output.pop('name')
216 217 return output
217 218
218 219 def upgrade_outputs(outputs):
219 220 """upgrade outputs of a code cell from v3 to v4"""
220 221 return [upgrade_output(op) for op in outputs]
221 222
222 223 def downgrade_outputs(outputs):
223 224 """downgrade outputs of a code cell to v3 from v4"""
224 225 return [downgrade_output(op) for op in outputs]
225 226
226 227 def downgrade(nb):
227 228 """Convert a v4 notebook to v3.
228 229
229 230 Parameters
230 231 ----------
231 232 nb : NotebookNode
232 233 The Python representation of the notebook to convert.
233 234 """
234 235 if nb.nbformat != nbformat:
235 236 return nb
236 237
237 238 # Validate the notebook before conversion
238 239 _warn_if_invalid(nb, nbformat)
239 240
240 241 nb.nbformat = v3.nbformat
241 242 nb.nbformat_minor = v3.nbformat_minor
242 243 cells = [ downgrade_cell(cell) for cell in nb.pop('cells') ]
243 244 nb.worksheets = [v3.new_worksheet(cells=cells)]
244 245 nb.metadata.setdefault('name', '')
245 246
246 247 # Validate the converted notebook before returning it
247 248 _warn_if_invalid(nb, v3.nbformat)
248 249
249 250 nb.orig_nbformat = nb.metadata.pop('orig_nbformat', nbformat)
250 251 nb.orig_nbformat_minor = nb.metadata.pop('orig_nbformat_minor', nbformat_minor)
251 252
252 253 return nb
@@ -1,375 +1,371
1 1 {
2 2 "$schema": "http://json-schema.org/draft-04/schema#",
3 3 "description": "IPython Notebook v4.0 JSON schema.",
4 4 "type": "object",
5 5 "additionalProperties": false,
6 6 "required": ["metadata", "nbformat_minor", "nbformat", "cells"],
7 7 "properties": {
8 8 "metadata": {
9 9 "description": "Notebook root-level metadata.",
10 10 "type": "object",
11 11 "additionalProperties": true,
12 12 "properties": {
13 13 "kernelspec": {
14 14 "description": "Kernel information.",
15 15 "type": "object",
16 16 "required": ["name", "display_name"],
17 17 "properties": {
18 18 "name": {
19 19 "description": "Name of the kernel specification.",
20 20 "type": "string"
21 21 },
22 22 "display_name": {
23 23 "description": "Name to display in UI.",
24 24 "type": "string"
25 25 }
26 26 }
27 27 },
28 28 "language_info": {
29 29 "description": "Kernel information.",
30 30 "type": "object",
31 31 "required": ["name"],
32 32 "properties": {
33 33 "name": {
34 34 "description": "The programming language which this kernel runs.",
35 35 "type": "string"
36 36 },
37 37 "codemirror_mode": {
38 38 "description": "The codemirror mode to use for code in this language.",
39 39 "oneOf": [
40 40 {"type": "string"},
41 41 {"type": "object"}
42 42 ]
43 43 },
44 44 "file_extension": {
45 45 "description": "The file extension for files in this language.",
46 46 "type": "string"
47 47 },
48 48 "mimetype": {
49 49 "description": "The mimetype corresponding to files in this language.",
50 50 "type": "string"
51 51 },
52 52 "pygments_lexer": {
53 53 "description": "The pygments lexer to use for code in this language.",
54 54 "type": "string"
55 55 }
56 56 }
57 57 },
58 "signature": {
59 "description": "Hash of the notebook.",
60 "type": "string"
61 },
62 58 "orig_nbformat": {
63 59 "description": "Original notebook format (major number) before converting the notebook between versions. This should never be written to a file.",
64 60 "type": "integer",
65 61 "minimum": 1
66 62 }
67 63 }
68 64 },
69 65 "nbformat_minor": {
70 66 "description": "Notebook format (minor number). Incremented for backward compatible changes to the notebook format.",
71 67 "type": "integer",
72 68 "minimum": 0
73 69 },
74 70 "nbformat": {
75 71 "description": "Notebook format (major number). Incremented between backwards incompatible changes to the notebook format.",
76 72 "type": "integer",
77 73 "minimum": 4,
78 74 "maximum": 4
79 75 },
80 76 "cells": {
81 77 "description": "Array of cells of the current notebook.",
82 78 "type": "array",
83 79 "items": {"$ref": "#/definitions/cell"}
84 80 }
85 81 },
86 82
87 83 "definitions": {
88 84 "cell": {
89 85 "type": "object",
90 86 "oneOf": [
91 87 {"$ref": "#/definitions/raw_cell"},
92 88 {"$ref": "#/definitions/markdown_cell"},
93 89 {"$ref": "#/definitions/code_cell"}
94 90 ]
95 91 },
96 92
97 93 "raw_cell": {
98 94 "description": "Notebook raw nbconvert cell.",
99 95 "type": "object",
100 96 "additionalProperties": false,
101 97 "required": ["cell_type", "metadata", "source"],
102 98 "properties": {
103 99 "cell_type": {
104 100 "description": "String identifying the type of cell.",
105 101 "enum": ["raw"]
106 102 },
107 103 "metadata": {
108 104 "description": "Cell-level metadata.",
109 105 "type": "object",
110 106 "additionalProperties": true,
111 107 "properties": {
112 108 "format": {
113 109 "description": "Raw cell metadata format for nbconvert.",
114 110 "type": "string"
115 111 },
116 112 "name": {"$ref": "#/definitions/misc/metadata_name"},
117 113 "tags": {"$ref": "#/definitions/misc/metadata_tags"}
118 114 }
119 115 },
120 116 "source": {"$ref": "#/definitions/misc/source"}
121 117 }
122 118 },
123 119
124 120 "markdown_cell": {
125 121 "description": "Notebook markdown cell.",
126 122 "type": "object",
127 123 "additionalProperties": false,
128 124 "required": ["cell_type", "metadata", "source"],
129 125 "properties": {
130 126 "cell_type": {
131 127 "description": "String identifying the type of cell.",
132 128 "enum": ["markdown"]
133 129 },
134 130 "metadata": {
135 131 "description": "Cell-level metadata.",
136 132 "type": "object",
137 133 "properties": {
138 134 "name": {"$ref": "#/definitions/misc/metadata_name"},
139 135 "tags": {"$ref": "#/definitions/misc/metadata_tags"}
140 136 },
141 137 "additionalProperties": true
142 138 },
143 139 "source": {"$ref": "#/definitions/misc/source"}
144 140 }
145 141 },
146 142
147 143 "code_cell": {
148 144 "description": "Notebook code cell.",
149 145 "type": "object",
150 146 "additionalProperties": false,
151 147 "required": ["cell_type", "metadata", "source", "outputs", "execution_count"],
152 148 "properties": {
153 149 "cell_type": {
154 150 "description": "String identifying the type of cell.",
155 151 "enum": ["code"]
156 152 },
157 153 "metadata": {
158 154 "description": "Cell-level metadata.",
159 155 "type": "object",
160 156 "additionalProperties": true,
161 157 "properties": {
162 158 "collapsed": {
163 159 "description": "Whether the cell is collapsed/expanded.",
164 160 "type": "boolean"
165 161 },
166 162 "autoscroll": {
167 163 "description": "Whether the cell's output is scrolled, unscrolled, or autoscrolled.",
168 164 "enum": [true, false, "auto"]
169 165 },
170 166 "name": {"$ref": "#/definitions/misc/metadata_name"},
171 167 "tags": {"$ref": "#/definitions/misc/metadata_tags"}
172 168 }
173 169 },
174 170 "source": {"$ref": "#/definitions/misc/source"},
175 171 "outputs": {
176 172 "description": "Execution, display, or stream outputs.",
177 173 "type": "array",
178 174 "items": {"$ref": "#/definitions/output"}
179 175 },
180 176 "execution_count": {
181 177 "description": "The code cell's prompt number. Will be null if the cell has not been run.",
182 178 "type": ["integer", "null"],
183 179 "minimum": 0
184 180 }
185 181 }
186 182 },
187 183
188 184 "unrecognized_cell": {
189 185 "description": "Unrecognized cell from a future minor-revision to the notebook format.",
190 186 "type": "object",
191 187 "additionalProperties": true,
192 188 "required": ["cell_type", "metadata"],
193 189 "properties": {
194 190 "cell_type": {
195 191 "description": "String identifying the type of cell.",
196 192 "not" : {
197 193 "enum": ["markdown", "code", "raw"]
198 194 }
199 195 },
200 196 "metadata": {
201 197 "description": "Cell-level metadata.",
202 198 "type": "object",
203 199 "properties": {
204 200 "name": {"$ref": "#/definitions/misc/metadata_name"},
205 201 "tags": {"$ref": "#/definitions/misc/metadata_tags"}
206 202 },
207 203 "additionalProperties": true
208 204 }
209 205 }
210 206 },
211 207
212 208 "output": {
213 209 "type": "object",
214 210 "oneOf": [
215 211 {"$ref": "#/definitions/execute_result"},
216 212 {"$ref": "#/definitions/display_data"},
217 213 {"$ref": "#/definitions/stream"},
218 214 {"$ref": "#/definitions/error"}
219 215 ]
220 216 },
221 217
222 218 "execute_result": {
223 219 "description": "Result of executing a code cell.",
224 220 "type": "object",
225 221 "additionalProperties": false,
226 222 "required": ["output_type", "data", "metadata", "execution_count"],
227 223 "properties": {
228 224 "output_type": {
229 225 "description": "Type of cell output.",
230 226 "enum": ["execute_result"]
231 227 },
232 228 "execution_count": {
233 229 "description": "A result's prompt number.",
234 230 "type": ["integer", "null"],
235 231 "minimum": 0
236 232 },
237 233 "data": {"$ref": "#/definitions/misc/mimebundle"},
238 234 "metadata": {"$ref": "#/definitions/misc/output_metadata"}
239 235 }
240 236 },
241 237
242 238 "display_data": {
243 239 "description": "Data displayed as a result of code cell execution.",
244 240 "type": "object",
245 241 "additionalProperties": false,
246 242 "required": ["output_type", "data", "metadata"],
247 243 "properties": {
248 244 "output_type": {
249 245 "description": "Type of cell output.",
250 246 "enum": ["display_data"]
251 247 },
252 248 "data": {"$ref": "#/definitions/misc/mimebundle"},
253 249 "metadata": {"$ref": "#/definitions/misc/output_metadata"}
254 250 }
255 251 },
256 252
257 253 "stream": {
258 254 "description": "Stream output from a code cell.",
259 255 "type": "object",
260 256 "additionalProperties": false,
261 257 "required": ["output_type", "name", "text"],
262 258 "properties": {
263 259 "output_type": {
264 260 "description": "Type of cell output.",
265 261 "enum": ["stream"]
266 262 },
267 263 "name": {
268 264 "description": "The name of the stream (stdout, stderr).",
269 265 "type": "string"
270 266 },
271 267 "text": {
272 268 "description": "The stream's text output, represented as an array of strings.",
273 269 "$ref": "#/definitions/misc/multiline_string"
274 270 }
275 271 }
276 272 },
277 273
278 274 "error": {
279 275 "description": "Output of an error that occurred during code cell execution.",
280 276 "type": "object",
281 277 "additionalProperties": false,
282 278 "required": ["output_type", "ename", "evalue", "traceback"],
283 279 "properties": {
284 280 "output_type": {
285 281 "description": "Type of cell output.",
286 282 "enum": ["error"]
287 283 },
288 284 "ename": {
289 285 "description": "The name of the error.",
290 286 "type": "string"
291 287 },
292 288 "evalue": {
293 289 "description": "The value, or message, of the error.",
294 290 "type": "string"
295 291 },
296 292 "traceback": {
297 293 "description": "The error's traceback, represented as an array of strings.",
298 294 "type": "array",
299 295 "items": {"type": "string"}
300 296 }
301 297 }
302 298 },
303 299
304 300 "unrecognized_output": {
305 301 "description": "Unrecognized output from a future minor-revision to the notebook format.",
306 302 "type": "object",
307 303 "additionalProperties": true,
308 304 "required": ["output_type"],
309 305 "properties": {
310 306 "output_type": {
311 307 "description": "Type of cell output.",
312 308 "not": {
313 309 "enum": ["execute_result", "display_data", "stream", "error"]
314 310 }
315 311 }
316 312 }
317 313 },
318 314
319 315 "misc": {
320 316 "metadata_name": {
321 317 "description": "The cell's name. If present, must be a non-empty string.",
322 318 "type": "string",
323 319 "pattern": "^.+$"
324 320 },
325 321 "metadata_tags": {
326 322 "description": "The cell's tags. Tags must be unique, and must not contain commas.",
327 323 "type": "array",
328 324 "uniqueItems": true,
329 325 "items": {
330 326 "type": "string",
331 327 "pattern": "^[^,]+$"
332 328 }
333 329 },
334 330 "source": {
335 331 "description": "Contents of the cell, represented as an array of lines.",
336 332 "$ref": "#/definitions/misc/multiline_string"
337 333 },
338 334 "execution_count": {
339 335 "description": "The code cell's prompt number. Will be null if the cell has not been run.",
340 336 "type": ["integer", "null"],
341 337 "minimum": 0
342 338 },
343 339 "mimebundle": {
344 340 "description": "A mime-type keyed dictionary of data",
345 341 "type": "object",
346 342 "additionalProperties": false,
347 343 "properties": {
348 344 "application/json": {
349 345 "type": "object"
350 346 }
351 347 },
352 348 "patternProperties": {
353 349 "^(?!application/json$)[a-zA-Z0-9]+/[a-zA-Z0-9\\-\\+\\.]+$": {
354 350 "description": "mimetype output (e.g. text/plain), represented as either an array of strings or a string.",
355 351 "$ref": "#/definitions/misc/multiline_string"
356 352 }
357 353 }
358 354 },
359 355 "output_metadata": {
360 356 "description": "Cell output metadata.",
361 357 "type": "object",
362 358 "additionalProperties": true
363 359 },
364 360 "multiline_string": {
365 361 "oneOf" : [
366 362 {"type": "string"},
367 363 {
368 364 "type": "array",
369 365 "items": {"type": "string"}
370 366 }
371 367 ]
372 368 }
373 369 }
374 370 }
375 371 }
@@ -1,95 +1,96
1 1 """Base classes and utilities for readers and writers."""
2 2
3 3 # Copyright (c) IPython Development Team.
4 4 # Distributed under the terms of the Modified BSD License.
5 5
6 6 from IPython.utils.py3compat import string_types, cast_unicode_py2
7 7
8 8
9 9 def rejoin_lines(nb):
10 10 """rejoin multiline text into strings
11 11
12 12 For reversing effects of ``split_lines(nb)``.
13 13
14 14 This only rejoins lines that have been split, so if text objects were not split
15 15 they will pass through unchanged.
16 16
17 17 Used when reading JSON files that may have been passed through split_lines.
18 18 """
19 19 for cell in nb.cells:
20 20 if 'source' in cell and isinstance(cell.source, list):
21 21 cell.source = ''.join(cell.source)
22 22 if cell.get('cell_type', None) == 'code':
23 23 for output in cell.get('outputs', []):
24 24 output_type = output.get('output_type', '')
25 25 if output_type in {'execute_result', 'display_data'}:
26 26 for key, value in output.get('data', {}).items():
27 27 if key != 'application/json' and isinstance(value, list):
28 28 output.data[key] = ''.join(value)
29 29 elif output_type:
30 30 if isinstance(output.get('text', ''), list):
31 31 output.text = ''.join(output.text)
32 32 return nb
33 33
34 34
35 35 def split_lines(nb):
36 36 """split likely multiline text into lists of strings
37 37
38 38 For file output more friendly to line-based VCS. ``rejoin_lines(nb)`` will
39 39 reverse the effects of ``split_lines(nb)``.
40 40
41 41 Used when writing JSON files.
42 42 """
43 43 for cell in nb.cells:
44 44 source = cell.get('source', None)
45 45 if isinstance(source, string_types):
46 46 cell['source'] = source.splitlines(True)
47 47
48 48 if cell.cell_type == 'code':
49 49 for output in cell.outputs:
50 50 if output.output_type in {'execute_result', 'display_data'}:
51 51 for key, value in output.data.items():
52 52 if key != 'application/json' and isinstance(value, string_types):
53 53 output.data[key] = value.splitlines(True)
54 54 elif output.output_type == 'stream':
55 55 if isinstance(output.text, string_types):
56 56 output.text = output.text.splitlines(True)
57 57 return nb
58 58
59 59
60 60 def strip_transient(nb):
61 61 """Strip transient values that shouldn't be stored in files.
62 62
63 63 This should be called in *both* read and write.
64 64 """
65 65 nb.metadata.pop('orig_nbformat', None)
66 66 nb.metadata.pop('orig_nbformat_minor', None)
67 nb.metadata.pop('signature', None)
67 68 for cell in nb.cells:
68 69 cell.metadata.pop('trusted', None)
69 70 return nb
70 71
71 72
72 73 class NotebookReader(object):
73 74 """A class for reading notebooks."""
74 75
75 76 def reads(self, s, **kwargs):
76 77 """Read a notebook from a string."""
77 78 raise NotImplementedError("loads must be implemented in a subclass")
78 79
79 80 def read(self, fp, **kwargs):
80 81 """Read a notebook from a file like object"""
81 82 nbs = cast_unicode_py2(fp.read())
82 83 return self.reads(nbs, **kwargs)
83 84
84 85
85 86 class NotebookWriter(object):
86 87 """A class for writing notebooks."""
87 88
88 89 def writes(self, nb, **kwargs):
89 90 """Write a notebook to a string."""
90 91 raise NotImplementedError("loads must be implemented in a subclass")
91 92
92 93 def write(self, nb, fp, **kwargs):
93 94 """Write a notebook to a file like object"""
94 95 nbs = cast_unicode_py2(self.writes(nb, **kwargs))
95 96 return fp.write(nbs)
@@ -1,103 +1,101
1 1 {
2 2 "cells": [
3 3 {
4 4 "cell_type": "markdown",
5 5 "metadata": {},
6 6 "source": [
7 7 "<img src=\"../images/ipython_logo.png\">"
8 8 ]
9 9 },
10 10 {
11 11 "cell_type": "markdown",
12 12 "metadata": {},
13 13 "source": [
14 14 "Back to the main [Index](../Index.ipynb)"
15 15 ]
16 16 },
17 17 {
18 18 "cell_type": "markdown",
19 19 "metadata": {},
20 20 "source": [
21 21 "# Customization"
22 22 ]
23 23 },
24 24 {
25 25 "cell_type": "markdown",
26 26 "metadata": {},
27 27 "source": [
28 28 "IPython has rich APIs for customization. Many behaviors of the different IPython applications can be configured using command line arguments or configuration files. IPython's core syntax and command line features can also be customized through input filters, custom magic commands, etc."
29 29 ]
30 30 },
31 31 {
32 32 "cell_type": "markdown",
33 33 "metadata": {},
34 34 "source": [
35 35 "## Tutorials"
36 36 ]
37 37 },
38 38 {
39 39 "cell_type": "markdown",
40 40 "metadata": {},
41 41 "source": [
42 42 "Coming soon."
43 43 ]
44 44 },
45 45 {
46 46 "cell_type": "markdown",
47 47 "metadata": {},
48 48 "source": [
49 49 "## Examples"
50 50 ]
51 51 },
52 52 {
53 53 "cell_type": "markdown",
54 54 "metadata": {},
55 55 "source": [
56 56 "Coming soon."
57 57 ]
58 58 },
59 59 {
60 60 "cell_type": "markdown",
61 61 "metadata": {},
62 62 "source": [
63 63 "## Non-notebook examples"
64 64 ]
65 65 },
66 66 {
67 67 "cell_type": "markdown",
68 68 "metadata": {},
69 69 "source": [
70 70 "This directory also contains examples that are regular Python (`.py`) files."
71 71 ]
72 72 },
73 73 {
74 74 "cell_type": "code",
75 75 "execution_count": 1,
76 76 "metadata": {
77 77 "collapsed": false
78 78 },
79 79 "outputs": [
80 80 {
81 81 "data": {
82 82 "text/html": [
83 83 "<a href='appconfig.py' target='_blank'>appconfig.py</a><br>"
84 84 ],
85 85 "text/plain": [
86 86 "/Users/bgranger/Documents/Computing/IPython/code/ipython/examples/Customization/appconfig.py"
87 87 ]
88 88 },
89 89 "metadata": {},
90 90 "output_type": "display_data"
91 91 }
92 92 ],
93 93 "source": [
94 94 "%run ../utils/list_pyfiles.ipy"
95 95 ]
96 96 }
97 97 ],
98 "metadata": {
99 "signature": "sha256:de8cb1aff3da9097ba3fc7afab4327fc589f2bb1c154feeeb5ed97c87e37486f"
100 },
98 "metadata": {},
101 99 "nbformat": 4,
102 100 "nbformat_minor": 0
103 101 } No newline at end of file
@@ -1,194 +1,192
1 1 {
2 2 "cells": [
3 3 {
4 4 "cell_type": "markdown",
5 5 "metadata": {},
6 6 "source": [
7 7 "<img src=\"../images/ipython_logo.png\">"
8 8 ]
9 9 },
10 10 {
11 11 "cell_type": "markdown",
12 12 "metadata": {},
13 13 "source": [
14 14 "Back to the main [Index](../Index.ipynb)"
15 15 ]
16 16 },
17 17 {
18 18 "cell_type": "markdown",
19 19 "metadata": {},
20 20 "source": [
21 21 "# Embedding IPython Into Other Applications"
22 22 ]
23 23 },
24 24 {
25 25 "cell_type": "markdown",
26 26 "metadata": {},
27 27 "source": [
28 28 "The architecture of IPython is built with reusable components. These components include:\n",
29 29 "\n",
30 30 "* The configuration system for processing command line arguments and configuration files\n",
31 31 "* The IPython `InteractiveShell` object that provides the core interactive features across the entire code base\n",
32 32 "* The IPython kernel, which provides the capabilities of the `InteractiveShell` object over a ZeroMQ/JSON based message protocol to various frontends\n",
33 33 "* The IPython frontends (Notebook, Qt Console, Console, Terminal)\n",
34 34 "\n",
35 35 "These components can be embedded into other applications."
36 36 ]
37 37 },
38 38 {
39 39 "cell_type": "markdown",
40 40 "metadata": {},
41 41 "source": [
42 42 "## Tutorials"
43 43 ]
44 44 },
45 45 {
46 46 "cell_type": "markdown",
47 47 "metadata": {},
48 48 "source": [
49 49 "Coming soon."
50 50 ]
51 51 },
52 52 {
53 53 "cell_type": "markdown",
54 54 "metadata": {},
55 55 "source": [
56 56 "## Examples"
57 57 ]
58 58 },
59 59 {
60 60 "cell_type": "markdown",
61 61 "metadata": {},
62 62 "source": [
63 63 "Coming soon."
64 64 ]
65 65 },
66 66 {
67 67 "cell_type": "markdown",
68 68 "metadata": {},
69 69 "source": [
70 70 "## Non-notebook examples"
71 71 ]
72 72 },
73 73 {
74 74 "cell_type": "markdown",
75 75 "metadata": {},
76 76 "source": [
77 77 "This directory also contains examples that are regular Python (`.py`) files."
78 78 ]
79 79 },
80 80 {
81 81 "cell_type": "code",
82 82 "execution_count": 1,
83 83 "metadata": {
84 84 "collapsed": false
85 85 },
86 86 "outputs": [
87 87 {
88 88 "data": {
89 89 "text/html": [
90 90 "<a href='embed_class_long.py' target='_blank'>embed_class_long.py</a><br>"
91 91 ],
92 92 "text/plain": [
93 93 "/Users/bgranger/Documents/Computing/IPython/code/ipython/examples/Embedding/embed_class_long.py"
94 94 ]
95 95 },
96 96 "metadata": {},
97 97 "output_type": "display_data"
98 98 },
99 99 {
100 100 "data": {
101 101 "text/html": [
102 102 "<a href='embed_class_short.py' target='_blank'>embed_class_short.py</a><br>"
103 103 ],
104 104 "text/plain": [
105 105 "/Users/bgranger/Documents/Computing/IPython/code/ipython/examples/Embedding/embed_class_short.py"
106 106 ]
107 107 },
108 108 "metadata": {},
109 109 "output_type": "display_data"
110 110 },
111 111 {
112 112 "data": {
113 113 "text/html": [
114 114 "<a href='embed_function.py' target='_blank'>embed_function.py</a><br>"
115 115 ],
116 116 "text/plain": [
117 117 "/Users/bgranger/Documents/Computing/IPython/code/ipython/examples/Embedding/embed_function.py"
118 118 ]
119 119 },
120 120 "metadata": {},
121 121 "output_type": "display_data"
122 122 },
123 123 {
124 124 "data": {
125 125 "text/html": [
126 126 "<a href='inprocess_qtconsole.py' target='_blank'>inprocess_qtconsole.py</a><br>"
127 127 ],
128 128 "text/plain": [
129 129 "/Users/bgranger/Documents/Computing/IPython/code/ipython/examples/Embedding/inprocess_qtconsole.py"
130 130 ]
131 131 },
132 132 "metadata": {},
133 133 "output_type": "display_data"
134 134 },
135 135 {
136 136 "data": {
137 137 "text/html": [
138 138 "<a href='inprocess_terminal.py' target='_blank'>inprocess_terminal.py</a><br>"
139 139 ],
140 140 "text/plain": [
141 141 "/Users/bgranger/Documents/Computing/IPython/code/ipython/examples/Embedding/inprocess_terminal.py"
142 142 ]
143 143 },
144 144 "metadata": {},
145 145 "output_type": "display_data"
146 146 },
147 147 {
148 148 "data": {
149 149 "text/html": [
150 150 "<a href='internal_ipkernel.py' target='_blank'>internal_ipkernel.py</a><br>"
151 151 ],
152 152 "text/plain": [
153 153 "/Users/bgranger/Documents/Computing/IPython/code/ipython/examples/Embedding/internal_ipkernel.py"
154 154 ]
155 155 },
156 156 "metadata": {},
157 157 "output_type": "display_data"
158 158 },
159 159 {
160 160 "data": {
161 161 "text/html": [
162 162 "<a href='ipkernel_qtapp.py' target='_blank'>ipkernel_qtapp.py</a><br>"
163 163 ],
164 164 "text/plain": [
165 165 "/Users/bgranger/Documents/Computing/IPython/code/ipython/examples/Embedding/ipkernel_qtapp.py"
166 166 ]
167 167 },
168 168 "metadata": {},
169 169 "output_type": "display_data"
170 170 },
171 171 {
172 172 "data": {
173 173 "text/html": [
174 174 "<a href='ipkernel_wxapp.py' target='_blank'>ipkernel_wxapp.py</a><br>"
175 175 ],
176 176 "text/plain": [
177 177 "/Users/bgranger/Documents/Computing/IPython/code/ipython/examples/Embedding/ipkernel_wxapp.py"
178 178 ]
179 179 },
180 180 "metadata": {},
181 181 "output_type": "display_data"
182 182 }
183 183 ],
184 184 "source": [
185 185 "%run ../utils/list_pyfiles.ipy"
186 186 ]
187 187 }
188 188 ],
189 "metadata": {
190 "signature": "sha256:627cdf03b8de558c9344f9d1e8f0beeb2448e37e492d676e6db7b07d33251a2b"
191 },
189 "metadata": {},
192 190 "nbformat": 4,
193 191 "nbformat_minor": 0
194 192 } No newline at end of file
@@ -1,1807 +1,1805
1 1 {
2 2 "cells": [
3 3 {
4 4 "cell_type": "markdown",
5 5 "metadata": {
6 6 "slideshow": {
7 7 "slide_type": "slide"
8 8 }
9 9 },
10 10 "source": [
11 11 "# IPython: beyond plain Python"
12 12 ]
13 13 },
14 14 {
15 15 "cell_type": "markdown",
16 16 "metadata": {},
17 17 "source": [
18 18 "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."
19 19 ]
20 20 },
21 21 {
22 22 "cell_type": "markdown",
23 23 "metadata": {
24 24 "slideshow": {
25 25 "slide_type": "slide"
26 26 }
27 27 },
28 28 "source": [
29 29 "## First things first: running code, getting help"
30 30 ]
31 31 },
32 32 {
33 33 "cell_type": "markdown",
34 34 "metadata": {},
35 35 "source": [
36 36 "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",
37 37 " \n",
38 38 "- `Alt-Enter` to force the creation of a new cell unconditionally (useful when inserting new content in the middle of an existing notebook).\n",
39 39 "- `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."
40 40 ]
41 41 },
42 42 {
43 43 "cell_type": "code",
44 44 "execution_count": 1,
45 45 "metadata": {
46 46 "collapsed": false
47 47 },
48 48 "outputs": [
49 49 {
50 50 "name": "stdout",
51 51 "output_type": "stream",
52 52 "text": [
53 53 "Hi\n"
54 54 ]
55 55 }
56 56 ],
57 57 "source": [
58 58 "print \"Hi\""
59 59 ]
60 60 },
61 61 {
62 62 "cell_type": "markdown",
63 63 "metadata": {
64 64 "slideshow": {
65 65 "slide_type": "slide"
66 66 }
67 67 },
68 68 "source": [
69 69 "Getting help:"
70 70 ]
71 71 },
72 72 {
73 73 "cell_type": "code",
74 74 "execution_count": 2,
75 75 "metadata": {
76 76 "collapsed": false
77 77 },
78 78 "outputs": [],
79 79 "source": [
80 80 "?"
81 81 ]
82 82 },
83 83 {
84 84 "cell_type": "markdown",
85 85 "metadata": {
86 86 "slideshow": {
87 87 "slide_type": "slide"
88 88 }
89 89 },
90 90 "source": [
91 91 "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."
92 92 ]
93 93 },
94 94 {
95 95 "cell_type": "code",
96 96 "execution_count": 3,
97 97 "metadata": {
98 98 "collapsed": false
99 99 },
100 100 "outputs": [],
101 101 "source": [
102 102 "import collections\n",
103 103 "collections.namedtuple?"
104 104 ]
105 105 },
106 106 {
107 107 "cell_type": "code",
108 108 "execution_count": 4,
109 109 "metadata": {
110 110 "collapsed": false
111 111 },
112 112 "outputs": [],
113 113 "source": [
114 114 "collections.Counter??"
115 115 ]
116 116 },
117 117 {
118 118 "cell_type": "code",
119 119 "execution_count": 5,
120 120 "metadata": {
121 121 "collapsed": false
122 122 },
123 123 "outputs": [],
124 124 "source": [
125 125 "*int*?"
126 126 ]
127 127 },
128 128 {
129 129 "cell_type": "markdown",
130 130 "metadata": {
131 131 "slideshow": {
132 132 "slide_type": "slide"
133 133 }
134 134 },
135 135 "source": [
136 136 "An IPython quick reference card:"
137 137 ]
138 138 },
139 139 {
140 140 "cell_type": "code",
141 141 "execution_count": 6,
142 142 "metadata": {
143 143 "collapsed": false
144 144 },
145 145 "outputs": [],
146 146 "source": [
147 147 "%quickref"
148 148 ]
149 149 },
150 150 {
151 151 "cell_type": "markdown",
152 152 "metadata": {
153 153 "slideshow": {
154 154 "slide_type": "slide"
155 155 }
156 156 },
157 157 "source": [
158 158 "## Tab completion"
159 159 ]
160 160 },
161 161 {
162 162 "cell_type": "markdown",
163 163 "metadata": {},
164 164 "source": [
165 165 "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."
166 166 ]
167 167 },
168 168 {
169 169 "cell_type": "code",
170 170 "execution_count": 8,
171 171 "metadata": {
172 172 "collapsed": false
173 173 },
174 174 "outputs": [],
175 175 "source": [
176 176 "collections."
177 177 ]
178 178 },
179 179 {
180 180 "cell_type": "markdown",
181 181 "metadata": {
182 182 "slideshow": {
183 183 "slide_type": "slide"
184 184 }
185 185 },
186 186 "source": [
187 187 "## The interactive workflow: input, output, history"
188 188 ]
189 189 },
190 190 {
191 191 "cell_type": "code",
192 192 "execution_count": 7,
193 193 "metadata": {
194 194 "collapsed": false
195 195 },
196 196 "outputs": [
197 197 {
198 198 "data": {
199 199 "text/plain": [
200 200 "12"
201 201 ]
202 202 },
203 203 "execution_count": 7,
204 204 "metadata": {},
205 205 "output_type": "execute_result"
206 206 }
207 207 ],
208 208 "source": [
209 209 "2+10"
210 210 ]
211 211 },
212 212 {
213 213 "cell_type": "code",
214 214 "execution_count": 8,
215 215 "metadata": {
216 216 "collapsed": false
217 217 },
218 218 "outputs": [
219 219 {
220 220 "data": {
221 221 "text/plain": [
222 222 "22"
223 223 ]
224 224 },
225 225 "execution_count": 8,
226 226 "metadata": {},
227 227 "output_type": "execute_result"
228 228 }
229 229 ],
230 230 "source": [
231 231 "_+10"
232 232 ]
233 233 },
234 234 {
235 235 "cell_type": "markdown",
236 236 "metadata": {
237 237 "slideshow": {
238 238 "slide_type": "slide"
239 239 }
240 240 },
241 241 "source": [
242 242 "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):"
243 243 ]
244 244 },
245 245 {
246 246 "cell_type": "code",
247 247 "execution_count": 9,
248 248 "metadata": {
249 249 "collapsed": false
250 250 },
251 251 "outputs": [],
252 252 "source": [
253 253 "10+20;"
254 254 ]
255 255 },
256 256 {
257 257 "cell_type": "code",
258 258 "execution_count": 10,
259 259 "metadata": {
260 260 "collapsed": false
261 261 },
262 262 "outputs": [
263 263 {
264 264 "data": {
265 265 "text/plain": [
266 266 "22"
267 267 ]
268 268 },
269 269 "execution_count": 10,
270 270 "metadata": {},
271 271 "output_type": "execute_result"
272 272 }
273 273 ],
274 274 "source": [
275 275 "_"
276 276 ]
277 277 },
278 278 {
279 279 "cell_type": "markdown",
280 280 "metadata": {
281 281 "slideshow": {
282 282 "slide_type": "slide"
283 283 }
284 284 },
285 285 "source": [
286 286 "The output is stored in `_N` and `Out[N]` variables:"
287 287 ]
288 288 },
289 289 {
290 290 "cell_type": "code",
291 291 "execution_count": 11,
292 292 "metadata": {
293 293 "collapsed": false
294 294 },
295 295 "outputs": [
296 296 {
297 297 "data": {
298 298 "text/plain": [
299 299 "True"
300 300 ]
301 301 },
302 302 "execution_count": 11,
303 303 "metadata": {},
304 304 "output_type": "execute_result"
305 305 }
306 306 ],
307 307 "source": [
308 308 "_10 == Out[10]"
309 309 ]
310 310 },
311 311 {
312 312 "cell_type": "markdown",
313 313 "metadata": {
314 314 "slideshow": {
315 315 "slide_type": "slide"
316 316 }
317 317 },
318 318 "source": [
319 319 "And the last three have shorthands for convenience:"
320 320 ]
321 321 },
322 322 {
323 323 "cell_type": "code",
324 324 "execution_count": 12,
325 325 "metadata": {
326 326 "collapsed": false
327 327 },
328 328 "outputs": [
329 329 {
330 330 "name": "stdout",
331 331 "output_type": "stream",
332 332 "text": [
333 333 "last output: True\n",
334 334 "next one : 22\n",
335 335 "and next : 22\n"
336 336 ]
337 337 }
338 338 ],
339 339 "source": [
340 340 "print 'last output:', _\n",
341 341 "print 'next one :', __\n",
342 342 "print 'and next :', ___"
343 343 ]
344 344 },
345 345 {
346 346 "cell_type": "code",
347 347 "execution_count": 13,
348 348 "metadata": {
349 349 "collapsed": false,
350 350 "slideshow": {
351 351 "slide_type": "-"
352 352 }
353 353 },
354 354 "outputs": [
355 355 {
356 356 "data": {
357 357 "text/plain": [
358 358 "u'_10 == Out[10]'"
359 359 ]
360 360 },
361 361 "execution_count": 13,
362 362 "metadata": {},
363 363 "output_type": "execute_result"
364 364 }
365 365 ],
366 366 "source": [
367 367 "In[11]"
368 368 ]
369 369 },
370 370 {
371 371 "cell_type": "code",
372 372 "execution_count": 14,
373 373 "metadata": {
374 374 "collapsed": false
375 375 },
376 376 "outputs": [
377 377 {
378 378 "data": {
379 379 "text/plain": [
380 380 "u'In[11]'"
381 381 ]
382 382 },
383 383 "execution_count": 14,
384 384 "metadata": {},
385 385 "output_type": "execute_result"
386 386 }
387 387 ],
388 388 "source": [
389 389 "_i"
390 390 ]
391 391 },
392 392 {
393 393 "cell_type": "code",
394 394 "execution_count": 15,
395 395 "metadata": {
396 396 "collapsed": false
397 397 },
398 398 "outputs": [
399 399 {
400 400 "data": {
401 401 "text/plain": [
402 402 "u'In[11]'"
403 403 ]
404 404 },
405 405 "execution_count": 15,
406 406 "metadata": {},
407 407 "output_type": "execute_result"
408 408 }
409 409 ],
410 410 "source": [
411 411 "_ii"
412 412 ]
413 413 },
414 414 {
415 415 "cell_type": "code",
416 416 "execution_count": 16,
417 417 "metadata": {
418 418 "collapsed": false,
419 419 "slideshow": {
420 420 "slide_type": "subslide"
421 421 }
422 422 },
423 423 "outputs": [
424 424 {
425 425 "name": "stdout",
426 426 "output_type": "stream",
427 427 "text": [
428 428 "last input: _ii\n",
429 429 "next one : _i\n",
430 430 "and next : In[11]\n"
431 431 ]
432 432 }
433 433 ],
434 434 "source": [
435 435 "print 'last input:', _i\n",
436 436 "print 'next one :', _ii\n",
437 437 "print 'and next :', _iii"
438 438 ]
439 439 },
440 440 {
441 441 "cell_type": "code",
442 442 "execution_count": 17,
443 443 "metadata": {
444 444 "collapsed": false
445 445 },
446 446 "outputs": [
447 447 {
448 448 "name": "stdout",
449 449 "output_type": "stream",
450 450 "text": [
451 451 " 1: print \"Hi\"\n",
452 452 " 2: ?\n",
453 453 " 3:\n",
454 454 "import collections\n",
455 455 "collections.namedtuple?\n",
456 456 " 4: collections.Counter??\n",
457 457 " 5: *int*?\n"
458 458 ]
459 459 }
460 460 ],
461 461 "source": [
462 462 "%history -n 1-5"
463 463 ]
464 464 },
465 465 {
466 466 "cell_type": "markdown",
467 467 "metadata": {
468 468 "slideshow": {
469 469 "slide_type": "subslide"
470 470 }
471 471 },
472 472 "source": [
473 473 "**Exercise**\n",
474 474 "\n",
475 475 "Write the last 10 lines of history to a file named `log.py`."
476 476 ]
477 477 },
478 478 {
479 479 "cell_type": "markdown",
480 480 "metadata": {
481 481 "slideshow": {
482 482 "slide_type": "slide"
483 483 }
484 484 },
485 485 "source": [
486 486 "## Accessing the underlying operating system"
487 487 ]
488 488 },
489 489 {
490 490 "cell_type": "code",
491 491 "execution_count": 18,
492 492 "metadata": {
493 493 "collapsed": false
494 494 },
495 495 "outputs": [
496 496 {
497 497 "name": "stdout",
498 498 "output_type": "stream",
499 499 "text": [
500 500 "/home/fperez/ipython/tutorial/notebooks\r\n"
501 501 ]
502 502 }
503 503 ],
504 504 "source": [
505 505 "!pwd"
506 506 ]
507 507 },
508 508 {
509 509 "cell_type": "code",
510 510 "execution_count": 19,
511 511 "metadata": {
512 512 "collapsed": false
513 513 },
514 514 "outputs": [
515 515 {
516 516 "name": "stdout",
517 517 "output_type": "stream",
518 518 "text": [
519 519 "My current directory's files:\n",
520 520 "['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"
521 521 ]
522 522 }
523 523 ],
524 524 "source": [
525 525 "files = !ls\n",
526 526 "print \"My current directory's files:\"\n",
527 527 "print files"
528 528 ]
529 529 },
530 530 {
531 531 "cell_type": "code",
532 532 "execution_count": 20,
533 533 "metadata": {
534 534 "collapsed": false
535 535 },
536 536 "outputs": [
537 537 {
538 538 "name": "stdout",
539 539 "output_type": "stream",
540 540 "text": [
541 541 "[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"
542 542 ]
543 543 }
544 544 ],
545 545 "source": [
546 546 "!echo $files"
547 547 ]
548 548 },
549 549 {
550 550 "cell_type": "code",
551 551 "execution_count": 21,
552 552 "metadata": {
553 553 "collapsed": false
554 554 },
555 555 "outputs": [
556 556 {
557 557 "name": "stdout",
558 558 "output_type": "stream",
559 559 "text": [
560 560 "BACKGROUNDJOBS.IPYNB\r\n"
561 561 ]
562 562 }
563 563 ],
564 564 "source": [
565 565 "!echo {files[0].upper()}"
566 566 ]
567 567 },
568 568 {
569 569 "cell_type": "markdown",
570 570 "metadata": {},
571 571 "source": [
572 572 "Note that all this is available even in multiline blocks:"
573 573 ]
574 574 },
575 575 {
576 576 "cell_type": "code",
577 577 "execution_count": 27,
578 578 "metadata": {
579 579 "collapsed": false
580 580 },
581 581 "outputs": [
582 582 {
583 583 "name": "stdout",
584 584 "output_type": "stream",
585 585 "text": [
586 586 "00 - BackgroundJobs\r\n",
587 587 "01 - Custom Display Logic\r\n",
588 588 "02 - Customizing IPython - Condensed\r\n",
589 589 "03 - Customizing IPython - Config\r\n",
590 590 "04 - Customizing IPython - Extensions\r\n",
591 591 "05 - Customizing IPython - Magics\r\n",
592 592 "--\n",
593 593 "--\n",
594 594 "--\n",
595 595 "09 - Index\r\n",
596 596 "10 - Interactive Widgets\r\n",
597 597 "11 - IPython - beyond plain Python\r\n",
598 598 "--\n",
599 599 "13 - Markdown Cells\r\n",
600 600 "--\n",
601 601 "--\n",
602 602 "16 - NbConvert from command line\r\n",
603 603 "17 - NbConvert Python library\r\n",
604 604 "18 - Notebook and javascript extension\r\n",
605 605 "19 - Notebook Basics\r\n",
606 606 "20 - Overview of IPython.parallel\r\n",
607 607 "--\n",
608 608 "22 - Rich Display System\r\n",
609 609 "23 - Running a Secure Public Notebook\r\n",
610 610 "24 - Running Code\r\n",
611 611 "25 - Sample\r\n",
612 612 "--\n",
613 613 "27 - Terminal usage\r\n",
614 614 "--\n",
615 615 "29 - Typesetting Math Using MathJax\r\n"
616 616 ]
617 617 }
618 618 ],
619 619 "source": [
620 620 "import os\n",
621 621 "for i,f in enumerate(files):\n",
622 622 " if f.endswith('ipynb'):\n",
623 623 " !echo {\"%02d\" % i} - \"{os.path.splitext(f)[0]}\"\n",
624 624 " else:\n",
625 625 " print '--'"
626 626 ]
627 627 },
628 628 {
629 629 "cell_type": "markdown",
630 630 "metadata": {},
631 631 "source": [
632 632 "## Beyond Python: magic functions"
633 633 ]
634 634 },
635 635 {
636 636 "cell_type": "markdown",
637 637 "metadata": {},
638 638 "source": [
639 639 "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",
640 640 " \n",
641 641 "- To provide an orthogonal namespace for controlling IPython itself and exposing other system-oriented functionality.\n",
642 642 "\n",
643 643 "- 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."
644 644 ]
645 645 },
646 646 {
647 647 "cell_type": "code",
648 648 "execution_count": 28,
649 649 "metadata": {
650 650 "collapsed": false
651 651 },
652 652 "outputs": [],
653 653 "source": [
654 654 "%magic"
655 655 ]
656 656 },
657 657 {
658 658 "cell_type": "markdown",
659 659 "metadata": {},
660 660 "source": [
661 661 "Line vs cell magics:"
662 662 ]
663 663 },
664 664 {
665 665 "cell_type": "code",
666 666 "execution_count": 29,
667 667 "metadata": {
668 668 "collapsed": false
669 669 },
670 670 "outputs": [
671 671 {
672 672 "name": "stdout",
673 673 "output_type": "stream",
674 674 "text": [
675 675 "10000000 loops, best of 3: 190 ns per loop\n"
676 676 ]
677 677 }
678 678 ],
679 679 "source": [
680 680 "%timeit range(10)"
681 681 ]
682 682 },
683 683 {
684 684 "cell_type": "code",
685 685 "execution_count": 30,
686 686 "metadata": {
687 687 "collapsed": false
688 688 },
689 689 "outputs": [
690 690 {
691 691 "name": "stdout",
692 692 "output_type": "stream",
693 693 "text": [
694 694 "1000000 loops, best of 3: 888 ns per loop\n"
695 695 ]
696 696 }
697 697 ],
698 698 "source": [
699 699 "%%timeit\n",
700 700 "range(10)\n",
701 701 "range(100)"
702 702 ]
703 703 },
704 704 {
705 705 "cell_type": "markdown",
706 706 "metadata": {},
707 707 "source": [
708 708 "Line magics can be used even inside code blocks:"
709 709 ]
710 710 },
711 711 {
712 712 "cell_type": "code",
713 713 "execution_count": 31,
714 714 "metadata": {
715 715 "collapsed": false
716 716 },
717 717 "outputs": [
718 718 {
719 719 "name": "stdout",
720 720 "output_type": "stream",
721 721 "text": [
722 722 "size: 010000000 loops, best of 3: 129 ns per loop\n",
723 723 " size: 1001000000 loops, best of 3: 649 ns per loop\n",
724 724 " size: 2001000000 loops, best of 3: 1.09 \u00b5s per loop\n",
725 725 " size: 3001000000 loops, best of 3: 1.74 \u00b5s per loop\n",
726 726 " size: 400100000 loops, best of 3: 2.72 \u00b5s per loop\n",
727 727 "\n"
728 728 ]
729 729 }
730 730 ],
731 731 "source": [
732 732 "for i in range(5):\n",
733 733 " size = i*100\n",
734 734 " print 'size:',size, \n",
735 735 " %timeit range(size)"
736 736 ]
737 737 },
738 738 {
739 739 "cell_type": "markdown",
740 740 "metadata": {},
741 741 "source": [
742 742 "Magics can do anything they want with their input, so it doesn't have to be valid Python:"
743 743 ]
744 744 },
745 745 {
746 746 "cell_type": "code",
747 747 "execution_count": 32,
748 748 "metadata": {
749 749 "collapsed": false
750 750 },
751 751 "outputs": [
752 752 {
753 753 "name": "stdout",
754 754 "output_type": "stream",
755 755 "text": [
756 756 "My shell is: /bin/bash\n",
757 757 "My memory status is:\n",
758 758 " total used free shared buffers cached\n",
759 759 "Mem: 7870888 6389328 1481560 0 662860 2505172\n",
760 760 "-/+ buffers/cache: 3221296 4649592\n",
761 761 "Swap: 3905532 4852 3900680\n"
762 762 ]
763 763 }
764 764 ],
765 765 "source": [
766 766 "%%bash\n",
767 767 "echo \"My shell is:\" $SHELL\n",
768 768 "echo \"My memory status is:\"\n",
769 769 "free"
770 770 ]
771 771 },
772 772 {
773 773 "cell_type": "markdown",
774 774 "metadata": {},
775 775 "source": [
776 776 "Another interesting cell magic: create any file you want locally from the notebook:"
777 777 ]
778 778 },
779 779 {
780 780 "cell_type": "code",
781 781 "execution_count": 33,
782 782 "metadata": {
783 783 "collapsed": false
784 784 },
785 785 "outputs": [
786 786 {
787 787 "name": "stdout",
788 788 "output_type": "stream",
789 789 "text": [
790 790 "Writing test.txt\n"
791 791 ]
792 792 }
793 793 ],
794 794 "source": [
795 795 "%%writefile test.txt\n",
796 796 "This is a test file!\n",
797 797 "It can contain anything I want...\n",
798 798 "\n",
799 799 "And more..."
800 800 ]
801 801 },
802 802 {
803 803 "cell_type": "code",
804 804 "execution_count": 34,
805 805 "metadata": {
806 806 "collapsed": false
807 807 },
808 808 "outputs": [
809 809 {
810 810 "name": "stdout",
811 811 "output_type": "stream",
812 812 "text": [
813 813 "This is a test file!\r\n",
814 814 "It can contain anything I want...\r\n",
815 815 "\r\n",
816 816 "And more..."
817 817 ]
818 818 }
819 819 ],
820 820 "source": [
821 821 "!cat test.txt"
822 822 ]
823 823 },
824 824 {
825 825 "cell_type": "markdown",
826 826 "metadata": {},
827 827 "source": [
828 828 "Let's see what other magics are currently defined in the system:"
829 829 ]
830 830 },
831 831 {
832 832 "cell_type": "code",
833 833 "execution_count": 35,
834 834 "metadata": {
835 835 "collapsed": false
836 836 },
837 837 "outputs": [
838 838 {
839 839 "data": {
840 840 "application/json": {
841 841 "cell": {
842 842 "!": "OSMagics",
843 843 "HTML": "Other",
844 844 "SVG": "Other",
845 845 "bash": "Other",
846 846 "capture": "ExecutionMagics",
847 847 "debug": "ExecutionMagics",
848 848 "file": "Other",
849 849 "html": "DisplayMagics",
850 850 "javascript": "DisplayMagics",
851 851 "latex": "DisplayMagics",
852 852 "perl": "Other",
853 853 "prun": "ExecutionMagics",
854 854 "pypy": "Other",
855 855 "python": "Other",
856 856 "python2": "Other",
857 857 "python3": "Other",
858 858 "ruby": "Other",
859 859 "script": "ScriptMagics",
860 860 "sh": "Other",
861 861 "svg": "DisplayMagics",
862 862 "sx": "OSMagics",
863 863 "system": "OSMagics",
864 864 "time": "ExecutionMagics",
865 865 "timeit": "ExecutionMagics",
866 866 "writefile": "OSMagics"
867 867 },
868 868 "line": {
869 869 "alias": "OSMagics",
870 870 "alias_magic": "BasicMagics",
871 871 "autocall": "AutoMagics",
872 872 "automagic": "AutoMagics",
873 873 "autosave": "KernelMagics",
874 874 "bookmark": "OSMagics",
875 875 "cat": "Other",
876 876 "cd": "OSMagics",
877 877 "cl": "Other",
878 878 "clear": "KernelMagics",
879 879 "clk": "Other",
880 880 "colors": "BasicMagics",
881 881 "config": "ConfigMagics",
882 882 "connect_info": "KernelMagics",
883 883 "cp": "Other",
884 884 "d": "Other",
885 885 "dd": "Other",
886 886 "debug": "ExecutionMagics",
887 887 "dhist": "OSMagics",
888 888 "dirs": "OSMagics",
889 889 "dl": "Other",
890 890 "doctest_mode": "KernelMagics",
891 891 "dx": "Other",
892 892 "ed": "Other",
893 893 "edit": "KernelMagics",
894 894 "env": "OSMagics",
895 895 "gui": "BasicMagics",
896 896 "hist": "Other",
897 897 "history": "HistoryMagics",
898 898 "install_default_config": "DeprecatedMagics",
899 899 "install_ext": "ExtensionMagics",
900 900 "install_profiles": "DeprecatedMagics",
901 901 "killbgscripts": "ScriptMagics",
902 902 "ldir": "Other",
903 903 "less": "KernelMagics",
904 904 "lf": "Other",
905 905 "lk": "Other",
906 906 "ll": "Other",
907 907 "load": "CodeMagics",
908 908 "load_ext": "ExtensionMagics",
909 909 "loadpy": "CodeMagics",
910 910 "logoff": "LoggingMagics",
911 911 "logon": "LoggingMagics",
912 912 "logstart": "LoggingMagics",
913 913 "logstate": "LoggingMagics",
914 914 "logstop": "LoggingMagics",
915 915 "ls": "Other",
916 916 "lsmagic": "BasicMagics",
917 917 "lx": "Other",
918 918 "macro": "ExecutionMagics",
919 919 "magic": "BasicMagics",
920 920 "man": "KernelMagics",
921 921 "matplotlib": "PylabMagics",
922 922 "mkdir": "Other",
923 923 "more": "KernelMagics",
924 924 "mv": "Other",
925 925 "notebook": "BasicMagics",
926 926 "page": "BasicMagics",
927 927 "pastebin": "CodeMagics",
928 928 "pdb": "ExecutionMagics",
929 929 "pdef": "NamespaceMagics",
930 930 "pdoc": "NamespaceMagics",
931 931 "pfile": "NamespaceMagics",
932 932 "pinfo": "NamespaceMagics",
933 933 "pinfo2": "NamespaceMagics",
934 934 "popd": "OSMagics",
935 935 "pprint": "BasicMagics",
936 936 "precision": "BasicMagics",
937 937 "profile": "BasicMagics",
938 938 "prun": "ExecutionMagics",
939 939 "psearch": "NamespaceMagics",
940 940 "psource": "NamespaceMagics",
941 941 "pushd": "OSMagics",
942 942 "pwd": "OSMagics",
943 943 "pycat": "OSMagics",
944 944 "pylab": "PylabMagics",
945 945 "qtconsole": "KernelMagics",
946 946 "quickref": "BasicMagics",
947 947 "recall": "HistoryMagics",
948 948 "rehashx": "OSMagics",
949 949 "reload_ext": "ExtensionMagics",
950 950 "rep": "Other",
951 951 "rerun": "HistoryMagics",
952 952 "reset": "NamespaceMagics",
953 953 "reset_selective": "NamespaceMagics",
954 954 "rm": "Other",
955 955 "rmdir": "Other",
956 956 "run": "ExecutionMagics",
957 957 "save": "CodeMagics",
958 958 "sc": "OSMagics",
959 959 "store": "StoreMagics",
960 960 "sx": "OSMagics",
961 961 "system": "OSMagics",
962 962 "tb": "ExecutionMagics",
963 963 "time": "ExecutionMagics",
964 964 "timeit": "ExecutionMagics",
965 965 "unalias": "OSMagics",
966 966 "unload_ext": "ExtensionMagics",
967 967 "who": "NamespaceMagics",
968 968 "who_ls": "NamespaceMagics",
969 969 "whos": "NamespaceMagics",
970 970 "xdel": "NamespaceMagics",
971 971 "xmode": "BasicMagics"
972 972 }
973 973 },
974 974 "text/plain": [
975 975 "Available line magics:\n",
976 976 "%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",
977 977 "\n",
978 978 "Available cell magics:\n",
979 979 "%%! %%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",
980 980 "\n",
981 981 "Automagic is ON, % prefix IS NOT needed for line magics."
982 982 ]
983 983 },
984 984 "execution_count": 35,
985 985 "metadata": {},
986 986 "output_type": "execute_result"
987 987 }
988 988 ],
989 989 "source": [
990 990 "%lsmagic"
991 991 ]
992 992 },
993 993 {
994 994 "cell_type": "markdown",
995 995 "metadata": {},
996 996 "source": [
997 997 "## Running normal Python code: execution and errors"
998 998 ]
999 999 },
1000 1000 {
1001 1001 "cell_type": "markdown",
1002 1002 "metadata": {},
1003 1003 "source": [
1004 1004 "Not only can you input normal Python code, you can even paste straight from a Python or IPython shell session:"
1005 1005 ]
1006 1006 },
1007 1007 {
1008 1008 "cell_type": "code",
1009 1009 "execution_count": 36,
1010 1010 "metadata": {
1011 1011 "collapsed": false
1012 1012 },
1013 1013 "outputs": [
1014 1014 {
1015 1015 "name": "stdout",
1016 1016 "output_type": "stream",
1017 1017 "text": [
1018 1018 "1\n",
1019 1019 "1\n",
1020 1020 "2\n",
1021 1021 "3\n",
1022 1022 "5\n",
1023 1023 "8\n"
1024 1024 ]
1025 1025 }
1026 1026 ],
1027 1027 "source": [
1028 1028 ">>> # Fibonacci series:\n",
1029 1029 "... # the sum of two elements defines the next\n",
1030 1030 "... a, b = 0, 1\n",
1031 1031 ">>> while b < 10:\n",
1032 1032 "... print b\n",
1033 1033 "... a, b = b, a+b"
1034 1034 ]
1035 1035 },
1036 1036 {
1037 1037 "cell_type": "code",
1038 1038 "execution_count": 37,
1039 1039 "metadata": {
1040 1040 "collapsed": false
1041 1041 },
1042 1042 "outputs": [
1043 1043 {
1044 1044 "name": "stdout",
1045 1045 "output_type": "stream",
1046 1046 "text": [
1047 1047 "0 1 2 3 4 5 6 7 8 9\n"
1048 1048 ]
1049 1049 }
1050 1050 ],
1051 1051 "source": [
1052 1052 "In [1]: for i in range(10):\n",
1053 1053 " ...: print i,\n",
1054 1054 " ...: "
1055 1055 ]
1056 1056 },
1057 1057 {
1058 1058 "cell_type": "markdown",
1059 1059 "metadata": {},
1060 1060 "source": [
1061 1061 "And when your code produces errors, you can control how they are displayed with the `%xmode` magic:"
1062 1062 ]
1063 1063 },
1064 1064 {
1065 1065 "cell_type": "code",
1066 1066 "execution_count": 38,
1067 1067 "metadata": {
1068 1068 "collapsed": false
1069 1069 },
1070 1070 "outputs": [
1071 1071 {
1072 1072 "name": "stdout",
1073 1073 "output_type": "stream",
1074 1074 "text": [
1075 1075 "Writing mod.py\n"
1076 1076 ]
1077 1077 }
1078 1078 ],
1079 1079 "source": [
1080 1080 "%%writefile mod.py\n",
1081 1081 "\n",
1082 1082 "def f(x):\n",
1083 1083 " return 1.0/(x-1)\n",
1084 1084 "\n",
1085 1085 "def g(y):\n",
1086 1086 " return f(y+1)"
1087 1087 ]
1088 1088 },
1089 1089 {
1090 1090 "cell_type": "markdown",
1091 1091 "metadata": {},
1092 1092 "source": [
1093 1093 "Now let's call the function `g` with an argument that would produce an error:"
1094 1094 ]
1095 1095 },
1096 1096 {
1097 1097 "cell_type": "code",
1098 1098 "execution_count": 39,
1099 1099 "metadata": {
1100 1100 "collapsed": false
1101 1101 },
1102 1102 "outputs": [
1103 1103 {
1104 1104 "ename": "ZeroDivisionError",
1105 1105 "evalue": "float division by zero",
1106 1106 "output_type": "error",
1107 1107 "traceback": [
1108 1108 "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mZeroDivisionError\u001b[0m Traceback (most recent call last)",
1109 1109 "\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",
1110 1110 "\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",
1111 1111 "\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",
1112 1112 "\u001b[1;31mZeroDivisionError\u001b[0m: float division by zero"
1113 1113 ]
1114 1114 }
1115 1115 ],
1116 1116 "source": [
1117 1117 "import mod\n",
1118 1118 "mod.g(0)"
1119 1119 ]
1120 1120 },
1121 1121 {
1122 1122 "cell_type": "code",
1123 1123 "execution_count": 40,
1124 1124 "metadata": {
1125 1125 "collapsed": false
1126 1126 },
1127 1127 "outputs": [
1128 1128 {
1129 1129 "name": "stdout",
1130 1130 "output_type": "stream",
1131 1131 "text": [
1132 1132 "Exception reporting mode: Plain\n"
1133 1133 ]
1134 1134 },
1135 1135 {
1136 1136 "ename": "ZeroDivisionError",
1137 1137 "evalue": "float division by zero",
1138 1138 "output_type": "error",
1139 1139 "traceback": [
1140 1140 "Traceback \u001b[1;36m(most recent call last)\u001b[0m:\n",
1141 1141 " 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",
1142 1142 " 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",
1143 1143 "\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",
1144 1144 "\u001b[1;31mZeroDivisionError\u001b[0m\u001b[1;31m:\u001b[0m float division by zero\n"
1145 1145 ]
1146 1146 }
1147 1147 ],
1148 1148 "source": [
1149 1149 "%xmode plain\n",
1150 1150 "mod.g(0)"
1151 1151 ]
1152 1152 },
1153 1153 {
1154 1154 "cell_type": "code",
1155 1155 "execution_count": 41,
1156 1156 "metadata": {
1157 1157 "collapsed": false
1158 1158 },
1159 1159 "outputs": [
1160 1160 {
1161 1161 "name": "stdout",
1162 1162 "output_type": "stream",
1163 1163 "text": [
1164 1164 "Exception reporting mode: Verbose\n"
1165 1165 ]
1166 1166 },
1167 1167 {
1168 1168 "ename": "ZeroDivisionError",
1169 1169 "evalue": "float division by zero",
1170 1170 "output_type": "error",
1171 1171 "traceback": [
1172 1172 "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mZeroDivisionError\u001b[0m Traceback (most recent call last)",
1173 1173 "\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",
1174 1174 "\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",
1175 1175 "\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",
1176 1176 "\u001b[1;31mZeroDivisionError\u001b[0m: float division by zero"
1177 1177 ]
1178 1178 }
1179 1179 ],
1180 1180 "source": [
1181 1181 "%xmode verbose\n",
1182 1182 "mod.g(0)"
1183 1183 ]
1184 1184 },
1185 1185 {
1186 1186 "cell_type": "markdown",
1187 1187 "metadata": {},
1188 1188 "source": [
1189 1189 "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."
1190 1190 ]
1191 1191 },
1192 1192 {
1193 1193 "cell_type": "code",
1194 1194 "execution_count": 42,
1195 1195 "metadata": {
1196 1196 "collapsed": false
1197 1197 },
1198 1198 "outputs": [
1199 1199 {
1200 1200 "name": "stdout",
1201 1201 "output_type": "stream",
1202 1202 "text": [
1203 1203 "Exception reporting mode: Context\n"
1204 1204 ]
1205 1205 }
1206 1206 ],
1207 1207 "source": [
1208 1208 "%xmode context"
1209 1209 ]
1210 1210 },
1211 1211 {
1212 1212 "cell_type": "markdown",
1213 1213 "metadata": {},
1214 1214 "source": [
1215 1215 "## Running code in other languages with special `%%` magics"
1216 1216 ]
1217 1217 },
1218 1218 {
1219 1219 "cell_type": "code",
1220 1220 "execution_count": 43,
1221 1221 "metadata": {
1222 1222 "collapsed": false
1223 1223 },
1224 1224 "outputs": [
1225 1225 {
1226 1226 "name": "stdout",
1227 1227 "output_type": "stream",
1228 1228 "text": [
1229 1229 "July"
1230 1230 ]
1231 1231 }
1232 1232 ],
1233 1233 "source": [
1234 1234 "%%perl\n",
1235 1235 "@months = (\"July\", \"August\", \"September\");\n",
1236 1236 "print $months[0];"
1237 1237 ]
1238 1238 },
1239 1239 {
1240 1240 "cell_type": "code",
1241 1241 "execution_count": 44,
1242 1242 "metadata": {
1243 1243 "collapsed": false
1244 1244 },
1245 1245 "outputs": [
1246 1246 {
1247 1247 "name": "stdout",
1248 1248 "output_type": "stream",
1249 1249 "text": [
1250 1250 "Hello World!\n"
1251 1251 ]
1252 1252 }
1253 1253 ],
1254 1254 "source": [
1255 1255 "%%ruby\n",
1256 1256 "name = \"world\"\n",
1257 1257 "puts \"Hello #{name.capitalize}!\""
1258 1258 ]
1259 1259 },
1260 1260 {
1261 1261 "cell_type": "markdown",
1262 1262 "metadata": {},
1263 1263 "source": [
1264 1264 "### Exercise"
1265 1265 ]
1266 1266 },
1267 1267 {
1268 1268 "cell_type": "markdown",
1269 1269 "metadata": {},
1270 1270 "source": [
1271 1271 "Write a cell that executes in Bash and prints your current working directory as well as the date.\n",
1272 1272 "\n",
1273 1273 "Apologies to Windows users who may not have Bash available, not sure how to obtain the equivalent result with `cmd.exe` or Powershell."
1274 1274 ]
1275 1275 },
1276 1276 {
1277 1277 "cell_type": "code",
1278 1278 "execution_count": null,
1279 1279 "metadata": {
1280 1280 "collapsed": false
1281 1281 },
1282 1282 "outputs": [],
1283 1283 "source": [
1284 1284 "%load soln/bash-script"
1285 1285 ]
1286 1286 },
1287 1287 {
1288 1288 "cell_type": "markdown",
1289 1289 "metadata": {},
1290 1290 "source": [
1291 1291 "## Raw Input in the notebook"
1292 1292 ]
1293 1293 },
1294 1294 {
1295 1295 "cell_type": "markdown",
1296 1296 "metadata": {},
1297 1297 "source": [
1298 1298 "Since 1.0 the IPython notebook web application support `raw_input` which for example allow us to invoke the `%debug` magic in the notebook:"
1299 1299 ]
1300 1300 },
1301 1301 {
1302 1302 "cell_type": "code",
1303 1303 "execution_count": 45,
1304 1304 "metadata": {
1305 1305 "collapsed": false
1306 1306 },
1307 1307 "outputs": [
1308 1308 {
1309 1309 "ename": "ZeroDivisionError",
1310 1310 "evalue": "float division by zero",
1311 1311 "output_type": "error",
1312 1312 "traceback": [
1313 1313 "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mZeroDivisionError\u001b[0m Traceback (most recent call last)",
1314 1314 "\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",
1315 1315 "\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",
1316 1316 "\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",
1317 1317 "\u001b[1;31mZeroDivisionError\u001b[0m: float division by zero"
1318 1318 ]
1319 1319 }
1320 1320 ],
1321 1321 "source": [
1322 1322 "mod.g(0)"
1323 1323 ]
1324 1324 },
1325 1325 {
1326 1326 "cell_type": "code",
1327 1327 "execution_count": 38,
1328 1328 "metadata": {
1329 1329 "collapsed": false
1330 1330 },
1331 1331 "outputs": [
1332 1332 {
1333 1333 "name": "stdout",
1334 1334 "output_type": "stream",
1335 1335 "text": [
1336 1336 "> \u001b[0;32m/Users/bussonniermatthias/ipython-in-depth/notebooks/mod.py\u001b[0m(3)\u001b[0;36mf\u001b[0;34m()\u001b[0m\n",
1337 1337 "\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",
1338 1338 "\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",
1339 1339 "\u001b[0m\u001b[0;32m 4 \u001b[0;31m\u001b[0;34m\u001b[0m\u001b[0m\n",
1340 1340 "\u001b[0m\n",
1341 1341 "ipdb> x\n",
1342 1342 "1\n",
1343 1343 "ipdb> up\n",
1344 1344 "> \u001b[0;32m/Users/bussonniermatthias/ipython-in-depth/notebooks/mod.py\u001b[0m(6)\u001b[0;36mg\u001b[0;34m()\u001b[0m\n",
1345 1345 "\u001b[0;32m 4 \u001b[0;31m\u001b[0;34m\u001b[0m\u001b[0m\n",
1346 1346 "\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",
1347 1347 "\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",
1348 1348 "\u001b[0m\n",
1349 1349 "ipdb> y\n",
1350 1350 "0\n",
1351 1351 "ipdb> up\n",
1352 1352 "> \u001b[0;32m<ipython-input-37-5e708f13c839>\u001b[0m(1)\u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n",
1353 1353 "\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",
1354 1354 "\u001b[0m\n",
1355 1355 "ipdb> exit\n"
1356 1356 ]
1357 1357 }
1358 1358 ],
1359 1359 "source": [
1360 1360 "%debug"
1361 1361 ]
1362 1362 },
1363 1363 {
1364 1364 "cell_type": "markdown",
1365 1365 "metadata": {},
1366 1366 "source": [
1367 1367 "Don't foget to exit your debugging session. Raw input can of course be use to ask for user input:"
1368 1368 ]
1369 1369 },
1370 1370 {
1371 1371 "cell_type": "code",
1372 1372 "execution_count": 39,
1373 1373 "metadata": {
1374 1374 "collapsed": false
1375 1375 },
1376 1376 "outputs": [
1377 1377 {
1378 1378 "name": "stdout",
1379 1379 "output_type": "stream",
1380 1380 "text": [
1381 1381 "Are you enjoying this tutorial ?Yes !\n",
1382 1382 "enjoy is : Yes !\n"
1383 1383 ]
1384 1384 }
1385 1385 ],
1386 1386 "source": [
1387 1387 "enjoy = raw_input('Are you enjoying this tutorial ?')\n",
1388 1388 "print 'enjoy is :', enjoy"
1389 1389 ]
1390 1390 },
1391 1391 {
1392 1392 "cell_type": "markdown",
1393 1393 "metadata": {},
1394 1394 "source": [
1395 1395 "## Plotting in the notebook"
1396 1396 ]
1397 1397 },
1398 1398 {
1399 1399 "cell_type": "markdown",
1400 1400 "metadata": {},
1401 1401 "source": [
1402 1402 "This magic configures matplotlib to render its figures inline:"
1403 1403 ]
1404 1404 },
1405 1405 {
1406 1406 "cell_type": "code",
1407 1407 "execution_count": 46,
1408 1408 "metadata": {
1409 1409 "collapsed": false
1410 1410 },
1411 1411 "outputs": [],
1412 1412 "source": [
1413 1413 "%matplotlib inline"
1414 1414 ]
1415 1415 },
1416 1416 {
1417 1417 "cell_type": "code",
1418 1418 "execution_count": 47,
1419 1419 "metadata": {
1420 1420 "collapsed": false
1421 1421 },
1422 1422 "outputs": [],
1423 1423 "source": [
1424 1424 "import numpy as np\n",
1425 1425 "import matplotlib.pyplot as plt"
1426 1426 ]
1427 1427 },
1428 1428 {
1429 1429 "cell_type": "code",
1430 1430 "execution_count": 48,
1431 1431 "metadata": {
1432 1432 "collapsed": false
1433 1433 },
1434 1434 "outputs": [
1435 1435 {
1436 1436 "data": {
1437 1437 "image/png": [
1438 1438 "iVBORw0KGgoAAAANSUhEUgAAAXoAAAEKCAYAAAAcgp5RAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\n",
1439 1439 "AAALEgAACxIB0t1+/AAAIABJREFUeJztnXt4VdWZ/78nJBDCJRBCEkgCIQmXgNwsmCkaDQpSQPF+\n",
1440 1440 "QQtUcEpVtNP2acfO/KZFn9Zi1c5MSzti6wXqCIhWwQoolIkgFFMFQQUhIIHcSCAQCJCQ5Jz9+2O5\n",
1441 1441 "ITk5l31Za+2193k/z5NHQvY5exmS7/me7/uud/k0TdNAEARBeJY4pxdAEARBiIWEniAIwuOQ0BME\n",
1442 1442 "QXgcEnqCIAiPQ0JPEAThcUjoCYIgPA4JPeEJiouL8eKLLwIA/vd//xfTpk0z9fjFixdjzpw5XNf0\n",
1443 1443 "yiuvoKioKOzXZ8yYgT//+c9c70kQoSChJ5SmuLgYKSkpaGlpiXidz+eDz+cDANx///147733Ln0t\n",
1444 1444 "Li4OX3311aXPS0pKkJ2d3enxslm/fj33FxeCCAUJPaEs5eXlKC0tRVpaGtatW2fruaLtC1Rt36Df\n",
1445 1445 "73d6CYSHIKEnlGXFihWYMmUK5syZg+XLlxt+XPvI5NprrwUAjB07Fr1798aKFSswY8YMVFdXo1ev\n",
1446 1446 "Xujduzdqamo6PcfOnTsxadIk9O3bF+PGjcMHH3wQ9n4VFRW4/fbbkZaWhtTUVDz66KMdvv7jH/8Y\n",
1447 1447 "KSkpyM3NxcaNGy/9ffu46ZVXXsHVV1+NH/7wh0hNTcXixYuxfPlyXH311Xj00UfRp08fFBQUYMuW\n",
1448 1448 "LYa/DwShQ0JPKMuKFStwzz334O6778Z7772Huro608+xdetWAMDevXtx9uxZzJ07Fxs2bMDAgQPR\n",
1449 1449 "2NiIs2fPYsCAAR0eU1VVhZtuugk/+9nPcPr0aTz77LO44447cPLkyU7P7/f7cdNNN2HIkCE4evQo\n",
1450 1450 "qqqqMHv27Etf/+ijjzBixAjU19fjJz/5CRYsWHDpa+3jJgAoLS1FXl4e6urq8O///u/QNA2lpaXI\n",
1451 1451 "z89HfX09nnjiCdx+++04ffq06e8DEduQ0BNK8uGHH6KqqgqzZs3C0KFDMXLkSLz22mtcnjtaTPPq\n",
1452 1452 "q69ixowZ+Na3vgUAmDJlCiZMmID169d3ura0tBQ1NTV45pln0L17d3Tr1g2TJk269PXBgwdjwYIF\n",
1453 1453 "8Pl8mDt3LmpqasK+YA0cOBCPPPII4uLikJiYCABIS0vD97//fXTp0gV33303hg8fjnfffdfq/zoR\n",
1454 1454 "o5DQE0qyfPly3HjjjejVqxcA4K677jIV39jh6NGjWLNmDfr27XvpY/v27Th+/HinaysqKjB48GDE\n",
1455 1455 "xYX+VcrIyLj056SkJADAuXPnQl4bXCAGgMzMzA6fDx48GNXV1Yb/XwgCAOKdXgBBBNPU1ITXX38d\n",
1456 1456 "gUDgUqxy8eJFNDQ0YO/evRgzZoyt54/WYTNo0CDMmTMHL7zwQtTnys7OxrFjx+D3+9GlSxfu66qq\n",
1457 1457 "qurw+dGjR3HLLbfYug8Re5CjJ5Tj7bffRnx8PPbv3489e/Zgz5492L9/P4qKirBixQrTz5eeno7D\n",
1458 1458 "hw93+Ly+vh5nz54Nef23v/1tvPPOO3j//ffh9/vR3NyMkpKSTqILAIWFhRgwYAAef/xxXLhwAc3N\n",
1459 1459 "zdixY4fpNYajrq4Ov/3tb9Ha2oo1a9bgwIEDmDFjBrfnJ2IDEnpCOVasWIH58+cjKysLaWlpSEtL\n",
1460 1460 "Q3p6OhYtWoTXXnsNgUAg4uODi5yLFy/GvHnz0LdvX7zxxhsYMWIEZs+ejdzcXKSkpKCmpqbDY7Ky\n",
1461 1461 "srB27Vo89dRTSEtLw6BBg/Dcc8+FvG9cXBzeeecdHDp0CIMGDUJ2djZef/31kOvQ/87ImnUKCwtR\n",
1462 1462 "VlaG/v374z/+4z/wxhtvoG/fvpG/gQQRhM/uwSPz58/Hu+++i7S0NHz22Wchr3nsscewYcMGJCUl\n",
1463 1463 "4ZVXXsH48ePt3JIgYoJXXnkFL774IrZt2+b0UgiXY9vRP/DAAx16g4NZv349Dh06hLKyMrzwwgt4\n",
1464 1464 "6KGH7N6SIAiCMIFtoS8qKor4VnLdunWYN28eAPY2tKGhAbW1tXZvSxCeJ1ycQxBmEZ7RV1VVdWgb\n",
1465 1465 "y8rKQmVlpejbEoTrmTdv3qUNXwRhBynF2OAyALkUgiAIeQjvo8/MzERFRcWlzysrKzttAgGA/Pz8\n",
1466 1466 "Di1wBEEQRHTy8vJw6NChiNcId/SzZs261Pu8c+dO9OnTB+np6Z2uO3z4MDRNc+3Hz3/+85B/7/dr\n",
1467 1467 "uP9+DVOmaDhzpuPXWls1zJ2rYcYMdp1qa3fq4803NRQVaQgENLz7roaRI9mfVV//8eMakpM1tLRo\n",
1468 1468 "GDZMQ2mp89//Bx/U8MtfarjmGg1vvSX35+fZZzXcc4+Gvn01VFaK//5Pm6bh5ps13H03n/WH+35m\n",
1469 1469 "ZGj40Y/k/VxF+zBikG0L/ezZszFp0iQcOHAA2dnZeOmll7Bs2TIsW7YMADtcITc3F/n5+Vi4cCH+\n",
1470 1470 "8Ic/2L2lq3jySeCrr4B164DevTt+LT4e+NOfgDNngGefdWZ9KvLqq8B3vgP4fMD06UBjI7B/v9Or\n",
1471 1471 "is7//R9w3XVAQgIweTLAcd+UZXbsAGbOBK69FtizR+69P/4YuOkmdv933hF7L00Ddu8G5swBjhwR\n",
1472 1472 "d589e4D//E9g6FBx9xCB7ehm5cqVUa9ZunSp3du4kg8+AJYtA3btArp3D31NQgLw5z8DEycC994L\n",
1473 1473 "DBokd42q0dAA/O1vwMsvs899PiYW77wDjBzp7NqisWULcMMN7M9XX83W/P3vO7ee1lZmMoYPB664\n",
1474 1474 "AvjLX+Te/9AhID8fqKsT/0JdUwMEAkBREfDww2Lu0dYGfPEFe+H6egSTa6CdsZwoLi7u8HlLC/Dd\n",
1475 1475 "7wLPPw8ETcHtxJAhwKJFwL/9m7j1RSJ47U6ybRtw1VVAcvLlv7v55siOUJX1l5QwJw8AkyYB27cz\n",
1476 1476 "pxkNUesvKwOys4HERCb0n38u5DZh13/4MBP6wYOBo0fF3Ftn925g/HggPR24cIG9CzSK0e9/WRn7\n",
1477 1477 "XXabyAMk9NwI/mH5r/9ib++Mzp/64Q+B995jP0yyUUUoASb0wcesFhezd0XNzaEfo8L6m5qAY8eA\n",
1478 1478 "ggL2eW4uc4BGOolFrX/fvsvvgoYPB8rLw38P7RBq/adOAX4/0K+fHKE/eJB9730+ZpzMxDdGv/8H\n",
1479 1479 "DwIjRlhbn9OQ0Augqgr49a+Z2Buld2/gkUeAZ54Rty43EErou3cHhg0D9u51Zk1GKCsD8vJY3QVg\n",
1480 1480 "glNQwMTBKb74Ahg1iv25a1f24nPggJx7627e55Mj9LW1gD4ROjeXRVa8OXkSSEvj/7wyIKEXwM9+\n",
1481 1481 "xmKb/Hxzj/ve94A1a1hxNha5cAH47DOgsLDz1yZOBP7xD/lrMsqXX3Z2e/n5LKd2ivaOHmDr+/JL\n",
1482 1482 "Ofc+dIi98AFAaipw8aK5OMUstbWXRVik0Kem8n9eGZDQc6a8HHj7beDHPzb/2IwMYNo0wMIkXk+w\n",
1483 1483 "Zw8To6/P5+jAhAmsi0NVVBT6o0dZjKGTlcXebcpAd/SAHFdfW8vyecB8dGOUEydI6ImvWbIEWLgQ\n",
1484 1484 "sDpJdsGC2BX6vXuBsWNDf82Njn7oUGeFvqoKaL83MTMTkHU4VWUle2HRkSn0GRms04c3J08C/fvz\n",
1485 1485 "f14ZkNBzpLISeP114Ac/sP4ckyez53Ey23WKPXuAcIdHjRrFRLO1Ve6ajHLggFqOPhBg4te+4ysz\n",
1486 1486 "U56jr6u7LLyAXKHv1w+or+d/D4puCADAb34DPPCAvVf9+HjgnnsAA9sTPMeePeEdfbdurFVQ1SkZ\n",
1487 1487 "7TNpnbw8tt4o56QIoa4O6NOHFWF1Bg6U5+hPnOj4ezBwIBDiyF0uaBr7/9Uz+pQUMUIf/P/kJkjo\n",
1488 1488 "OXHuHLB8OfDYY/af6847gbfesv88biIQYIXYSMfByiwmmuHsWdZKGBzX9ezJ9gPU1MhfU3BsA8h3\n",
1489 1489 "9O07VFJTmSMWQUMD68xKTGSfk6PvDAk9J/78Z9bvPXiw/ef65jeZ8xK5lVs1jh1jLaYpKeGvUVXo\n",
1490 1490 "KyrYu41QQ1mzs9nXZVNdzVx0e3RHb2QTl11OnOgo9P36iRP69rGNfi8S+o6Q0HNA04Df/Q549FE+\n",
1491 1491 "z9elC9sNum4dn+dzA6GKmcGoLvShkFkAbU8oR9+zJxu50dAg9t4tLayVsk+fy38n0tEHC32PHmyz\n",
1492 1492 "Gs/NYRcvsk1x7XdsuwkSeg787W9MnK+7jt9zzpjBdsrGCgcPsk1RkXCj0A8cKC8uaU8oodfXI/qF\n",
1493 1493 "R3e+ce3UJTVVjMsGOgu9z8feGZ46xe8e9fXsnYJbj9IgoefA88+zXa08fwgmTwY+/JC5o1jg4EG2\n",
1494 1494 "TT8Sw4fL29lphmPH1HP0oaIbfT2iX3hCFS1FRjfh7sfzhcXNsQ1AQm+bkyeBzZuB2bP5Pm9KCuvD\n",
1495 1495 "Li3l+7yqYsTR9+vH3pKLjh7MoqKjDyf06enMAYskuBALXBZ6EfWBhobOhXAS+o6Q0NvktddYni4i\n",
1496 1496 "u7v+ejb6NhYwIvT6wKrycilLMoyKGX24zT0iIxSd4EIswLpiEhKA8+f536+hofPvH2+hD/Vi4iZI\n",
1497 1497 "6G3y0kusd14EN9zA8n+v09TEeqyNdCzl5KjXjaSiow/nQEV1pLSnri70i4yo+ObMmY6FX/1ePP8/\n",
1498 1498 "z55153hiHRJ6G+zezX7IRE3JLSoCPvlEjAtSia++YiIfb+AYHBUdfbiYBJDbu96ecEIvsvtFJ5zQ\n",
1499 1499 "i7r3mTOdHT3vYmxjY+cT4twECb0NXnqJHXkXJ+i72KMHcOWVrCjrZY4eZU7dCKo5+nPn2GapcCKQ\n",
1500 1500 "nMzqCiInNwbT3MzaAUM5UBmO/tQpdp9gRMVGDQ1yHD0JfQzS3MzGFMybJ/Y+sZDTHz1qfKOZqMmE\n",
1501 1501 "VtHnoIfruPL5mNuXuTu2vp6Jaqg1yXD04fJskdGNaEdP0U2Msm4dm8ti1Ila5eqrgb//Xew9nObo\n",
1502 1502 "UeNn5ebkqBXdBPdwhyItTcw0xXBE6hCR4ehDOWxA3ItMqPslJzNx5gVFNzHKq6+Kd/MAG8+7axd7\n",
1503 1503 "++9Vjh0z7uhVE/rjxy+fbBSO/v1ZJ4osIgm9LEcfSuh5u2ydUI6+Vy++Qk+OPgZpaAA++AC49Vbx\n",
1504 1504 "9+rTh3V0iDrYWQXMRDfJyawXm+cvsR2OH4/u6FUSet3Ri5x3E07oe/cW8+8W6n69e/Oti1BGH4O8\n",
1505 1505 "/TbLzmX9wxcWAh99JOdeTmBG6H0+dqCFkUO3ZdD+rNJwqBTddO/OmgcuXBB3/3BCn5zM/5jMixfZ\n",
1506 1506 "u93u3Tv+PW9HT9FNDLJ6NZsZLwsvC31LCxPBUHNZwqGS0LvN0QPi4xuZQq/30AcXnkU4eopuYoj6\n",
1507 1507 "emDHDuCmm+Td08tCX1nJTkEy0kOvI/Ps02gYcfSqCb3IgmxTE/uvPhu+PaKEPtSudHL0HSGhN8lf\n",
1508 1508 "/sIO8O7ZU949R49m8YYquTRPzHTc6GRmusvRqxTdAOIPAQnl5gH+nTBA6F2xABP6xkZ+tQhy9DGG\n",
1509 1509 "7NgGYDNCxo1T+3Bsq5jpuNFRKbox0l7phKMPtWFJR9RRe0Bkoe/dm7+jDzXnBmC/MwkJl99h2IWK\n",
1510 1510 "sTFEbS3w8cdsVrxsvBrfmCnE6qgk9KEGeAUjW+ijDeDq04e/4La/dyRHLyqjDwWvLp+2Nlb0TUqy\n",
1511 1511 "/1xOQUJvgjfeAGbO7Fzhl8GECWzujdewKvQqZPQXL7JicrS39LrQyzjCDwBOnw4vfoC3hD6cowf4\n",
1512 1512 "FWQbG9m/sVsPHQFI6E3hRGyjM24csGePM/cWiRWhVyWjr69nMUg0AejWjblBWXP0jTh6UWuJJPTd\n",
1513 1513 "uzN3zPMwnUiRCq+CrNsLsQAJvWGqqtimpWnTnLn/0KFsXorM4VgysCL0qanMGba2ilmTUfTj5Ywg\n",
1514 1514 "K77RtMhiCzgn9D4f/4LsuXPh31HxcvRuL8QCJPSGWbMGuOUW5s6cID4eGDkS+OwzZ+4vgkAg8iz3\n",
1515 1515 "cMTFMbGX2ckSCjNC36+fmO3/wZw7x1obExLCX5Oc7IzQA/wLsufOhe+A4+Xo3V6IBUjoDeNkbKMz\n",
1516 1516 "dqy34pu6OvbL2KOH+cdmZIg/Ei8aZoRe1JyXYKLl84Bzjh7gn9NHEnpexVg9o3czJPQGOHoUOHSI\n",
1517 1517 "nfjkJF4T+spKVli1goyzT6OhotAbOfJOZDE23AYmHd5CH0mE9V56u0R6MXELJPQGeP114LbbIr8d\n",
1518 1518 "lsHYscCnnzq7Bp5UV5sbfdAeNwq96PHAgPOOPpr7daOjP3/e3a2VAAm9IVSIbQBgzBhWEPb7nV4J\n",
1519 1519 "H2pq2PgDK6Sns12pTqJiRm/E0YvM6KMVLkUUYyNl9Dwc/YUL1uJFlSChj8KhQyxiuO46p1fCnFhq\n",
1520 1520 "KnD4sNMr4UOks1ajQRl9aFRw9JEKlyKiGxmOnoTe47z+OnDHHeaGbonESzm9HaF3Y3Qjy9FHE/qk\n",
1521 1521 "JNaaevEi//tHi25EdN1EyuhJ6Bkk9FFQJbbR8ZLQ241uSOg7YyS68fnEFWSjRTe9ejFx5kWk6KZH\n",
1522 1522 "DybSdiGh9zhffskGRF1zjdMruczo0d45bcquo3dTRq9SdAOIGUcARI9uevbkK/SRohueQk/FWA+z\n",
1523 1523 "ejVw111sg44qjBwJ7N/v9Cr4EEvRjUrFWEBcTh8tuuFVINWR4eipGOthNE292AZgoxCOHhWTr8qk\n",
1524 1524 "rY0JZbTJj+Ho18/ZMQiBAHPPKSnGrlfN0YsQ+rY2oLk5sijydPStreyeoQ45ASi6aQ8JfRg+/5z9\n",
1525 1525 "A//TPzm9ko507Qrk5ABlZU6vxB61tayDyGqRu0sX9niZ43/bc+YM++U3urdCz8RFt8ZG27CkI6LF\n",
1526 1526 "8tw59j2JNOStZ09+jv78efZ84e5HQn8ZEvowrF4N3H23mqNJCwrcH9/YKcTqOJnT19dHPsUpmC5d\n",
1527 1527 "WGwhakeqjtHt+rzPVNXvHW0mDM9ibKR8HmBfo4yeQUIfAk0DVq1SL7bRKSgA9u1zehX2sJPP6ziZ\n",
1528 1528 "05vJ53VkxDdGhZ53Vm703jyjm2ijCSijvwwJfQh27WJi/41vOL2S0HihIBuLQi9yo5KO0dnpIoTe\n",
1529 1529 "yDhfntFNpB56gKKb9pDQh2D1auDee9WMbQCKbnSc3B1rVehViW5EOXqVopvERFawtVsXIaEHsHHj\n",
1530 1530 "RowYMQJDhw7F008/3enrJSUlSE5Oxvjx4zF+/Hj84he/sHtLoWga2w2ramwDACNGAAcPunvmTSw6\n",
1531 1531 "epEzZgBjXS86sRDd+HwsW7fr6r2Q0dva2O/3+7Fo0SJs3rwZmZmZmDhxImbNmoWCgoIO11133XVY\n",
1532 1532 "t26drYXK4qOP2JFno0c7vZLw9OjBRO7IESA/3+nVWIOX0Dt1jq6Kjt5I14uOU9GN7rLb2uyPFTEy\n",
1533 1533 "PliPb+wcHBLzGX1paSny8/ORk5ODhIQE3HvvvVi7dm2n6zRZpyJzQO+dVzW20Rk50t0FWV5dN+To\n",
1534 1534 "L2PmbFOnohufj5+rj5bRA/Zzek1jQu92R29L6KuqqpDd7hy4rKwsVFVVdbjG5/Nhx44dGDt2LGbM\n",
1535 1535 "mIF9CquT3385n1cdt+f0PBy9GzN60UJv9CQkp6IbgF9B9ty56AJsV+ibmtjxoV26WH8OFbD15sln\n",
1536 1536 "wPZeeeWVqKioQFJSEjZs2IBbb70VBw8eDHnt4sWLL/25uLgYxcXFdpZnmq1bmXiMGCH1tpYoKAA+\n",
1537 1537 "/NDpVVijrY21GVrdFavjRkd/5IiY9QDmDrEWFd0YeUfBy9EbiVTsCr2K+XxJSQlKSkpMPcaW0Gdm\n",
1538 1538 "ZqKiouLS5xUVFcgKOhuuV7ufvOnTp+Phhx/GqVOnkBJi73h7oXeC114DZs92dAmGGTYMePllp1dh\n",
1539 1539 "jdpaJpJ2M9qUFOaQ/X75joscfWfOnTN2YhivzhujQm/nXirm88Em+Iknnoj6GFvRzYQJE1BWVoby\n",
1540 1540 "8nK0tLRg9erVmDVrVodramtrL2X0paWl0DQtpMg7zcWLwF/+ona3TXuGDnXvGITjx9k7J7vExzPR\n",
1541 1541 "EN2bHgqrjl5kMVYFoTciiryiGyPZOQ9Hr5rQW8GWp4qPj8fSpUsxbdo0+P1+LFiwAAUFBVi2bBkA\n",
1542 1542 "YOHChXjjjTfwP//zP4iPj0dSUhJWrVrFZeG8ee89YNQoYNAgp1dijIwMlh8aOWhCNWprWezCg9RU\n",
1543 1543 "NkrarOjaxcxAMx0Zjt7JYqw+eyYabotuYl7oARbHTJ8+vcPfLVy48NKfH3nkETzyyCN2byOclSvd\n",
1544 1544 "E9sArHshP5+5+okTnV6NOUQI/fDhfJ7PCG1t7EXWiKi1RyVHr4utpvHrMDMqijzPcpXh6FXL6K1A\n",
1545 1545 "O2PBfuA3bGCz593EsGHujG9ECL1M9AmRZgVStKM3U4yNj2fdJBcu8Lu/meiGl6MXLfQqZvRWIKEH\n",
1546 1546 "sG4dMGmSuWmEKjB0KNsh6zbq6ux33Og4IfRW4zKVHD3AP74xGt3wLMbKEHpy9B7BbbGNjlsLsjwd\n",
1547 1547 "fb9+rDAqk4YGYzPfg0lOZq5b1P5BMxk9wO/wbB2j0U2PHnxeYIzEKnZHFTc1sZ3ybifmhb6+nvXP\n",
1548 1548 "33qr0ysxDwm9uxx9fDwbAcDzzNT2qODojQo9j8hIhqMnofcIb74JTJtm7hdEFfSM3kUTJgDErtAD\n",
1549 1549 "YnN6p4XeyOwZgO+ceBJ6Y8S80L/6KnDffU6vwhp6S6FsobOL2zP6M2esC73InN5MMRZw1tHLEvqk\n",
1550 1550 "JHvvHiij9wCHDwNffgnMmOH0Sqzh87kvvvH72fiD/v35PB85+ss46ehbWtiB6V27Rr/WrvjqGOmI\n",
1551 1551 "SUpirtwq5Og9wIoVrAhr5IdTVdwm9CdPMrGzO/5Ap18/dwm9SEdvpRjL86BuoyOSZTr67t3tvaiQ\n",
1552 1552 "0LucQABYvhz4znecXok9hg1zV4tlXR2/fB4gR98eJx290dZKgI/Qa5oxEbb77oGE3uVs3crcz7hx\n",
1553 1553 "Tq/EHvn5wKFDTq/COLW1/PJ5AOjbl2XTbW38njMaqjp6JzN6M6MCeAh9czPb8BUXRcF4ZPQk9C7m\n",
1554 1554 "lVeYm1f9gJFo5OaKHX3LG54dNwCbWtmnD5s9IwsVHb2mGTuIoz08hd7orliAT0ZvdDQBj4yeirEu\n",
1555 1555 "5dw54O23gfvvd3ol9snNBb76yulVGIe30APy4xsVHf2FC6zWZKb24eboxmg3DGX0jJgU+jffBIqK\n",
1556 1556 "+AuOE6SlsR9GkVvrecI7owecEXorO2MBcY7ebCEWcHd0Y1ToKaNnxKTQv/SS+4uwOj6fu+Ib3hk9\n",
1557 1557 "IL/zRkVHb7YQC7g7ujE6bIyEnhFzQr9vH+tSCTofxdW4Tei94OhVy+jNFmIB56IbPTcPBKzfz0x0\n",
1558 1558 "09xsffc4bZhyKS+8AMyfDyQkOL0SfgwZ4p6cXpTQyxps5vczUbM6MiM5WVx047TQG3X0cXFs5o+d\n",
1559 1559 "IqlRAY6LY7WL5mZr9/GKo+e0bcUdNDWxkQcff+z0SviSmwscOOD0KowhKqOXdUi4fgB2tLa+cPTp\n",
1560 1560 "Iy66cUtGD1zO6a3OejfjtPX4xopge0XoY8rRv/46cNVVQE6O0yvhi1s6bzSN75wbHZnRjd2jG73q\n",
1561 1561 "6I0ONNOROYPGToslCb0LWbYM+N73nF4Ff9wi9A0N7C17YiLf55VZjLUr9KIcvQoZvRVHb+d+Zh29\n",
1562 1562 "FWjDlMvYuxeoqHDvALNI5OQAR4/aK27JQEQ+D7jL0SclsQFgLS381gRYc/Q9egAXL/LZVSxb6M04\n",
1563 1563 "eju99LRhymU8/zzw4IP8hmmpRFISGwVQXe30SiIjIp8H3CX0Pp8YV29F6H0+Jrg8DkIx014J2D98\n",
1564 1564 "xMxZrlYdvd/PXgTdPPRQJyaE/tQpYNUq4LvfdXol4nBDfCOihx6QL/RWN0vpiMjprRRjAX7xjZn2\n",
1565 1565 "SoCJryxHbzWj1/N5t49JAWJE6JctA265BRgwwOmViMMtQi/C0ScnM7GSMdjMrqMHLp8dyxMrjh7g\n",
1566 1566 "K/Rei268UogFYqC9sqUF+N3vgI0bnV6JWNywaUqU0LcfbMbrQJNw8BD63r35RzdWirEAP6G3Et3I\n",
1567 1567 "dPRWhN4rm6WAGHD0q1YBo0YBY8Y4vRKxuMHRi8roAdZ5I2PTFDn60JiNbnhk9KKF3kuO3tNCr2nA\n",
1568 1568 "c88BP/qR0ysRjxt2x4rK6AEgJYXVYkTDy9GLEHqnM3ozjt5NGb0X8LTQb9nCcttp05xeiXjc4OhF\n",
1569 1569 "RTeA+xy9Cl03AHsMj64blfvoKaP3uND/+tfAD3/ojap5NAYOZBk1j0OXReEFoT9zRk1Hbyej59Ve\n",
1570 1570 "KTu6Ed1e6ZXNUoCHhf6jj4D9+4E5c5xeiRzi4tjGqfJyp1cSHpEZPUU31oS+Z0/7Qq9p5oQXcEcx\n",
1571 1571 "1iubpQAPC/2TTwI//ak3NjsYReX45vx5tgHFjOszA0U31oXebkbf3MymwXbpYvwxlNHLxZNC/49/\n",
1572 1572 "sJEH8+c7vRK5qFyQ1WMbUTGam4Set6NvaWHjL6zMEOLh6M3GNgD10cvGk0K/eDHw+OPslPhYIjcX\n",
1573 1573 "OHzY6VWERsTUyvbIiG4CAevOuT28hV5fk5UXUR5Cb2XcMLVXysVzQl9SwrL5Bx90eiXyGTJE3Yxe\n",
1574 1574 "ZD4PyHH0Z88yYTQTUYSCd3RjtRALOCv0qkc3tGFKUTQN+MlPgF/+MvbcPAAMHsymWKqIaEcvQ+h5\n",
1575 1575 "xDaAOEdvBV7RjVmht5PR68Vfo26bHL3HhH7NGvb2+p57nF6JM8Sy0MuIblQWeiubpQA+7ZVmd8UC\n",
1576 1576 "9hx9SwvrMjN6HChl9B4S+gsXgH/9V9Y7b/WYN7fTrx/7JeDduscDcvSX4R3dOO3oZWf0Zls5ydF7\n",
1577 1577 "SOifeoodE3j99U6vxDl8vsuHkKiGaKHv2RNobbV+CLQReAl9r17sxVjT7D8X4LzQW4lu7Dh6s9m5\n",
1578 1578 "nYyehF4hDh5kB4v85jdOr8R5Bg9WsyArWuh9PvHxDS+h79qVxQ68djHbLcba7aO3Et3YyejNCr2d\n",
1579 1579 "6IaKsYoQCAAPPcQ2R2VmOr0a51E1pxc5/kBHdHzDY/yBDs8Jlk47eivRTfful/v/zWLF0VN043L+\n",
1580 1580 "8Af2g/b97zu9EjVQVehFO3pAvNDzcvQA34KsnWKsLvR2YiQrQu/zWXfaJPTmcbXQl5WxzVHLl3vz\n",
1581 1581 "LFgrqCj0fj+LVFJTxd7HLdENwLcga8fRd+3KRNfOYeVWdsYC1uMbK9FNU5P5FzMSegW4eBG4/37g\n",
1582 1582 "Zz8Dhg93ejXqoGIx9tQpJmyiX4xlOHq758Xq8HT0djJ6wH6LpRVHD1gvyJoV+oQE9mLW2ir2Pirj\n",
1583 1583 "WqF/7DGBCpV3AAAezUlEQVRg0CDg0UedXolaqFiMlRHbALEd3dgRers5vR2htxKpWLmflfjGS47e\n",
1584 1584 "lYHHn/4EbN0KlJbGxqx5M2RksEhApR9SWUIfy9GN1YwesC/0VtorAXmOHrgs9Gb+/VT6HbKL6xz9\n",
1585 1585 "X/8K/L//B7z1lv3hUl4kLg7IygKOHXN6JZchR98Zrzl6lTN6/V5me+lJ6B1i61bggQeAtWuBESOc\n",
1586 1586 "Xo26qFaQJaHvjGpCb6eXXnZ0Y0XorXT40IYpB3j3XeDOO4GVK4HCQqdXozaqFWQpuukMz+jGbjE2\n",
1587 1587 "lqIbM9CGqXZs3LgRI0aMwNChQ/H000+HvOaxxx7D0KFDMXbsWOzevdvU82sa65V/8EHgnXeAKVPs\n",
1588 1588 "rtj7qFaQ9YKjDwSYoNrJwtujmqN3IrqRLfQU3VjE7/dj0aJF2LhxI/bt24eVK1di//79Ha5Zv349\n",
1589 1589 "Dh06hLKyMrzwwgt46KGHDD//8ePArFms+LptGzl5o6gW3cjYFQswoRfl6BsbmTDxahFVZcMU4Fx7\n",
1590 1590 "peyM3oyj11sxjU7IVB1bQl9aWor8/Hzk5OQgISEB9957L9auXdvhmnXr1mHevHkAgMLCQjQ0NKC2\n",
1591 1591 "tjbi8544AfzbvwGjRgFjxwI7dwL5+XZWGluoJvQyo5v6en7DwtrDc/wBwC+68fuZ87QitDpORjdW\n",
1592 1592 "M3orIxfM3MtLbh6wKfRVVVXIzs6+9HlWVhaqqqqiXlNZWRny+Z58Epg8GcjLA06fBj75BPjFL2Lr\n",
1593 1593 "gG8exKrQJyYyB2Z3dksoeG6WAvg5+nPnmFu1M5rbbdHN+fPiHb2XNksBNvvofQab2LUgixXucZs2\n",
1594 1594 "LUZ2NtsENXVqMXJyiu0sL2bJymJxSWurGm89ZQk9cDm+4d16y7MQC/AbasbjDNuePVlMagW/n+1S\n",
1595 1595 "t+J+k5KAmhrzj5OR0avs6EtKSlBSUmLqMbaEPjMzExUVFZc+r6ioQFZWVsRrKisrkRlmzOS2bYvt\n",
1596 1596 "LIf4moQElolXVbEOHCdpamJCwKuIGQ09vhk8mO/z8hb63r35RDd283nAXnulLrpWNi6q3F6pstAX\n",
1597 1597 "FxejuLj40udPPPFE1MfYim4mTJiAsrIylJeXo6WlBatXr8asWbM6XDNr1iysWLECALBz50706dMH\n",
1598 1598 "6TIqczGOKp03J04wNy9rB7OozhsRQq+So7ca3VgdaAao3V6pstBbwZajj4+Px9KlSzFt2jT4/X4s\n",
1599 1599 "WLAABQUFWLZsGQBg4cKFmDFjBtavX4/8/Hz06NEDL7/8MpeFE5FRJaeXGdsA4jpvRAh9YyMrHNt5\n",
1600 1600 "EXRa6K123ADWxwfLEHovbZYCOMy6mT59OqZPn97h7xYuXNjh86VLl9q9DWGSWBV6PbrhDW+h79KF\n",
1601 1601 "Ccm5c/aE2u5mKcBee6UdoZft6M0YAC9tlgJctDOWMIcqu2OdcPRuEHqAT3zjtKO32loJ2Oujp/ZK\n",
1602 1602 "c5DQexRVHH1tLUU34eDRecOrGGvH0dvJ6FWNbsjRE65AlWJsXZ2cXbE6boluAD6dN047eieiG1l9\n",
1603 1603 "9OToCeUZNAiorLR2+DJPKLoJD4/ohkdG72R0Y9bRt7ayn2mz+0Os9NGToyeUp3t3Fg1Y3QjDC690\n",
1604 1604 "3Zw5w3dnLMBnDAIvR2+1j95udGPW0esCbLZTyWxGT46ecA0qFGSp6yY8qhRju3ZlbZ5WDgi3215p\n",
1605 1605 "VuitjiagjJ7wLCoUZL0U3fB29LyE3m4x1uez3mJpJ7rp3p29uJiJF+0IvZnohhw94RqcLshqGtsZ\n",
1606 1606 "27+/vHv27cviEJ61CU3jP70SUCe6Aazn9HaiG5/PWqRCjt48JPQexmlH39DAflm6dZN3z/h4JjwN\n",
1607 1607 "Dfyes7GRCRLvAXGqFGMBe0JvZ0Sy2fjGSg89QBk9Cb2HcVroZcc2OrzjGxH5PMCvj95Jobcz6wYw\n",
1608 1608 "30tPjt4aJPQexulirJNCz7PzRpTQ8+qj5zEZ1InoBjDv6K300Ov3oYye8CR6Ri/ixCUjyDpCMBje\n",
1609 1609 "nTcihV4lR2+lxdJOMRaQ5+i7dmU9+G1txq4nR0+4ht692Q+4qAOzo0HRTWTsRjea5o3oxmxGb0WA\n",
1610 1610 "fT5zrp4cPeEqnMzpvRLdnD7Nunl4Yze6aWpixWceRWI77ZUyoxs7R/yZyenJ0ROuwsmc3imhj5Xo\n",
1611 1611 "hpebB5zL6M1GN1YzeoAcPeFhnOylp+gmMnajG16FWMBedOOG9krAXIslOXrCVVB0Yx9RQt+zJxM5\n",
1612 1612 "v9/a41Vw9LIzelknWpGjJ1wFRTf2ESX0cXFMtKxOjuS1WQqwJvSaZs9hA9aiGxlCT46ecBXk6O3T\n",
1613 1613 "0CCmGAvYi2+cdvRNTayrq0sX6/e10kdvR+gpoyc8iVMZfUsLEyJRAhkJ3hn96dNiHD1gr/OGd0Zv\n",
1614 1614 "to/ebmwDyC3GGs3o29pYnNa1q7X7qAgJvcfp14+Jrt2NOWY5cQJITWXxhGzcEt0A9jpveDp6K+2V\n",
1615 1615 "djtuAPmO3ojQ6+fFmp15rzIk9B7H53Mmp3cqtgFYHNLUxHZC8kCk0Ls5uuHl6GV13RiNbryWzwMk\n",
1616 1616 "9DGBEzn98eNARobce+r4fCwy4pXTi3b0VqMbp4uxdlsrATWLsV7L5wES+pjAiZzeSaEH+MU3gQAT\n",
1617 1617 "NN6HjujEuqOXGd0YzejJ0ROuxAlHX1vrrNDz6rw5e5aJmahag92M3skNUzwyetk7Y8nRE57FiYze\n",
1618 1618 "aUfPq/NGZMcNYL/rhhy9uXtRRk94lljL6AF+0Y3IfB6wF93wzOi7dWNthWYK2LwyetVGIJCjJ1xJ\n",
1619 1619 "LGb0vKIb0UKviqO3ckC47OgmEACam62LsJn2SnL0hOvIyGBiYuaEHbuoIPS8HL3ITV92MvqzZ/kW\n",
1620 1620 "ic3GN7Kjm6YmIDHRer2EMnrC08TFAdnZwLFj8u7ptNDHQnRz5oz7hd5MdGOnEAtQRk/EADJz+qYm\n",
1621 1621 "9iFSIKPBK7pRuRh79iy/rhvAmtDbzei7d2dxTCAQ/Vo7hVj9XuToCU8jM6fXWyud3ELOM7oRLfRW\n",
1622 1622 "HL2mOS/0PDL6uDgWxxhx2naFnjJ6wvPIdPROxzaA96ObCxfY0C0exwjqOBHdAMYLsnZHIpvJ6Eno\n",
1623 1623 "CVcis5deBaHn2XUjuhhrJbrh7eYBZ6IbwHhBloejN5rRU3RDuBKZ0Y0qQu8GR9+jB8uo29rMPY53\n",
1624 1624 "IRZg7ZVmRhXziG4A4wVZu8VYMxk9OXrClciObtLT5dwrHN27Xz4ByQ6ihd7nY87c7Cx4VRw9D6E3\n",
1625 1625 "GqnIzOjJ0ROuJDOTFUl5je6NhAqO3ufjE9+I7roBrMU3Ihy9kxm9StENOXrCtSQkAAMGAJWV4u+l\n",
1626 1626 "gtADfOIb0Y4esFaQVcXR88joZQl9YqKxVk5y9ISrkZXTqyL0PDpvZAi9lRZLFRw9r4zeTDeMHaGP\n",
1627 1627 "i2MzfZqbo9+HHD3hWmTl9KoIvd3opqUFuHiR3zyZcFiJbpx29IEAv35zWcVYwNiLCjl6wtXIEHpN\n",
1628 1628 "Y7UAp4uxgP3o5tQp9q5A9MYvq9GNk45e3z3KY06/rGKsfq9oOT05esLVyOilP3uW1QN4ZLd2sRvd\n",
1629 1629 "1Nez5xCN1eiGt6M3M72Sh+jqyMroAWMtluToCVcjI6NXJbYB7Ec39fXsOURjNboR4eiNtnny6rgB\n",
1630 1630 "5Aq9kXcP5OgJVyMjuqmuVkvoeUQ3orES3Yhw9GaiG55C37OnWkJPjp5wNYMGsfZKI5MCrVJVxXr2\n",
1631 1631 "VYBHdCPL0butvZK30Bu5Lw+nTRk94XkSE5n41dSIu4dKQm83upHl6N24YYpnRm/0vpTRW4eEPsYQ\n",
1632 1632 "ndNXV6sl9G5w9G7cMOWEo5cR3bS1sXe8PKeCqoBloT916hSmTp2KYcOG4cYbb0RDQ0PI63JycjBm\n",
1633 1633 "zBiMHz8eV111leWFEnwQndOr5OhTUtzj6FVor0xMZCMyjAxY86rQ627eybMURGBZ6JcsWYKpU6fi\n",
1634 1634 "4MGDuOGGG7BkyZKQ1/l8PpSUlGD37t0oLS21vFCCD7Eo9Jpm7fEqd92IKMb6fHILozqyhT5SRu/F\n",
1635 1635 "fB6wIfTr1q3DvHnzAADz5s3D22+/HfZazepvGsEd0b30Kgl9167MpVo9k1VWH73Z6CYQYKInYseu\n",
1636 1636 "0RZLtxZjo2X0XsznARtCX1tbi/Svtz+mp6ejtrY25HU+nw9TpkzBhAkT8Mc//tHq7QhO5OQAR46I\n",
1637 1637 "ee5AgPXRDxgg5vmtYKcge+qUml03jY3M2fLYlRqMUdH1anTjVUcfH+mLU6dOxfHjxzv9/S9/+csO\n",
1638 1638 "n/t8PvjChFrbt2/HgAEDcOLECUydOhUjRoxAUVFRyGsXL1586c/FxcUoLi6OsnzCLLm5wFdfiXnu\n",
1639 1639 "EyeYO+3WTczzW0EvyA4ZYv6xMh29mehGRD6vY0Z0eb2gG7lnWxv7sPuzlZTEBtWFww2OvqSkBCUl\n",
1640 1640 "JaYeE1HoN23aFPZr6enpOH78ODIyMlBTU4O0tLSQ1w34+qehf//+uO2221BaWmpI6Akx5OQAx44B\n",
1641 1641 "fj/QpQvf51YpttGx00svy9EnJjIRa2lhcVM0ROTzOkaFvrERyM+Xd0/dzdstkiYlsc6wcLjB0Qeb\n",
1642 1642 "4CeeeCLqYyy/+Zs1axaWL18OAFi+fDluvfXWTtdcuHABjV8HfufPn8f777+P0aNHW70lwYHERCAt\n",
1643 1643 "Daio4P/cKgq91ejmwgVWxJXh7vRTpozGNyo4+sZGfi82iYnsRS5Stw+v4i9l9CZ5/PHHsWnTJgwb\n",
1644 1644 "NgxbtmzB448/DgCorq7GzJkzAQDHjx9HUVERxo0bh8LCQtx000248cYb+aycsIyo+EZVobfi6HU3\n",
1645 1645 "L6vNzkxBVrSjN1KM5dnHb6Tbh8eIYiD6QeT6VE6vETG6iURKSgo2b97c6e8HDhyId999FwCQm5uL\n",
1646 1646 "Tz/91PrqCCHk5QGHDwPXX8/3eauqgIED+T6nXaxGN7LyeR0zLZYiNku1X4dsoQcuv5MI907F7qEj\n",
1647 1647 "7e8T7QWFV5FZJWhnbAwiytGrtCtWx2p0I6uHXqdvX3Y+rRFERjdGC8OihD4cvKKbaPfh2U2kEiT0\n",
1648 1648 "MQhFN9GRVYjVMSP0IqMbo+8sSOjdBQl9DKJHN7xRUejdEt2Qo1dD6Hnu+FUJEvoYJNYcvZXoJlYd\n",
1649 1649 "vZGisKaxa3juzDUiwDyKseToiZghNZUNrzIqLEZoamIFM5niaASr0U2sOnoj0c3Fi6xThufGuGjH\n",
1650 1650 "GPJ09JGKsST0hGfw+Vh8w9PVV1eznZKqTf2zGt3EsqOPJvROjEjm2XVDjp6IGXjHN5WVQFYWv+fj\n",
1651 1651 "Rd++7Je3tdXc41R39CKLsdGiG56bpXSiCXBjI5+oqGtXNpOppSX01ymjJzxFbi7fgmx5ORuvoBpx\n",
1652 1652 "ccyZnzhh7nGy2yvNzM5vaGAvDCJQ1dHzume0zVnk6AlPwTu6UVXoASA9HairM/cYWYeO6Jhx9KdO\n",
1653 1653 "eU/oe/WK/E6C57uISC8qJPSEp8jLA8rK+D2fykKflgaEmaIdFpU3TJ0+Le5FyEh0I0Loo92XZ5dP\n",
1654 1654 "NKGn6IbwDMOH8xX6o0fZ6VUqkp5uTugDAXUdvd/P3K2orpvERPbf5ubw1/BurQSMCb0MR08jEAhP\n",
1655 1655 "kZ3NXKvRw6CjobKjNxvdNDSwX3aZc/X79GGRSSAQ+Tq940bEoSM60eIbJxw9RTf2IKGPUeLi2Dxx\n",
1656 1656 "Hq6+rY1tlsrOtv9cIjAb3dTVscfIJD6ebQiKNlBMZD6vE62XXoTQG3lxoejGOiT0Mczw4cDBg/af\n",
1657 1657 "p7qabcJS6WSp9piNbmpr5Qs9YCy+EZnP60TbHetURi/a0QcC7jh4xAok9DHMsGHAgQP2n+foUXVj\n",
1658 1658 "G8C80Dvh6AFjLZaqOHrZGb2M6EY/dIT3yWsqQEIfwwwbxsfRq5zPA+YzeqeE3si4htOnxQt9tBil\n",
1659 1659 "oYHVFGTeU0Z049V8HiChj2mGD+fj6FUXejdk9ACLv06ejHyNjG6gaKIr4sVG76PXtM5fa2lh3UZ6\n",
1660 1660 "R5BdIgm9F/N5gIQ+ptEdfahfLjOUl6vbWgkw0T5xInpHi47KQi/D0aekRK4ViFhD166sIB2qrVOP\n",
1661 1661 "bXjNUSJHT8QU/foBCQnmd40Go3pG37UrixqMjkFQWehlOPpotQIR0Q0Q/p2ErJHIXu2hB0joYx4e\n",
1662 1662 "BVnVoxuAnWVbU2Ps2ro6luvLRhVH37dvZKEXtYZwBVneQ9TCHYBO0Q3hWewWZP1+oKICGDSI35pE\n",
1663 1663 "MHAgawM1Ajl6+dENEF7oebdz9uoVXujJ0ROexG4vfU0NEwZehTJRmBX6/v3FricUqalqdN1Eim6a\n",
1664 1664 "m9mLu4hec1nRjb4LOZgzZ8SNlnAaEvoYZ9gw4MsvrT/+yBH1YxvAuNDrJ2XJnHOjY8TRnzgh/kUo\n",
1665 1665 "ktDrLzQiDpiRFd0kJ7M6QzANDST0hEe54grg88+tP76sDBg6lN96RDFggDGhr6lx7qQsI0IvI1aK\n",
1666 1666 "tENX5DsKWdFNJEcvosisAiT0MU5+PusxjzZjJRxlZexdgeoYLcZWV7NrnaBfPyb04dpd/X4mRk52\n",
1667 1667 "3YgWehnRDTl6Iubo0gUoKLDu6g8edI/QG3H0Tgq9vv0+3OlH9fVMZEVv0e/Th4mr39/5ayKFPtyM\n",
1668 1668 "Hd7zffT7BL+gkqMnPM2YMcDevdYe65boxg1CD0SOb2QVibt0YQ46lLsW1UMPsOcNFRnx7jRKSGB7\n",
1669 1669 "K4JfUMnRE55m9Gjgs8/MPy4QYOfOukHo09NZIbOtLfJ1Tgt9//7hN7DJKMTqhMvpRTr6cLN+RLSU\n",
1670 1670 "hsrpydETnsaq0FdVMQfkht7jhARWxIzm6p0W+owM4Pjx0F+T2d8fLqf3itCHyunJ0ROeRo9uzM68\n",
1671 1671 "OXDAHfm8zqBBbFxDJJwW+gEDwgu9TEfvdaHv06ez0JOjJzxNWhrLLKuqzD3uiy9Ye6ZbGDwYOHYs\n",
1672 1672 "8jVOC31GRvjuIBUcfX29uK4f2Y4+OLohR094HisF2c8/B0aNErMeEURz9JrGXuycdvThhF6mo09N\n",
1673 1673 "DT0ErrZW3BygcEIv4sUl2NFrGu2MJWIAKzn9F1+4S+ijOfrTp9lZuk7+skcTelmOPiMj9Ax/kULf\n",
1674 1674 "ty8T3/bjpFtbWXeM6DNqz59n72q7duV7H1UgoScAmHf0muY+oY/m6PUpnE7sitWJJPQyZ/CEKwqL\n",
1675 1675 "nOwZH8/aOts7bb2dM46zUgU7ei+7eYCEnviaK68EPvnE+PWVlWyDT79+4tbEm2iO/sgRYMgQeesJ\n",
1676 1676 "RaRibGUlkJkpZx3p6Z3XEQiIf1cRHN+ImtYZ7OhF7g9QARJ6AgAwciTLpyONp23P3r0s7nETuqMP\n",
1677 1677 "112kwlx9/SDz4DUGAuzfJytLzjpCRTenTrFWWpHxhiyhJ0dPxCTx8czVf/yxses//hiYMEHsmniT\n",
1678 1678 "nMzGKYc7P7a83HlHn5jIDr8ILkqeOMFyalnjoEM5epH5vI5MoW9varzcWgmQ0BPtuOoqoLTU2LWf\n",
1679 1679 "fOI+oQciz99XZeRyqJy+ogLIzpa3hvR0lse3L4zKOHmrX7+ObZ2ihD74HYvItlEVIKEnLlFYCOzc\n",
1680 1680 "aezajz8GvvENsesRQaSjE1Vw9ACrJQQXjSsr5cU2ANCtG3tn0d71OuHoRQlwcLFZH0/tVUjoiUsU\n",
1681 1681 "FQHbt4eeWtie6mqgpYUJktsI5+g1TY2MHgByc9kMofbIdvRAZzGUIfTB/fvV1WIEOHhjGgk9ETOk\n",
1682 1682 "p7OPaG2WO3cCEyc624ZolXBn5B47xjJa3v3aVsjLA776quPfVVTIdfRAaKEX3cefmcneveiIeoHr\n",
1683 1683 "0we4eJGdJgaQ0BMxRnExUFIS+ZoPPmDXuZHhw0NHN59/rs44h1COvrJSvqMPLsjW1DDxF0lwbCVK\n",
1684 1684 "6H2+ji9kJPRETFFcDGzZEvmakhL3Cn1eHhOSixc7/r1K4xxyczs7+mPH5Dv6IUM6ruPQIfb9E8mg\n",
1685 1685 "QR33OoiMrNrvWSChJ2KKqVOZY9ff0gZz6hTrTrnySrnr4kViIotvgsc9qObojxy53PGi70IuKJC7\n",
1686 1686 "juCYS8YhM9nZbL+A388+amrEbRIjR0/ELCkprG1y06bQX9+0iRVtExLkrosnEyd2biNVSeh79GA9\n",
1687 1687 "/3qxsLqafb9FF0KDaV+4bmxkx++J3pnbrRv7GaypYSKcksL+TgR6G+v582ymDm2YImKKW24B3n47\n",
1688 1688 "9NfeeAO44w656+FN8H6B5mYmaCNHOremYIYNA/btY3/+7DNndiHrjl7TWGyTn89/5kwo9JxedKeR\n",
1689 1689 "7uh1N+/G5gKjWP5nW7NmDUaNGoUuXbpg165dYa/buHEjRowYgaFDh+Lpp5+2ejtCInfeCaxdy1xc\n",
1690 1690 "e86fB95/n70QuJlgod++HRg7ljlpVfjmN4EdO9ifnRL6fv2Y+J08KfdsYD2nr6hgfxaF7ui9HtsA\n",
1691 1691 "NoR+9OjReOutt3DttdeGvcbv92PRokXYuHEj9u3bh5UrV2L//v1Wb6k0JdFaVRQmeO2ZmazY+tpr\n",
1692 1692 "Ha9bswaYNEm9QWZmv/ejRrFfbv1YwU2bWG3CKUKt/+qrnRd6n+/yBrNIQs/7Z1939EeOiBX6ggJg\n",
1693 1693 "927g3XdLhN5HBSwL/YgRIzAsyjlypaWlyM/PR05ODhISEnDvvfdi7dq1Vm+pNF4SegBYtAh49lkW\n",
1694 1694 "awCsMParXwE/+YnctRnB7Pc+IQG4/fbLL2Tvv6+e0E+axPYrtLYC27Y5N25i1CjgH/9g74DCdSXx\n",
1695 1695 "/tmfOBH429+A9euByZO5PnUHCgtZJLV6dYmj//4yEJq4VVVVIbtdyJaVlYUqs+fVEY5w/fWsOPnz\n",
1696 1696 "n7OMdskStlnGrW2VwcydCyxfDmzYwKKJwkKnV9SR1FR20tUPfsBm0I8d68w6vvMd4De/AT78ELjt\n",
1697 1697 "Njn3vPlmNmLj00+BG28Ud5+EBNZYUF4OzJwp7j4qEB/pi1OnTsXxEMOxn3rqKdx8881Rn9zn5epG\n",
1698 1698 "DPD737NfgDffZI5++3bvFKyKilhxccYM5hxV7CJ6/nlg+nRg2TLn1nDNNaxoec01bESxDLp3ZwX/\n",
1699 1699 "c+fET+ucOpW9oMjuaJKOZpPi4mLtk08+Cfm1v//979q0adMuff7UU09pS5YsCXltXl6eBoA+6IM+\n",
1700 1700 "6IM+THzk5eVF1emIjt4oWpiTHCZMmICysjKUl5dj4MCBWL16NVauXBny2kOHDvFYCkEQBBGE5Yz+\n",
1701 1701 "rbfeQnZ2Nnbu3ImZM2di+vTpAIDq6mrM/Drwio+Px9KlSzFt2jSMHDkS99xzDwpkb+8jCIKIcXxa\n",
1702 1702 "ODtOEARBeALHd8a6eUPV/PnzkZ6ejtFuOzz1ayoqKjB58mSMGjUKV1xxBX772986vSRTNDc3o7Cw\n",
1703 1703 "EOPGjcPIkSPx05/+1Oklmcbv92P8+PGGmhtUJCcnB2PGjMH48eNx1VVXOb0cUzQ0NODOO+9EQUEB\n",
1704 1704 "Ro4ciZ1GT91RgAMHDmD8+PGXPpKTkyP//lqov3Kjra1Ny8vL044cOaK1tLRoY8eO1fbt2+fkkkyx\n",
1705 1705 "detWbdeuXdoVV1zh9FIsUVNTo+3evVvTNE1rbGzUhg0b5qrvv6Zp2vnz5zVN07TW1latsLBQ27Zt\n",
1706 1706 "m8MrMsdzzz2n3XfffdrNN9/s9FIskZOTo9XX1zu9DEvMnTtXe/HFFzVNYz8/DQ0NDq/IGn6/X8vI\n",
1707 1707 "yNCOHTsW9hpHHb3bN1QVFRWhb9++Ti/DMhkZGRg3bhwAoGfPnigoKEC1vl3UJSQlJQEAWlpa4Pf7\n",
1708 1708 "keKigz8rKyuxfv16PPjgg2EbGtyAG9d+5swZbNu2DfPnzwfA6onJLp1qtnnzZuTl5XXYsxSMo0JP\n",
1709 1709 "G6rUoby8HLt370ahajuHohAIBDBu3Dikp6dj8uTJGKnSZLIo/OAHP8AzzzyDOBmTwgTh8/kwZcoU\n",
1710 1710 "TJgwAX/84x+dXo5hjhw5gv79++OBBx7AlVdeiX/+53/GhXCzuRVn1apVuO+++yJe4+hPGG2oUoNz\n",
1711 1711 "587hzjvvxH//93+jp6xdMZyIi4vDp59+isrKSmzdutU1oyj++te/Ii0tDePHj3elI9bZvn07du/e\n",
1712 1712 "jQ0bNuD3v/89tm3b5vSSDNHW1oZdu3bh4Ycfxq5du9CjRw8sWbLE6WWZpqWlBe+88w7uuuuuiNc5\n",
1713 1713 "KvSZmZmoqKi49HlFRQWyZB+jE+O0trbijjvuwLe//W3ceuutTi/HMsnJyZg5cyY+/vhjp5diiB07\n",
1714 1714 "dmDdunUYMmQIZs+ejS1btmDu3LlOL8s0A74e+9i/f3/cdtttKA0e9K8oWVlZyMrKwsSJEwEAd955\n",
1715 1715 "Z8QpvKqyYcMGfOMb30D//v0jXueo0LffUNXS0oLVq1dj1qxZTi4pptA0DQsWLMDIkSPxL//yL04v\n",
1716 1716 "xzQnT55EQ0MDAKCpqQmbNm3C+PHjHV6VMZ566ilUVFTgyJEjWLVqFa6//nqsWLHC6WWZ4sKFC2j8\n",
1717 1717 "epb1+fPn8f7777umAy0jIwPZ2dk4+PXJKps3b8YoVc6SNMHKlSsxe/bsqNdx2RlrlfYbqvx+PxYs\n",
1718 1718 "WOCqDVWzZ8/GBx98gPr6emRnZ+PJJ5/EAw884PSyDLN9+3a8+uqrl9rjAOBXv/oVvvWtbzm8MmPU\n",
1719 1719 "1NRg3rx5CAQCCAQCmDNnDm644Qanl2UJN8aYtbW1uO3rSWdtbW24//77caPIKWSc+d3vfof7778f\n",
1720 1720 "LS0tyMvLw8svv+z0kkxx/vx5bN682VBthDZMEQRBeBz3lvsJgiAIQ5DQEwRBeBwSeoIgCI9DQk8Q\n",
1721 1721 "BOFxSOgJgiA8Dgk9QRCExyGhJwiC8Dgk9ARBEB7n/wOimSfhIIMDngAAAABJRU5ErkJggg==\n"
1722 1722 ],
1723 1723 "text/plain": [
1724 1724 "<matplotlib.figure.Figure at 0x3436950>"
1725 1725 ]
1726 1726 },
1727 1727 "metadata": {},
1728 1728 "output_type": "display_data"
1729 1729 }
1730 1730 ],
1731 1731 "source": [
1732 1732 "x = np.linspace(0, 2*np.pi, 300)\n",
1733 1733 "y = np.sin(x**2)\n",
1734 1734 "plt.plot(x, y)\n",
1735 1735 "plt.title(\"A little chirp\")\n",
1736 1736 "fig = plt.gcf() # let's keep the figure object around for later..."
1737 1737 ]
1738 1738 },
1739 1739 {
1740 1740 "cell_type": "markdown",
1741 1741 "metadata": {},
1742 1742 "source": [
1743 1743 "## The IPython kernel/client model"
1744 1744 ]
1745 1745 },
1746 1746 {
1747 1747 "cell_type": "code",
1748 1748 "execution_count": 43,
1749 1749 "metadata": {
1750 1750 "collapsed": false
1751 1751 },
1752 1752 "outputs": [
1753 1753 {
1754 1754 "name": "stdout",
1755 1755 "output_type": "stream",
1756 1756 "text": [
1757 1757 "{\n",
1758 1758 " \"stdin_port\": 50023, \n",
1759 1759 " \"ip\": \"127.0.0.1\", \n",
1760 1760 " \"control_port\": 50024, \n",
1761 1761 " \"hb_port\": 50025, \n",
1762 1762 " \"signature_scheme\": \"hmac-sha256\", \n",
1763 1763 " \"key\": \"b54b8859-d64d-48bb-814a-909f9beb3316\", \n",
1764 1764 " \"shell_port\": 50021, \n",
1765 1765 " \"transport\": \"tcp\", \n",
1766 1766 " \"iopub_port\": 50022\n",
1767 1767 "}\n",
1768 1768 "\n",
1769 1769 "Paste the above JSON into a file, and connect with:\n",
1770 1770 " $> ipython <app> --existing <file>\n",
1771 1771 "or, if you are local, you can connect with just:\n",
1772 1772 " $> ipython <app> --existing kernel-30f00f4a-230c-4e64-bea5-0e5f6a52cb40.json \n",
1773 1773 "or even just:\n",
1774 1774 " $> ipython <app> --existing \n",
1775 1775 "if this is the most recent IPython session you have started.\n"
1776 1776 ]
1777 1777 }
1778 1778 ],
1779 1779 "source": [
1780 1780 "%connect_info"
1781 1781 ]
1782 1782 },
1783 1783 {
1784 1784 "cell_type": "markdown",
1785 1785 "metadata": {},
1786 1786 "source": [
1787 1787 "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:"
1788 1788 ]
1789 1789 },
1790 1790 {
1791 1791 "cell_type": "code",
1792 1792 "execution_count": 83,
1793 1793 "metadata": {
1794 1794 "collapsed": false
1795 1795 },
1796 1796 "outputs": [],
1797 1797 "source": [
1798 1798 "%qtconsole"
1799 1799 ]
1800 1800 }
1801 1801 ],
1802 "metadata": {
1803 "signature": "sha256:31071a05d0ecd75ed72fe3f0de0ad447a6f85cffe382c26efa5e68db1fee54ee"
1804 },
1802 "metadata": {},
1805 1803 "nbformat": 4,
1806 1804 "nbformat_minor": 0
1807 1805 } No newline at end of file
@@ -1,489 +1,487
1 1 {
2 2 "cells": [
3 3 {
4 4 "cell_type": "markdown",
5 5 "metadata": {},
6 6 "source": [
7 7 "# Capturing Output With <tt>%%capture</tt>"
8 8 ]
9 9 },
10 10 {
11 11 "cell_type": "markdown",
12 12 "metadata": {},
13 13 "source": [
14 14 "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."
15 15 ]
16 16 },
17 17 {
18 18 "cell_type": "code",
19 19 "execution_count": 9,
20 20 "metadata": {
21 21 "collapsed": false
22 22 },
23 23 "outputs": [],
24 24 "source": [
25 25 "from __future__ import print_function\n",
26 26 "import sys"
27 27 ]
28 28 },
29 29 {
30 30 "cell_type": "markdown",
31 31 "metadata": {},
32 32 "source": [
33 33 "By default, `%%capture` discards these streams. This is a simple way to suppress unwanted output."
34 34 ]
35 35 },
36 36 {
37 37 "cell_type": "code",
38 38 "execution_count": 10,
39 39 "metadata": {
40 40 "collapsed": false
41 41 },
42 42 "outputs": [],
43 43 "source": [
44 44 "%%capture\n",
45 45 "print('hi, stdout')\n",
46 46 "print('hi, stderr', file=sys.stderr)"
47 47 ]
48 48 },
49 49 {
50 50 "cell_type": "markdown",
51 51 "metadata": {},
52 52 "source": [
53 53 "If you specify a name, then stdout/stderr will be stored in an object in your namespace."
54 54 ]
55 55 },
56 56 {
57 57 "cell_type": "code",
58 58 "execution_count": 11,
59 59 "metadata": {
60 60 "collapsed": false
61 61 },
62 62 "outputs": [],
63 63 "source": [
64 64 "%%capture captured\n",
65 65 "print('hi, stdout')\n",
66 66 "print('hi, stderr', file=sys.stderr)"
67 67 ]
68 68 },
69 69 {
70 70 "cell_type": "code",
71 71 "execution_count": 12,
72 72 "metadata": {
73 73 "collapsed": false
74 74 },
75 75 "outputs": [
76 76 {
77 77 "data": {
78 78 "text/plain": [
79 79 "<IPython.utils.capture.CapturedIO at 0x1076c9310>"
80 80 ]
81 81 },
82 82 "execution_count": 12,
83 83 "metadata": {},
84 84 "output_type": "execute_result"
85 85 }
86 86 ],
87 87 "source": [
88 88 "captured"
89 89 ]
90 90 },
91 91 {
92 92 "cell_type": "markdown",
93 93 "metadata": {},
94 94 "source": [
95 95 "Calling the object writes the output to stdout/stderr as appropriate."
96 96 ]
97 97 },
98 98 {
99 99 "cell_type": "code",
100 100 "execution_count": 13,
101 101 "metadata": {
102 102 "collapsed": false
103 103 },
104 104 "outputs": [
105 105 {
106 106 "name": "stdout",
107 107 "output_type": "stream",
108 108 "text": [
109 109 "hi, stdout\n"
110 110 ]
111 111 },
112 112 {
113 113 "name": "stderr",
114 114 "output_type": "stream",
115 115 "text": [
116 116 "hi, stderr\n"
117 117 ]
118 118 }
119 119 ],
120 120 "source": [
121 121 "captured()"
122 122 ]
123 123 },
124 124 {
125 125 "cell_type": "code",
126 126 "execution_count": 14,
127 127 "metadata": {
128 128 "collapsed": false
129 129 },
130 130 "outputs": [
131 131 {
132 132 "data": {
133 133 "text/plain": [
134 134 "'hi, stdout\\n'"
135 135 ]
136 136 },
137 137 "execution_count": 14,
138 138 "metadata": {},
139 139 "output_type": "execute_result"
140 140 }
141 141 ],
142 142 "source": [
143 143 "captured.stdout"
144 144 ]
145 145 },
146 146 {
147 147 "cell_type": "code",
148 148 "execution_count": 15,
149 149 "metadata": {
150 150 "collapsed": false
151 151 },
152 152 "outputs": [
153 153 {
154 154 "data": {
155 155 "text/plain": [
156 156 "'hi, stderr\\n'"
157 157 ]
158 158 },
159 159 "execution_count": 15,
160 160 "metadata": {},
161 161 "output_type": "execute_result"
162 162 }
163 163 ],
164 164 "source": [
165 165 "captured.stderr"
166 166 ]
167 167 },
168 168 {
169 169 "cell_type": "markdown",
170 170 "metadata": {},
171 171 "source": [
172 172 "`%%capture` grabs all output types, not just stdout/stderr, so you can do plots and use IPython's display system inside `%%capture`"
173 173 ]
174 174 },
175 175 {
176 176 "cell_type": "code",
177 177 "execution_count": 16,
178 178 "metadata": {
179 179 "collapsed": false
180 180 },
181 181 "outputs": [],
182 182 "source": [
183 183 "%matplotlib inline\n",
184 184 "import matplotlib.pyplot as plt\n",
185 185 "import numpy as np"
186 186 ]
187 187 },
188 188 {
189 189 "cell_type": "code",
190 190 "execution_count": 17,
191 191 "metadata": {
192 192 "collapsed": false
193 193 },
194 194 "outputs": [],
195 195 "source": [
196 196 "%%capture wontshutup\n",
197 197 "\n",
198 198 "print(\"setting up X\")\n",
199 199 "x = np.linspace(0,5,1000)\n",
200 200 "print(\"step 2: constructing y-data\")\n",
201 201 "y = np.sin(x)\n",
202 202 "print(\"step 3: display info about y\")\n",
203 203 "plt.plot(x,y)\n",
204 204 "print(\"okay, I'm done now\")"
205 205 ]
206 206 },
207 207 {
208 208 "cell_type": "code",
209 209 "execution_count": 18,
210 210 "metadata": {
211 211 "collapsed": false
212 212 },
213 213 "outputs": [
214 214 {
215 215 "name": "stdout",
216 216 "output_type": "stream",
217 217 "text": [
218 218 "setting up X\n",
219 219 "step 2: constructing y-data\n",
220 220 "step 3: display info about y\n",
221 221 "okay, I'm done now\n"
222 222 ]
223 223 },
224 224 {
225 225 "data": {
226 226 "image/png": [
227 227 "iVBORw0KGgoAAAANSUhEUgAAAXoAAAEACAYAAAC9Gb03AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\n",
228 228 "AAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xt8z3X/x/HHmOqHcupq2HaZy7A5j0nJNKcUWVI/h1Rz\n",
229 229 "qKSEUnT8oStSOlxqV4WrRK5rDv1ySCMp39KYoVXE9UPlalsskgiF+f7+eIewscP3u/fn+/k+77fb\n",
230 230 "98by2b7P28qr917vU4jX6/UiIiKuVc52ABER8S8VehERl1OhFxFxORV6ERGXU6EXEXE5FXoREZcr\n",
231 231 "daEfNGgQYWFhNG3atNBnhg8fTv369WnevDlZWVmlfUsRESmGUhf6gQMHsmzZskL/PC0tje3bt7Nt\n",
232 232 "2zamTZvG0KFDS/uWIiJSDKUu9AkJCVSrVq3QP1+8eDHJyckAtGnThn379pGXl1fatxURkSLye48+\n",
233 233 "NzeXyMjIkx9HRESQk5Pj77cVEZHflclk7JmnLISEhJTF24qICBDq7zcIDw8nOzv75Mc5OTmEh4ef\n",
234 234 "9Vx0dDRff/21v+OIiLhKvXr12L59+zmf8fuIPikpiVmzZgGQkZFB1apVCQsLO+u5r7/+Gq/Xq5fX\n",
235 235 "y9ixY/3ydQ8d8vKvf3lJSvJy8cVe2rf3MnGil08+MX9W2q+/d6+XpUu9PPywl2bNvFx6qZfkZC8f\n",
236 236 "fODl2DFnfS8C8aXvhb4XBb2KMkAu9Yi+X79+fPzxx+zZs4fIyEjGjx/P0aNHARgyZAjdunUjLS2N\n",
237 237 "6OhoKlWqxIwZM0r7llJMX3wBr7wC8+dD69Zw663wxhtQo4Zv36daNbj2WvN6+mn47jt45x0YPRp2\n",
238 238 "74bbb4ehQyEiwrfvKyLnVupCn5qaet5nUlJSSvs2UkxeL7z/Pjz/PGzZAvfcA19+WbZF9s9/hpEj\n",
239 239 "zWvjRvjHP6BZM/M/glGjoFWrsssiEsy0M9aBEhMTS/y5Xi+kpUHLljBmjBlFf/MNPPqo3ZF006Yw\n",
240 240 "ZYrJ0qoV9OwJSUnmp41zKc33wm30vThF34viCfF6vY64eCQkJASHRAlYq1fDww/Dnj0wcSLccAM4\n",
241 241 "dYHTr7/Ca6/BpEmQmGjy/uUvtlOJBJ6i1E6N6F0gLw9uuw369oVBg0ybpGdP5xZ5gIsuMi2d7duh\n",
242 242 "SRMzdzB2LBw+bDuZiPuo0Aew/HwzydqkCdSuDZs3w4ABUL687WRFV7kyPP44ZGWZ/I0awZIltlOJ\n",
243 243 "uItaNwFq+3ZITjZF/dVXoXFj24l8Y8UKuOsuaN8e/vY3qFrVdiIRZ1PrxoW8XtPbvuIK6N0bPB73\n",
244 244 "FHmAzp3N6qCKFc0E7jnOyxORItKIPoD8+KNZRfPDD/DWWxATYzuRf61YYeYc+vQxk7UVKthOJOI8\n",
245 245 "GtG7yNq1Zslk48ZmdY3bizyY0f2J3n379vCf/9hOJBKYVOgdzuuFl1+GHj3MOvRnnw2ukW2NGvDu\n",
246 246 "u9CrF1x+uVo5IiWh1o2D/fYb3HmnWS759ttQr57tRHatWmXmJcaMgREjnL18VKSsFKV2qtA71O7d\n",
247 247 "cOONULMmzJplJifFtG+SkiA+3iwtvfBC24lE7FKPPkBt3gxt2pi+9Lx5KvJ/VKcOpKfD3r2mh//j\n",
248 248 "j7YTiTifCr3DfPKJORJg7Fiz0qSc/g2dpXJl+N//NUtMExLgD9cdiEgB/H7xiBTdu++a5YSpqWa0\n",
249 249 "KoUrVw4mT4ZateCqq2DpUnftJxDxJRV6h5g9Gx58EN57z6wukaJ54AEIC4OOHc3Z91ddZTuRiPNo\n",
250 250 "MtYBXnoJnnvOLB1s1Mh2msD0/vvmYLd580zrSyRYaNVNAJg8GaZNM7tA69SxnSawrVxpll/OmQOd\n",
251 251 "OtlOI1I2tOrG4Z5/3hR5j0dF3hc6dDCTtH37wvLlttOIOIcKvSUvvmhOnVy5EsLDbadxj/btYeFC\n",
252 252 "cy/u0qW204g4g1o3FkyZYvryK1eae1XF99asMTdsqWcvbqfWjQNNn27OWf/oIxV5f7rySpg71/Ts\n",
253 253 "MzNtpxGxSyP6MvTOOzBsmNkUFR1tO01wePddc17QihXmJi4Rt9GI3kFWroS77zbr5FXky06PHmY+\n",
254 254 "pGtXcyuXSDDShqky8Nln5vKM+fMhLs52muDTrx/s32+K/erVZoOVSDBRofezbdvg+uvNMsqrr7ad\n",
255 255 "JngNGQLff29G+CtXQqVKthOJlB316P1ozx4zKThmDNxxh+004vXCwIHm5MsFC8zF6iKBTjtjLfr1\n",
256 256 "V3MwWfv25hRKcYYjR6B7d2jQAFJSdHmJBD4Veku8XrNh5+hRsx1fRw07y88/m+ONb7sNHnrIdhqR\n",
257 257 "0ilK7VSP3g/GjYOvvza9YBV556lSBdLSTFstOtrc5CXiZir0PvbWW+bqv4wM+K//sp1GChMRYfr0\n",
258 258 "111n7uJt1sx2IhH/0XjTh9auNeejL1miJXyBID7eHEVxww3mjl4Rt1Kh95Fdu+Dmm+H113XTUSDp\n",
259 259 "1w9uucX8uztyxHYaEf/QZKwPHDlibjjq0sXc9SqB5fhx06evWRNee00rcSSwaNVNGRk6FHbuNGfZ\n",
260 260 "aPI1MB04AG3bwj33mH+fIoFCq27KwPTp5uKQtWtV5APZxRebydm2baFVK93bK+6iEX0pnDjzfNUq\n",
261 261 "aNjQdhrxhUWLYPhw2LABLr3UdhqR89PplX60Z485qOz111Xk3eSGG05N0Obn204j4hsa0ZfA8eNm\n",
262 262 "G32zZvDMM7bTiK8dOwbXXAPt2sGTT9pOI3JuGtH7yaRJ8Msv8NRTtpOIP4SGQmoqzJhh7g8QCXQa\n",
263 263 "0RfTxx9D376wfr0u9Xa79HTo1ctcRVinju00IgXTiN7H8vKgf3+YOVNFPhhcdZU59KxfP3NAnUig\n",
264 264 "0oi+iPLzzQ1FV14Jf/2r7TRSVk7Mx7RsCRMm2E4jcjZtmPKhJ5806+U/+EAXVgSbH34wV0DOmgWd\n",
265 265 "OtlOI3I6FXofSU+Hm24yd7/Wrm07jdiwYgUkJ0NWFlx2me00IqeoR+8DP/9sLhGZNk1FPph17gwD\n",
266 266 "Bphif/y47TQixaMR/Xn0728uqnjlFdtJxLajR80F7716wYMP2k4jYuism1KaPdv8qL5+ve0k4gQV\n",
267 267 "Kpj19a1bQ2KiOc9eJBCUunWzbNkyYmJiqF+/Ps8UsE3U4/FQpUoV4uLiiIuL46kA2WX0zTdw//3m\n",
268 268 "L3bFirbTiFPUqWMuK7ntNjh0yHYakaIpVesmPz+fhg0bsmLFCsLDw2ndujWpqanExsaefMbj8fDC\n",
269 269 "Cy+wePHicwdxUOvm2DFzeXTv3qbYi5ypf3+oXh1eftl2Egl2fp+MzczMJDo6mqioKCpUqEDfvn1Z\n",
270 270 "tGjRWc85pYAX1ZNPwiWXwIgRtpOIU6WkmJMu33/fdhKR8ytVoc/NzSUyMvLkxxEREeTm5p72TEhI\n",
271 271 "CKtXr6Z58+Z069aNzZs3l+Yt/S4jw6ywefNNnS8vhatWzfw3Mngw/Pij7TQi51aqydiQIty51rJl\n",
272 272 "S7Kzs6lYsSJLly6lZ8+ebN26tcBnx40bd/L3iYmJJCYmliZesR06ZJbPpaRArVpl+tYSgDp2NO29\n",
273 273 "u++GefN0BaGUDY/Hg8fjKdbnlKpHn5GRwbhx41i2bBkATz/9NOXKlWPMmDGFfk7dunXZsGED1atX\n",
274 274 "Pz2IA3r0I0fC7t3wz39ajSEB5NdfzeqbMWPMBK1IWfN7jz4+Pp5t27axY8cOjhw5wty5c0lKSjrt\n",
275 275 "mby8vJMhMjMz8Xq9ZxV5J1i5Et5+W5NrUjwXXWQGBqNGwX/+YzuNSMFK1boJDQ0lJSWFrl27kp+f\n",
276 276 "z+DBg4mNjWXq1KkADBkyhLfffptXX32V0NBQKlasyJw5c3wS3Jf274dBg0xv3oH/DxKHa97cFPpB\n",
277 277 "g8xZSJrbEafRzljgzjvNr9OnW3l7cYH8fHOs8YABpmcvUlZ0qFkRpKXBPffAl1+aJZUiJbVlC7Rv\n",
278 278 "D+vWQVSU7TQSLFToz2PvXnPv61tvQYcOZfrW4lLPPmvW1quFI2VFp1eex333wc03q8iL7zzwgLlP\n",
279 279 "eNo020lETgnaQ80WLTJ3gX7xhe0k4iahoWYjVfv2cO21auGIMwRl62bfPmjSBP71L/MXUsTXTrRw\n",
280 280 "VqzQRirxL/XoC3HHHXDBBTpjXvzn2DGzCmfgQK3CEf9SoS/Ahx+av3ybNmmVjfiXVuFIWdBk7BkO\n",
281 281 "HjRr5l97TUVe/C821txEdddd4IzhlASroCr0jz9ufpzu1s12EgkWo0bBnj1mCa+ILUHTulmzxtz1\n",
282 282 "uWkT1Kjht7cROctnn8F118HGjXDZZbbTiNuodfO7334z54ZPmaIiL2WvZUu4/XbdVib2BMWI/okn\n",
283 283 "zGhqwQItdRM7Dh2Cpk3N6ahqHYovadUNZkNU587m19q1ff7lRYpsxQrzk+WmTXDxxbbTiFsEfaHP\n",
284 284 "z4crroAhQ8zaeRHbBg40K76mTLGdRNwi6Av9yy+by0Q8HrVsxBl+/NHsyl64ENq0sZ1G3CCoC31O\n",
285 285 "DrRoAZ9+CjExPvuyIqU2Zw5MmAAbNpgd2iKlEdSrboYPh3vvVZEX5+nTB+rUMefhiJQFV47oFy2C\n",
286 286 "0aPNBOxFF/nkS4r41HffmWWX6enQsKHtNBLIgrJ1c+AANG4MM2fqnHlxtilTzKDkww81hyQlF5St\n",
287 287 "m7FjoWNHFXlxvnvvNUdmz55tO4m4natG9Ce2mn/1FVx6qY+CifjRunXQowds3gzVq9tOI4EoqFo3\n",
288 288 "+flmudqwYTBggO9yifjbsGFw9ChMnWo7iQSioCr0U6aYtckffaR+pwSWn3+GRo1g/nxo29Z2Ggk0\n",
289 289 "QVPos7MhLk4rGCRwzZ17am19hQq200ggCZrJ2OHD4b77VOQlcPXuDbVqwd/+ZjuJuFHAj+gXLoQx\n",
290 290 "Y+DLL+HCC/0QTKSMfP21mWfasMFsqBIpCte3bg4eNL3NN9/Uckpxh6eeMitxFi2ynUQChetbN3/9\n",
291 291 "KyQkqMiLezz0EGzdan5SFfGVgB3Rb9kC7dubC0Vq1vRjMJEy5vGYG6k2b4bKlW2nEadzbevG64VO\n",
292 292 "naBnTzMRK+I2AwaYTX/PPWc7iTidawt9aqo5+W/dOggN9XMwEQt27zbn1i9fDs2b204jTubKQr9/\n",
293 293 "P8TGanOJuN/06WahwapVUC6gZ9PEn1w5GTtuHHTtqiIv7jd4MBw7BrNm2U4igS6gRvQbN5re/Fdf\n",
294 294 "wZ/+VEbBRCzasAG6dzeLD6pVs51GnMhVrRuv16yy6d8f7r67DIOJWHbPPeb8pr//3XYScSJXFfqZ\n",
295 295 "MyElBTIyoHz5MgwmYtlPP5l5qffeg1atbKcRp3FNof/pJ7MD9t13IT6+jIOJOMCMGfDaa7BmjSZm\n",
296 296 "5XSumYx9/HGzZl5FXoJVcrJZSvz667aTSCBy/Ij+xGSUbuCRYPf552bF2ebNUKOG7TTiFAHfujl+\n",
297 297 "HK680ky+DhxoKZiIg4wYAYcPw7RptpOIUwR86+Yf/zA/riYn204i4gxPPglLlsDatbaTSCBx7Ih+\n",
298 298 "zx5o3FhbwEXONHs2vPgiZGZqBZoE+Ij+kUegXz8VeZEz9e9vTrVU+0aKypEj+owM6NXL7AasUsVy\n",
299 299 "MBEH2rQJOnY0v152me00YlNAjujz881OwMmTVeRFCtOkCdx2Gzz8sO0kEggcV+hffdUU+FtusZ1E\n",
300 300 "xNnGjjVzWOnptpOI0zmqdbNrl5cmTeDjj81OWBE5tzlz4OmnzX4T3c0QnMqkdbNs2TJiYmKoX78+\n",
301 301 "zzzzTIHPDB8+nPr169O8eXOysrIK/VoPPWTWy6vIixRNnz5m89Qrr9hOIk5WqhF9fn4+DRs2ZMWK\n",
302 302 "FYSHh9O6dWtSU1OJjY09+UxaWhopKSmkpaWxdu1aRowYQUZGxtlBQkKIjPTqnkyRYtqyBRISzDHe\n",
303 303 "tWrZTiNlze8j+szMTKKjo4mKiqJChQr07duXRYsWnfbM4sWLSf59x1ObNm3Yt28feXl5BX69F15Q\n",
304 304 "kRcprthYc0nJQw/ZTiJOVapCn5ubS2Rk5MmPIyIiyM3NPe8zOTk5BX69m24qTRqR4PXEE/DJJ2Z+\n",
305 305 "S+RMpZq+CQkJKdJzZ/5YUdjnjR8/7uTvExMTSUxMLGk0kaBSubLZLXvvvZCVBRUq2E4k/uLxePB4\n",
306 306 "PMX6nFIV+vDwcLKzs09+nJ2dTURExDmfycnJITw8vMCvN27cuNLEEQlqvXqZ3bJTpsCDD9pOI/5y\n",
307 307 "5iB4/Pjx5/2cUrVu4uPj2bZtGzt27ODIkSPMnTuXpKSk055JSkpi1u+3G2dkZFC1alXCwsJK87Yi\n",
308 308 "UoCQEHML26RJUEh3VIJUqUb0oaGhpKSk0LVrV/Lz8xk8eDCxsbFMnToVgCFDhtCtWzfS0tKIjo6m\n",
309 309 "UqVKzJgxwyfBReRs9evD0KEwahTMnWs7jTiFozZMOSSKSEA7dMic/Dp9OnTubDuN+FtAnnUjIqVT\n",
310 310 "sSK89JKZmP3tN9tpxAlU6EVcqEcPaNgQnn/edhJxArVuRFzq22+hdWtYvx6iomynEX9R60YkiNWt\n",
311 311 "CyNHmpcENxV6ERd78EH46it47z3bScQmFXoRF7voIrO2/r774PBh22nEFhV6EZfr2hVatoRCThGX\n",
312 312 "IKDJWJEgkJ0NcXGwdi3Uq2c7jfiSJmNFBIDISBg92rRwNJ4KPir0IkFi5EjYsQMWLrSdRMqaWjci\n",
313 313 "QcTjgeRk2LwZKlWynUZ8Qa0bETlNYiK0awdPPWU7iZQljehFgszOndC0KXz6KcTE2E4jpaURvYic\n",
314 314 "pVYtePxxGDZME7PBQoVeJAgNGwa7d8O8ebaTSFlQ60YkSKWnQ58+sGULXHyx7TRSUkWpnSr0IkFs\n",
315 315 "4ECoXl3HGQcyFXoROacffoAmTeDDD80ErQQeTcaKyDlddhmMH29uo9I4y71U6EWC3F13mZMt33rL\n",
316 316 "dhLxF7VuRIR16yApyZxdX7267TRSHOrRi0iR3Xcf/PorTJ9uO4kUhwq9iBTZzz9D48aQmgoJCbbT\n",
317 317 "SFFpMlZEiqxKFZgyBYYMgd9+s51GfEmFXkRO6tULoqNh8mTbScSX1LoRkdN89525enDNGqhf33Ya\n",
318 318 "OR+1bkSk2P78Z3j0URg6VGvr3UKFXkTOMnw47N0Ls2fbTiK+oNaNiBRo/Xq4/nqztr5GDdtppDBa\n",
319 319 "XikipTJiBPzyC7z+uu0kUhgVehEplf37zdr62bPh6qttp5GCaDJWRErlkkvgpZe0tj7QqdCLyDnd\n",
320 320 "eKO5W3bSJNtJpKTUuhGR88rONmvrP/4YGjWynUb+SK0bEfGJyEh48kkYPBjy822nkeJSoReRIhky\n",
321 321 "BC64AF5+2XYSKS61bkSkyLZuhbZtITMT/vIX22kE1LoRER9r0ABGjza3UmlcFjhU6EWkWB54APbt\n",
322 322 "gzfesJ1EikqtGxEpti+/hE6d4IsvoHZt22mCm1o3IuIXzZqZ0y11wmVgUKEXkRJ57DHYvh3mzbOd\n",
323 323 "RM5HrRsRKbGMDLNzduNGuPRS22mCkw41ExG/e+AB2LnTXCouZU89ehHxuwkTICsL5s+3nUQKoxG9\n",
324 324 "iJTa2rWQlGRW4dSsaTtNcFHrRkTKzGOPwaZNsHAhhITYThM8/Nq62bt3L126dKFBgwZcc8017Nu3\n",
325 325 "r8DnoqKiaNasGXFxcVx++eUlfTsRcbixY2HHDpg503YSOVOJC/2kSZPo0qULW7dupVOnTkwq5LDq\n",
326 326 "kJAQPB4PWVlZZGZmljioiDjbBRfArFnw0EPw3Xe208gflbjQL168mOTkZACSk5NZuHBhoc+qJSMS\n",
327 327 "HJo3h/vvh0GD4Phx22nkhBIX+ry8PMLCwgAICwsjLy+vwOdCQkLo3Lkz8fHxTJ8+vaRvJyIBYvRo\n",
328 328 "c6H4q6/aTiInhJ7rD7t06cKuXbvO+ucTJkw47eOQkBBCCpl9SU9Pp1atWuzevZsuXboQExNDQkJC\n",
329 329 "gc+OGzfu5O8TExNJTEw8T3wRcZrQUNOnv+oquOYaqF/fdiJ38Xg8eDyeYn1OiVfdxMTE4PF4qFmz\n",
330 330 "Jjt37qRDhw78+9//PufnjB8/nsqVKzNq1Kizg2jVjYirvPQS/POf8OmnUKGC7TTu5ddVN0lJScz8\n",
331 331 "fXp95syZ9OzZ86xnDh06xIEDBwA4ePAgy5cvp2nTpiV9SxEJIMOGQfXqMH687SRS4hH93r176d27\n",
332 332 "N9999x1RUVHMmzePqlWr8v3333PnnXfy3nvv8c0339CrVy8Ajh07Rv/+/XnkkUcKDqIRvYjr5OVB\n",
333 333 "ixYwdy60b287jTtpw5SIWJeWZo4z/vxzqFbNdhr3UaEXEUcYPhx27TIje+2a9S0daiYijvDss7Bl\n",
334 334 "C7z5pu0kwUkjehEpE5s2QYcOsHq1llz6kkb0IuIYTZqY83D69YPffrOdJrhoRC8iZcbrhV69IDLS\n",
335 335 "rLOX0tOIXkQcJSQE3ngDliyBt9+2nSZ4aEQvImVu/Xro1s3066OjbacJbBrRi4gjxcebfv1//zcc\n",
336 336 "Pmw7jftpRC8iVni90LcvVK0KU6faThO4NKIXEccKCYHp02HlSnP4mfiPRvQiYtUXX0DnzvDRR6Az\n",
337 337 "D4tPI3oRcbzmzeHFF6FnT9i713Yad9KIXkQc4YEHzO7ZtDRzeYkUjUb0IhIwnn0W8vPh0UdtJ3Ef\n",
338 338 "FXoRcYTQUHO65fz5MGeO7TTuotaNiDjKicnZ5cshLs52GudT60ZEAk7z5pCSYiZnd+60ncYdVOhF\n",
339 339 "xHH69IE77oAePeDgQdtpAp9aNyLiSF4vDBgA+/ebA9DKl7edyJnUuhGRgHVi5+xPP8GYMbbTBDYV\n",
340 340 "ehFxrAsugHfegXff1Xk4paFtCSLiaNWrm01U7dpBrVqQlGQ7UeDRiF5EHK9ePTOqv+MO+Phj22kC\n",
341 341 "jwq9iASE+HhITTVn2Gdl2U4TWFToRSRgdOoEr74K3bvDtm220wQO9ehFJKDcdJM55bJrV1i1CsLD\n",
342 342 "bSdyPhV6EQk4d95pll127Agej5mklcKp0ItIQBo92px22aGDuaVKxb5wKvQiErAeeQSOHzcj+5Ur\n",
343 343 "oWZN24mcSYVeRALaY4+dKvYffaRiXxAVehEJeE88YY5MSEiADz6AqCjbiZxFhV5EXOHxx6FqVVPs\n",
344 344 "ly6FJk1sJ3IOFXoRcY1hw8yRCZ07w8KFcMUVthM5gzZMiYir3HILvPGGORNn6VLbaZxBhV5EXKdb\n",
345 345 "NzOiHzQIXn7ZnG0fzHTxiIi41rffwvXXw9VXw5QpUKGC7US+p4tHRCSo1a0Lq1ebgt+9O/z4o+1E\n",
346 346 "dqjQi4irValijjhu2hRatYLMTNuJyp4KvYi4XmgoPP88vPCCaeWkpARX3149ehEJKtu3mzPto6Ph\n",
347 347 "tdegRg3biUpHPXoRkTNER5u+fUQENGtmril0O43oRSRoeTwwYAB06QKTJ5udtYFGI3oRkXNITIQv\n",
348 348 "v4Ty5SE2FmbPdmfvXiN6ERFg7VoYOhQuucRssmra1HaiotGIXkSkiNq0gXXroHdv08q59Vb45hvb\n",
349 349 "qXxDhV5E5Hfly8M995iLxxs0gMsvN6P87dttJzvbsWPmspWiKHGhnz9/Po0bN6Z8+fJ89tlnhT63\n",
350 350 "bNkyYmJiqF+/Ps8880xJ305EpMxcfDH8z//Av/9tTsO88kq48Ub49FP7Pfyffzb7AaKjzdHMRVHi\n",
351 351 "Qt+0aVMWLFhA+/btC30mPz+fYcOGsWzZMjZv3kxqaipbtmwp6VsGDY/HYzuCY+h7cYq+F6eU1ffi\n",
352 352 "0kthwgTYscMcfTxwIDRuDM8+C99/XyYRAHM37vLl0L8/1KljWkzz5kF6etE+v8SFPiYmhgYNGpzz\n",
353 353 "mczMTKKjo4mKiqJChQr07duXRYsWlfQtg4b+Qp+i78Up+l6cUtbfi0qV4N57YetWmDrV/Nq4MVx1\n",
354 354 "FUyaBF995fuR/oEDsGABDB4M4eHw6KPmfP3t2yE11bSVisqvF4/k5uYSGRl58uOIiAjWrl3rz7cU\n",
355 355 "EfGbE9cVJiSYYxQ8HliyxByYdvCgafFceaW53aphQ3OoWlFOzNy7F/7v/8xr3TpYs8b8vm1bc2TD\n",
356 356 "o49CvXolz33OQt+lSxd27dp11j+fOHEiPXr0OO8XDwkJKXkyEREHu+giuPZa80pJgZwcU6AzMuCV\n",
357 357 "V8yoPzcXqlUzxyzUqAEXXGA+1+uF/fvNaZp79ph/1qCBebVqZVb8tGwJF17oo7DeUkpMTPRu2LCh\n",
358 358 "wD9bs2aNt2vXric/njhxonfSpEkFPluvXj0voJdeeumlVzFe9erVO2+d9knrxltIcyo+Pp5t27ax\n",
359 359 "Y8cOateuzdy5c0lNTS3w2e1OXL8kIuICJZ6MXbBgAZGRkWRkZNC9e3euu+46AL7//nu6d+8OQGho\n",
360 360 "KCkpKXTt2pVGjRrRp08fYmNjfZNcRESKxDFHIIiIiH9Y3xmrDVWnDBo0iLCwMJoGyiEbfpKdnU2H\n",
361 361 "Dh1o3LgxTZo04aWXXrIdyZpff/2VNm3a0KJFCxo1asQjjzxiO5J1+fn5xMXFFWlBiJtFRUXRrFkz\n",
362 362 "4uLiuPw8ay2tjujz8/Np2LAhK1asIDw8nNatW5Oamhq07Z1Vq1ZRuXJlbr/9djZu3Gg7jjW7du1i\n",
363 363 "165dtGjRgl9++YVWrVqxcOHCoP3v4tChQ1SsWJFjx47Rrl07nnvuOdq1a2c7ljUvvPACGzZs4MCB\n",
364 364 "AyxevNh2HGvq1q3Lhg0bqF69+nmftTqi14aq0yUkJFCtWjXbMayrWbMmLVq0AKBy5crExsbyfVlu\n",
365 365 "Q3SYihUrAnDkyBHy8/OL9BfbrXJyckhLS+OOO+7QabcUvhDmTFYLfUEbqnJzcy0mEqfZsWMHWVlZ\n",
366 366 "tGnTxnYUa44fP06LFi0ICwujQ4cONGrUyHYka+6//34mT55MuXLWu87WhYSE0LlzZ+Lj45k+ffo5\n",
367 367 "n7X63dKGKjmXX375hZtvvpkpU6ZQuXJl23GsKVeuHJ9//jk5OTl88sknQXsUwpIlS7jsssuIi4vT\n",
368 368 "aB5IT08nKyuLpUuX8ve//51Vq1YV+qzVQh8eHk52dvbJj7Ozs4mIiLCYSJzi6NGj3HTTTdx66630\n",
369 369 "7NnTdhxHqFKlCt27d2f9+vW2o1ixevVqFi9eTN26denXrx8fffQRt99+u+1Y1tSqVQuAP/3pT9x4\n",
370 370 "441kZmYW+qzVQv/HDVVHjhxh7ty5JCUl2YwkDuD1ehk8eDCNGjVi5MiRtuNYtWfPHvbt2wfA4cOH\n",
371 371 "+eCDD4iLi7Ocyo6JEyeSnZ3Nt99+y5w5c+jYsSOzZs2yHcuKQ4cOceDAAQAOHjzI8uXLz7laz2qh\n",
372 372 "14aq0/VNJLb3AAAAlUlEQVTr14+2bduydetWIiMjmTFjhu1IVqSnpzN79mxWrlxJXFwccXFxLFu2\n",
373 373 "zHYsK3bu3EnHjh1p0aIFbdq0oUePHnTq1Ml2LEcI5tZvXl4eCQkJJ/+7uP7667nmmmsKfV4bpkRE\n",
374 374 "XE5T1yIiLqdCLyLicir0IiIup0IvIuJyKvQiIi6nQi8i4nIq9CIiLqdCLyLicv8PoaUAhzXYTeQA\n",
375 375 "AAAASUVORK5CYII=\n"
376 376 ],
377 377 "text/plain": [
378 378 "<matplotlib.figure.Figure at 0x10866ae90>"
379 379 ]
380 380 },
381 381 "metadata": {},
382 382 "output_type": "display_data"
383 383 }
384 384 ],
385 385 "source": [
386 386 "wontshutup()"
387 387 ]
388 388 },
389 389 {
390 390 "cell_type": "markdown",
391 391 "metadata": {},
392 392 "source": [
393 393 "And you can selectively disable capturing stdout, stderr or rich display, by passing `--no-stdout`, `--no-stderr` and `--no-display`"
394 394 ]
395 395 },
396 396 {
397 397 "cell_type": "code",
398 398 "execution_count": 19,
399 399 "metadata": {
400 400 "collapsed": false
401 401 },
402 402 "outputs": [
403 403 {
404 404 "name": "stderr",
405 405 "output_type": "stream",
406 406 "text": [
407 407 "hello, stderr\n"
408 408 ]
409 409 }
410 410 ],
411 411 "source": [
412 412 "%%capture cap --no-stderr\n",
413 413 "print('hi, stdout')\n",
414 414 "print(\"hello, stderr\", file=sys.stderr)"
415 415 ]
416 416 },
417 417 {
418 418 "cell_type": "code",
419 419 "execution_count": 20,
420 420 "metadata": {
421 421 "collapsed": false
422 422 },
423 423 "outputs": [
424 424 {
425 425 "data": {
426 426 "text/plain": [
427 427 "'hi, stdout\\n'"
428 428 ]
429 429 },
430 430 "execution_count": 20,
431 431 "metadata": {},
432 432 "output_type": "execute_result"
433 433 }
434 434 ],
435 435 "source": [
436 436 "cap.stdout"
437 437 ]
438 438 },
439 439 {
440 440 "cell_type": "code",
441 441 "execution_count": 21,
442 442 "metadata": {
443 443 "collapsed": false
444 444 },
445 445 "outputs": [
446 446 {
447 447 "data": {
448 448 "text/plain": [
449 449 "''"
450 450 ]
451 451 },
452 452 "execution_count": 21,
453 453 "metadata": {},
454 454 "output_type": "execute_result"
455 455 }
456 456 ],
457 457 "source": [
458 458 "cap.stderr"
459 459 ]
460 460 },
461 461 {
462 462 "cell_type": "code",
463 463 "execution_count": 22,
464 464 "metadata": {
465 465 "collapsed": false
466 466 },
467 467 "outputs": [
468 468 {
469 469 "data": {
470 470 "text/plain": [
471 471 "[]"
472 472 ]
473 473 },
474 474 "execution_count": 22,
475 475 "metadata": {},
476 476 "output_type": "execute_result"
477 477 }
478 478 ],
479 479 "source": [
480 480 "cap.outputs"
481 481 ]
482 482 }
483 483 ],
484 "metadata": {
485 "signature": "sha256:df6354daf203e842bc040989d149760382d8ceec769160e4efe8cde9dfcb9107"
486 },
484 "metadata": {},
487 485 "nbformat": 4,
488 486 "nbformat_minor": 0
489 487 } No newline at end of file
@@ -1,1325 +1,1323
1 1 {
2 2 "cells": [
3 3 {
4 4 "cell_type": "markdown",
5 5 "metadata": {},
6 6 "source": [
7 7 "# Custom Display Logic"
8 8 ]
9 9 },
10 10 {
11 11 "cell_type": "markdown",
12 12 "metadata": {},
13 13 "source": [
14 14 "## Overview"
15 15 ]
16 16 },
17 17 {
18 18 "cell_type": "markdown",
19 19 "metadata": {},
20 20 "source": [
21 21 "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",
22 22 "\n",
23 23 "* JavaScript\n",
24 24 "* HTML\n",
25 25 "* PNG\n",
26 26 "* JPEG\n",
27 27 "* SVG\n",
28 28 "* LaTeX\n",
29 29 "* PDF\n",
30 30 "\n",
31 31 "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",
32 32 "\n",
33 33 "1. Implementing special display methods such as `_repr_html_` when you define your class.\n",
34 34 "2. Registering a display function for a particular existing class.\n",
35 35 "\n",
36 36 "This Notebook describes and illustrates both approaches."
37 37 ]
38 38 },
39 39 {
40 40 "cell_type": "markdown",
41 41 "metadata": {},
42 42 "source": [
43 43 "Import the IPython display functions."
44 44 ]
45 45 },
46 46 {
47 47 "cell_type": "code",
48 48 "execution_count": 1,
49 49 "metadata": {
50 50 "collapsed": false
51 51 },
52 52 "outputs": [],
53 53 "source": [
54 54 "from IPython.display import (\n",
55 55 " display, display_html, display_png, display_svg\n",
56 56 ")"
57 57 ]
58 58 },
59 59 {
60 60 "cell_type": "markdown",
61 61 "metadata": {},
62 62 "source": [
63 63 "Parts of this notebook need the matplotlib inline backend:"
64 64 ]
65 65 },
66 66 {
67 67 "cell_type": "code",
68 68 "execution_count": 2,
69 69 "metadata": {
70 70 "collapsed": false
71 71 },
72 72 "outputs": [],
73 73 "source": [
74 74 "%matplotlib inline\n",
75 75 "import numpy as np\n",
76 76 "import matplotlib.pyplot as plt"
77 77 ]
78 78 },
79 79 {
80 80 "cell_type": "markdown",
81 81 "metadata": {},
82 82 "source": [
83 83 "## Special display methods"
84 84 ]
85 85 },
86 86 {
87 87 "cell_type": "markdown",
88 88 "metadata": {},
89 89 "source": [
90 90 "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",
91 91 "\n",
92 92 "* `_repr_html_`: return raw HTML as a string\n",
93 93 "* `_repr_json_`: return raw JSON as a string\n",
94 94 "* `_repr_jpeg_`: return raw JPEG data\n",
95 95 "* `_repr_png_`: return raw PNG data\n",
96 96 "* `_repr_svg_`: return raw SVG data as a string\n",
97 97 "* `_repr_latex_`: return LaTeX commands in a string surrounded by \"$\"."
98 98 ]
99 99 },
100 100 {
101 101 "cell_type": "markdown",
102 102 "metadata": {},
103 103 "source": [
104 104 "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."
105 105 ]
106 106 },
107 107 {
108 108 "cell_type": "code",
109 109 "execution_count": 3,
110 110 "metadata": {
111 111 "collapsed": false
112 112 },
113 113 "outputs": [],
114 114 "source": [
115 115 "from IPython.core.pylabtools import print_figure\n",
116 116 "from IPython.display import Image, SVG, Math\n",
117 117 "\n",
118 118 "class Gaussian(object):\n",
119 119 " \"\"\"A simple object holding data sampled from a Gaussian distribution.\n",
120 120 " \"\"\"\n",
121 121 " def __init__(self, mean=0.0, std=1, size=1000):\n",
122 122 " self.data = np.random.normal(mean, std, size)\n",
123 123 " self.mean = mean\n",
124 124 " self.std = std\n",
125 125 " self.size = size\n",
126 126 " # For caching plots that may be expensive to compute\n",
127 127 " self._png_data = None\n",
128 128 " \n",
129 129 " def _figure_data(self, format):\n",
130 130 " fig, ax = plt.subplots()\n",
131 131 " ax.hist(self.data, bins=50)\n",
132 132 " ax.set_title(self._repr_latex_())\n",
133 133 " ax.set_xlim(-10.0,10.0)\n",
134 134 " data = print_figure(fig, format)\n",
135 135 " # We MUST close the figure, otherwise IPython's display machinery\n",
136 136 " # will pick it up and send it as output, resulting in a double display\n",
137 137 " plt.close(fig)\n",
138 138 " return data\n",
139 139 " \n",
140 140 " def _repr_png_(self):\n",
141 141 " if self._png_data is None:\n",
142 142 " self._png_data = self._figure_data('png')\n",
143 143 " return self._png_data\n",
144 144 " \n",
145 145 " def _repr_latex_(self):\n",
146 146 " return r'$\\mathcal{N}(\\mu=%.2g, \\sigma=%.2g),\\ N=%d$' % (self.mean,\n",
147 147 " self.std, self.size)"
148 148 ]
149 149 },
150 150 {
151 151 "cell_type": "markdown",
152 152 "metadata": {},
153 153 "source": [
154 154 "Create an instance of the Gaussian distribution and return it to display the default representation:"
155 155 ]
156 156 },
157 157 {
158 158 "cell_type": "code",
159 159 "execution_count": 4,
160 160 "metadata": {
161 161 "collapsed": false
162 162 },
163 163 "outputs": [
164 164 {
165 165 "data": {
166 166 "image/png": [
167 167 "iVBORw0KGgoAAAANSUhEUgAAAXIAAAENCAYAAAASUO4dAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\n",
168 168 "AAALEgAACxIB0t1+/AAAElNJREFUeJzt3X+wXGV9x/H3JpefITfhCr1JSyCIRH5UJbQgrVhXChas\n",
169 169 "DXE6onbaBoownRG0tVUSOg63vxQY+8tRoVOQuTIOSq3QQGtNiGyr1SK0IfxqTBNNB2zuhUJoLogk\n",
170 170 "kO0fz9ncvZu9956z9+yefXbfr5mdPefZs7tPbnY/++z3POcsSJIkSZIkSZIkSZIkSZIkSZIkSZJ6\n",
171 171 "1olFd6DNlgJHFt0JKYt5RXdAXe8sYAtwEyHEzym2O233DPCxojshZVEqugPqGjcD/wrc3tB+E/BV\n",
172 172 "4EFgHXBNm57/1wij4bOBu4Avtel5Gp0B/Drw+3VtZwGnAl/oUB+m06xvq4HTgP3AD5n8/8raLqkH\n",
173 173 "fQf424a204GLkuU3AVe36blfV/fYxwC76UwJ5yOED6nbmtyWJcTfTPjweQoYSNqGCR9G9wI/n1Pf\n",
174 174 "FgH/Xrf+HeA1GduPaaEv6nKWVgQwH7gPOA84vK69DHwjWX5X3XLeTmeynPG/wHbgZ9r0XPX+HPj7\n",
175 175 "aW57hvABk8YDwD8B24BfTdrGCSH+HuDbOfXtF4An6ta3EP7PsrS/vYW+qMsNzL6J+sDpwCbCV/mL\n",
176 176 "CKNLgCOAl5Pls4BPZHzc1wJXzHD7vxHC6h+ZHPmXCCWW7RmfK+tz1kxXXtxC+DBJ0495wD7g08BH\n",
177 177 "gS8n7QuAl3Ls23HA83XrzwMnA89lbFePMcgFoS59O6EU8H5CkB8G7K3b5kigWrc+H/hn4Nxk/Vbg\n",
178 178 "k0wNvu8T6uqz2Qc8liz/MvAQ8PA0264A/gQ4FvhZoAL8A6HGn+U5a6rTtO9OniuNMwl9fowwkj4T\n",
179 179 "+I8mjz3Xvi0Gfly3vhc4KtkuS7t6jKUVQXhzvwysB94B/AQh3B+o22Z+w31+DvjvZLmUrLc6iq5Z\n",
180 180 "DFxK2MHXzBAhsH+TUCLYlGx78zTbpzHdiPwl4NCUj/FG4BHCDsXPEer9rwe+N4d+NevbREPbEYRR\n",
181 181 "d9Z29RhH5FoE/ChZniDUeq8CngU+W7fdKw33uxD4erK8Eni0yWNnKSWUgLXAB4AXgBOY/KCo+WDS\n",
182 182 "p9oo87C6vrfynDD9iHwR6UOvfkB0C+ED7Qngr3Lu2w7Ct5Ca1xBG/s+nbD8maZfUI44izET5babO\n",
183 183 "ZDgT+D8OroePMvVr+YPATyfLHweuBFbNoT8fItSklxC+DbwtaT+ZyaC8kTAtEEJd/1NzeL6aS2k+\n",
184 184 "a+Uq4Bfr1uv7Ue8QwjeEejcT6v55920BUz8wtxC+PWVtV49p/Lqs/lEGvkUoCdxb174LeAOwmamj\n",
185 185 "tyFCMPyAUJ9eRxjxLSSURBYBOwl14KzOJdTnrwR+D7ic8OEwQZjbvr3u8k7CTr8zCDX5/S08X81V\n",
186 186 "hNLMm5J/w2Ymd+5eCfw1k99E6vtRcxZh1H08oQw1kbR/n1DG+FbOfXshuawi/P/dSxjF78vYrj61\n",
187 187 "GPgK8J+Er4xvJryxNxKmXG1ItlFchjNsu5iwkxFCwPxp/t1p6lDgrR16rprDCTsti+6HlKtR4LeS\n",
188 188 "5QHC6OtGJuf+XgNcX0C/1Fm/QyjDfJrOzPMGeC+d/+Z4KWFnZdH9kHKziOZfl7cyOaJbkqyrt5WY\n",
189 189 "eWddL1gGXFx0J6S8nUGo/91GqJn+DaFWurtum1LDuiSpQ9LMIx8gzGT4XHL9ImGaWL0q00/jkiS1\n",
190 190 "UZp55E8llweT9a8QZiyMEUoqY4RDqp9uvONJJ51U3bFjRz49laT+sYP05/pJNSIfA55k8nDl84HH\n",
191 191 "gXuANUnbGuDug3qyYwfVatVLDpfrrruu8D700sW/p3/Pbr4AJ6UNcUh/ZOfVwBcJU7B2AJcR9uDf\n",
192 192 "SZjzuxO4JMsTS5LykTbItxAOfmh0fo59kSS1wJNmRaJcLhfdhZ7i3zNf/j2L1e6feqsm9R5JUkql\n",
193 193 "Ugky5LMjckmKnEEuSZEzyCUpcga5JEXOIJekyBnkUocMDg5RKpUYHBwquivqMU4/lDokTCmrAiV8\n",
194 194 "X2gmTj+UpD5jkEsdN0CpVLLMotxYWpE6pL60Mnn6fsssOpilFUnqMwa5JEXOIJe6iFMU1Qpr5FKH\n",
195 195 "pKmRO0VRYI1ckvqOQS5JkTPIJSlyBrkkRc4gl6TIGeSSFDmDXGoT54SrU5xHLrVJ45xw55ErLeeR\n",
196 196 "S1KfMcglKXIGuSRFziCXpMgNpNxuJ7AHeBXYB5wNDAFfBk5Ibr8EeD73HkqSZpR2RF4FysBKQogD\n",
197 197 "rAU2AiuATcm6JKnDspRWGqfCrAJGk+VRYHUuPZIkZZJlRH4f8BBwRdI2DIwny+PJuiSpw9LWyN8C\n",
198 198 "7AKOJZRTtjbcXmXyCAdJUgelDfJdyfUzwF2EOvk4sAQYA5YCTze748jIyIHlcrlMuVxuradSTxqg\n",
199 199 "VCqxcOHR7NnzXNGdUUEqlQqVSqXl+6c5BPRIYD4wASwANgB/CJwPPAvcQNjRuZiDd3h6iL76VtpD\n",
200 200 "9KfbxvdO/8p6iH6aEfkwYRRe2/6LhDB/CLgTuJzJ6YeSpA7zpFlSmzgiV6s8aZYk9RmDXJIiZ5BL\n",
201 201 "UuQMcqmL+StDSsOdnVKb5LGz052f/cmdnZLUZwxySYqcQS5JkTPIJSlyBrkkRc4gl6TIGeSSFDmD\n",
202 202 "XJIiZ5BLUuQMcmmO2nMY/UDt6D5pVh6iL83RdIfRz/UQ/cZr30v9w0P0JanPGOSSFDmDXJIiZ5BL\n",
203 203 "UuQMckmKnEEuSZEzyCUpcga5JEXOIJekyBnkkhQ5g1ySImeQS1LkDHJJilzaIJ8PbAbuSdaHgI3A\n",
204 204 "NmADsDj/rkm9wlPSqr3SBvmHgSeYPPfmWkKQrwA2JeuSmnqFybeOlL80QX4c8E7gFibPj7sKGE2W\n",
205 205 "R4HV+XdNkpRGmiD/C+CjwP66tmFgPFkeT9YlSQUYmOX2dwFPE+rj5Wm2qTLD98aRkZEDy+VymXJ5\n",
206 206 "uoeRpP5UqVSoVCot33+2PTCfAH6DUOQ7HBgEvgqcRQj2MWApcD9wSpP7+1Nv6nlpfuqt+TX4U29q\n",
207 207 "Ju+fersWWAacCLwP+AYh2NcDa5Jt1gB3Z+2oJCkfWeeR14YE1wMXEKYfnpesS5IK0O7JrZZW1POK\n",
208 208 "KK0MDg4xMbEbgIULj2bPnufa+C9Up2UtrRjk0hwVEeST23HQbYpf3jVySVKXm236oaSOmO0w/trt\n",
209 209 "hwD7OtQnxcIgl7pC7TD+6cK8/vaZtlM/srQiSZEzyCUpcga5JEXOIJekyBnkkhQ5g1ySImeQS1Lk\n",
210 210 "DHJJipxBLkmRM8glKXIGuSRFziCXpMgZ5JIUOYNckiJnkEtS5AxySYqcQS5JkTPIpdyEn2MbHBwq\n",
211 211 "uiPqM/7Um5Sb8HNsExP+DJs6yxG5JEXOIJekyBnkUvSszfc7a+RS9KzN9ztH5JIUudmC/HDgAeBh\n",
212 212 "4Angk0n7ELAR2AZsABa3q4OSpJnNFuQ/Bt4OnAG8MVk+F1hLCPIVwKZkXZJUgDSllR8l14cC84Hd\n",
213 213 "wCpgNGkfBVbn3zVJUhppgnweobQyDtwPPA4MJ+sk18Nt6Z0kaVZpZq3sJ5RWFgFfJ5RX6lWTS1Mj\n",
214 214 "IyMHlsvlMuVyOWsfpcINDg4xMbGbhQuPZs+e54rujnpMpVKhUqm0fP+s85U+DrwEfAAoA2PAUsJI\n",
215 215 "/ZQm21er1WkzXopGqVQijFdKNL6m62+r36ZZ+9RrZrgt7fXUx/D91hvCayd9Ps9WWjmGyRkpRwAX\n",
216 216 "AJuB9cCapH0NcHemXkqScjNbaWUpYWfmvORyO2GWymbgTuByYCdwSfu6KEmaSbsPBbO0op7QrLRS\n",
217 217 "q5sH3VBaOQR4xTp+D8haWjHIpRSaBflMQV1UjdxaeW/Iu0YuSepyBrkkRc4gl6TIGeSSFDmDXJIi\n",
218 218 "Z5BLuRuozTqQOsIgl3IXfrFH6hSDXJIiZ5BLUuQMckmKnEEuSZEzyCUpcga5JEXOIJekyBnkkhQ5\n",
219 219 "g1ySImeQS1LkDHJJipxBLkmRM8glKXIDRXdAiounqFX3cUQuZVI7Ra2nqVX3MMglKXIGuSRFziCX\n",
220 220 "ZjA4OGRNXF3PIJdmMDGxG+vh6nYGuSRFLk2QLwPuBx4HHgM+lLQPARuBbcAGYHE7OihJmlmaIN8H\n",
221 221 "/C5wOnAO8EHgVGAtIchXAJuSdUldolbfHxwcKrorarNW9uLcDXwmubwNGAeWABXglIZtq9Wq9UXF\n",
222 222 "K+zorBLeKvXXNGnLet2+x6hWq1P67vswLskO9tT5nLVGvhxYCTwADBNCnOR6OONjSZJykOUQ/aOA\n",
223 223 "vwM+DEw03DbtoW4jIyMHlsvlMuVyOVMHJanXVSoVKpVKy/dPO3Q/BLgX+Brwl0nbVqAMjAFLCTtE\n",
224 224 "La2op1haURHaUVopAbcCTzAZ4gDrgTXJ8hpC7VyS1GFpEv9c4F+AR5gcAqwDvgvcCRwP7AQuAZ5v\n",
225 225 "uK8jckXNEbmKkHVE3u5jjw1yRc0gVxHaPWtFktRlDHJJipxBLkmRM8ilJjx9rWJikEtNePpaxcQg\n",
226 226 "l6TIGeSSFDmDXKpjbVwxMsilOtbGFSODXJIiZ5BLPWfA8lCfMcilnvMKlof6i0EuSZEzyCUpcga5\n",
227 227 "JEXOIJekyBnkkhQ5g1ySImeQS1LkDHJJipxBLkmRM8ilPlM7w+Pg4FDRXVFOBorugKTOqp3hcWLC\n",
228 228 "87H0CkfkkhQ5g1ySImeQS1LkDHJJipxBLkmRSxPknwfGgUfr2oaAjcA2YAOwOP+uSZLSSBPktwEX\n",
229 229 "NrStJQT5CmBTsi4pKuEn4ZxTHr80Qf5NYHdD2ypgNFkeBVbn2SlJnVD7SbhqMrdcsWq1Rj5MKLeQ\n",
230 230 "XA/n0x1JUlZ57Oys4i+9SlJhWj1EfxxYAowBS4Gnp9twZGTkwHK5XKZcLrf4lJJaE2rhCxcezZ49\n",
231 231 "zxXdGTVRqVSoVCot3z/tyRaWA/cAb0jWbwSeBW4g7OhcTPMdntVq1cG64lEqlQhfMGe7JsU23fcY\n",
232 232 "1Wq1yb+RA7epO4T/o9T5nKq0cgfwbeD1wJPAZcD1wAWE6YfnJeuSpAK0+/RnjsjVlQYHh5iY2H1Q\n",
233 233 "ucERubpB1hG5p7FVX/JUruolHqIvSZEzyCUpcga5+kbtJ86S+mMfGujjf3tvM8jVN2p18f49fq12\n",
234 234 "SL56jUEuSZEzyCUpcga5el6tNq6ZDHg624g5j1w9b7I2bphPL9TPnVcfJ0fkkhQ5g1x9zpKC4mdp\n",
235 235 "RX3OkoLi54hckiJnkEtS5AxySYqcQS5JkTPIJSlyBrkkRc4glwBP8aqYGeQS4CleFTODXJIiZ5BL\n",
236 236 "UuQMckmKnEEuSZHzpFmKyq5du3jxxRc57LDDWLZsWdHdkbqCI3JFY//+/Rx//AmsXHkhy5efyNjY\n",
237 237 "2JTba78E5Clp5yJMwyyVDm167d+2OzkiVzSq1SqvvvoqL7ywnQULjmfv3r1Tbq/9EpCnpJ2L2jTM\n",
238 238 "UtNr/7bdyRG5JEVurkF+IbAV+C/gmrl3R5KU1VyCfD7wGUKYnwa8Hzg1j07pYJVKpeguRGRqnVd5\n",
239 239 "mvrTeLX9Es3arKd3zlyC/GxgO7AT2Ad8Cbg4hz6pCYM8i1qddx8edp+32k/j7QYm90vAdQe11dbV\n",
240 240 "fnMJ8p8CnqxbfyppkyR10FyC3KGOClBlcPBXePnlZ5g3z331EoQ5Ra06Bxgh1MgB1gH7gRvqttkO\n",
241 241 "nDSH55CkfrQDeF0nnmggebLlwKHAw7izU5KicxHwPcLIe13BfZEkSZIE8B7gceBV4MyG29YRDh7a\n",
242 242 "Cryjw/3qBSOE2UGbk8uFM26t6XggW752Ao8QXpPfLbYr0fk8MA48Wtc2BGwEtgEbgMUF9ItTgBXA\n",
243 243 "/UwN8tMIdfRDCHX17XiKgKyuAz5SdCciN5/w2ltOeC26b2fufkAIH2X3VmAlU4P8RuBjyfI1wPWz\n",
244 244 "PUg7gnQr4ZOk0cXAHYSjNHYS3kxnt+H5e52HKs6NB7K1h6/L1nwTaDxyahUwmiyPAqtne5BOjoh/\n",
245 245 "klAWqPEAotZcDWwBbqWgr1yR80C2/FWB+4CHgCsK7ksvGCaUW0iuh2e7Q6unsd0ILGnSfi1wT4bH\n",
246 246 "8aCig033t/0D4Cbgj5L1Pwb+DLi8Q/3qFb7m8vcWYBdwLOH1u5Uw0tTcVUnxmm01yC9o4T4/BOp/\n",
247 247 "0uW4pE1Tpf3b3kK2D00Fja/DZUz9pqjsdiXXzwB3EcpXBnnrxgmDuTFgKfD0bHdod2mlvm62Hngf\n",
248 248 "4eChE4GTcQ93Vkvrlt/N1B0kSuchwmtvOeG1+F7Ca1OtORJYmCwvIMxG83U5N+uBNcnyGuDuIjrx\n",
249 249 "bkIN8iXCJ8rX6m67lrCjaSvwS53vWvS+QJjmtYXwnztr7UxNeSBbfk4kzPx5GHgM/55Z3QH8D7CX\n",
250 250 "kJuXEWYA3UfB0w8lSZIkSZIkSZIkSZIkSZIkSZIktcn/A4eK9UXawRDUAAAAAElFTkSuQmCC\n"
251 251 ],
252 252 "text/latex": [
253 253 "$\\mathcal{N}(\\mu=2, \\sigma=1),\\ N=1000$"
254 254 ],
255 255 "text/plain": [
256 256 "<__main__.Gaussian at 0x106e7ae10>"
257 257 ]
258 258 },
259 259 "execution_count": 4,
260 260 "metadata": {},
261 261 "output_type": "execute_result"
262 262 }
263 263 ],
264 264 "source": [
265 265 "x = Gaussian(2.0, 1.0)\n",
266 266 "x"
267 267 ]
268 268 },
269 269 {
270 270 "cell_type": "markdown",
271 271 "metadata": {},
272 272 "source": [
273 273 "You can also pass the object to the `display` function to display the default representation:"
274 274 ]
275 275 },
276 276 {
277 277 "cell_type": "code",
278 278 "execution_count": 5,
279 279 "metadata": {
280 280 "collapsed": false
281 281 },
282 282 "outputs": [
283 283 {
284 284 "data": {
285 285 "image/png": [
286 286 "iVBORw0KGgoAAAANSUhEUgAAAXIAAAENCAYAAAASUO4dAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\n",
287 287 "AAALEgAACxIB0t1+/AAAElNJREFUeJzt3X+wXGV9x/H3JpefITfhCr1JSyCIRH5UJbQgrVhXChas\n",
288 288 "DXE6onbaBoownRG0tVUSOg63vxQY+8tRoVOQuTIOSq3QQGtNiGyr1SK0IfxqTBNNB2zuhUJoLogk\n",
289 289 "kO0fz9ncvZu9956z9+yefXbfr5mdPefZs7tPbnY/++z3POcsSJIkSZIkSZIkSZIkSZIkSZIkSZJ6\n",
290 290 "1olFd6DNlgJHFt0JKYt5RXdAXe8sYAtwEyHEzym2O233DPCxojshZVEqugPqGjcD/wrc3tB+E/BV\n",
291 291 "4EFgHXBNm57/1wij4bOBu4Avtel5Gp0B/Drw+3VtZwGnAl/oUB+m06xvq4HTgP3AD5n8/8raLqkH\n",
292 292 "fQf424a204GLkuU3AVe36blfV/fYxwC76UwJ5yOED6nbmtyWJcTfTPjweQoYSNqGCR9G9wI/n1Pf\n",
293 293 "FgH/Xrf+HeA1GduPaaEv6nKWVgQwH7gPOA84vK69DHwjWX5X3XLeTmeynPG/wHbgZ9r0XPX+HPj7\n",
294 294 "aW57hvABk8YDwD8B24BfTdrGCSH+HuDbOfXtF4An6ta3EP7PsrS/vYW+qMsNzL6J+sDpwCbCV/mL\n",
295 295 "CKNLgCOAl5Pls4BPZHzc1wJXzHD7vxHC6h+ZHPmXCCWW7RmfK+tz1kxXXtxC+DBJ0495wD7g08BH\n",
296 296 "gS8n7QuAl3Ls23HA83XrzwMnA89lbFePMcgFoS59O6EU8H5CkB8G7K3b5kigWrc+H/hn4Nxk/Vbg\n",
297 297 "k0wNvu8T6uqz2Qc8liz/MvAQ8PA0264A/gQ4FvhZoAL8A6HGn+U5a6rTtO9OniuNMwl9fowwkj4T\n",
298 298 "+I8mjz3Xvi0Gfly3vhc4KtkuS7t6jKUVQXhzvwysB94B/AQh3B+o22Z+w31+DvjvZLmUrLc6iq5Z\n",
299 299 "DFxK2MHXzBAhsH+TUCLYlGx78zTbpzHdiPwl4NCUj/FG4BHCDsXPEer9rwe+N4d+NevbREPbEYRR\n",
300 300 "d9Z29RhH5FoE/ChZniDUeq8CngU+W7fdKw33uxD4erK8Eni0yWNnKSWUgLXAB4AXgBOY/KCo+WDS\n",
301 301 "p9oo87C6vrfynDD9iHwR6UOvfkB0C+ED7Qngr3Lu2w7Ct5Ca1xBG/s+nbD8maZfUI44izET5babO\n",
302 302 "ZDgT+D8OroePMvVr+YPATyfLHweuBFbNoT8fItSklxC+DbwtaT+ZyaC8kTAtEEJd/1NzeL6aS2k+\n",
303 303 "a+Uq4Bfr1uv7Ue8QwjeEejcT6v55920BUz8wtxC+PWVtV49p/Lqs/lEGvkUoCdxb174LeAOwmamj\n",
304 304 "tyFCMPyAUJ9eRxjxLSSURBYBOwl14KzOJdTnrwR+D7ic8OEwQZjbvr3u8k7CTr8zCDX5/S08X81V\n",
305 305 "hNLMm5J/w2Ymd+5eCfw1k99E6vtRcxZh1H08oQw1kbR/n1DG+FbOfXshuawi/P/dSxjF78vYrj61\n",
306 306 "GPgK8J+Er4xvJryxNxKmXG1ItlFchjNsu5iwkxFCwPxp/t1p6lDgrR16rprDCTsti+6HlKtR4LeS\n",
307 307 "5QHC6OtGJuf+XgNcX0C/1Fm/QyjDfJrOzPMGeC+d/+Z4KWFnZdH9kHKziOZfl7cyOaJbkqyrt5WY\n",
308 308 "eWddL1gGXFx0J6S8nUGo/91GqJn+DaFWurtum1LDuiSpQ9LMIx8gzGT4XHL9ImGaWL0q00/jkiS1\n",
309 309 "UZp55E8llweT9a8QZiyMEUoqY4RDqp9uvONJJ51U3bFjRz49laT+sYP05/pJNSIfA55k8nDl84HH\n",
310 310 "gXuANUnbGuDug3qyYwfVatVLDpfrrruu8D700sW/p3/Pbr4AJ6UNcUh/ZOfVwBcJU7B2AJcR9uDf\n",
311 311 "SZjzuxO4JMsTS5LykTbItxAOfmh0fo59kSS1wJNmRaJcLhfdhZ7i3zNf/j2L1e6feqsm9R5JUkql\n",
312 312 "Ugky5LMjckmKnEEuSZEzyCUpcga5JEXOIJekyBnkUocMDg5RKpUYHBwquivqMU4/lDokTCmrAiV8\n",
313 313 "X2gmTj+UpD5jkEsdN0CpVLLMotxYWpE6pL60Mnn6fsssOpilFUnqMwa5JEXOIJe6iFMU1Qpr5FKH\n",
314 314 "pKmRO0VRYI1ckvqOQS5JkTPIJSlyBrkkRc4gl6TIGeSSFDmDXGoT54SrU5xHLrVJ45xw55ErLeeR\n",
315 315 "S1KfMcglKXIGuSRFziCXpMgNpNxuJ7AHeBXYB5wNDAFfBk5Ibr8EeD73HkqSZpR2RF4FysBKQogD\n",
316 316 "rAU2AiuATcm6JKnDspRWGqfCrAJGk+VRYHUuPZIkZZJlRH4f8BBwRdI2DIwny+PJuiSpw9LWyN8C\n",
317 317 "7AKOJZRTtjbcXmXyCAdJUgelDfJdyfUzwF2EOvk4sAQYA5YCTze748jIyIHlcrlMuVxuradSTxqg\n",
318 318 "VCqxcOHR7NnzXNGdUUEqlQqVSqXl+6c5BPRIYD4wASwANgB/CJwPPAvcQNjRuZiDd3h6iL76VtpD\n",
319 319 "9KfbxvdO/8p6iH6aEfkwYRRe2/6LhDB/CLgTuJzJ6YeSpA7zpFlSmzgiV6s8aZYk9RmDXJIiZ5BL\n",
320 320 "UuQMcqmL+StDSsOdnVKb5LGz052f/cmdnZLUZwxySYqcQS5JkTPIJSlyBrkkRc4gl6TIGeSSFDmD\n",
321 321 "XJIiZ5BLUuQMcmmO2nMY/UDt6D5pVh6iL83RdIfRz/UQ/cZr30v9w0P0JanPGOSSFDmDXJIiZ5BL\n",
322 322 "UuQMckmKnEEuSZEzyCUpcga5JEXOIJekyBnkkhQ5g1ySImeQS1LkDHJJilzaIJ8PbAbuSdaHgI3A\n",
323 323 "NmADsDj/rkm9wlPSqr3SBvmHgSeYPPfmWkKQrwA2JeuSmnqFybeOlL80QX4c8E7gFibPj7sKGE2W\n",
324 324 "R4HV+XdNkpRGmiD/C+CjwP66tmFgPFkeT9YlSQUYmOX2dwFPE+rj5Wm2qTLD98aRkZEDy+VymXJ5\n",
325 325 "uoeRpP5UqVSoVCot33+2PTCfAH6DUOQ7HBgEvgqcRQj2MWApcD9wSpP7+1Nv6nlpfuqt+TX4U29q\n",
326 326 "Ju+fersWWAacCLwP+AYh2NcDa5Jt1gB3Z+2oJCkfWeeR14YE1wMXEKYfnpesS5IK0O7JrZZW1POK\n",
327 327 "KK0MDg4xMbEbgIULj2bPnufa+C9Up2UtrRjk0hwVEeST23HQbYpf3jVySVKXm236oaSOmO0w/trt\n",
328 328 "hwD7OtQnxcIgl7pC7TD+6cK8/vaZtlM/srQiSZEzyCUpcga5JEXOIJekyBnkkhQ5g1ySImeQS1Lk\n",
329 329 "DHJJipxBLkmRM8glKXIGuSRFziCXpMgZ5JIUOYNckiJnkEtS5AxySYqcQS5JkTPIpdyEn2MbHBwq\n",
330 330 "uiPqM/7Um5Sb8HNsExP+DJs6yxG5JEXOIJekyBnkUvSszfc7a+RS9KzN9ztH5JIUudmC/HDgAeBh\n",
331 331 "4Angk0n7ELAR2AZsABa3q4OSpJnNFuQ/Bt4OnAG8MVk+F1hLCPIVwKZkXZJUgDSllR8l14cC84Hd\n",
332 332 "wCpgNGkfBVbn3zVJUhppgnweobQyDtwPPA4MJ+sk18Nt6Z0kaVZpZq3sJ5RWFgFfJ5RX6lWTS1Mj\n",
333 333 "IyMHlsvlMuVyOWsfpcINDg4xMbGbhQuPZs+e54rujnpMpVKhUqm0fP+s85U+DrwEfAAoA2PAUsJI\n",
334 334 "/ZQm21er1WkzXopGqVQijFdKNL6m62+r36ZZ+9RrZrgt7fXUx/D91hvCayd9Ps9WWjmGyRkpRwAX\n",
335 335 "AJuB9cCapH0NcHemXkqScjNbaWUpYWfmvORyO2GWymbgTuByYCdwSfu6KEmaSbsPBbO0op7QrLRS\n",
336 336 "q5sH3VBaOQR4xTp+D8haWjHIpRSaBflMQV1UjdxaeW/Iu0YuSepyBrkkRc4gl6TIGeSSFDmDXJIi\n",
337 337 "Z5BLuRuozTqQOsIgl3IXfrFH6hSDXJIiZ5BLUuQMckmKnEEuSZEzyCUpcga5JEXOIJekyBnkkhQ5\n",
338 338 "g1ySImeQS1LkDHJJipxBLkmRM8glKXIDRXdAiounqFX3cUQuZVI7Ra2nqVX3MMglKXIGuSRFziCX\n",
339 339 "ZjA4OGRNXF3PIJdmMDGxG+vh6nYGuSRFLk2QLwPuBx4HHgM+lLQPARuBbcAGYHE7OihJmlmaIN8H\n",
340 340 "/C5wOnAO8EHgVGAtIchXAJuSdUldolbfHxwcKrorarNW9uLcDXwmubwNGAeWABXglIZtq9Wq9UXF\n",
341 341 "K+zorBLeKvXXNGnLet2+x6hWq1P67vswLskO9tT5nLVGvhxYCTwADBNCnOR6OONjSZJykOUQ/aOA\n",
342 342 "vwM+DEw03DbtoW4jIyMHlsvlMuVyOVMHJanXVSoVKpVKy/dPO3Q/BLgX+Brwl0nbVqAMjAFLCTtE\n",
343 343 "La2op1haURHaUVopAbcCTzAZ4gDrgTXJ8hpC7VyS1GFpEv9c4F+AR5gcAqwDvgvcCRwP7AQuAZ5v\n",
344 344 "uK8jckXNEbmKkHVE3u5jjw1yRc0gVxHaPWtFktRlDHJJipxBLkmRM8ilJjx9rWJikEtNePpaxcQg\n",
345 345 "l6TIGeSSFDmDXKpjbVwxMsilOtbGFSODXJIiZ5BLPWfA8lCfMcilnvMKlof6i0EuSZEzyCUpcga5\n",
346 346 "JEXOIJekyBnkkhQ5g1ySImeQS1LkDHJJipxBLkmRM8ilPlM7w+Pg4FDRXVFOBorugKTOqp3hcWLC\n",
347 347 "87H0CkfkkhQ5g1ySImeQS1LkDHJJipxBLkmRSxPknwfGgUfr2oaAjcA2YAOwOP+uSZLSSBPktwEX\n",
348 348 "NrStJQT5CmBTsi4pKuEn4ZxTHr80Qf5NYHdD2ypgNFkeBVbn2SlJnVD7SbhqMrdcsWq1Rj5MKLeQ\n",
349 349 "XA/n0x1JUlZ57Oys4i+9SlJhWj1EfxxYAowBS4Gnp9twZGTkwHK5XKZcLrf4lJJaE2rhCxcezZ49\n",
350 350 "zxXdGTVRqVSoVCot3z/tyRaWA/cAb0jWbwSeBW4g7OhcTPMdntVq1cG64lEqlQhfMGe7JsU23fcY\n",
351 351 "1Wq1yb+RA7epO4T/o9T5nKq0cgfwbeD1wJPAZcD1wAWE6YfnJeuSpAK0+/RnjsjVlQYHh5iY2H1Q\n",
352 352 "ucERubpB1hG5p7FVX/JUruolHqIvSZEzyCUpcga5+kbtJ86S+mMfGujjf3tvM8jVN2p18f49fq12\n",
353 353 "SL56jUEuSZEzyCUpcga5el6tNq6ZDHg624g5j1w9b7I2bphPL9TPnVcfJ0fkkhQ5g1x9zpKC4mdp\n",
354 354 "RX3OkoLi54hckiJnkEtS5AxySYqcQS5JkTPIJSlyBrkkRc4glwBP8aqYGeQS4CleFTODXJIiZ5BL\n",
355 355 "UuQMckmKnEEuSZHzpFmKyq5du3jxxRc57LDDWLZsWdHdkbqCI3JFY//+/Rx//AmsXHkhy5efyNjY\n",
356 356 "2JTba78E5Clp5yJMwyyVDm167d+2OzkiVzSq1SqvvvoqL7ywnQULjmfv3r1Tbq/9EpCnpJ2L2jTM\n",
357 357 "UtNr/7bdyRG5JEVurkF+IbAV+C/gmrl3R5KU1VyCfD7wGUKYnwa8Hzg1j07pYJVKpeguRGRqnVd5\n",
358 358 "mvrTeLX9Es3arKd3zlyC/GxgO7AT2Ad8Cbg4hz6pCYM8i1qddx8edp+32k/j7QYm90vAdQe11dbV\n",
359 359 "fnMJ8p8CnqxbfyppkyR10FyC3KGOClBlcPBXePnlZ5g3z331EoQ5Ra06Bxgh1MgB1gH7gRvqttkO\n",
360 360 "nDSH55CkfrQDeF0nnmggebLlwKHAw7izU5KicxHwPcLIe13BfZEkSZIE8B7gceBV4MyG29YRDh7a\n",
361 361 "Cryjw/3qBSOE2UGbk8uFM26t6XggW752Ao8QXpPfLbYr0fk8MA48Wtc2BGwEtgEbgMUF9ItTgBXA\n",
362 362 "/UwN8tMIdfRDCHX17XiKgKyuAz5SdCciN5/w2ltOeC26b2fufkAIH2X3VmAlU4P8RuBjyfI1wPWz\n",
363 363 "PUg7gnQr4ZOk0cXAHYSjNHYS3kxnt+H5e52HKs6NB7K1h6/L1nwTaDxyahUwmiyPAqtne5BOjoh/\n",
364 364 "klAWqPEAotZcDWwBbqWgr1yR80C2/FWB+4CHgCsK7ksvGCaUW0iuh2e7Q6unsd0ILGnSfi1wT4bH\n",
365 365 "8aCig033t/0D4Cbgj5L1Pwb+DLi8Q/3qFb7m8vcWYBdwLOH1u5Uw0tTcVUnxmm01yC9o4T4/BOp/\n",
366 366 "0uW4pE1Tpf3b3kK2D00Fja/DZUz9pqjsdiXXzwB3EcpXBnnrxgmDuTFgKfD0bHdod2mlvm62Hngf\n",
367 367 "4eChE4GTcQ93Vkvrlt/N1B0kSuchwmtvOeG1+F7Ca1OtORJYmCwvIMxG83U5N+uBNcnyGuDuIjrx\n",
368 368 "bkIN8iXCJ8rX6m67lrCjaSvwS53vWvS+QJjmtYXwnztr7UxNeSBbfk4kzPx5GHgM/55Z3QH8D7CX\n",
369 369 "kJuXEWYA3UfB0w8lSZIkSZIkSZIkSZIkSZIkSZIktcn/A4eK9UXawRDUAAAAAElFTkSuQmCC\n"
370 370 ],
371 371 "text/latex": [
372 372 "$\\mathcal{N}(\\mu=2, \\sigma=1),\\ N=1000$"
373 373 ],
374 374 "text/plain": [
375 375 "<__main__.Gaussian at 0x106e7ae10>"
376 376 ]
377 377 },
378 378 "metadata": {},
379 379 "output_type": "display_data"
380 380 }
381 381 ],
382 382 "source": [
383 383 "display(x)"
384 384 ]
385 385 },
386 386 {
387 387 "cell_type": "markdown",
388 388 "metadata": {},
389 389 "source": [
390 390 "Use `display_png` to view the PNG representation:"
391 391 ]
392 392 },
393 393 {
394 394 "cell_type": "code",
395 395 "execution_count": 6,
396 396 "metadata": {
397 397 "collapsed": false
398 398 },
399 399 "outputs": [
400 400 {
401 401 "data": {
402 402 "image/png": [
403 403 "iVBORw0KGgoAAAANSUhEUgAAAXIAAAENCAYAAAASUO4dAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\n",
404 404 "AAALEgAACxIB0t1+/AAAElNJREFUeJzt3X+wXGV9x/H3JpefITfhCr1JSyCIRH5UJbQgrVhXChas\n",
405 405 "DXE6onbaBoownRG0tVUSOg63vxQY+8tRoVOQuTIOSq3QQGtNiGyr1SK0IfxqTBNNB2zuhUJoLogk\n",
406 406 "kO0fz9ncvZu9956z9+yefXbfr5mdPefZs7tPbnY/++z3POcsSJIkSZIkSZIkSZIkSZIkSZIkSZJ6\n",
407 407 "1olFd6DNlgJHFt0JKYt5RXdAXe8sYAtwEyHEzym2O233DPCxojshZVEqugPqGjcD/wrc3tB+E/BV\n",
408 408 "4EFgHXBNm57/1wij4bOBu4Avtel5Gp0B/Drw+3VtZwGnAl/oUB+m06xvq4HTgP3AD5n8/8raLqkH\n",
409 409 "fQf424a204GLkuU3AVe36blfV/fYxwC76UwJ5yOED6nbmtyWJcTfTPjweQoYSNqGCR9G9wI/n1Pf\n",
410 410 "FgH/Xrf+HeA1GduPaaEv6nKWVgQwH7gPOA84vK69DHwjWX5X3XLeTmeynPG/wHbgZ9r0XPX+HPj7\n",
411 411 "aW57hvABk8YDwD8B24BfTdrGCSH+HuDbOfXtF4An6ta3EP7PsrS/vYW+qMsNzL6J+sDpwCbCV/mL\n",
412 412 "CKNLgCOAl5Pls4BPZHzc1wJXzHD7vxHC6h+ZHPmXCCWW7RmfK+tz1kxXXtxC+DBJ0495wD7g08BH\n",
413 413 "gS8n7QuAl3Ls23HA83XrzwMnA89lbFePMcgFoS59O6EU8H5CkB8G7K3b5kigWrc+H/hn4Nxk/Vbg\n",
414 414 "k0wNvu8T6uqz2Qc8liz/MvAQ8PA0264A/gQ4FvhZoAL8A6HGn+U5a6rTtO9OniuNMwl9fowwkj4T\n",
415 415 "+I8mjz3Xvi0Gfly3vhc4KtkuS7t6jKUVQXhzvwysB94B/AQh3B+o22Z+w31+DvjvZLmUrLc6iq5Z\n",
416 416 "DFxK2MHXzBAhsH+TUCLYlGx78zTbpzHdiPwl4NCUj/FG4BHCDsXPEer9rwe+N4d+NevbREPbEYRR\n",
417 417 "d9Z29RhH5FoE/ChZniDUeq8CngU+W7fdKw33uxD4erK8Eni0yWNnKSWUgLXAB4AXgBOY/KCo+WDS\n",
418 418 "p9oo87C6vrfynDD9iHwR6UOvfkB0C+ED7Qngr3Lu2w7Ct5Ca1xBG/s+nbD8maZfUI44izET5babO\n",
419 419 "ZDgT+D8OroePMvVr+YPATyfLHweuBFbNoT8fItSklxC+DbwtaT+ZyaC8kTAtEEJd/1NzeL6aS2k+\n",
420 420 "a+Uq4Bfr1uv7Ue8QwjeEejcT6v55920BUz8wtxC+PWVtV49p/Lqs/lEGvkUoCdxb174LeAOwmamj\n",
421 421 "tyFCMPyAUJ9eRxjxLSSURBYBOwl14KzOJdTnrwR+D7ic8OEwQZjbvr3u8k7CTr8zCDX5/S08X81V\n",
422 422 "hNLMm5J/w2Ymd+5eCfw1k99E6vtRcxZh1H08oQw1kbR/n1DG+FbOfXshuawi/P/dSxjF78vYrj61\n",
423 423 "GPgK8J+Er4xvJryxNxKmXG1ItlFchjNsu5iwkxFCwPxp/t1p6lDgrR16rprDCTsti+6HlKtR4LeS\n",
424 424 "5QHC6OtGJuf+XgNcX0C/1Fm/QyjDfJrOzPMGeC+d/+Z4KWFnZdH9kHKziOZfl7cyOaJbkqyrt5WY\n",
425 425 "eWddL1gGXFx0J6S8nUGo/91GqJn+DaFWurtum1LDuiSpQ9LMIx8gzGT4XHL9ImGaWL0q00/jkiS1\n",
426 426 "UZp55E8llweT9a8QZiyMEUoqY4RDqp9uvONJJ51U3bFjRz49laT+sYP05/pJNSIfA55k8nDl84HH\n",
427 427 "gXuANUnbGuDug3qyYwfVatVLDpfrrruu8D700sW/p3/Pbr4AJ6UNcUh/ZOfVwBcJU7B2AJcR9uDf\n",
428 428 "SZjzuxO4JMsTS5LykTbItxAOfmh0fo59kSS1wJNmRaJcLhfdhZ7i3zNf/j2L1e6feqsm9R5JUkql\n",
429 429 "Ugky5LMjckmKnEEuSZEzyCUpcga5JEXOIJekyBnkUocMDg5RKpUYHBwquivqMU4/lDokTCmrAiV8\n",
430 430 "X2gmTj+UpD5jkEsdN0CpVLLMotxYWpE6pL60Mnn6fsssOpilFUnqMwa5JEXOIJe6iFMU1Qpr5FKH\n",
431 431 "pKmRO0VRYI1ckvqOQS5JkTPIJSlyBrkkRc4gl6TIGeSSFDmDXGoT54SrU5xHLrVJ45xw55ErLeeR\n",
432 432 "S1KfMcglKXIGuSRFziCXpMgNpNxuJ7AHeBXYB5wNDAFfBk5Ibr8EeD73HkqSZpR2RF4FysBKQogD\n",
433 433 "rAU2AiuATcm6JKnDspRWGqfCrAJGk+VRYHUuPZIkZZJlRH4f8BBwRdI2DIwny+PJuiSpw9LWyN8C\n",
434 434 "7AKOJZRTtjbcXmXyCAdJUgelDfJdyfUzwF2EOvk4sAQYA5YCTze748jIyIHlcrlMuVxuradSTxqg\n",
435 435 "VCqxcOHR7NnzXNGdUUEqlQqVSqXl+6c5BPRIYD4wASwANgB/CJwPPAvcQNjRuZiDd3h6iL76VtpD\n",
436 436 "9KfbxvdO/8p6iH6aEfkwYRRe2/6LhDB/CLgTuJzJ6YeSpA7zpFlSmzgiV6s8aZYk9RmDXJIiZ5BL\n",
437 437 "UuQMcqmL+StDSsOdnVKb5LGz052f/cmdnZLUZwxySYqcQS5JkTPIJSlyBrkkRc4gl6TIGeSSFDmD\n",
438 438 "XJIiZ5BLUuQMcmmO2nMY/UDt6D5pVh6iL83RdIfRz/UQ/cZr30v9w0P0JanPGOSSFDmDXJIiZ5BL\n",
439 439 "UuQMckmKnEEuSZEzyCUpcga5JEXOIJekyBnkkhQ5g1ySImeQS1LkDHJJilzaIJ8PbAbuSdaHgI3A\n",
440 440 "NmADsDj/rkm9wlPSqr3SBvmHgSeYPPfmWkKQrwA2JeuSmnqFybeOlL80QX4c8E7gFibPj7sKGE2W\n",
441 441 "R4HV+XdNkpRGmiD/C+CjwP66tmFgPFkeT9YlSQUYmOX2dwFPE+rj5Wm2qTLD98aRkZEDy+VymXJ5\n",
442 442 "uoeRpP5UqVSoVCot33+2PTCfAH6DUOQ7HBgEvgqcRQj2MWApcD9wSpP7+1Nv6nlpfuqt+TX4U29q\n",
443 443 "Ju+fersWWAacCLwP+AYh2NcDa5Jt1gB3Z+2oJCkfWeeR14YE1wMXEKYfnpesS5IK0O7JrZZW1POK\n",
444 444 "KK0MDg4xMbEbgIULj2bPnufa+C9Up2UtrRjk0hwVEeST23HQbYpf3jVySVKXm236oaSOmO0w/trt\n",
445 445 "hwD7OtQnxcIgl7pC7TD+6cK8/vaZtlM/srQiSZEzyCUpcga5JEXOIJekyBnkkhQ5g1ySImeQS1Lk\n",
446 446 "DHJJipxBLkmRM8glKXIGuSRFziCXpMgZ5JIUOYNckiJnkEtS5AxySYqcQS5JkTPIpdyEn2MbHBwq\n",
447 447 "uiPqM/7Um5Sb8HNsExP+DJs6yxG5JEXOIJekyBnkUvSszfc7a+RS9KzN9ztH5JIUudmC/HDgAeBh\n",
448 448 "4Angk0n7ELAR2AZsABa3q4OSpJnNFuQ/Bt4OnAG8MVk+F1hLCPIVwKZkXZJUgDSllR8l14cC84Hd\n",
449 449 "wCpgNGkfBVbn3zVJUhppgnweobQyDtwPPA4MJ+sk18Nt6Z0kaVZpZq3sJ5RWFgFfJ5RX6lWTS1Mj\n",
450 450 "IyMHlsvlMuVyOWsfpcINDg4xMbGbhQuPZs+e54rujnpMpVKhUqm0fP+s85U+DrwEfAAoA2PAUsJI\n",
451 451 "/ZQm21er1WkzXopGqVQijFdKNL6m62+r36ZZ+9RrZrgt7fXUx/D91hvCayd9Ps9WWjmGyRkpRwAX\n",
452 452 "AJuB9cCapH0NcHemXkqScjNbaWUpYWfmvORyO2GWymbgTuByYCdwSfu6KEmaSbsPBbO0op7QrLRS\n",
453 453 "q5sH3VBaOQR4xTp+D8haWjHIpRSaBflMQV1UjdxaeW/Iu0YuSepyBrkkRc4gl6TIGeSSFDmDXJIi\n",
454 454 "Z5BLuRuozTqQOsIgl3IXfrFH6hSDXJIiZ5BLUuQMckmKnEEuSZEzyCUpcga5JEXOIJekyBnkkhQ5\n",
455 455 "g1ySImeQS1LkDHJJipxBLkmRM8glKXIDRXdAiounqFX3cUQuZVI7Ra2nqVX3MMglKXIGuSRFziCX\n",
456 456 "ZjA4OGRNXF3PIJdmMDGxG+vh6nYGuSRFLk2QLwPuBx4HHgM+lLQPARuBbcAGYHE7OihJmlmaIN8H\n",
457 457 "/C5wOnAO8EHgVGAtIchXAJuSdUldolbfHxwcKrorarNW9uLcDXwmubwNGAeWABXglIZtq9Wq9UXF\n",
458 458 "K+zorBLeKvXXNGnLet2+x6hWq1P67vswLskO9tT5nLVGvhxYCTwADBNCnOR6OONjSZJykOUQ/aOA\n",
459 459 "vwM+DEw03DbtoW4jIyMHlsvlMuVyOVMHJanXVSoVKpVKy/dPO3Q/BLgX+Brwl0nbVqAMjAFLCTtE\n",
460 460 "La2op1haURHaUVopAbcCTzAZ4gDrgTXJ8hpC7VyS1GFpEv9c4F+AR5gcAqwDvgvcCRwP7AQuAZ5v\n",
461 461 "uK8jckXNEbmKkHVE3u5jjw1yRc0gVxHaPWtFktRlDHJJipxBLkmRM8ilJjx9rWJikEtNePpaxcQg\n",
462 462 "l6TIGeSSFDmDXKpjbVwxMsilOtbGFSODXJIiZ5BLPWfA8lCfMcilnvMKlof6i0EuSZEzyCUpcga5\n",
463 463 "JEXOIJekyBnkkhQ5g1ySImeQS1LkDHJJipxBLkmRM8ilPlM7w+Pg4FDRXVFOBorugKTOqp3hcWLC\n",
464 464 "87H0CkfkkhQ5g1ySImeQS1LkDHJJipxBLkmRSxPknwfGgUfr2oaAjcA2YAOwOP+uSZLSSBPktwEX\n",
465 465 "NrStJQT5CmBTsi4pKuEn4ZxTHr80Qf5NYHdD2ypgNFkeBVbn2SlJnVD7SbhqMrdcsWq1Rj5MKLeQ\n",
466 466 "XA/n0x1JUlZ57Oys4i+9SlJhWj1EfxxYAowBS4Gnp9twZGTkwHK5XKZcLrf4lJJaE2rhCxcezZ49\n",
467 467 "zxXdGTVRqVSoVCot3z/tyRaWA/cAb0jWbwSeBW4g7OhcTPMdntVq1cG64lEqlQhfMGe7JsU23fcY\n",
468 468 "1Wq1yb+RA7epO4T/o9T5nKq0cgfwbeD1wJPAZcD1wAWE6YfnJeuSpAK0+/RnjsjVlQYHh5iY2H1Q\n",
469 469 "ucERubpB1hG5p7FVX/JUruolHqIvSZEzyCUpcga5+kbtJ86S+mMfGujjf3tvM8jVN2p18f49fq12\n",
470 470 "SL56jUEuSZEzyCUpcga5el6tNq6ZDHg624g5j1w9b7I2bphPL9TPnVcfJ0fkkhQ5g1x9zpKC4mdp\n",
471 471 "RX3OkoLi54hckiJnkEtS5AxySYqcQS5JkTPIJSlyBrkkRc4glwBP8aqYGeQS4CleFTODXJIiZ5BL\n",
472 472 "UuQMckmKnEEuSZHzpFmKyq5du3jxxRc57LDDWLZsWdHdkbqCI3JFY//+/Rx//AmsXHkhy5efyNjY\n",
473 473 "2JTba78E5Clp5yJMwyyVDm167d+2OzkiVzSq1SqvvvoqL7ywnQULjmfv3r1Tbq/9EpCnpJ2L2jTM\n",
474 474 "UtNr/7bdyRG5JEVurkF+IbAV+C/gmrl3R5KU1VyCfD7wGUKYnwa8Hzg1j07pYJVKpeguRGRqnVd5\n",
475 475 "mvrTeLX9Es3arKd3zlyC/GxgO7AT2Ad8Cbg4hz6pCYM8i1qddx8edp+32k/j7QYm90vAdQe11dbV\n",
476 476 "fnMJ8p8CnqxbfyppkyR10FyC3KGOClBlcPBXePnlZ5g3z331EoQ5Ra06Bxgh1MgB1gH7gRvqttkO\n",
477 477 "nDSH55CkfrQDeF0nnmggebLlwKHAw7izU5KicxHwPcLIe13BfZEkSZIE8B7gceBV4MyG29YRDh7a\n",
478 478 "Cryjw/3qBSOE2UGbk8uFM26t6XggW752Ao8QXpPfLbYr0fk8MA48Wtc2BGwEtgEbgMUF9ItTgBXA\n",
479 479 "/UwN8tMIdfRDCHX17XiKgKyuAz5SdCciN5/w2ltOeC26b2fufkAIH2X3VmAlU4P8RuBjyfI1wPWz\n",
480 480 "PUg7gnQr4ZOk0cXAHYSjNHYS3kxnt+H5e52HKs6NB7K1h6/L1nwTaDxyahUwmiyPAqtne5BOjoh/\n",
481 481 "klAWqPEAotZcDWwBbqWgr1yR80C2/FWB+4CHgCsK7ksvGCaUW0iuh2e7Q6unsd0ILGnSfi1wT4bH\n",
482 482 "8aCig033t/0D4Cbgj5L1Pwb+DLi8Q/3qFb7m8vcWYBdwLOH1u5Uw0tTcVUnxmm01yC9o4T4/BOp/\n",
483 483 "0uW4pE1Tpf3b3kK2D00Fja/DZUz9pqjsdiXXzwB3EcpXBnnrxgmDuTFgKfD0bHdod2mlvm62Hngf\n",
484 484 "4eChE4GTcQ93Vkvrlt/N1B0kSuchwmtvOeG1+F7Ca1OtORJYmCwvIMxG83U5N+uBNcnyGuDuIjrx\n",
485 485 "bkIN8iXCJ8rX6m67lrCjaSvwS53vWvS+QJjmtYXwnztr7UxNeSBbfk4kzPx5GHgM/55Z3QH8D7CX\n",
486 486 "kJuXEWYA3UfB0w8lSZIkSZIkSZIkSZIkSZIkSZIktcn/A4eK9UXawRDUAAAAAElFTkSuQmCC\n"
487 487 ]
488 488 },
489 489 "metadata": {},
490 490 "output_type": "display_data"
491 491 }
492 492 ],
493 493 "source": [
494 494 "display_png(x)"
495 495 ]
496 496 },
497 497 {
498 498 "cell_type": "markdown",
499 499 "metadata": {},
500 500 "source": [
501 501 "<div class=\"alert alert-success\">\n",
502 502 "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",
503 503 "</div>"
504 504 ]
505 505 },
506 506 {
507 507 "cell_type": "markdown",
508 508 "metadata": {},
509 509 "source": [
510 510 "Create a new Gaussian with different parameters:"
511 511 ]
512 512 },
513 513 {
514 514 "cell_type": "code",
515 515 "execution_count": 7,
516 516 "metadata": {
517 517 "collapsed": false
518 518 },
519 519 "outputs": [
520 520 {
521 521 "data": {
522 522 "image/png": [
523 523 "iVBORw0KGgoAAAANSUhEUgAAAXcAAAENCAYAAAD0eSVZAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\n",
524 524 "AAALEgAACxIB0t1+/AAAE3lJREFUeJzt3X2UXOVBx/HvkE2AQJZ0S00CpCZNGyHYVmIDVEEGBExr\n",
525 525 "TwjHU160GFqKx9PSUvW0JKBlfSlStGp7tPQIpSdUCaZa3qStCSmjPYq8CAkvIQ2JRgltFoSk2R6j\n",
526 526 "hDL+8dzJ3pmd3Z258/7M93POnNx79748XO7+9pnnPve5IEmSJEmSJEmSJEmSJEmSJEmSJElSD1jY\n",
527 527 "6QK02DxgZqcLIdXqsE4XQD1rGbAFuJkQ7Kd3tjgt9xLwqU4XQqpVrtMFUNf7EvDPwFcrlt8MfB14\n",
528 528 "FFgDXNOi468ElgCvAy9UKUcr/DKhpn4qcBdwZ7J8GXAScHsbyjCRico20Xmqd7mkPvEQ8LWKZScD\n",
529 529 "70mm3wl8rEXHPgb4t4qyHNuiY5W8lbH/nmOBvZQ3OdUT7KcRAng3MJAsm0MI5L8HfqYJZVtA9fP0\n",
530 530 "xjqXt/q8qs1sltFkpgEPAOcAR6SW54FvJ9PvS003288BW1PzW4CzW3SskpMZa375b2AH8NOpn79E\n",
531 531 "CNlaPAx8C9gO/FKybIQQ7O8H/qUJZVtG9fN0Tp3LW31e1WYDU6+iPnYysAn4KUJN/a5k+ZHA/yXT\n",
532 532 "y4Ab6tzvW4ArJ/n5vwL3ACcA+1LL9wFvq/NY9R7zG4x9K8kRmkB2pNbbQgj7HUztMOAg8AXgk8Df\n",
533 533 "JMuPAg40qWzPAe+m+nl6pc7liojhrsmcSmiLvRO4lBDuhwOvptaZCRRT89OAfwTOSOa/DPwh5WH4\n",
534 534 "74R2+qnMBv43Nf8qcPQE6y4G/gB4E/AuoADcT7hnUM8xDwJPJ9O/CDwGbE79fG9yrFosTbZ/GviT\n",
535 535 "ZP5xys9XM8r2Xqqfp2KdyxURm2U0maMJNfR7gfOBHyME/sOpdaZVbPNu4D+T6VwyX0stt5pRym/6\n",
536 536 "H0modVYaIoT4rxKaFzYBH2As2LOYDVye7CftADCjxn28A3iScNPyi4T28p8AvttAuaqVbT/Vz9NE\n",
537 537 "56/W86oeZs1dEzkG+J9kepTQdnwV8DLwF6n1XqvYbjnwD8n0KcBTVfZdazPETkItvORYQs230keT\n",
538 538 "MpVqo4enyl7vMSEE32rgw8APgR9n7A/WMdQehOnK062EP3Jbgc83uWyV5+mNhPO0r8blE51XSRE5\n",
539 539 "mtAD5tcp70GxFPgB49vX11L+lf5R4CeT6d8Bfg1YkbEsR1H+x2EL4dsDhDbiUnjeROiiCOE+wR9n\n",
540 540 "PF7Jxwnt6nMJ31TOSv3sKuDnU/PpcqRNJ3yTSPsSod282WWbSfXzNNH5m+y8SorU+YRmhM9U+dlf\n",
541 541 "E2qMaR8i9MCA0N49AlxLaAf+LeA64NwGynMZ8NvAp4FfSS1/lvAtAUJXxasJPVKuprFvpGcAPyKc\n",
542 542 "g9eT6eNTP7+V8p5D6XKULCM8A/BXFdsuoba29Sxlm+g81btcfeI2wi9r+q/8HxEu6C2EC/iY1M/W\n",
543 543 "EO7ebyOEhHrTnDrWnU24kQmhDbjaH4VWmAGc2aZjlRxBuDHa6XJIDTuT8e2m5zH2NfTG5AOhVrKZ\n",
544 544 "8HV0AaF90Ru2/eEThCacL1DeJ7yVLmb8zdxWu5xwQ7TT5ZCaYgHVb4oBXEj46gnjH0H/FvGPN6Ig\n",
545 545 "x+Q3BGMwH7ig04WQatVob5kPAeuS6eMId/VLdlPe3qh4FYFbOl2IFns++Ug9oZFmk+sIDz/cMck6\n",
546 546 "lQ9rSJLaIGvN/XJCb4h0l7AXCF9dS05IlpVZtGhRcefOnRkPK0l9aye1j2uUqea+nDBOxgWUP8J8\n",
547 547 "L3AJoffAQkL/30fGlW7nTorFop8mfa6//vqOlyGmj+fT89mtH2BRPUE9Vc19HeEhiWMJ7Y3XE26c\n",
548 548 "zgA2Jus8BHyE8OTd+uTf15JlNstIUgdMFe6XVll22yTr30D9IwRKkprMfug9Lp/Pd7oIUfF8Npfn\n",
549 549 "s3M68Zq9YtJ+JEmqUS6Xgzoy25q7JEXIcJekCBnukhQhw12SImS4S1KEDHf1jcHBIXK53KHP4OBQ\n",
550 550 "p4sktYxdIdU3Qley9LWXw2tRvcKukJIkw12SYmS4S1KEDHdpEt6EVa/yhqr6RpYbqt6EVbfwhqqU\n",
551 551 "qKx1S/3EmruiVa3Wbc1dvcqauyTJcJekGBnukhQhw12SImS4S1KEDHdJipDhLjWgsi+9T7GqW9jP\n",
552 552 "XdFqRz/38T+vbb9SveznLkky3CUpRoa7JEXIcJdSHGxMsZgq3G8DRoCnUsuGgI3AdmADMDv1szXA\n",
553 553 "c8A24PzmFVNqj9HRvYQbpKWP1JumCvevAMsrlq0mhPtiYFMyD7AEuDj5dznwxRr2L3XQwLhujFIs\n",
554 554 "pgrf7wB7K5atANYm02uBlcn0BcA64CCwC9gBnNqUUkot8RrltXRr6opHlpr1HEJTDcm/c5Lp44Dd\n",
555 555 "qfV2A8dnL5okKatGm02mqu5YFZKkDhjIsM0IMBfYA8wDXkyWvwDMT613QrJsnOHh4UPT+XyefD6f\n",
556 556 "oRiSFK9CoUChUMi8fS13kBYA9wFvT+ZvAl4GPku4mTo7+XcJcAehnf144AHgrYyvvTv8gNqiluEH\n",
557 557 "qg0dUM+QBQ4/oHapd/iBqWru64CzgGOB54FPAzcC64ErCDdOL0rW3Zos30q4U/URbJaRpI5w4DBF\n",
558 558 "y5q7YuLAYZIkw12SYmS4S1KEDHdJipDhLkkRMtzVEyqH4vU9pdLk7AqpnjDVu0xr3caukOpVzX6I\n",
559 559 "SVKZAYcGVk8w3KW6lIYJLjHo1Z1sc5ekCBnukhQhw12SImS4S1KEDHdJipDhLkkRMtwlKUKGuyRF\n",
560 560 "yHCXpAj5hKp6VOUwANOBg50qjNR1DHf1qGrDAFQbBEzqTzbLSFKEDHdJipDhLkkRMtwlKUKGuyRF\n",
561 561 "yHCXpAgZ7pIUIcNdkiJkuEtShBoJ9zXAM8BTwB3A4cAQsBHYDmwAZjdaQElS/bKG+wLgSmAp8HZg\n",
562 562 "GnAJsJoQ7ouBTcm8JKnNsob7fsIoTTMJ49PMBL4HrADWJuusBVY2WkCp1w0ODpHL5Q59BgeHOl0k\n",
563 563 "9YGs4f4K8Dngvwihvo9QY58DjCTrjCTzUl8bHd1LGNQsfMK81FpZR4VcBHyC0DzzA+BrwAcq1ild\n",
564 564 "zeMMDw8fms7n8+Tz+YzFkKQ4FQoFCoVC5u2zjol6MXAe8OFk/jLgdOAc4GxgDzAPeBA4sWLbYrFY\n",
565 565 "NfOlCYWx2ycb4neiIX9bvU31faSv8Wpl93dA9UreX1BzZmdtltlGCPMjk4OdC2wF7gNWJeusAu7O\n",
566 566 "uH9JUgOyNstsAW4HHgNeBx4H/hKYBawHrgB2ARc1XkRJUr068aoam2VUN5tl1O/a1SwjSepihrsk\n",
567 567 "Rchwl6QIGe6SFCHDXZIiZLhLUoQMd0mKkOEuSREy3CUpQoa7JEXIcJekCBnukhQhw12SImS4S1KE\n",
568 568 "DHdJilDWl3VImtBAaextqWMMd6npXmP8Cz2k9rJZRpIiZLhLUoQMd0mKkOEuSREy3CUpQoa7JEXI\n",
569 569 "cJekCBnukhQhw12SImS4S1KEDHd1pcHBIXK53KGPpPo0Eu6zgb8FngW2AqcBQ8BGYDuwIVlHqtvo\n",
570 570 "6F7C+CylT0wGyv5w5XI5BgeHOl0oRaaRcP888A3gJOAdwDZgNSHcFwObknlJZUoDi419wh8zqXmy\n",
571 571 "ft89BngCeEvF8m3AWcAIMBcoACdWrFMsFmOriakeg4NDZWE2a9Yb2L//lbJ1QlNM5ciK9cy3a5vm\n",
572 572 "HdffC00maZ6sObOz1twXAi8BXwEeB24BjgLmEIKd5N85GfeviFU2uVhrlZov63juA8BS4CrgUeDP\n",
573 573 "GN8EM2Fj6fDw8KHpfD5PPp/PWAxJilOhUKBQKGTePmuzzFzgIUINHuAMYA2hmeZsYA8wD3gQm2VU\n",
574 574 "oVqTS+U1YbOMVK5dzTJ7gOcJN04BzgWeAe4DViXLVgF3Z9y/+sr43iOSGtPIb9E7gVuBGcBO4IPA\n",
575 575 "NGA98GZgF3ARsK9iO2vufW7qWnm1Zdbc1d/qrbl3oopkuPc5w73aNtMJXSSDaj2I1N/qDXdfkC11\n",
576 576 "hfKXao+O2jSlxjj8gCRFyHCXpAgZ7pIUIcNdkiJkuEtShAx3SYqQ4S5JETLcJSlChrskRchwl6QI\n",
577 577 "Ge6SFCHDXepKA75AWw1x4DCpKzmQmBpjzV0tNzg45Is4pDaz5q6WG3shdokBL7WaNXdJipDhLkkR\n",
578 578 "MtwlKUKGu9QT7Bqp+nhDVeoJdo1Ufay5S1KEDHdJipDhLkkRMtwlKUKGuyRFyHCXpAgZ7pIUoUbD\n",
579 579 "fRrwBHBfMj8EbAS2AxuA2Q3uX5KUQaPhfjWwlbGnK1YTwn0xsCmZlyS1WSPhfgLwXuBWxsZwXQGs\n",
580 580 "TabXAisb2L8kKaNGwv1PgU8Cr6eWzQFGkumRZF6S1GZZx5Z5H/Aiob09P8E6Rcrf0HDI8PDwoel8\n",
581 581 "Pk8+P9EuJKk/FQoFCoVC5u2zjj50A3AZYTSjI4BB4OvAMkLY7wHmAQ8CJ1ZsWywWq2a+IhVerVf5\n",
582 582 "JqbJ5mtZpxX76K3j+nvUX5JXVNac2VmbZa4F5gMLgUuAbxPC/l5gVbLOKuDujPtXj6h8P6pD0Urd\n",
583 583 "oVlD/paqEDcC64ErgF3ARU3av7pU5ftRHYpW6g6d+E20WSYi45tcphNa6yrF2zzSmeOOP8+zZr2B\n",
584 584 "/ftfQXGqt1nGl3WoycpfKhFYm2++8efZb01Kc/gBSYqQ4S5JETLcJSlChrskRchwl6QIGe6SFCHD\n",
585 585 "XZIiZLhLUoQMd0mKkOEuRWPAQdx0iMMPSNEoH5LA4Qj6mzV3SYqQ4S5JETLcJSlChrskRchwl6Jl\n",
586 586 "75l+Zm8ZKVr2nuln1twlKUKGuyRFyHCXpAgZ7pIUIcNdkiJkuEtShAx3SYqQ4a66DA4OlT0YI6k7\n",
587 587 "+RCT6jI6upf0gzFgwEvdyJq71DccjqCfZA33+cCDwDPA08DHk+VDwEZgO7ABmN1oASU1S2k4gvAJ\n",
588 588 "38IUq6zhfhD4DeBk4HTgo8BJwGpCuC8GNiXzkqQ2yxrue4DNyfQPgWeB44EVwNpk+VpgZUOlkyRl\n",
589 589 "0ow29wXAKcDDwBxgJFk+ksxLktqs0XA/Gvg74GpgtOJnpcY9SVKbNdIVcjoh2L8K3J0sGwHmEppt\n",
590 590 "5gEvVttweHj40HQ+nyefzzdQDEmKT6FQoFAoZN4+ayflHKFN/WXCjdWSm5JlnyXcTJ3N+JuqxWLR\n",
591 591 "Cn03GhwcqtKDYjrh/nlaZT/3yeZrWacZ23jcLPvwd7F3JA8N1pzZWcP9DOCfgCcZu1rWAI8A64E3\n",
592 592 "A7uAi4B9Fdsa7l0qXDzdEDoe13BXpXaFeyMM9y5luPfbcQ33XlJvuPuEqiRFyHCX+lb5cAQOSRAX\n",
593 593 "Bw6T+lZpOIIxo6MOBBcLa+6SFCHDXZIiZLhLUoQMd0mKkOEuSREy3CUpQoZ7H/Nl11K87Ofex3zZ\n",
594 594 "tRQva+6SFCHDvY/YDKOpVQ5JMMPhCXqUzTJ9xGYYTa1ySILykSQdnqB3WHOXpAgZ7pIUIcM9EpXt\n",
595 595 "6baPSv3NNvdIjG9Pt31U6mfW3KM2YO8YNZkv+OgV1tyjVq3ng9QIX/DRK6y5S1KEDHdJipDhLkkR\n",
596 596 "MtwlKUKGexeo7KNeS+8Dx4lR9xiw90wXMty7wFgf9fAJ8/VtI3VOqQdN9es3S+WlFq3abyw6UeUr\n",
597 597 "FouGUVqoeZd3WZzqHFXbZnzIT7VOt+7D4/bOPqqvk75+s1zftWjVfrtV8g295sy2n7ukJhuwqbAL\n",
598 598 "tKJZZjmwDXgOuKYF+5fU1cqbadQZzQ73acCfEwJ+CXApcFKTj9EHxj/iXfnShDGFThVSqkGhyrKp\n",
599 599 "r++p5/1mMJVmN8ucCuwAdiXzdwIXAM82+Tg96/77v8n992+YYq3xj3hXb/uE8MuTb0rZpOYrVFlW\n",
600 600 "6/VdS1u/JtLscD8eeD41vxs4rcnH6Gm33HIH99zzOvCuZMljnSyOpEg1O9xtYJvC9OmHceSRTzN9\n",
601 601 "+n4ADh7czYEDHS6UpOg0O9xfAOan5ucTau9pO3O53KImH7fnHDiwuWJJ5VfMal85J1rndzNs04zj\n",
602 602 "tnIfHrd39tE9x428LX5nJw8+kBRgATAD2Iw3VCUpCu8Bvku4sbqmw2WRJEmSVK/3A88APwKWVvxs\n",
603 603 "DeGhp23A+W0uVwyGCfc2nkg+yztamt7kw3fNtQt4knA9PtLZovSk24AR4KnUsiFgI7Ad2ADM7kC5\n",
604 604 "qjoRWAw8SHm4LyG0zU8ntNXvwAHN6nU98JudLkQPm0a47hYQrkPvFTXuPwhhpGzOBE6hPNxvAj6V\n",
605 605 "TF8D3DjZDtoZotsIf3EqXQCsAw4S/trvIDwMpfpE3U2gxdIP3x1k7OE7NcZrMrvvAJXDw64A1ibT\n",
606 606 "a4GVk+2gG2rIx1HeXXI34WEo1edjwBbgy3TR17UeUe3hO6/BxhSBBwhP6V3Z4bLEYg6hqYbk3zmT\n",
607 607 "rdzsfu4bgblVll8L3FfHfnwYaryJzu11wM3A7yXzvw98DriiTeWKgddb8/0s8H3gTYRrdxuhNqrm\n",
608 608 "mHJUtmaH+3kZtql88OmEZJnK1Xpub6W+P6Sq7eE71ef7yb8vAXcRmr4M98aMECp4e4B5wIuTrdyp\n",
609 609 "Zpl0W9y9wCWEh54WAm/Du+v1mpeavpDymzCa2mOE624B4Tq8mHBdKpuZwKxk+ihCDzivycbdC6xK\n",
610 610 "plcBd3ewLGUuJLRrHiD85flm6mfXEm5obQN+of1F63m3E7qdbSH8D5+0LU5V+fBd8ywk9DjaDDyN\n",
611 611 "5zOLdcD3gFcJuflBQu+jB+jCrpCSJEmSJEmSJEmSJEmSJEmSJEmS+tD/AzUxDUJku6WfAAAAAElF\n",
612 612 "TkSuQmCC\n"
613 613 ],
614 614 "text/latex": [
615 615 "$\\mathcal{N}(\\mu=0, \\sigma=2),\\ N=2000$"
616 616 ],
617 617 "text/plain": [
618 618 "<__main__.Gaussian at 0x106e9ce90>"
619 619 ]
620 620 },
621 621 "execution_count": 7,
622 622 "metadata": {},
623 623 "output_type": "execute_result"
624 624 }
625 625 ],
626 626 "source": [
627 627 "x2 = Gaussian(0, 2, 2000)\n",
628 628 "x2"
629 629 ]
630 630 },
631 631 {
632 632 "cell_type": "markdown",
633 633 "metadata": {},
634 634 "source": [
635 635 "You can then compare the two Gaussians by displaying their histograms:"
636 636 ]
637 637 },
638 638 {
639 639 "cell_type": "code",
640 640 "execution_count": 8,
641 641 "metadata": {
642 642 "collapsed": false
643 643 },
644 644 "outputs": [
645 645 {
646 646 "data": {
647 647 "image/png": [
648 648 "iVBORw0KGgoAAAANSUhEUgAAAXIAAAENCAYAAAASUO4dAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\n",
649 649 "AAALEgAACxIB0t1+/AAAElNJREFUeJzt3X+wXGV9x/H3JpefITfhCr1JSyCIRH5UJbQgrVhXChas\n",
650 650 "DXE6onbaBoownRG0tVUSOg63vxQY+8tRoVOQuTIOSq3QQGtNiGyr1SK0IfxqTBNNB2zuhUJoLogk\n",
651 651 "kO0fz9ncvZu9956z9+yefXbfr5mdPefZs7tPbnY/++z3POcsSJIkSZIkSZIkSZIkSZIkSZIkSZJ6\n",
652 652 "1olFd6DNlgJHFt0JKYt5RXdAXe8sYAtwEyHEzym2O233DPCxojshZVEqugPqGjcD/wrc3tB+E/BV\n",
653 653 "4EFgHXBNm57/1wij4bOBu4Avtel5Gp0B/Drw+3VtZwGnAl/oUB+m06xvq4HTgP3AD5n8/8raLqkH\n",
654 654 "fQf424a204GLkuU3AVe36blfV/fYxwC76UwJ5yOED6nbmtyWJcTfTPjweQoYSNqGCR9G9wI/n1Pf\n",
655 655 "FgH/Xrf+HeA1GduPaaEv6nKWVgQwH7gPOA84vK69DHwjWX5X3XLeTmeynPG/wHbgZ9r0XPX+HPj7\n",
656 656 "aW57hvABk8YDwD8B24BfTdrGCSH+HuDbOfXtF4An6ta3EP7PsrS/vYW+qMsNzL6J+sDpwCbCV/mL\n",
657 657 "CKNLgCOAl5Pls4BPZHzc1wJXzHD7vxHC6h+ZHPmXCCWW7RmfK+tz1kxXXtxC+DBJ0495wD7g08BH\n",
658 658 "gS8n7QuAl3Ls23HA83XrzwMnA89lbFePMcgFoS59O6EU8H5CkB8G7K3b5kigWrc+H/hn4Nxk/Vbg\n",
659 659 "k0wNvu8T6uqz2Qc8liz/MvAQ8PA0264A/gQ4FvhZoAL8A6HGn+U5a6rTtO9OniuNMwl9fowwkj4T\n",
660 660 "+I8mjz3Xvi0Gfly3vhc4KtkuS7t6jKUVQXhzvwysB94B/AQh3B+o22Z+w31+DvjvZLmUrLc6iq5Z\n",
661 661 "DFxK2MHXzBAhsH+TUCLYlGx78zTbpzHdiPwl4NCUj/FG4BHCDsXPEer9rwe+N4d+NevbREPbEYRR\n",
662 662 "d9Z29RhH5FoE/ChZniDUeq8CngU+W7fdKw33uxD4erK8Eni0yWNnKSWUgLXAB4AXgBOY/KCo+WDS\n",
663 663 "p9oo87C6vrfynDD9iHwR6UOvfkB0C+ED7Qngr3Lu2w7Ct5Ca1xBG/s+nbD8maZfUI44izET5babO\n",
664 664 "ZDgT+D8OroePMvVr+YPATyfLHweuBFbNoT8fItSklxC+DbwtaT+ZyaC8kTAtEEJd/1NzeL6aS2k+\n",
665 665 "a+Uq4Bfr1uv7Ue8QwjeEejcT6v55920BUz8wtxC+PWVtV49p/Lqs/lEGvkUoCdxb174LeAOwmamj\n",
666 666 "tyFCMPyAUJ9eRxjxLSSURBYBOwl14KzOJdTnrwR+D7ic8OEwQZjbvr3u8k7CTr8zCDX5/S08X81V\n",
667 667 "hNLMm5J/w2Ymd+5eCfw1k99E6vtRcxZh1H08oQw1kbR/n1DG+FbOfXshuawi/P/dSxjF78vYrj61\n",
668 668 "GPgK8J+Er4xvJryxNxKmXG1ItlFchjNsu5iwkxFCwPxp/t1p6lDgrR16rprDCTsti+6HlKtR4LeS\n",
669 669 "5QHC6OtGJuf+XgNcX0C/1Fm/QyjDfJrOzPMGeC+d/+Z4KWFnZdH9kHKziOZfl7cyOaJbkqyrt5WY\n",
670 670 "eWddL1gGXFx0J6S8nUGo/91GqJn+DaFWurtum1LDuiSpQ9LMIx8gzGT4XHL9ImGaWL0q00/jkiS1\n",
671 671 "UZp55E8llweT9a8QZiyMEUoqY4RDqp9uvONJJ51U3bFjRz49laT+sYP05/pJNSIfA55k8nDl84HH\n",
672 672 "gXuANUnbGuDug3qyYwfVatVLDpfrrruu8D700sW/p3/Pbr4AJ6UNcUh/ZOfVwBcJU7B2AJcR9uDf\n",
673 673 "SZjzuxO4JMsTS5LykTbItxAOfmh0fo59kSS1wJNmRaJcLhfdhZ7i3zNf/j2L1e6feqsm9R5JUkql\n",
674 674 "Ugky5LMjckmKnEEuSZEzyCUpcga5JEXOIJekyBnkUocMDg5RKpUYHBwquivqMU4/lDokTCmrAiV8\n",
675 675 "X2gmTj+UpD5jkEsdN0CpVLLMotxYWpE6pL60Mnn6fsssOpilFUnqMwa5JEXOIJe6iFMU1Qpr5FKH\n",
676 676 "pKmRO0VRYI1ckvqOQS5JkTPIJSlyBrkkRc4gl6TIGeSSFDmDXGoT54SrU5xHLrVJ45xw55ErLeeR\n",
677 677 "S1KfMcglKXIGuSRFziCXpMgNpNxuJ7AHeBXYB5wNDAFfBk5Ibr8EeD73HkqSZpR2RF4FysBKQogD\n",
678 678 "rAU2AiuATcm6JKnDspRWGqfCrAJGk+VRYHUuPZIkZZJlRH4f8BBwRdI2DIwny+PJuiSpw9LWyN8C\n",
679 679 "7AKOJZRTtjbcXmXyCAdJUgelDfJdyfUzwF2EOvk4sAQYA5YCTze748jIyIHlcrlMuVxuradSTxqg\n",
680 680 "VCqxcOHR7NnzXNGdUUEqlQqVSqXl+6c5BPRIYD4wASwANgB/CJwPPAvcQNjRuZiDd3h6iL76VtpD\n",
681 681 "9KfbxvdO/8p6iH6aEfkwYRRe2/6LhDB/CLgTuJzJ6YeSpA7zpFlSmzgiV6s8aZYk9RmDXJIiZ5BL\n",
682 682 "UuQMcqmL+StDSsOdnVKb5LGz052f/cmdnZLUZwxySYqcQS5JkTPIJSlyBrkkRc4gl6TIGeSSFDmD\n",
683 683 "XJIiZ5BLUuQMcmmO2nMY/UDt6D5pVh6iL83RdIfRz/UQ/cZr30v9w0P0JanPGOSSFDmDXJIiZ5BL\n",
684 684 "UuQMckmKnEEuSZEzyCUpcga5JEXOIJekyBnkkhQ5g1ySImeQS1LkDHJJilzaIJ8PbAbuSdaHgI3A\n",
685 685 "NmADsDj/rkm9wlPSqr3SBvmHgSeYPPfmWkKQrwA2JeuSmnqFybeOlL80QX4c8E7gFibPj7sKGE2W\n",
686 686 "R4HV+XdNkpRGmiD/C+CjwP66tmFgPFkeT9YlSQUYmOX2dwFPE+rj5Wm2qTLD98aRkZEDy+VymXJ5\n",
687 687 "uoeRpP5UqVSoVCot33+2PTCfAH6DUOQ7HBgEvgqcRQj2MWApcD9wSpP7+1Nv6nlpfuqt+TX4U29q\n",
688 688 "Ju+fersWWAacCLwP+AYh2NcDa5Jt1gB3Z+2oJCkfWeeR14YE1wMXEKYfnpesS5IK0O7JrZZW1POK\n",
689 689 "KK0MDg4xMbEbgIULj2bPnufa+C9Up2UtrRjk0hwVEeST23HQbYpf3jVySVKXm236oaSOmO0w/trt\n",
690 690 "hwD7OtQnxcIgl7pC7TD+6cK8/vaZtlM/srQiSZEzyCUpcga5JEXOIJekyBnkkhQ5g1ySImeQS1Lk\n",
691 691 "DHJJipxBLkmRM8glKXIGuSRFziCXpMgZ5JIUOYNckiJnkEtS5AxySYqcQS5JkTPIpdyEn2MbHBwq\n",
692 692 "uiPqM/7Um5Sb8HNsExP+DJs6yxG5JEXOIJekyBnkUvSszfc7a+RS9KzN9ztH5JIUudmC/HDgAeBh\n",
693 693 "4Angk0n7ELAR2AZsABa3q4OSpJnNFuQ/Bt4OnAG8MVk+F1hLCPIVwKZkXZJUgDSllR8l14cC84Hd\n",
694 694 "wCpgNGkfBVbn3zVJUhppgnweobQyDtwPPA4MJ+sk18Nt6Z0kaVZpZq3sJ5RWFgFfJ5RX6lWTS1Mj\n",
695 695 "IyMHlsvlMuVyOWsfpcINDg4xMbGbhQuPZs+e54rujnpMpVKhUqm0fP+s85U+DrwEfAAoA2PAUsJI\n",
696 696 "/ZQm21er1WkzXopGqVQijFdKNL6m62+r36ZZ+9RrZrgt7fXUx/D91hvCayd9Ps9WWjmGyRkpRwAX\n",
697 697 "AJuB9cCapH0NcHemXkqScjNbaWUpYWfmvORyO2GWymbgTuByYCdwSfu6KEmaSbsPBbO0op7QrLRS\n",
698 698 "q5sH3VBaOQR4xTp+D8haWjHIpRSaBflMQV1UjdxaeW/Iu0YuSepyBrkkRc4gl6TIGeSSFDmDXJIi\n",
699 699 "Z5BLuRuozTqQOsIgl3IXfrFH6hSDXJIiZ5BLUuQMckmKnEEuSZEzyCUpcga5JEXOIJekyBnkkhQ5\n",
700 700 "g1ySImeQS1LkDHJJipxBLkmRM8glKXIDRXdAiounqFX3cUQuZVI7Ra2nqVX3MMglKXIGuSRFziCX\n",
701 701 "ZjA4OGRNXF3PIJdmMDGxG+vh6nYGuSRFLk2QLwPuBx4HHgM+lLQPARuBbcAGYHE7OihJmlmaIN8H\n",
702 702 "/C5wOnAO8EHgVGAtIchXAJuSdUldolbfHxwcKrorarNW9uLcDXwmubwNGAeWABXglIZtq9Wq9UXF\n",
703 703 "K+zorBLeKvXXNGnLet2+x6hWq1P67vswLskO9tT5nLVGvhxYCTwADBNCnOR6OONjSZJykOUQ/aOA\n",
704 704 "vwM+DEw03DbtoW4jIyMHlsvlMuVyOVMHJanXVSoVKpVKy/dPO3Q/BLgX+Brwl0nbVqAMjAFLCTtE\n",
705 705 "La2op1haURHaUVopAbcCTzAZ4gDrgTXJ8hpC7VyS1GFpEv9c4F+AR5gcAqwDvgvcCRwP7AQuAZ5v\n",
706 706 "uK8jckXNEbmKkHVE3u5jjw1yRc0gVxHaPWtFktRlDHJJipxBLkmRM8ilJjx9rWJikEtNePpaxcQg\n",
707 707 "l6TIGeSSFDmDXKpjbVwxMsilOtbGFSODXJIiZ5BLPWfA8lCfMcilnvMKlof6i0EuSZEzyCUpcga5\n",
708 708 "JEXOIJekyBnkkhQ5g1ySImeQS1LkDHJJipxBLkmRM8ilPlM7w+Pg4FDRXVFOBorugKTOqp3hcWLC\n",
709 709 "87H0CkfkkhQ5g1ySImeQS1LkDHJJipxBLkmRSxPknwfGgUfr2oaAjcA2YAOwOP+uSZLSSBPktwEX\n",
710 710 "NrStJQT5CmBTsi4pKuEn4ZxTHr80Qf5NYHdD2ypgNFkeBVbn2SlJnVD7SbhqMrdcsWq1Rj5MKLeQ\n",
711 711 "XA/n0x1JUlZ57Oys4i+9SlJhWj1EfxxYAowBS4Gnp9twZGTkwHK5XKZcLrf4lJJaE2rhCxcezZ49\n",
712 712 "zxXdGTVRqVSoVCot3z/tyRaWA/cAb0jWbwSeBW4g7OhcTPMdntVq1cG64lEqlQhfMGe7JsU23fcY\n",
713 713 "1Wq1yb+RA7epO4T/o9T5nKq0cgfwbeD1wJPAZcD1wAWE6YfnJeuSpAK0+/RnjsjVlQYHh5iY2H1Q\n",
714 714 "ucERubpB1hG5p7FVX/JUruolHqIvSZEzyCUpcga5+kbtJ86S+mMfGujjf3tvM8jVN2p18f49fq12\n",
715 715 "SL56jUEuSZEzyCUpcga5el6tNq6ZDHg624g5j1w9b7I2bphPL9TPnVcfJ0fkkhQ5g1x9zpKC4mdp\n",
716 716 "RX3OkoLi54hckiJnkEtS5AxySYqcQS5JkTPIJSlyBrkkRc4glwBP8aqYGeQS4CleFTODXJIiZ5BL\n",
717 717 "UuQMckmKnEEuSZHzpFmKyq5du3jxxRc57LDDWLZsWdHdkbqCI3JFY//+/Rx//AmsXHkhy5efyNjY\n",
718 718 "2JTba78E5Clp5yJMwyyVDm167d+2OzkiVzSq1SqvvvoqL7ywnQULjmfv3r1Tbq/9EpCnpJ2L2jTM\n",
719 719 "UtNr/7bdyRG5JEVurkF+IbAV+C/gmrl3R5KU1VyCfD7wGUKYnwa8Hzg1j07pYJVKpeguRGRqnVd5\n",
720 720 "mvrTeLX9Es3arKd3zlyC/GxgO7AT2Ad8Cbg4hz6pCYM8i1qddx8edp+32k/j7QYm90vAdQe11dbV\n",
721 721 "fnMJ8p8CnqxbfyppkyR10FyC3KGOClBlcPBXePnlZ5g3z331EoQ5Ra06Bxgh1MgB1gH7gRvqttkO\n",
722 722 "nDSH55CkfrQDeF0nnmggebLlwKHAw7izU5KicxHwPcLIe13BfZEkSZIE8B7gceBV4MyG29YRDh7a\n",
723 723 "Cryjw/3qBSOE2UGbk8uFM26t6XggW752Ao8QXpPfLbYr0fk8MA48Wtc2BGwEtgEbgMUF9ItTgBXA\n",
724 724 "/UwN8tMIdfRDCHX17XiKgKyuAz5SdCciN5/w2ltOeC26b2fufkAIH2X3VmAlU4P8RuBjyfI1wPWz\n",
725 725 "PUg7gnQr4ZOk0cXAHYSjNHYS3kxnt+H5e52HKs6NB7K1h6/L1nwTaDxyahUwmiyPAqtne5BOjoh/\n",
726 726 "klAWqPEAotZcDWwBbqWgr1yR80C2/FWB+4CHgCsK7ksvGCaUW0iuh2e7Q6unsd0ILGnSfi1wT4bH\n",
727 727 "8aCig033t/0D4Cbgj5L1Pwb+DLi8Q/3qFb7m8vcWYBdwLOH1u5Uw0tTcVUnxmm01yC9o4T4/BOp/\n",
728 728 "0uW4pE1Tpf3b3kK2D00Fja/DZUz9pqjsdiXXzwB3EcpXBnnrxgmDuTFgKfD0bHdod2mlvm62Hngf\n",
729 729 "4eChE4GTcQ93Vkvrlt/N1B0kSuchwmtvOeG1+F7Ca1OtORJYmCwvIMxG83U5N+uBNcnyGuDuIjrx\n",
730 730 "bkIN8iXCJ8rX6m67lrCjaSvwS53vWvS+QJjmtYXwnztr7UxNeSBbfk4kzPx5GHgM/55Z3QH8D7CX\n",
731 731 "kJuXEWYA3UfB0w8lSZIkSZIkSZIkSZIkSZIkSZIktcn/A4eK9UXawRDUAAAAAElFTkSuQmCC\n"
732 732 ]
733 733 },
734 734 "metadata": {},
735 735 "output_type": "display_data"
736 736 },
737 737 {
738 738 "data": {
739 739 "image/png": [
740 740 "iVBORw0KGgoAAAANSUhEUgAAAXcAAAENCAYAAAD0eSVZAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\n",
741 741 "AAALEgAACxIB0t1+/AAAE3lJREFUeJzt3X2UXOVBx/HvkE2AQJZ0S00CpCZNGyHYVmIDVEEGBExr\n",
742 742 "TwjHU160GFqKx9PSUvW0JKBlfSlStGp7tPQIpSdUCaZa3qStCSmjPYq8CAkvIQ2JRgltFoSk2R6j\n",
743 743 "hDL+8dzJ3pmd3Z258/7M93POnNx79748XO7+9pnnPve5IEmSJEmSJEmSJEmSJEmSJEmSJElSD1jY\n",
744 744 "6QK02DxgZqcLIdXqsE4XQD1rGbAFuJkQ7Kd3tjgt9xLwqU4XQqpVrtMFUNf7EvDPwFcrlt8MfB14\n",
745 745 "FFgDXNOi468ElgCvAy9UKUcr/DKhpn4qcBdwZ7J8GXAScHsbyjCRico20Xmqd7mkPvEQ8LWKZScD\n",
746 746 "70mm3wl8rEXHPgb4t4qyHNuiY5W8lbH/nmOBvZQ3OdUT7KcRAng3MJAsm0MI5L8HfqYJZVtA9fP0\n",
747 747 "xjqXt/q8qs1sltFkpgEPAOcAR6SW54FvJ9PvS003288BW1PzW4CzW3SskpMZa375b2AH8NOpn79E\n",
748 748 "CNlaPAx8C9gO/FKybIQQ7O8H/qUJZVtG9fN0Tp3LW31e1WYDU6+iPnYysAn4KUJN/a5k+ZHA/yXT\n",
749 749 "y4Ab6tzvW4ArJ/n5vwL3ACcA+1LL9wFvq/NY9R7zG4x9K8kRmkB2pNbbQgj7HUztMOAg8AXgk8Df\n",
750 750 "JMuPAg40qWzPAe+m+nl6pc7liojhrsmcSmiLvRO4lBDuhwOvptaZCRRT89OAfwTOSOa/DPwh5WH4\n",
751 751 "74R2+qnMBv43Nf8qcPQE6y4G/gB4E/AuoADcT7hnUM8xDwJPJ9O/CDwGbE79fG9yrFosTbZ/GviT\n",
752 752 "ZP5xys9XM8r2Xqqfp2KdyxURm2U0maMJNfR7gfOBHyME/sOpdaZVbPNu4D+T6VwyX0stt5pRym/6\n",
753 753 "H0modVYaIoT4rxKaFzYBH2As2LOYDVye7CftADCjxn28A3iScNPyi4T28p8AvttAuaqVbT/Vz9NE\n",
754 754 "56/W86oeZs1dEzkG+J9kepTQdnwV8DLwF6n1XqvYbjnwD8n0KcBTVfZdazPETkItvORYQs230keT\n",
755 755 "MpVqo4enyl7vMSEE32rgw8APgR9n7A/WMdQehOnK062EP3Jbgc83uWyV5+mNhPO0r8blE51XSRE5\n",
756 756 "mtAD5tcp70GxFPgB49vX11L+lf5R4CeT6d8Bfg1YkbEsR1H+x2EL4dsDhDbiUnjeROiiCOE+wR9n\n",
757 757 "PF7Jxwnt6nMJ31TOSv3sKuDnU/PpcqRNJ3yTSPsSod282WWbSfXzNNH5m+y8SorU+YRmhM9U+dlf\n",
758 758 "E2qMaR8i9MCA0N49AlxLaAf+LeA64NwGynMZ8NvAp4FfSS1/lvAtAUJXxasJPVKuprFvpGcAPyKc\n",
759 759 "g9eT6eNTP7+V8p5D6XKULCM8A/BXFdsuoba29Sxlm+g81btcfeI2wi9r+q/8HxEu6C2EC/iY1M/W\n",
760 760 "EO7ebyOEhHrTnDrWnU24kQmhDbjaH4VWmAGc2aZjlRxBuDHa6XJIDTuT8e2m5zH2NfTG5AOhVrKZ\n",
761 761 "8HV0AaF90Ru2/eEThCacL1DeJ7yVLmb8zdxWu5xwQ7TT5ZCaYgHVb4oBXEj46gnjH0H/FvGPN6Ig\n",
762 762 "x+Q3BGMwH7ig04WQatVob5kPAeuS6eMId/VLdlPe3qh4FYFbOl2IFns++Ug9oZFmk+sIDz/cMck6\n",
763 763 "lQ9rSJLaIGvN/XJCb4h0l7AXCF9dS05IlpVZtGhRcefOnRkPK0l9aye1j2uUqea+nDBOxgWUP8J8\n",
764 764 "L3AJoffAQkL/30fGlW7nTorFop8mfa6//vqOlyGmj+fT89mtH2BRPUE9Vc19HeEhiWMJ7Y3XE26c\n",
765 765 "zgA2Jus8BHyE8OTd+uTf15JlNstIUgdMFe6XVll22yTr30D9IwRKkprMfug9Lp/Pd7oIUfF8Npfn\n",
766 766 "s3M68Zq9YtJ+JEmqUS6Xgzoy25q7JEXIcJekCBnukhQhw12SImS4S1KEDHf1jcHBIXK53KHP4OBQ\n",
767 767 "p4sktYxdIdU3Qley9LWXw2tRvcKukJIkw12SYmS4S1KEDHdpEt6EVa/yhqr6RpYbqt6EVbfwhqqU\n",
768 768 "qKx1S/3EmruiVa3Wbc1dvcqauyTJcJekGBnukhQhw12SImS4S1KEDHdJipDhLjWgsi+9T7GqW9jP\n",
769 769 "XdFqRz/38T+vbb9SveznLkky3CUpRoa7JEXIcJdSHGxMsZgq3G8DRoCnUsuGgI3AdmADMDv1szXA\n",
770 770 "c8A24PzmFVNqj9HRvYQbpKWP1JumCvevAMsrlq0mhPtiYFMyD7AEuDj5dznwxRr2L3XQwLhujFIs\n",
771 771 "pgrf7wB7K5atANYm02uBlcn0BcA64CCwC9gBnNqUUkot8RrltXRr6opHlpr1HEJTDcm/c5Lp44Dd\n",
772 772 "qfV2A8dnL5okKatGm02mqu5YFZKkDhjIsM0IMBfYA8wDXkyWvwDMT613QrJsnOHh4UPT+XyefD6f\n",
773 773 "oRiSFK9CoUChUMi8fS13kBYA9wFvT+ZvAl4GPku4mTo7+XcJcAehnf144AHgrYyvvTv8gNqiluEH\n",
774 774 "qg0dUM+QBQ4/oHapd/iBqWru64CzgGOB54FPAzcC64ErCDdOL0rW3Zos30q4U/URbJaRpI5w4DBF\n",
775 775 "y5q7YuLAYZIkw12SYmS4S1KEDHdJipDhLkkRMtzVEyqH4vU9pdLk7AqpnjDVu0xr3caukOpVzX6I\n",
776 776 "SVKZAYcGVk8w3KW6lIYJLjHo1Z1sc5ekCBnukhQhw12SImS4S1KEDHdJipDhLkkRMtwlKUKGuyRF\n",
777 777 "yHCXpAj5hKp6VOUwANOBg50qjNR1DHf1qGrDAFQbBEzqTzbLSFKEDHdJipDhLkkRMtwlKUKGuyRF\n",
778 778 "yHCXpAgZ7pIUIcNdkiJkuEtShBoJ9zXAM8BTwB3A4cAQsBHYDmwAZjdaQElS/bKG+wLgSmAp8HZg\n",
779 779 "GnAJsJoQ7ouBTcm8JKnNsob7fsIoTTMJ49PMBL4HrADWJuusBVY2WkCp1w0ODpHL5Q59BgeHOl0k\n",
780 780 "9YGs4f4K8Dngvwihvo9QY58DjCTrjCTzUl8bHd1LGNQsfMK81FpZR4VcBHyC0DzzA+BrwAcq1ild\n",
781 781 "zeMMDw8fms7n8+Tz+YzFkKQ4FQoFCoVC5u2zjol6MXAe8OFk/jLgdOAc4GxgDzAPeBA4sWLbYrFY\n",
782 782 "NfOlCYWx2ycb4neiIX9bvU31faSv8Wpl93dA9UreX1BzZmdtltlGCPMjk4OdC2wF7gNWJeusAu7O\n",
783 783 "uH9JUgOyNstsAW4HHgNeBx4H/hKYBawHrgB2ARc1XkRJUr068aoam2VUN5tl1O/a1SwjSepihrsk\n",
784 784 "Rchwl6QIGe6SFCHDXZIiZLhLUoQMd0mKkOEuSREy3CUpQoa7JEXIcJekCBnukhQhw12SImS4S1KE\n",
785 785 "DHdJilDWl3VImtBAaextqWMMd6npXmP8Cz2k9rJZRpIiZLhLUoQMd0mKkOEuSREy3CUpQoa7JEXI\n",
786 786 "cJekCBnukhQhw12SImS4S1KEDHd1pcHBIXK53KGPpPo0Eu6zgb8FngW2AqcBQ8BGYDuwIVlHqtvo\n",
787 787 "6F7C+CylT0wGyv5w5XI5BgeHOl0oRaaRcP888A3gJOAdwDZgNSHcFwObknlJZUoDi419wh8zqXmy\n",
788 788 "ft89BngCeEvF8m3AWcAIMBcoACdWrFMsFmOriakeg4NDZWE2a9Yb2L//lbJ1QlNM5ciK9cy3a5vm\n",
789 789 "HdffC00maZ6sObOz1twXAi8BXwEeB24BjgLmEIKd5N85GfeviFU2uVhrlZov63juA8BS4CrgUeDP\n",
790 790 "GN8EM2Fj6fDw8KHpfD5PPp/PWAxJilOhUKBQKGTePmuzzFzgIUINHuAMYA2hmeZsYA8wD3gQm2VU\n",
791 791 "oVqTS+U1YbOMVK5dzTJ7gOcJN04BzgWeAe4DViXLVgF3Z9y/+sr43iOSGtPIb9E7gVuBGcBO4IPA\n",
792 792 "NGA98GZgF3ARsK9iO2vufW7qWnm1Zdbc1d/qrbl3oopkuPc5w73aNtMJXSSDaj2I1N/qDXdfkC11\n",
793 793 "hfKXao+O2jSlxjj8gCRFyHCXpAgZ7pIUIcNdkiJkuEtShAx3SYqQ4S5JETLcJSlChrskRchwl6QI\n",
794 794 "Ge6SFCHDXepKA75AWw1x4DCpKzmQmBpjzV0tNzg45Is4pDaz5q6WG3shdokBL7WaNXdJipDhLkkR\n",
795 795 "MtwlKUKGu9QT7Bqp+nhDVeoJdo1Ufay5S1KEDHdJipDhLkkRMtwlKUKGuyRFyHCXpAgZ7pIUoUbD\n",
796 796 "fRrwBHBfMj8EbAS2AxuA2Q3uX5KUQaPhfjWwlbGnK1YTwn0xsCmZlyS1WSPhfgLwXuBWxsZwXQGs\n",
797 797 "TabXAisb2L8kKaNGwv1PgU8Cr6eWzQFGkumRZF6S1GZZx5Z5H/Aiob09P8E6Rcrf0HDI8PDwoel8\n",
798 798 "Pk8+P9EuJKk/FQoFCoVC5u2zjj50A3AZYTSjI4BB4OvAMkLY7wHmAQ8CJ1ZsWywWq2a+IhVerVf5\n",
799 799 "JqbJ5mtZpxX76K3j+nvUX5JXVNac2VmbZa4F5gMLgUuAbxPC/l5gVbLOKuDujPtXj6h8P6pD0Urd\n",
800 800 "oVlD/paqEDcC64ErgF3ARU3av7pU5ftRHYpW6g6d+E20WSYi45tcphNa6yrF2zzSmeOOP8+zZr2B\n",
801 801 "/ftfQXGqt1nGl3WoycpfKhFYm2++8efZb01Kc/gBSYqQ4S5JETLcJSlChrskRchwl6QIGe6SFCHD\n",
802 802 "XZIiZLhLUoQMd0mKkOEuRWPAQdx0iMMPSNEoH5LA4Qj6mzV3SYqQ4S5JETLcJSlChrskRchwl6Jl\n",
803 803 "75l+Zm8ZKVr2nuln1twlKUKGuyRFyHCXpAgZ7pIUIcNdkiJkuEtShAx3SYqQ4a66DA4OlT0YI6k7\n",
804 804 "+RCT6jI6upf0gzFgwEvdyJq71DccjqCfZA33+cCDwDPA08DHk+VDwEZgO7ABmN1oASU1S2k4gvAJ\n",
805 805 "38IUq6zhfhD4DeBk4HTgo8BJwGpCuC8GNiXzkqQ2yxrue4DNyfQPgWeB44EVwNpk+VpgZUOlkyRl\n",
806 806 "0ow29wXAKcDDwBxgJFk+ksxLktqs0XA/Gvg74GpgtOJnpcY9SVKbNdIVcjoh2L8K3J0sGwHmEppt\n",
807 807 "5gEvVttweHj40HQ+nyefzzdQDEmKT6FQoFAoZN4+ayflHKFN/WXCjdWSm5JlnyXcTJ3N+JuqxWLR\n",
808 808 "Cn03GhwcqtKDYjrh/nlaZT/3yeZrWacZ23jcLPvwd7F3JA8N1pzZWcP9DOCfgCcZu1rWAI8A64E3\n",
809 809 "A7uAi4B9Fdsa7l0qXDzdEDoe13BXpXaFeyMM9y5luPfbcQ33XlJvuPuEqiRFyHCX+lb5cAQOSRAX\n",
810 810 "Bw6T+lZpOIIxo6MOBBcLa+6SFCHDXZIiZLhLUoQMd0mKkOEuSREy3CUpQoZ7H/Nl11K87Ofex3zZ\n",
811 811 "tRQva+6SFCHDvY/YDKOpVQ5JMMPhCXqUzTJ9xGYYTa1ySILykSQdnqB3WHOXpAgZ7pIUIcM9EpXt\n",
812 812 "6baPSv3NNvdIjG9Pt31U6mfW3KM2YO8YNZkv+OgV1tyjVq3ng9QIX/DRK6y5S1KEDHdJipDhLkkR\n",
813 813 "MtwlKUKGexeo7KNeS+8Dx4lR9xiw90wXMty7wFgf9fAJ8/VtI3VOqQdN9es3S+WlFq3abyw6UeUr\n",
814 814 "FouGUVqoeZd3WZzqHFXbZnzIT7VOt+7D4/bOPqqvk75+s1zftWjVfrtV8g295sy2n7ukJhuwqbAL\n",
815 815 "tKJZZjmwDXgOuKYF+5fU1cqbadQZzQ73acCfEwJ+CXApcFKTj9EHxj/iXfnShDGFThVSqkGhyrKp\n",
816 816 "r++p5/1mMJVmN8ucCuwAdiXzdwIXAM82+Tg96/77v8n992+YYq3xj3hXb/uE8MuTb0rZpOYrVFlW\n",
817 817 "6/VdS1u/JtLscD8eeD41vxs4rcnH6Gm33HIH99zzOvCuZMljnSyOpEg1O9xtYJvC9OmHceSRTzN9\n",
818 818 "+n4ADh7czYEDHS6UpOg0O9xfAOan5ucTau9pO3O53KImH7fnHDiwuWJJ5VfMal85J1rndzNs04zj\n",
819 819 "tnIfHrd39tE9x428LX5nJw8+kBRgATAD2Iw3VCUpCu8Bvku4sbqmw2WRJEmSVK/3A88APwKWVvxs\n",
820 820 "DeGhp23A+W0uVwyGCfc2nkg+yztamt7kw3fNtQt4knA9PtLZovSk24AR4KnUsiFgI7Ad2ADM7kC5\n",
821 821 "qjoRWAw8SHm4LyG0zU8ntNXvwAHN6nU98JudLkQPm0a47hYQrkPvFTXuPwhhpGzOBE6hPNxvAj6V\n",
822 822 "TF8D3DjZDtoZotsIf3EqXQCsAw4S/trvIDwMpfpE3U2gxdIP3x1k7OE7NcZrMrvvAJXDw64A1ibT\n",
823 823 "a4GVk+2gG2rIx1HeXXI34WEo1edjwBbgy3TR17UeUe3hO6/BxhSBBwhP6V3Z4bLEYg6hqYbk3zmT\n",
824 824 "rdzsfu4bgblVll8L3FfHfnwYaryJzu11wM3A7yXzvw98DriiTeWKgddb8/0s8H3gTYRrdxuhNqrm\n",
825 825 "mHJUtmaH+3kZtql88OmEZJnK1Xpub6W+P6Sq7eE71ef7yb8vAXcRmr4M98aMECp4e4B5wIuTrdyp\n",
826 826 "Zpl0W9y9wCWEh54WAm/Du+v1mpeavpDymzCa2mOE624B4Tq8mHBdKpuZwKxk+ihCDzivycbdC6xK\n",
827 827 "plcBd3ewLGUuJLRrHiD85flm6mfXEm5obQN+of1F63m3E7qdbSH8D5+0LU5V+fBd8ywk9DjaDDyN\n",
828 828 "5zOLdcD3gFcJuflBQu+jB+jCrpCSJEmSJEmSJEmSJEmSJEmSJEmS+tD/AzUxDUJku6WfAAAAAElF\n",
829 829 "TkSuQmCC\n"
830 830 ]
831 831 },
832 832 "metadata": {},
833 833 "output_type": "display_data"
834 834 }
835 835 ],
836 836 "source": [
837 837 "display_png(x)\n",
838 838 "display_png(x2)"
839 839 ]
840 840 },
841 841 {
842 842 "cell_type": "markdown",
843 843 "metadata": {},
844 844 "source": [
845 845 "Note that like `print`, you can call any of the `display` functions multiple times in a cell."
846 846 ]
847 847 },
848 848 {
849 849 "cell_type": "markdown",
850 850 "metadata": {},
851 851 "source": [
852 852 "## Adding IPython display support to existing objects"
853 853 ]
854 854 },
855 855 {
856 856 "cell_type": "markdown",
857 857 "metadata": {},
858 858 "source": [
859 859 "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."
860 860 ]
861 861 },
862 862 {
863 863 "cell_type": "markdown",
864 864 "metadata": {},
865 865 "source": [
866 866 "First, consider how a NumPy polynomial object renders by default:"
867 867 ]
868 868 },
869 869 {
870 870 "cell_type": "code",
871 871 "execution_count": 9,
872 872 "metadata": {
873 873 "collapsed": false
874 874 },
875 875 "outputs": [
876 876 {
877 877 "data": {
878 878 "text/plain": [
879 879 "Polynomial([ 1., 2., 3.], [-10., 10.], [-1., 1.])"
880 880 ]
881 881 },
882 882 "execution_count": 9,
883 883 "metadata": {},
884 884 "output_type": "execute_result"
885 885 }
886 886 ],
887 887 "source": [
888 888 "p = np.polynomial.Polynomial([1,2,3], [-10, 10])\n",
889 889 "p"
890 890 ]
891 891 },
892 892 {
893 893 "cell_type": "markdown",
894 894 "metadata": {},
895 895 "source": [
896 896 "Next, define a function that pretty-prints a polynomial as a LaTeX string:"
897 897 ]
898 898 },
899 899 {
900 900 "cell_type": "code",
901 901 "execution_count": 10,
902 902 "metadata": {
903 903 "collapsed": false
904 904 },
905 905 "outputs": [],
906 906 "source": [
907 907 "def poly_to_latex(p):\n",
908 908 " terms = ['%.2g' % p.coef[0]]\n",
909 909 " if len(p) > 1:\n",
910 910 " term = 'x'\n",
911 911 " c = p.coef[1]\n",
912 912 " if c!=1:\n",
913 913 " term = ('%.2g ' % c) + term\n",
914 914 " terms.append(term)\n",
915 915 " if len(p) > 2:\n",
916 916 " for i in range(2, len(p)):\n",
917 917 " term = 'x^%d' % i\n",
918 918 " c = p.coef[i]\n",
919 919 " if c!=1:\n",
920 920 " term = ('%.2g ' % c) + term\n",
921 921 " terms.append(term)\n",
922 922 " px = '$P(x)=%s$' % '+'.join(terms)\n",
923 923 " dom = r', $x \\in [%.2g,\\ %.2g]$' % tuple(p.domain)\n",
924 924 " return px+dom"
925 925 ]
926 926 },
927 927 {
928 928 "cell_type": "markdown",
929 929 "metadata": {},
930 930 "source": [
931 931 "This produces, on our polynomial ``p``, the following:"
932 932 ]
933 933 },
934 934 {
935 935 "cell_type": "code",
936 936 "execution_count": 11,
937 937 "metadata": {
938 938 "collapsed": false
939 939 },
940 940 "outputs": [
941 941 {
942 942 "data": {
943 943 "text/plain": [
944 944 "'$P(x)=1+2 x+3 x^2$, $x \\\\in [-10,\\\\ 10]$'"
945 945 ]
946 946 },
947 947 "execution_count": 11,
948 948 "metadata": {},
949 949 "output_type": "execute_result"
950 950 }
951 951 ],
952 952 "source": [
953 953 "poly_to_latex(p)"
954 954 ]
955 955 },
956 956 {
957 957 "cell_type": "markdown",
958 958 "metadata": {},
959 959 "source": [
960 960 "You can render this string using the `Latex` class:"
961 961 ]
962 962 },
963 963 {
964 964 "cell_type": "code",
965 965 "execution_count": 12,
966 966 "metadata": {
967 967 "collapsed": false
968 968 },
969 969 "outputs": [
970 970 {
971 971 "data": {
972 972 "text/latex": [
973 973 "$P(x)=1+2 x+3 x^2$, $x \\in [-10,\\ 10]$"
974 974 ],
975 975 "text/plain": [
976 976 "<IPython.core.display.Latex object>"
977 977 ]
978 978 },
979 979 "execution_count": 12,
980 980 "metadata": {},
981 981 "output_type": "execute_result"
982 982 }
983 983 ],
984 984 "source": [
985 985 "from IPython.display import Latex\n",
986 986 "Latex(poly_to_latex(p))"
987 987 ]
988 988 },
989 989 {
990 990 "cell_type": "markdown",
991 991 "metadata": {},
992 992 "source": [
993 993 "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:"
994 994 ]
995 995 },
996 996 {
997 997 "cell_type": "code",
998 998 "execution_count": 13,
999 999 "metadata": {
1000 1000 "collapsed": false
1001 1001 },
1002 1002 "outputs": [
1003 1003 {
1004 1004 "name": "stdout",
1005 1005 "output_type": "stream",
1006 1006 "text": [
1007 1007 " text/plain : PlainTextFormatter\n",
1008 1008 " image/jpeg : JPEGFormatter\n",
1009 1009 " text/html : HTMLFormatter\n",
1010 1010 " image/svg+xml : SVGFormatter\n",
1011 1011 " image/png : PNGFormatter\n",
1012 1012 " application/javascript : JavascriptFormatter\n",
1013 1013 " text/markdown : MarkdownFormatter\n",
1014 1014 " text/latex : LatexFormatter\n",
1015 1015 " application/json : JSONFormatter\n",
1016 1016 " application/pdf : PDFFormatter\n"
1017 1017 ]
1018 1018 }
1019 1019 ],
1020 1020 "source": [
1021 1021 "ip = get_ipython()\n",
1022 1022 "for mime, formatter in ip.display_formatter.formatters.items():\n",
1023 1023 " print '%24s : %s' % (mime, formatter.__class__.__name__)"
1024 1024 ]
1025 1025 },
1026 1026 {
1027 1027 "cell_type": "markdown",
1028 1028 "metadata": {},
1029 1029 "source": [
1030 1030 "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:"
1031 1031 ]
1032 1032 },
1033 1033 {
1034 1034 "cell_type": "code",
1035 1035 "execution_count": 14,
1036 1036 "metadata": {
1037 1037 "collapsed": false
1038 1038 },
1039 1039 "outputs": [],
1040 1040 "source": [
1041 1041 "ip = get_ipython()\n",
1042 1042 "latex_f = ip.display_formatter.formatters['text/latex']"
1043 1043 ]
1044 1044 },
1045 1045 {
1046 1046 "cell_type": "markdown",
1047 1047 "metadata": {},
1048 1048 "source": [
1049 1049 "The formatter object has a couple of methods for registering custom display functions for existing types."
1050 1050 ]
1051 1051 },
1052 1052 {
1053 1053 "cell_type": "code",
1054 1054 "execution_count": 15,
1055 1055 "metadata": {
1056 1056 "collapsed": false
1057 1057 },
1058 1058 "outputs": [
1059 1059 {
1060 1060 "name": "stdout",
1061 1061 "output_type": "stream",
1062 1062 "text": [
1063 1063 "Help on method for_type in module IPython.core.formatters:\n",
1064 1064 "\n",
1065 1065 "for_type(self, typ, func=None) method of IPython.core.formatters.LatexFormatter instance\n",
1066 1066 " Add a format function for a given type.\n",
1067 1067 " \n",
1068 1068 " Parameters\n",
1069 1069 " -----------\n",
1070 1070 " typ : type or '__module__.__name__' string for a type\n",
1071 1071 " The class of the object that will be formatted using `func`.\n",
1072 1072 " func : callable\n",
1073 1073 " A callable for computing the format data.\n",
1074 1074 " `func` will be called with the object to be formatted,\n",
1075 1075 " and will return the raw data in this formatter's format.\n",
1076 1076 " Subclasses may use a different call signature for the\n",
1077 1077 " `func` argument.\n",
1078 1078 " \n",
1079 1079 " If `func` is None or not specified, there will be no change,\n",
1080 1080 " only returning the current value.\n",
1081 1081 " \n",
1082 1082 " Returns\n",
1083 1083 " -------\n",
1084 1084 " oldfunc : callable\n",
1085 1085 " The currently registered callable.\n",
1086 1086 " If you are registering a new formatter,\n",
1087 1087 " this will be the previous value (to enable restoring later).\n",
1088 1088 "\n"
1089 1089 ]
1090 1090 }
1091 1091 ],
1092 1092 "source": [
1093 1093 "help(latex_f.for_type)"
1094 1094 ]
1095 1095 },
1096 1096 {
1097 1097 "cell_type": "code",
1098 1098 "execution_count": 16,
1099 1099 "metadata": {
1100 1100 "collapsed": false
1101 1101 },
1102 1102 "outputs": [
1103 1103 {
1104 1104 "name": "stdout",
1105 1105 "output_type": "stream",
1106 1106 "text": [
1107 1107 "Help on method for_type_by_name in module IPython.core.formatters:\n",
1108 1108 "\n",
1109 1109 "for_type_by_name(self, type_module, type_name, func=None) method of IPython.core.formatters.LatexFormatter instance\n",
1110 1110 " Add a format function for a type specified by the full dotted\n",
1111 1111 " module and name of the type, rather than the type of the object.\n",
1112 1112 " \n",
1113 1113 " Parameters\n",
1114 1114 " ----------\n",
1115 1115 " type_module : str\n",
1116 1116 " The full dotted name of the module the type is defined in, like\n",
1117 1117 " ``numpy``.\n",
1118 1118 " type_name : str\n",
1119 1119 " The name of the type (the class name), like ``dtype``\n",
1120 1120 " func : callable\n",
1121 1121 " A callable for computing the format data.\n",
1122 1122 " `func` will be called with the object to be formatted,\n",
1123 1123 " and will return the raw data in this formatter's format.\n",
1124 1124 " Subclasses may use a different call signature for the\n",
1125 1125 " `func` argument.\n",
1126 1126 " \n",
1127 1127 " If `func` is None or unspecified, there will be no change,\n",
1128 1128 " only returning the current value.\n",
1129 1129 " \n",
1130 1130 " Returns\n",
1131 1131 " -------\n",
1132 1132 " oldfunc : callable\n",
1133 1133 " The currently registered callable.\n",
1134 1134 " If you are registering a new formatter,\n",
1135 1135 " this will be the previous value (to enable restoring later).\n",
1136 1136 "\n"
1137 1137 ]
1138 1138 }
1139 1139 ],
1140 1140 "source": [
1141 1141 "help(latex_f.for_type_by_name)"
1142 1142 ]
1143 1143 },
1144 1144 {
1145 1145 "cell_type": "markdown",
1146 1146 "metadata": {},
1147 1147 "source": [
1148 1148 "In this case, we will use `for_type_by_name` to register `poly_to_latex` as the display function for the `Polynomial` type:"
1149 1149 ]
1150 1150 },
1151 1151 {
1152 1152 "cell_type": "code",
1153 1153 "execution_count": 18,
1154 1154 "metadata": {
1155 1155 "collapsed": false
1156 1156 },
1157 1157 "outputs": [],
1158 1158 "source": [
1159 1159 "latex_f.for_type_by_name('numpy.polynomial.polynomial',\n",
1160 1160 " 'Polynomial', poly_to_latex)"
1161 1161 ]
1162 1162 },
1163 1163 {
1164 1164 "cell_type": "markdown",
1165 1165 "metadata": {},
1166 1166 "source": [
1167 1167 "Once the custom display function has been registered, all NumPy `Polynomial` instances will be represented by their LaTeX form instead:"
1168 1168 ]
1169 1169 },
1170 1170 {
1171 1171 "cell_type": "code",
1172 1172 "execution_count": 19,
1173 1173 "metadata": {
1174 1174 "collapsed": false
1175 1175 },
1176 1176 "outputs": [
1177 1177 {
1178 1178 "data": {
1179 1179 "text/latex": [
1180 1180 "$P(x)=1+2 x+3 x^2$, $x \\in [-10,\\ 10]$"
1181 1181 ],
1182 1182 "text/plain": [
1183 1183 "Polynomial([ 1., 2., 3.], [-10., 10.], [-1., 1.])"
1184 1184 ]
1185 1185 },
1186 1186 "execution_count": 19,
1187 1187 "metadata": {},
1188 1188 "output_type": "execute_result"
1189 1189 }
1190 1190 ],
1191 1191 "source": [
1192 1192 "p"
1193 1193 ]
1194 1194 },
1195 1195 {
1196 1196 "cell_type": "code",
1197 1197 "execution_count": 20,
1198 1198 "metadata": {
1199 1199 "collapsed": false
1200 1200 },
1201 1201 "outputs": [
1202 1202 {
1203 1203 "data": {
1204 1204 "text/latex": [
1205 1205 "$P(x)=-20+71 x+-15 x^2+x^3$, $x \\in [-1,\\ 1]$"
1206 1206 ],
1207 1207 "text/plain": [
1208 1208 "Polynomial([-20., 71., -15., 1.], [-1., 1.], [-1., 1.])"
1209 1209 ]
1210 1210 },
1211 1211 "execution_count": 20,
1212 1212 "metadata": {},
1213 1213 "output_type": "execute_result"
1214 1214 }
1215 1215 ],
1216 1216 "source": [
1217 1217 "p2 = np.polynomial.Polynomial([-20, 71, -15, 1])\n",
1218 1218 "p2"
1219 1219 ]
1220 1220 },
1221 1221 {
1222 1222 "cell_type": "markdown",
1223 1223 "metadata": {},
1224 1224 "source": [
1225 1225 "## More complex display with `_ipython_display_`"
1226 1226 ]
1227 1227 },
1228 1228 {
1229 1229 "cell_type": "markdown",
1230 1230 "metadata": {},
1231 1231 "source": [
1232 1232 "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",
1233 1233 "\n",
1234 1234 "**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",
1235 1235 "\n",
1236 1236 "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:"
1237 1237 ]
1238 1238 },
1239 1239 {
1240 1240 "cell_type": "code",
1241 1241 "execution_count": 21,
1242 1242 "metadata": {
1243 1243 "collapsed": false
1244 1244 },
1245 1245 "outputs": [],
1246 1246 "source": [
1247 1247 "import json\n",
1248 1248 "import uuid\n",
1249 1249 "from IPython.display import display_javascript, display_html, display\n",
1250 1250 "\n",
1251 1251 "class FlotPlot(object):\n",
1252 1252 " def __init__(self, x, y):\n",
1253 1253 " self.x = x\n",
1254 1254 " self.y = y\n",
1255 1255 " self.uuid = str(uuid.uuid4())\n",
1256 1256 " \n",
1257 1257 " def _ipython_display_(self):\n",
1258 1258 " json_data = json.dumps(zip(self.x, self.y))\n",
1259 1259 " display_html('<div id=\"{}\" style=\"height: 300px; width:80%;\"></div>'.format(self.uuid),\n",
1260 1260 " raw=True\n",
1261 1261 " )\n",
1262 1262 " display_javascript(\"\"\"\n",
1263 1263 " require([\"//cdnjs.cloudflare.com/ajax/libs/flot/0.8.2/jquery.flot.min.js\"], function() {\n",
1264 1264 " var line = JSON.parse(\"%s\");\n",
1265 1265 " console.log(line);\n",
1266 1266 " $.plot(\"#%s\", [line]);\n",
1267 1267 " });\n",
1268 1268 " \"\"\" % (json_data, self.uuid), raw=True)\n"
1269 1269 ]
1270 1270 },
1271 1271 {
1272 1272 "cell_type": "code",
1273 1273 "execution_count": 22,
1274 1274 "metadata": {
1275 1275 "collapsed": false
1276 1276 },
1277 1277 "outputs": [
1278 1278 {
1279 1279 "data": {
1280 1280 "text/html": [
1281 1281 "<div id=\"e75b8189-92cb-4cbb-9996-bb8ad5ff1b4e\" style=\"height: 300px; width:80%;\"></div>"
1282 1282 ]
1283 1283 },
1284 1284 "metadata": {},
1285 1285 "output_type": "display_data"
1286 1286 },
1287 1287 {
1288 1288 "data": {
1289 1289 "application/javascript": [
1290 1290 "\n",
1291 1291 " require([\"//cdnjs.cloudflare.com/ajax/libs/flot/0.8.2/jquery.flot.min.js\"], function() {\n",
1292 1292 " 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",
1293 1293 " console.log(line);\n",
1294 1294 " $.plot(\"#e75b8189-92cb-4cbb-9996-bb8ad5ff1b4e\", [line]);\n",
1295 1295 " });\n",
1296 1296 " "
1297 1297 ]
1298 1298 },
1299 1299 "metadata": {},
1300 1300 "output_type": "display_data"
1301 1301 }
1302 1302 ],
1303 1303 "source": [
1304 1304 "import numpy as np\n",
1305 1305 "x = np.linspace(0,10)\n",
1306 1306 "y = np.sin(x)\n",
1307 1307 "FlotPlot(x, np.sin(x))"
1308 1308 ]
1309 1309 },
1310 1310 {
1311 1311 "cell_type": "code",
1312 1312 "execution_count": null,
1313 1313 "metadata": {
1314 1314 "collapsed": false
1315 1315 },
1316 1316 "outputs": [],
1317 1317 "source": []
1318 1318 }
1319 1319 ],
1320 "metadata": {
1321 "signature": "sha256:86c779d5798c4a68bda7e71c8ef320cb7ba9d7e3d0f1bc4b828ee65f617a5ae3"
1322 },
1320 "metadata": {},
1323 1321 "nbformat": 4,
1324 1322 "nbformat_minor": 0
1325 1323 } No newline at end of file
@@ -1,168 +1,166
1 1 {
2 2 "cells": [
3 3 {
4 4 "cell_type": "markdown",
5 5 "metadata": {},
6 6 "source": [
7 7 "<img src=\"../images/ipython_logo.png\">"
8 8 ]
9 9 },
10 10 {
11 11 "cell_type": "markdown",
12 12 "metadata": {},
13 13 "source": [
14 14 "Back to the main [Index](../Index.ipynb)"
15 15 ]
16 16 },
17 17 {
18 18 "cell_type": "markdown",
19 19 "metadata": {},
20 20 "source": [
21 21 "# IPython Kernel"
22 22 ]
23 23 },
24 24 {
25 25 "cell_type": "markdown",
26 26 "metadata": {},
27 27 "source": [
28 28 "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."
29 29 ]
30 30 },
31 31 {
32 32 "cell_type": "markdown",
33 33 "metadata": {},
34 34 "source": [
35 35 "## Tutorials"
36 36 ]
37 37 },
38 38 {
39 39 "cell_type": "markdown",
40 40 "metadata": {},
41 41 "source": [
42 42 "* [Cell Magics](Cell Magics.ipynb)\n",
43 43 "* [Script Magics](Script Magics.ipynb)\n",
44 44 "* [Rich Output](Rich Output.ipynb)\n",
45 45 "* [Custom Display Logic](Custom Display Logic.ipynb)\n",
46 46 "* [Plotting in the Notebook](Plotting in the Notebook.ipynb)\n",
47 47 "* [Capturing Output](Capturing Output.ipynb)"
48 48 ]
49 49 },
50 50 {
51 51 "cell_type": "markdown",
52 52 "metadata": {},
53 53 "source": [
54 54 "## Examples"
55 55 ]
56 56 },
57 57 {
58 58 "cell_type": "markdown",
59 59 "metadata": {},
60 60 "source": [
61 61 "* [Background Jobs](Background Jobs.ipynb)\n",
62 62 "* [Trapezoid Rule](Trapezoid Rule.ipynb)\n",
63 63 "* [SymPy](SymPy.ipynb)\n",
64 64 "* [Raw Input in the Notebook](Raw Input in the Notebook.ipynb)"
65 65 ]
66 66 },
67 67 {
68 68 "cell_type": "markdown",
69 69 "metadata": {},
70 70 "source": [
71 71 "## Non-notebook examples"
72 72 ]
73 73 },
74 74 {
75 75 "cell_type": "markdown",
76 76 "metadata": {},
77 77 "source": [
78 78 "This directory also contains examples that are regular Python (`.py`) files."
79 79 ]
80 80 },
81 81 {
82 82 "cell_type": "code",
83 83 "execution_count": 1,
84 84 "metadata": {
85 85 "collapsed": false
86 86 },
87 87 "outputs": [
88 88 {
89 89 "data": {
90 90 "text/html": [
91 91 "<a href='example-demo.py' target='_blank'>example-demo.py</a><br>"
92 92 ],
93 93 "text/plain": [
94 94 "/Users/bgranger/Documents/Computing/IPython/code/ipython/examples/IPython Kernel/example-demo.py"
95 95 ]
96 96 },
97 97 "metadata": {},
98 98 "output_type": "display_data"
99 99 },
100 100 {
101 101 "data": {
102 102 "text/html": [
103 103 "<a href='ipython-get-history.py' target='_blank'>ipython-get-history.py</a><br>"
104 104 ],
105 105 "text/plain": [
106 106 "/Users/bgranger/Documents/Computing/IPython/code/ipython/examples/IPython Kernel/ipython-get-history.py"
107 107 ]
108 108 },
109 109 "metadata": {},
110 110 "output_type": "display_data"
111 111 }
112 112 ],
113 113 "source": [
114 114 "%run ../utils/list_pyfiles.ipy"
115 115 ]
116 116 },
117 117 {
118 118 "cell_type": "markdown",
119 119 "metadata": {},
120 120 "source": [
121 121 "There are also a set of examples that show how to integrate IPython with different GUI event loops:"
122 122 ]
123 123 },
124 124 {
125 125 "cell_type": "code",
126 126 "execution_count": 2,
127 127 "metadata": {
128 128 "collapsed": false
129 129 },
130 130 "outputs": [
131 131 {
132 132 "data": {
133 133 "text/html": [
134 134 "gui/<br>\n",
135 135 "&nbsp;&nbsp;<a href='gui/gui-glut.py' target='_blank'>gui-glut.py</a><br>\n",
136 136 "&nbsp;&nbsp;<a href='gui/gui-gtk.py' target='_blank'>gui-gtk.py</a><br>\n",
137 137 "&nbsp;&nbsp;<a href='gui/gui-gtk3.py' target='_blank'>gui-gtk3.py</a><br>\n",
138 138 "&nbsp;&nbsp;<a href='gui/gui-pyglet.py' target='_blank'>gui-pyglet.py</a><br>\n",
139 139 "&nbsp;&nbsp;<a href='gui/gui-qt.py' target='_blank'>gui-qt.py</a><br>\n",
140 140 "&nbsp;&nbsp;<a href='gui/gui-tk.py' target='_blank'>gui-tk.py</a><br>\n",
141 141 "&nbsp;&nbsp;<a href='gui/gui-wx.py' target='_blank'>gui-wx.py</a><br>"
142 142 ],
143 143 "text/plain": [
144 144 "gui/\n",
145 145 " gui-glut.py\n",
146 146 " gui-gtk.py\n",
147 147 " gui-gtk3.py\n",
148 148 " gui-pyglet.py\n",
149 149 " gui-qt.py\n",
150 150 " gui-tk.py\n",
151 151 " gui-wx.py"
152 152 ]
153 153 },
154 154 "metadata": {},
155 155 "output_type": "display_data"
156 156 }
157 157 ],
158 158 "source": [
159 159 "%run ../utils/list_subdirs.ipy"
160 160 ]
161 161 }
162 162 ],
163 "metadata": {
164 "signature": "sha256:ee769d05a7e195e4b8546ef9a866ef03e59bff2f0fcba499d168c06b516aa79a"
165 },
163 "metadata": {},
166 164 "nbformat": 4,
167 165 "nbformat_minor": 0
168 166 } No newline at end of file
@@ -1,740 +1,738
1 1 {
2 2 "cells": [
3 3 {
4 4 "cell_type": "markdown",
5 5 "metadata": {},
6 6 "source": [
7 7 "# Plotting with Matplotlib"
8 8 ]
9 9 },
10 10 {
11 11 "cell_type": "markdown",
12 12 "metadata": {},
13 13 "source": [
14 14 "IPython works with the [Matplotlib](http://matplotlib.org/) plotting library, which integrates Matplotlib with IPython's display system and event loop handling."
15 15 ]
16 16 },
17 17 {
18 18 "cell_type": "markdown",
19 19 "metadata": {},
20 20 "source": [
21 21 "## matplotlib mode"
22 22 ]
23 23 },
24 24 {
25 25 "cell_type": "markdown",
26 26 "metadata": {},
27 27 "source": [
28 28 "To make plots using Matplotlib, you must first enable IPython's matplotlib mode.\n",
29 29 "\n",
30 30 "To do this, run the `%matplotlib` magic command to enable plotting in the current Notebook.\n",
31 31 "\n",
32 32 "This magic takes an optional argument that specifies which Matplotlib backend should be used. Most of the time, in the Notebook, you will want to use the `inline` backend, which will embed plots inside the Notebook:"
33 33 ]
34 34 },
35 35 {
36 36 "cell_type": "code",
37 37 "execution_count": 1,
38 38 "metadata": {
39 39 "collapsed": false
40 40 },
41 41 "outputs": [],
42 42 "source": [
43 43 "%matplotlib inline"
44 44 ]
45 45 },
46 46 {
47 47 "cell_type": "markdown",
48 48 "metadata": {},
49 49 "source": [
50 50 "You can also use Matplotlib GUI backends in the Notebook, such as the Qt backend (`%matplotlib qt`). This will use Matplotlib's interactive Qt UI in a floating window to the side of your browser. Of course, this only works if your browser is running on the same system as the Notebook Server. You can always call the `display` function to paste figures into the Notebook document."
51 51 ]
52 52 },
53 53 {
54 54 "cell_type": "markdown",
55 55 "metadata": {},
56 56 "source": [
57 57 "## Making a simple plot"
58 58 ]
59 59 },
60 60 {
61 61 "cell_type": "markdown",
62 62 "metadata": {},
63 63 "source": [
64 64 "With matplotlib enabled, plotting should just work."
65 65 ]
66 66 },
67 67 {
68 68 "cell_type": "code",
69 69 "execution_count": 2,
70 70 "metadata": {
71 71 "collapsed": false
72 72 },
73 73 "outputs": [],
74 74 "source": [
75 75 "import matplotlib.pyplot as plt\n",
76 76 "import numpy as np"
77 77 ]
78 78 },
79 79 {
80 80 "cell_type": "code",
81 81 "execution_count": 3,
82 82 "metadata": {
83 83 "collapsed": false
84 84 },
85 85 "outputs": [
86 86 {
87 87 "data": {
88 88 "image/png": [
89 89 "iVBORw0KGgoAAAANSUhEUgAAAX0AAAEKCAYAAAD+XoUoAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\n",
90 90 "AAALEgAACxIB0t1+/AAAIABJREFUeJztfXt0VdWd/+fmwSvhkQTyDiAEFkRUUKwtLRqrSEFNtb6w\n",
91 91 "Vqlay2pL22lndVZX5zejrpkqTKdLnWFq0dVWmLFIO6NCfeCzqbSW0iKiFSqPiuYBIZAH5EEeN+f3\n",
92 92 "x+7OPTk5j/0859xkf9bKgiRnP+7NPZ/9OZ/vd393wrIsCwYGBgYGowIZUU/AwMDAwCA8GNI3MDAw\n",
93 93 "GEUwpG9gYGAwimBI38DAwGAUwZC+gYGBwSiCIX0DAwODUQRD+gZpjyeffBLLly/X0vcXv/hF/NM/\n",
94 94 "/ZPSPu+77z7cfvvtnr9fsGAB3njjDaVjGhhQGNI3iBzV1dXIz89Hb2+vUPvbbrsNL730kuJZESQS\n",
95 95 "CSQSCeV9+uHPf/4zLr30UqVjGhhQGNI3iBRHjx7F7t27UVhYiO3bt0c9HVeo3r8o018ymVQ4E4PR\n",
96 96 "CEP6BpFi8+bNuPLKK3H77bdj06ZNvtc+8cQTmD17NiZNmoRZs2bh5z//+eDPly5dOnhdRkYGHn30\n",
97 97 "UcyZMweTJk3CP//zP+PIkSP4xCc+gSlTpmDVqlXo6+sDANTW1qK8vBwPPvggpk2bhnPOOWewXzc8\n",
98 98 "99xzWLhwIfLy8vDJT34S7777rue17733HpYtW4aCggIUFxfjwQcfBECUfm9vL1avXo1JkyZhwYIF\n",
99 99 "2LNnz2C7mTNn4vXXXwdArKAbb7wRt99+OyZPnownnnhi8GerVq3CpEmTcNFFF+Gdd94JeKcNDAgM\n",
100 100 "6RtEis2bN+OWW27BzTffjJdeegknTpxwva6zsxPf/OY3sWPHDpw+fRq///3vsXDhQs9+X375Zezd\n",
101 101 "uxe7du3C+vXrcc8992DLli346KOP8O6772LLli2D1zY1NeHUqVNobGzEpk2b8OUvfxmHDh0a1ufe\n",
102 102 "vXtx99134/HHH0dLSwvWrFmDmpoaV1vqzJkzuPLKK7Fy5UocO3YMhw8fxhVXXAGAKP3t27fj1ltv\n",
103 103 "RXt7O2pqarB27drBtk77Z/v27bjpppvQ3t6O2267bfBnN998M1pbW/H5z38e1113Hfr7+33eaQMD\n",
104 104 "AkP6BpHht7/9LRoaGlBTU4M5c+agqqrKV2VnZGTg3XffRXd3N4qKilBVVeV57T/8wz8gNzcXVVVV\n",
105 105 "OO+887BixQrMnDkTkyZNwooVK7B3794h1//Lv/wLsrOzcemll+Lqq6/G1q1bB39HSfixxx7DmjVr\n",
106 106 "cPHFFyORSOCOO+7A2LFjsWvXrmHjP/fccygtLcW3vvUtjBkzBrm5ufjYxz42+PulS5fiM5/5DBKJ\n",
107 107 "BL7whS9g3759nq9lyZIlqKmpAQCMGzcOALB48WJ87nOfQ2ZmJr797W/j7NmzrvMwMHDCkL5BZNi0\n",
108 108 "aROuuuoqTJw4EQBw0003eVo8OTk52Lp1K3784x+jtLQU11xzDd5//33PvouKigb/P378+CHfjxs3\n",
109 109 "Dh0dHYPf5+XlYfz48YPfz5gxA8eOHRvW54cffogf/vCHyMvLG/yqr693vbaurg6zZs1imt+ECRNw\n",
110 110 "9uxZDAwMuF5bXl7u+7NEIoHy8nLXeRgYOGFI3yASdHd34xe/+AVef/11lJSUoKSkBD/84Q+xb98+\n",
111 111 "T3/6qquuwssvv4zjx49j3rx5uOeee4TGdtonra2t6OrqGvz+ww8/RGlp6bB206dPxz/+4z+itbV1\n",
112 112 "8KujowO33HKL67V//etfmcbnnS9AFhWKgYEB1NfXu87ZwMAJQ/oGkeDZZ59FVlYWDhw4gH379mHf\n",
113 113 "vn04cOAAli5dis2bNw+7/sSJE9i2bRs6OzuRnZ2NnJwcZGZmMo9nz5hxy56599570dfXh507d+L5\n",
114 114 "55/HTTfdNHgtvf6ee+7Bj3/8Y+zevRuWZaGzsxPPP//8kKcGimuuuQbHjh3DI488gp6eHpw5cwa7\n",
115 115 "d+/2HJ8Xe/bswTPPPIP+/n48/PDDGDduHD7+8Y9L92sw8mFI3yASbN68GXfddRfKy8tRWFiIwsJC\n",
116 116 "FBUVYe3atfj5z38+zOoYGBjAQw89hLKyMhQUFGDnzp149NFHAQzPpXdTxs7f278vLi5GXl4eSktL\n",
117 117 "cfvtt2Pjxo2YO3fusGsvuugiPP7441i7di3y8/MxZ84c1wUKAHJzc/HKK6/gV7/6FUpKSjB37lzU\n",
118 118 "1ta6ju81Z79rP/vZz2Lr1q3Iz8/Hk08+iaeffpprETQYvUjIHqJy11134fnnn0dhYaFn+to3vvEN\n",
119 119 "vPjii5gwYQKeeOIJLFq0SGZIAwNlqK2txe233z7ELok77r//fhw+fBj//d//HfVUDNIQ0kr/zjvv\n",
120 120 "xI4dOzx//8ILL+Dw4cM4dOgQHnvsMXzlK1+RHdLAYFTDHHZnIANp0l+6dCny8vI8f799+3asXr0a\n",
121 121 "AHDJJZegra0NTU1NssMaGCiD6jILuqGjNITB6EGW7gEaGhpQUVEx+H15eTnq6+uHpKwZGESF6upq\n",
122 122 "fPTRR1FPgwv33ntv1FMwSGOEEsh1Po4alWJgYGAQDbQr/bKysiFBsvr6epSVlQ27rrKyEkeOHNE9\n",
123 123 "HQMDA4MRhdmzZ+Pw4cPM12tX+jU1NYNpbbt27cKUKVNcrZ0jR44M5kTH6esHP7CwdKmF3t7Uz779\n",
124 124 "bQu33aZvzHvvvVfra2ppsZCba6Gjw0JJiYXDh8N/X6++2sL69RZmzND3Xhw6ZKG01ML06eT/qub+\n",
125 125 "9NMWxo61cPnl8n0lkxYmTbKQk2Ohs1P8vfi3f7MAWPjRj8TmsWcPab96NX/b1lbS9stf5m8LWJg6\n",
126 126 "la/N1q0WgHvxl7+wt7nhBjIW6/UbN5Lrd+xgu/5737NQWanuM8bzxSuWpUn/1ltvxZIlS/D++++j\n",
127 127 "oqICP/3pT7Fx40Zs3LgRALBy5UrMmjULlZWVWLNmDX70ox/JDhkampuBdeuAn/4UyM5O/fz++4HX\n",
128 128 "XgN8CizGGq+9BnzqU0BODnDZZcDOneHPYd8+4IYbgNZW4NQpPWPs3Qtccgkwfz7wl7+o6/fwYeDa\n",
129 129 "a4H9+9X0lZ8PFBUBjY3i/TQ0AMXFpD/R9oDY36K+nvz79tt87Wh9uNxcvnYHDpB/ed6vMWPIv6dP\n",
130 130 "s11Pr2O9vrkZqKsDPCppxArS9o69WqEXNmzYIDtMJPj+94FVq4DKyqE/z80FvvY14OGHgZ/8JJq5\n",
131 131 "yeDNNwF6RsenPgX89rfAF78Y3vgtLUB7O3DOOcDChYScr7xS/Th1dcD06eT/f/kLcM01avo9coQs\n",
132 132 "li+9RF5Lfr54X42NZI69vUBT0/DPGitOngQ+8QnApTgoExoagKoqMdKvqwMqKoC2Nr527e1AVhaZ\n",
133 133 "Ow8OHgQyMlILFQuam8m/778PXHxx8PVnzgz9l6X/nh7yb9xzVMyOXA+cOgU88QTw//6f++/vvht4\n",
134 134 "+mng7Fn1Y1dXV6vv1IZ33iFkCwAXXcSv0GSxfz8hmIwMYO5cQqJekHkvKBnNnUuIQhWOHCHkXF4u\n",
135 135 "p84BQnhTpwKFhYBHVelB+L0Xzc3AhReS1yyChgbg/PP5CRggYy5YQEicB21t5O/T08N3H7W2AuXl\n",
136 136 "1VzvfVMTeY9bW9muF1H6iQSQDolghvQ98MQT5BG+uNj99yUlwAUXAC+/rH5snaRvWcRaoaRPrY8w\n",
137 137 "H0s/+giYMYP8f/p0/xtFlvSnTwdKS4Hjx4W7GYbGRqCsjJC1CEnaQUm/qEiO9E+eBObM4SdeisZG\n",
138 138 "8nkWUfrHjpHPEa/Sb2sD8vL438fOTmDRIn7SP+cc0pYFZ86QRYJH6U+fLv95CAOG9F0wMAA8+iix\n",
139 139 "cPxw883AL34RzpxUge6Lo4vZ5MnApEkpXzYM2G2XigpxdRqEjz4i/RcVpV63Cpw6BRQUANOmqSN9\n",
140 140 "FqXvh+Zm8vQhSvrNzalFg/csljNnyHs8MEBUOyva2oApU/jfx44O8pTF+lqTSWLDzZjBTvqnT5Mx\n",
141 141 "eJT+9OlAdzfb9VHCkL4L3niDBDkvucT/us99DnjuOeLHpgsOHSJ2h32rxLx5qeBYGKC2CxCs9GVQ\n",
142 142 "X09uXFlCtcOyCIEUFKhV+jJztCxCOrNnEyK0BKo0dHQQAp4yhd0CsbedOJEICJ5Fp72djDd1aspz\n",
143 143 "Zx2vsBCwVcP2RVcXMHYsmR+P0i8rY1P6lkUWsLIyQ/ppiy1bgNtuG0qMbiguJjfaH/8YzrxU4PBh\n",
144 144 "Mmc7KisBj9LvWhAG6VsWIdTCQjbrhBVnzpBMkLFj+cnKDXbSF30aoeQ3eTKZFyux2XHmDElQmDqV\n",
145 145 "3+Lp6CBtJ0/ms3ja2kibvDy+dh0d5OmAlfS7u4EJE4iQ41H6ZWVsSr+nh3wmcnIM6aclenuB//s/\n",
146 146 "krXDgupq4G8Vc9MChw8PzxCZMQP48MPw5kBtF4DcWA0NYurUD6dPA+PGpW5GyyJkIQtq7QBq7Z2C\n",
147 147 "AvHUVTqnRIIoZ15vHSCkP3EiyUQSIf2JE8nYPEqf2jsTJvCRZWcnWSRZCby7Gxg/no/0eZT+2bPk\n",
148 148 "szZ+vCH9tMQrrxC7g3rOQUg30qeZJ3aETfrHj5NAOEBulDFj2L1TVtjJOZFQp/aptQOos3cKCghp\n",
149 149 "sgYNnejoIHEZgN9isfcxcSIfMVLQpwTesSnpjx/Prtrp4s1j74iQPo/SN6Sf5ti2jWwaYsXSpcCu\n",
150 150 "XXwBrCjxwQfAzJlDfzZzZnikPzBAiG7atNTPpk2Tt0mcsJM+IGefOPulefkq5n36NCE+WdKnG5x4\n",
151 151 "1TYFVfoipC9r70yYwE7gPT0kt3/yZD5PX6fS7+42pJ+2GBgggdlrr2VvM2UKCYymi69vz5yhCFPp\n",
152 152 "t7WRm4/ukATCIf38fP4AZVC/kyfLP6FQslVF+rzEC6TUc26uPOnzLDhdXWQ8HtLv6OBvw+vpWxb5\n",
153 153 "u5aWGqU/4rF3L3lM5t0V+fGPpwfp9/YSlU2tFYrSUmJ98KbqieDECaK67QiD9EW9bifsO3AnTVJD\n",
154 154 "+rm5pK+olH53N1mEs7IIMbKSqXP83Fy+BYPaLrykn5vLT/o84/T1kX/z89lejyH9NMZzz4lt1b/o\n",
155 155 "ImDPHvXzUY3GRpJx5DxKNTOT+NNhnG3T3DzU2gHUplRSUK+cQhXpnz5NFC1A1LkM6Q8MEJLIySFE\n",
156 156 "1tEhnm4po/Tp0wZAiFFU6fOSHrVFeAK5nZ0p0medJ6+909NDsqDGjmWzbc+eJf0b0k9D/OpXfNYO\n",
157 157 "RbqQvj1V0omSErKzUjeiVPqiG5fsOH06RZAy6hwgBDRhAilHkZUln24JkH95lbq9vYy9I0L6YSl9\n",
158 158 "HntHhPSN0k9DNDaSXPUlS/jbVlWRNEQZAggDdXVks5IbSkvDIX03pT9tmnql39pK8r8pVCl9uyqm\n",
159 159 "6ly0hIW9L0B8EbErfR4ytLen8+Al/d5esuN17Fh+0rMrZF5Pn8aEqBXjB97snbNnDemPCrz8MrBs\n",
160 160 "2dASyqzIziYFp8IuXMYLe6qkEyUl8sXDWNDcTKwkO/LziVeuEu3tKRsGELM93HDmTCo9MjOT3Ogi\n",
161 161 "6pz2ZS8rLBrMdZK+SMqlKOl3dpK2iUQ4Sr+zk8wRYG/HS/o9PYTEs7LIgp5MBvdvSD8N8eqrcuV9\n",
162 162 "08HiaWryLyAXhtJvaxteiph3RyYL7N47oEfpA3IWj7Mv0RiBrNJ32js87anyBsIhfaqqAfZ2op5+\n",
163 163 "IsGm9o3ST0NYFjlYRIb0Fy4kJYvjjOPHvWt9h0n6U6YM/Vlenpp0Sjva21OKHFAbyFVB1MBQW4X2\n",
164 164 "FYW9Q1MnaXsepd/VRdoA4ZA+JWSeuVJPn9WusY9hSH+EYv9+8qE45xzxPqqq1JykpBNNTd6kr6Kk\n",
165 165 "AAvCIn2dSt++mMikbcbF07erZ157x95WhvRZ2zlJn8feESX9oFr/JnsnDfHqq8AVV8j1QUlfdQ0Z\n",
166 166 "lTh+3NveUVFSgAXprvR12ju5udGQPiVFIFzSp21l7B1WpU/LfbBUxLWT/rhxRumPSMj6+QDxqXNy\n",
167 167 "+I5wCxt+Sn+kkb5T6avYSEX7VWXvOAO5vIXHKOy+ejqRPh2XJ3uHl5CBlAXFm40DGHtnRKKvjxwM\n",
168 168 "/ulPy/cVZ4snmUyVGnZDWKTf2jqc9HNzyY2l8lwCZ/YOTa+UhdPekfX0naTPS9jAcE8+HUjfsuQ9\n",
169 169 "fVblblf6fX3BKba8nj7N3hk3Ts/xqaox6kl/zx5ScMyZRiiCqirgvffk+9GBU6cICXqlpBYUkLRJ\n",
170 170 "3ccmuil9mZLAbjh7lpAKvXGBFJnJvD57jRoK3tIDdtjJGhAnfTtpi6RsimTE2NvSsXlIv6+PpLxm\n",
171 171 "ZorbO7zKPZEgn/+g3H7RQC5dVOKOUU/6b7wBXHqpmr7irPT9rB2A3Aw5OWp2rXphYCB1WpITKi0e\n",
172 172 "au3YD8GhOfUipErR2UlIICsr9TNRogZSWSX2vkTsASfpyyh9XrUqqvTtY7KSN8BPyAB5GuBpI0L6\n",
173 173 "48eTeyjoyWNgINzzqN0w6kl/505SHlkF4k76XkFcCt0WT0cHISU7aVKoJH1nEJdCppIlMFyZA2Jl\n",
174 174 "C+z9UeID5JS+PftGlvR5yoSrIH1q07AkQYjYO/RkK0Af6bMq/Z07yRkcUWJUk/7AAPC736kj/blz\n",
175 175 "yRm0cYRfjj6FbtJ3s3YoZAnZDqfvTiHr69tz0ilklL6zP9EnEVmlbyfusJS+vV1GBptKBlK7ZQE+\n",
176 176 "pU9Jn2Wh4LWQ6KKSlUUq1fotXn19Yrv+VWJUk/577xEvO0gBs6K4mNxwOi0SUcRB6fuRvmzxMjuc\n",
177 177 "vjuF7MLitGMAeaWvwt6x++rpaO8AhDRZ/fm42TuUyBMJQvx+ar+/35B+pNi5U52fD5A/emUlOZIw\n",
178 178 "bhhNSt9en8UOXUpflPTdPH1ZpU/tGR7f2N4+K4soVdazFdxIn8WmcZL+2LH8OfSsbexKX4T0gxZB\n",
179 179 "u3oPepLo63O3N8PEqCd9VdYORWUlOXw8bnAraexE1KSv6pxcL9JX4enbiQoQ89C9+hMh/WSSEDQl\n",
180 180 "NVr4jDcDhxI3wKf27W0zM9ltGueYIrtlWZ8OnJ5+0Px49wLY1XuQr2+UfoSwLJK5M1pI33kurRt0\n",
181 181 "k75bjj5Fuip91faOqDVjz1TiyYax90HBQ/r2IDLP2HbLhaedSMqm09PXYe9Q9R606BmlHyE++IAQ\n",
182 182 "/6xZavuNK+k7DxVxQxhK317j3g6VpK/L01cdyHXaOyI7Op2EDfBn4LiRPmt7GcVuPydZVzE0gN/e\n",
183 183 "4V1YeOwdo/QjBLV27ApJBQzpeyOsQK4upa8jkCtr77iRPosP7deHqL0DsKdR2okYELd3RDx9HnuH\n",
184 184 "ZV52Ig/a/GWUfoTQ4ecDhvT9EHUgN25KX6W9YwevvaPK0+cZ206sADuBi9o7PHEAGXvHKP0YQxfp\n",
185 185 "l5YSclNR50UV+vtJkNSLcCmiJn3dgVwZVQ54B3JVZu+I2Dt20gXkPX2eJwV7uijP2CqUvoiVpDNl\n",
186 186 "EzDZO7FFUxPJZlmwQH3fGRnAjBnAhx+q71sUra2kLEFmpv91Ok6wsiMspe/l6cuociCegVwn6QJq\n",
187 187 "PP2wlb4o6etI2eQhcYDP3jFKPyLs3Al88pPBJCiKmTPjRfqnTrEVlJs8mSwQus4EaGsbWvnSjjDs\n",
188 188 "HR2kL2vv2MlW5LxdFZ6+m70jGshlTaOUUfp0PJGxWEjcTvosBdp47B2j9COCLmuHYsYM4OhRff3z\n",
189 189 "gsXPB8jNlJmprya4V3kEIJxArizpewVyu7r4F0pKJHbVR8mWpy8Vnr5TdfMqfadi591kRdvp2JFr\n",
190 190 "WUNJnFfpZ2cHb1Qz2TtpAN2kP3NmepI+oLbEsRPOQ0PsUK30ddk7ToKl5YF5zwJwW0AyMoK38bv1\n",
191 191 "I0P6liVH+nblzTN2WJ4+HYdm6fFm47D8PUz2Tsxx+jRw8CCweLG+MeLm6fOQvk5f33k8oB0qA7n2\n",
192 192 "k6Ts0GHvAIR0eQ/PcAvAAvJ+PMBH+v39ZLGxW528pG8nb55dsiLZO319fFaNc3FhtXfsm61U2jtG\n",
193 193 "6UeAN98khG//IKhG3JT+yZPxUPodHf6k39GhJp7gZ+/IWFdepD9uHH+/Ti+cQtaPp/PhIW07+fLO\n",
194 194 "QVSxy7TjsWpExhHx9E32Toyh29oB0jeQC+gjfcvytl0AciOMGSOnxCnC9PQBsWPy3MhWpC9nOQNA\n",
195 195 "/FASkTm4lVPQ5emL+PNhkL7T3jFKP2ZQeVKWF4qKCHHG5ZDkOHj69NQpv4wpVcFcnZ6+KnvHi/RF\n",
196 196 "grDOp1YVpM/TPiyln0wSKyojI9WG194RIXFee8d4+jHC2bPA3r3AJz6hd5yMDGD69Pio/TiQvp+1\n",
197 197 "Q6EqmKvT03f654CYvaNK6XvZM1EpfVFPn1eBs47lHIeXxOnBKKzzMp5+zPDHPwLz53tbDCoRp7TN\n",
198 198 "OJC+XxCXQkUwl9pIcQ/k+nn6PErfqWSBcD19VUqfN3+edSwRpa/T3jFKP2SE4edTTJ8O1NWFM1YQ\n",
199 199 "0on0ZZV+Tw+5qdxuLF2kP9KUPstZrxRhevr2zB2ArXZ/GKTPY+8YpR8ywiT98nKgoSGcsYJw6hSQ\n",
200 200 "n892rU57J+gJS4Wn7xcs5jnZyQ1hBHJFlL4O0o+jp2/P3KHzDCJk3aRPTxkz2TsxRDIJ/P73wKc+\n",
201 201 "Fc54ZWVAfX04YwXBr469E+mu9L2sHYDEWnhTIu0II5ArovRVB3JZc+YHBoYr1zA9fRYCd74/rHYN\n",
202 202 "a55+MkmSE+jmL5O9EyO88w5QUhJ8epQqxEXp9/SQD6ZbANIN6U76XkFcCpW1cihU5+nLlFCg85Hx\n",
203 203 "9Hk3Somc2iWrwFnbyI4TFMh1KneTvRMjhGntAIT046D029sJkbMeFpOXR4quqUZYgVw/ewcQJ/2B\n",
204 204 "geElByiiztNXrfR5fHm3sUXahkX6vNk4LGUVnE86I17p79ixA/PmzcOcOXOwfv36Yb+vra3F5MmT\n",
205 205 "sWjRIixatAj/+q//KjukEMIm/bjYO37ljN0QpaefmytX7x7wt3cAcdKnZRMyXO4YkWMOVebp6/D0\n",
206 206 "WUsWi8YD3FI9ebN3dC0UPKRvt4Lo9XH39KWGTyaTWLt2LV599VWUlZXh4osvRk1NDebPnz/kussu\n",
207 207 "uwzbt2+XmqgMLIuQ/r//e3hj5ucTxRZEQroRF9JnUfo5OUBzs9w4Oknfzc8HxJS+szqlaF+6Arky\n",
208 208 "Sp/3YBOAnYzDeDrgLaDm7N/vSSLtlf7u3btRWVmJmTNnIjs7G6tWrcK2bduGXWfpKtDOiMOHyYdl\n",
209 209 "xozwxkwk4uHr+9Wwd8PkyaSN6j8ZK+nLKn1dnr5XEBcQD+SqsIrciDcsT19mwXG2ZbVq7IRJd3cn\n",
210 210 "k95tRJU+ayDX2X9QVc44KH0p0m9oaEBFRcXg9+Xl5WhwsFwikcCbb76JCy64ACtXrsT+/ftlhhRC\n",
211 211 "2NYORRwsHl6lP2aMuho4drDsyFVB+ro8fa8gLqA2Tz+d7B2VSp8l/dJJsAD/SVUsKZg8gVw3eyfu\n",
212 212 "efpSa06CITp44YUXoq6uDhMmTMCLL76I6667DgcPHnS99r777hv8f3V1Naqrq2WmN4g33oiG9OOg\n",
213 213 "9GkglwdTppBgrkpbyq+WPsWECfH19P2U/rhx/MFvVUpfRyCXR+k7x2bd2OWWVcPr6dN2fX3u7yVt\n",
214 214 "w0PKzvo+IkqfJ9tHBLW1taitrRVuLzV8WVkZ6mzbTuvq6lBeXj7kmok2ebdixQp89atfRUtLC/Jd\n",
215 215 "dgvZSV8ldu4EvvMdLV37Ig4ZPLxKH1B7ihUFq70j+4ThR85AfOyds2fdbbexY8lTESt0KX0Ri4a2\n",
216 216 "ZU33lA3KsrTjHYf3yUC2fxE4BfH999/P1V7K3lm8eDEOHTqEo0ePore3F1u3bkVNTc2Qa5qamgY9\n",
217 217 "/d27d8OyLFfC14XGRkJ8jthyKEhHewcgpK/qQBOKsOwdPxsG0BfIFbF3VHn6UeXpu9k7LIodcK+9\n",
218 218 "EwfS530ycLN3dCt9WUgNn5WVhQ0bNmD58uVIJpO4++67MX/+fGzcuBEAsGbNGvzv//4vHn30UWRl\n",
219 219 "ZWHChAl46qmnlEycFTt3kl24bql2ulFeDrz2Wvjj2tHWBpSW8rXRQfphBXK7u/3PDhg/Xr2nH2Vp\n",
220 220 "5ajtHdG6PW5kzGLvuC0yqklf5vqgQG7ae/oAsWxWrFgx5Gdr1qwZ/P/XvvY1fO1rX5MdRhhRBXGB\n",
221 221 "+Ng7PNk7gNrzailYPH1VpK9L6YcRyI2i4Jrz7yKzOUunvePM3mFpJ+K586RgilwftdIf8TtyoyR9\n",
222 222 "Y++kEKbS10H6XmUTALV5+mEXXPMKxsoofRF7R9TTZylwplu520k8HZT+iCb91lbggw+ACy+MZvyi\n",
223 223 "IqClhe0m0AWR7B2Vh5RTsHj6sqWPgWhIP53z9GWIW8bT5y1f4NaGjqcyMOtG4smk974V2ZhBFBjR\n",
224 224 "pP+b3wBLlkS3smZmAsXFwLFj0YwPxCN7x7LYyjDEOZAbpPRV5umHae/IKn2RtpZFiJQnYAqIB3J5\n",
225 225 "xnGOkUj4q3de+8gofc349a+Byy+Pdg5RWzxxsHfOnvU+2MSO8eNTVUFF4ZdlA8RL6Xt5+mEGcnXY\n",
226 226 "O6zkbd/mE5eUTd4xeDdnGaWvGa+/Hj3pl5QAx49HN74I6au2d1jrDyUS8hZPVJ6+SGllXUo/O5ss\n",
227 227 "nCyLpyzp83rsMu2iyN6hbbzU+6irvRNnNDeT4wqj8vMpSkqis3f6+giB8O6sVW3v8BSdk92glS6B\n",
228 228 "XD9Pn1WlJ5Ok5LNTOSYS4nXtAb7NWSKevohip+OFvTkL4Ld3jNKPCLW1JGsn6je4uDg6pd/eTtI1\n",
229 229 "WWvpU0Sl9AH5UgzpFMiVVfqUdN3+vjKkT9XqwIB/WzflrUux03Zhb84KasO7OcsofY2Ig7UDRBvI\n",
230 230 "FcncAfQo/aAgLoVsMFdXINdLmQPq8/RlNlZRyJB+IiGuvFnPrRVpF0dP3yj9GOHXvwY+/emoZxGt\n",
231 231 "py/i5wPqA7m89o5OpS9ixQDqlb7fcYm8St8NMqRP27N486JK34tY/Up6q0jZpNk1rCmYQWMYTz8m\n",
232 232 "aGwknv7550c9k2jtHVHSj9LeUUH6ftk7IqdcAf6kT290nqwj3UqfdXHzIn3d5O32dJGZGbybVSSQ\n",
233 233 "a1fWtIKm19/KjZR57B0/pU9TVek5AFFhRJL+r38NXHZZNPV2nIgykCuj9EdqIFcH6ScSasonAHxK\n",
234 234 "X5e9A7Azh3HZAAAgAElEQVRn4biRd5DF4Wbv0DFVWi8ibdzsF7/cex77iC4QvDE21YgBLarHa6/F\n",
235 235 "w9oBgMJC4ORJudxzUYjU3QHSN5CbTLrnjtshY+8ELSY8/fodlyiTY08RBum7KW/alpeIgeDMHxXZ\n",
236 236 "O0FtdNo7cfDzgRFI+pYFvPQSsHx51DMhyM4mavvkyfDHFlX6EyYQwvB71OZBWPYOVeN+SkqH0gf4\n",
237 237 "grn0dCa/2jssx1XGQel7KfagejhuY6omcJE2spuzeNI7o8KII/0//5ncgJWVUc8khah8fdHsnURC\n",
238 238 "rcUTdG6tHTKkH2TtAHpJnycA69yRSpGRQYhDdEcs73xEiRvwV/q8ih0QJ3CegmtB4+hU+s4FIiqM\n",
239 239 "ONKnKj9q38yOqHx9UaUPqLV4wvL0g4K4QGq3Ku9TTBDp8ywmfgodYLd43AqeUahQ+kHt/cibl4jp\n",
240 240 "mLztVMcB3IhZVcqmUfqasGNHfKwdiqiUvgzpq0zbDMveYVH6iYTaFEsKHqXv5edTsAZzo7Z3ZDx9\n",
241 241 "UXuHN3uHNxvHjZj9Ark8m7OM0teAzk7gD3+ITxCXIqoNWrKkr8reCYv0gzZmUeggfZ4+/TZ6AexK\n",
242 242 "PyiQy1riOGxPX7W9o3KHrc7NWUbpa0BtLXDRRcF128NGVBu0RLN3gOjsHZnsHRalD4gXSFMVyA2y\n",
243 243 "d1QofZnyyHQOujx9UXtHVfYOTwpm0BhupO+1+csofQ146SXgM5+JehbDYZR+fOwdQCyYy0L6KjZV\n",
244 244 "8fTlF8iVKZpG24sqfRZPP67ZO7Kbs/w2fxmlrwFx9POB6JS+aPYOMHIDuYD48YZ+pM+zqUqlpy9j\n",
245 245 "7wwMeKvPdMre0b05S5UdZJS+Yhw+TEjqgguinslwpKvSH4mBXIBf6VsWmzpX6emHYe9Q0nbLdJP1\n",
246 246 "9EU2Z8VlR67b9bx2kNv1RukrxrZtQE1NPEovOBGF0k8mCXmKxjeitHdElT5PIJeH9P1KGFOotHdk\n",
247 247 "M28A9pRLv/YiZRhY2vrZO7ztwiB9v+Csm3r3ut4ofcXYtg347GejnoU7Jk4kJNzREd6Yp0+TcUUX\n",
248 248 "wSgDuTL2Dmsgl7dkgp8yB9TVzAH4DiaXUfqypK+ynAJtp1rpi3j0up4MjNJXiJMngX37gCuuiHom\n",
249 249 "7kgkws/Vl8ncAaKzd8IgfV6lz0L6qvP0ZQO5oqWRKXQrfRF7RzR7h9ej5z1EhfXJIA5llYERQvrP\n",
250 250 "PQdceWXwjRklioqAEyfCG0/GzweI0o/C3pFN2WQJ5OoifR57JygoLLsjV4W9E9Rex+YslSUVRNro\n",
251 251 "DPyagmsKsW0bcN11Uc/CH4WF4ZK+TOYOoE7pW1b8lH7c7R0e0o/S3kmXzVm6ArNe13vtAzBKXxE6\n",
252 252 "O8nRiCtXRj0TfxQWAk1N4Y0nq/RVkX5vLzk0gvXDLkP6ugK5qu0dlYFcXfZOFJuzwiq4xrtrNiiQ\n",
253 253 "y7oQGaWvCL/6FbBkCVBQEPVM/DFa7R2eCptAijyDDuV2Q5RKn8feUeXp67Z3wt6cJZL142cl0RLW\n",
254 254 "uguuuV1vlL5GPPUUsGpV1LMIRtj2TlyUPo+1A5BsI5HaOEC0gVxee8evP9bdtFHbO6Keflj2TjKZ\n",
255 255 "2iHL2kZniqdR+grQ1kaORoy7nw9EY+/IZO+oUvq8pA+IWzxRB3JV2jsydXNY+4jK01dt7/BYL0Ft\n",
256 256 "VJVtMEpfE555hlTUlCG3sJBu9k5USh8QJ31WT38k2TsytXe8SJu2j6LgmsqUTS9lrXpHLuvmLKP0\n",
257 257 "FWDLFuDWW6OeBRvSLXtn7Fjiq7MSmRdESV8kbTOd7B3dgdwos3dYNmeFkbIp8kTBs8PWb05G6WtA\n",
258 258 "XR3wpz8B11wT9UzYkG7ZO4mEGosnbHsnXbJ3dOfp67Z3kkkSKM3M5G8rQsaWRcaULYYm0kbV5iyj\n",
259 259 "9CXxs5+RAC6LhxsH5OcTu8Tv8VUlZEkfGLmkH7W9E5c8fS97hrb3mwMlR69ibaoLrnmNFzXp82zO\n",
260 260 "MkpfAskk8JOfAF/6UtQzYUdmJkkrPXkynPFUkb5svaA4kn7U9o7KMgxRpWzqaOtn76gicEDvISr0\n",
261 261 "eq/aO0bpC+K114CpU4ELL4x6JnwI0+KRzd4B0k/pd3WlTxkG3QXXdG/O8iseJuLN03a6VXtQGxUF\n",
262 262 "2kztHQ14/PH0UvkUYQZz09neES2vHLW9E7anH2UgV6atiL0jktsvmrLpFsjlyd4xSl8xPviAlF24\n",
263 263 "7baoZ8KPsNI2BwYIWU+aJNdPuin9dLF3VHr6Udk7QfGAoNTLsOwdVSmbKjZnGaUviIceIipfltCi\n",
264 264 "QFj2TkcHIU5ZVZGbGx3p60zZjDqQG0aevorsHb85yOT4x9ne0bk5Ky5KPwZTYMepU8D//A/w5z9H\n",
265 265 "PRMxhGXvqLB2gPRS+v395MuLxOwQUfp+JA1EV3BNRz182j4oA0e1vRNExryHqUeVveOn9HNz3fsJ\n",
266 266 "E2ml9B99lJyOVVoa9UzEEJa9MxpJn5Zg8DvSkEKE9IOeIFTW3glzR66Mpy8ayBU5fMUvDqDSEhIp\n",
267 267 "uJZuVTZjMAU2tLUBjzwC7NwZ9UzEEZa9oyJzB4iW9Fta+NqwWjuAvnr6PT1kE1HQwhOn7B2v16XT\n",
268 268 "0083e8cvkOuVvWN25CrAD35ADj6fNy/qmYhjNNo7vKWVAXGlz0r6OgK5WVmE7L3IwdlfOtg7okpf\n",
269 269 "h70jkr2j296xLL4nA6P0OXD0KPDjHwN790Y9EzmERfqydXcoVCl9Xh9TN+mPG0euZ1HlABvp037P\n",
270 270 "ng1Wcyo8fcvy7yczk2RxJZPupRIAvdk7ovaOyEYrWhLC+bf0UtaqNmf195P31m2XsFH6kvjmN4Fv\n",
271 271 "fQuYPj3qmciB2juWpXecOCn9sPL0eUg/K4vcrKwlMXhIn9WLl/X0aa14L0JPJIItnqg8fT8F7ufP\n",
272 272 "u801keCvdSPi6fOQuKm9I4mtW4H33we+852oZyKPCRPIB1dFyWI/qCL9KFM2eUmfdTcuBY/Fw5K9\n",
273 273 "A7AHc1Uofb8cfQqZDVYsxB129o7fIuNFsqo8fd5FxSh9QRw9Cnz968CTT7LddOmAMCyedFf6Inn6\n",
274 274 "PEof4Dudi9feYelPBekH3RMsufa6PH2RdE8RewfQT/p+efejUunv2LED8+bNw5w5c7B+/XrXa77x\n",
275 275 "jW9gzpw5uOCCC7CX0ZhvbweuvRb43veAiy6SnWV8UFSkP4NHZfZOuhRc4yV96uuzQKW9E+TFA/JB\n",
276 276 "WNZ+ZIKxOhYMkR25tF0USp+3zMOIUPrJZBJr167Fjh07sH//fmzZsgUHDhwYcs0LL7yAw4cP49Ch\n",
277 277 "Q3jsscfwla98JbDf1lZSJ7+6mvj5IwlG6QcjDNLntXdYSJ/F3qHBPy8vnvajQunLePqUuLziT2EX\n",
278 278 "XAuKIaggfd6a/V7K3StQPCKU/u7du1FZWYmZM2ciOzsbq1atwrZt24Zcs337dqxevRoAcMkll6Ct\n",
279 279 "rQ1NPlL3j38EPvlJYPFi4OGH2bIr0glhkH5csnfojc+yS9YOUU+fV+lHYe+wkHV2NiGfgQHva/yK\n",
280 280 "rVHI2DsZGf5ZLjoyf6JW+rzZOCL9p73Sb2hoQEVFxeD35eXlaGhoCLymvr7etb+ampSl89BD/moo\n",
281 281 "XRGWvaOS9EWzjURUPiC3I5cVPEo/KNuGgsXeYQkKJxLBhK0ikOsXjA1qL7o5yyu3Paid33i8JMu7\n",
282 282 "SIjYO3FW+lJTSDDKcMvBGl7tEon7cOedwOHDQG1tNaqrq2WmF0sUFgJ/+YveMVSR/pgxRPGxkp4T\n",
283 283 "YZN+Otg7LEqf9tXT4/2adNs7QIr03f6GovEASnxuFKAje4fXflFB4rqrbNbW1qK2tla4vRTpl5WV\n",
284 284 "oa6ubvD7uro6lJeX+15TX1+PsrIy1/62bbtPZjppgcJC4De/0TuGKtIHUmmbUZA+6+YpQCyQy2Lv\n",
285 285 "WBZ7yiarvcO6gIhaMxQy9g5tL6r0RdpFnbIpkncfhdKvrh4qiO+//36u9lL2zuLFi3Ho0CEcPXoU\n",
286 286 "vb292Lp1K2pqaoZcU1NTg82bNwMAdu3ahSlTpqCoqEhm2LRGYSHQ3Kyvf8sinr6K7B1AztcXJf3M\n",
287 287 "THLjsJYqBvQpfXpjZzDcKarsHSDYmmFN2VSh9L3aigRyRQKyQDikryrvPu719KXWnaysLGzYsAHL\n",
288 288 "ly9HMpnE3Xffjfnz52Pjxo0AgDVr1mDlypV44YUXUFlZiZycHPzsZz9TMvF0he5AbmcnuVlVfbhk\n",
289 289 "0jZFSR9IqX3WJ4yuLiAvj71/VtJntXYAPfaOF1gCuarsHTf4KXYaDHUrAeFH3iInZwFqSV9F3v2I\n",
290 290 "r72zYsUKrFixYsjP1qxZM+T7DRs2yA4zYqCb9FVl7lBEofSBFOnn57Ndr8veYVXmrH2qIn3WQK4u\n",
291 291 "e8ePhO1tnX8T0VRPUaXvtmDzZuPQOkYDA0Of+PwWCbMj12AQ+fmEmFnrvvBCpZ8PyJG+SIVNCt5g\n",
292 292 "ri57h0fps9g7qjz9qO0d0cwflr0BvOOpVO5u19P6Pk4iF8kOioPSN6QfMjIzgYIC4ORJPf3HifRV\n",
293 293 "KH1W6CrDoNre4anjE2d7J0jpe6n2IFsIILaQW7swArlepOzWxtTeMWCGTotntJK+yOYsHUo/bvZO\n",
294 294 "lErfjVhZFgseAhdpIzqGk8hHbe0dA36kE+nLVNoMW+nr2Jylw95RRfo6d+TS9rKevhOitlDUpO9G\n",
295 295 "5Lybs4zSH8XQTfqq0jWB6LJ3cnL4Km3qDOSqzt5h6U9WpdP5xNHTF1H6qrN3eAK5Xm14N2cZpT+K\n",
296 296 "oZP0R1r2DiviEsgNy9OPOpCrw9On7XTbO5mZqdO27PBT4m5EzruoGKU/ipFO9o4s6fMelUgRF9Ln\n",
297 297 "KUERpr0jW3BtYMA/cEnbq7Z3ZDx9Vdk7Xqdt+SlxtzHMyVkGzBgtpN/RER7p856cFaW9E1Yg18/e\n",
298 298 "oSTqV+YiKG8+6EwAXvKmY+pW+l5tgjx9VntnRFfZNBDDaCH90WjvpEuefpDiZmmvw9MPI5Dr1UbV\n",
299 299 "9XGvsmlIPwLorL8TJ9IPU+nrJH2VO3JV5unL7MiVPXkrqL2fpx91yiZtw7rZivf6uNfeMaQfAdIp\n",
300 300 "eyc3N9raOyywrPTK3gmr4JqfvaOb9EV25ALhZO8A/J4+z/VuC4RbGYeoEIMpjD6MluwdWaXPmrJJ\n",
301 301 "b0YeFZXuefqsgVzRlEva3q8AmsjmrDgpfV57R2ZzFlX5cTgJ0JB+BMjNJSljPHnorIiTvSObp8+q\n",
302 302 "9Hk3ZgF6yjCEWU9ftuBaXJW+SAA4rECuzOasuPj5gCH9SJBI6PH1LUvP5qy4e/q81g6gpwxDmLV3\n",
303 303 "4mDvqA7IAmKxgCgDuaybs4Jed5gwpB8Rpk1Tb/F0dxPPUOSUKy/InJMblqcvQvojwd7RqdRl23uR\n",
304 304 "t6inH1Yg18/TZ7V3vHL6jdIf5dDh67e18R0kwoLsbPJhZbFC7LCseJN+3AO5umvvhGHvhOnp8z4d\n",
305 305 "8Kpx3s1ZrAtEFDCkHxF0kH5rq1o/n0LE4jl7NrVgiICH9Hk3ZgHRlmFQUXtHRZ6+DOnLFE6LQ/aO\n",
306 306 "qkAu6+Yso/QN0kbpA2JpmzJ+PhCO0u/pIWl0fkhneyeuKZvpuDmL58mAKn27JWqUvsGIV/pxJ/1E\n",
307 307 "IphYAb7aO8beSUFHwTXd2TuqNmdlZJAv+2EwRukbpJXSFyF9GT8f4MvTFyF9gM3i4dmRS31sv6cH\n",
308 308 "VSmbsnn6cVX6YQVyeWrp0Ot5C7TZ+zdK38Ao/QDw5OnznppFwUr6rEo/kQi2eFSmbMbd3hlJBdd4\n",
309 309 "NmcBwxcJo/QNjNIPAK+9wxvIBdQGXimCLJ6RYO/IlGWOi9LXuTnLrX+j9A2M0g8AvUG8ygDYodve\n",
310 310 "4SH9oIVEVe2dKPP0qVoXKcssk/XDS/q8GT88JE7nxJrXb5S+AaZNIztyg7JHeKBT6fNm78gqfYBd\n",
311 311 "7YuSvg6lH2TvhFlaWZe9I1OWWea4RJ5ArmWpJXFee8cofYNhGDuWkGJbm7o+dSl9kcPRZZU+oJ/0\n",
312 312 "dSj9IHsn7OMSddg7rG2j9PT7+8mxiF5VLXk3UInYO06lb0jfQHn9HdXF1iii8PQBdtIX2ZwFxNve\n",
313 313 "CSJ9lnnJHqIiWkrBb2wdnr7bAiOy81fV5ixg+CJhCq4ZAFDv67e2xieQq0rps6Rtppu9I0v6AwMk\n",
314 314 "BzyItHXZO6xlmUU9fScZJ5MkfuCl2nkJXKSNSNkGo/QNhkE16Y9WpZ8u9g7dpcmi+PxIn6ZrBtVm\n",
315 315 "p0rdrVieTBkHlgXD7ymBt8qmagL3auMXbOXZnAUYpW/gAaP0/cGaqx8n0vd7eqBEy3KQhp8fz/q0\n",
316 316 "kJHhfXSfbtJX6emHRfoiSp91kTBK3wCAWtJPJgnRTpqkpj874q70RTdnBdk7PMrc3qcsWQP+1oyK\n",
317 317 "flhJnzeTxt5WlacvUo45iPR5A7myi4RR+gYA1JJ+ezshfB1ncIqkbIadvaMjkMtTd4fCz94RIWtR\n",
318 318 "a4ZCVq2rbpuuSp/X3nH2b5S+AQC1pK/LzwfEUjZHgqfPa+0AwfYOa38ZGSTl0E1p88zLyyaKq6fv\n",
319 319 "NmaYnr4ue8cofQMAaklfl58PRJu9E+XmLFHS97J3eIq3Ad7B3DDtndGm9FVtznKrvWOUvkHaKP0o\n",
320 320 "PX2dKZs6lL4qe4f2JUv6XuQrS/osO3J5SyMA0ZO+rs1ZRukbAEgvpd/RwXdObphKX1cgV4e9EwXp\n",
321 321 "R2HvyByMHgbpiwRyZTZnGaVvAADIzycBWJaiYkHQqfSzssgHluV4QQoVSp8nZVNHIDdqe0dGpVPI\n",
322 322 "2Dteef4sm7NEd/O6PSHoyN5R5ekbpW/AhYwMoKAAOHlSvi+dSh/gz+BJB08/CnuHZ5467R0WtU7z\n",
323 323 "/J0KV7fSjyqQG+TpyywSRukbDEKVxaNT6QN8vr5lEdKPe/ZO2IHc7m7+3b1ufYWVvUPbO0lYZnNW\n",
324 324 "WKpdh6fPY++4Vdk0St8AgDrS11Vhk4InbbO3l6jEIGIIAgvpW1a8lL7fQnL2bHyUfhikH5ann5VF\n",
325 325 "NifyHEQuWyo56Hq3evpG6RsAUKv0dds7rKSvwtoB2Ei/p4fcTJmZ/P2zkD6PBw/42zuqlH5Ynj4g\n",
326 326 "Tvqinr4I6ScS7jtggxaKMDdnGaVvMAhV5ZV1K30e0lcRxAXYSF9U5QPR5OmHTfpR2jsiSl9kcxbg\n",
327 327 "TrIqC66Z2jsGymCUvjdY8vRlSD/u9o6K7J0o7R0nSdKS0H6KV6T2jls73WUYLMv/tZjaOwaeSBdP\n",
328 328 "nyd7J12Ufti1d1QGcmXtHRYiBcRJn3ra9uNAKakGna3La++4tdO9OYuezOX1WozSN/CEKtJvaSHp\n",
329 329 "n7oQhdJnydMX3ZgFpLe9E3X2ThCBJRLD1T5rfn9YpK/zzFuj9A08oYL0LSucPP24evoiG7OAYKXf\n",
330 330 "3a02kJuO2TtuAVnWpwRnW9YjGlWQftBYvGUVnNk4vE8SRukbDEIF6Z8+TchENkXSDzwpm2Fm7+gM\n",
331 331 "5HZ38y9efn2OlOwdFsXu1palXZSBXJ68e7+gL+C+SBilbwBADemfOkVKOuhEXJW+zFhBSl/EOkqH\n",
332 332 "7J2BAXHiBvjiATzqG1Br7/Ckhg4MkC+v1F+3sgqjTum3tLRg2bJlmDt3Lq666iq0tbW5Xjdz5kyc\n",
333 333 "f/75WLRoET72sY8JT3SkIjeXZAGwVJP0gm4/H+D39FWQPlWpyaT3NTKkn51NbnSnt0vR1cVvHam0\n",
334 334 "d3Rl71DSZj22USSbxm1sUU8/jOydoCAz7z6AEVl7Z926dVi2bBkOHjyIK664AuvWrXO9LpFIoLa2\n",
335 335 "Fnv37sXu3buFJzpSkUjI5+rHTemfOaPm2MZEIljtyywwiUSwHcNL+mHYO7LZO/RgdRbIKP0oPX1e\n",
336 336 "Ug5S4m7XB9k7I07pb9++HatXrwYArF69Gs8++6zntRZPTd5RCFmL59SpcJQ+a8rm6dPqzuoNIv3O\n",
337 337 "Trn4gZ/FI6L00yF7p7dXzZMCb1tWT9+N9FUrfd7sGqP0ATQ1NaGoqAgAUFRUhKamJtfrEokErrzy\n",
338 338 "SixevBiPP/646HAjGrKkHzd7R5XSB9hIX8ZKCiJ9Xk8/HbJ3VNlDLG15Pf3MzNTGJ57xVNk7qq6P\n",
339 339 "s9L3XXuWLVuG48ePD/v597///SHfJxIJJDzMsN/97ncoKSlBc3Mzli1bhnnz5mHp0qWu1953332D\n",
340 340 "/6+urkZ1dXXA9EcGVCh93fbOpElEwbPg9GmySKhAUK6+LOn72TGiSj/u2Tthkj6v0gdSBEuDqr29\n",
341 341 "wZ+nMEjcqdx5AsUqlX5tbS1qa2uF2/tO45VXXvH8XVFREY4fP47i4mIcO3YMhYWFrteVlJQAAKZN\n",
342 342 "m4brr78eu3fvZiL90QQVSv+cc9TNxw2TJ5MDX1gQtr3zt4+YEFTbO5SoLWt4UDCq7J2oSF/E06ft\n",
343 343 "+vpS71VPT/CTbNhKn2UfgK4duU5BfP/993O1F7Z3ampqsGnTJgDApk2bcN111w27pqurC2f+5gl0\n",
344 344 "dnbi5ZdfxnnnnSc65IhFOij9yZNJfR8WpJu9ozKQm5lJvpy+NCCWvaMjZVMF6bMQmKzSt4+nw97h\n",
345 345 "Ccy6efRRKX1ZCJP+d7/7XbzyyiuYO3cuXn/9dXz3u98FADQ2NuLqq68GABw/fhxLly7FwoULcckl\n",
346 346 "l+Caa67BVVddpWbmIwjp4OmPH08+9G4phE6otHd0Zu8ARE2qVPq0T7eFRMTecXu/0yV7R8TTdxtT\n",
347 347 "B+nLlmJmOeCdJ68/TAivPfn5+Xj11VeH/by0tBTPP/88AGDWrFl4++23xWc3SlBYCHjEwZkQRvZO\n",
348 348 "IpGyeKZN879Wtb3jt4dBd/aO6IlcsideAeqyd9xIW0bp69yRC7jbQizn+eq0dzIzUxu4MjKCX4vb\n",
349 349 "oqJzxzwPzI7cGKCkBDh2TLx9S4t+ewdg9/XTyd5RHcgFvDN4osre0WHviJA+q9IfOzYce8c5ht97\n",
350 350 "Qg9qoeqdV+mzvvYwYEg/BpAl/TCUPsBO+mHaOzpTNkWLuam0d9I5e8ep2FktDudCFRbp84xhlL6B\n",
351 351 "FAoKiDr22tTjh2SSkKzOWvoULKTf10e+RIugOREV6ff3ky+RG9XN3rGs0Ze9I+rpO1+3yEldrCmY\n",
352 352 "dN8oL+kbpW8ghYwMoKhITO23tRErReSMWF5MmRKcwUOtHZa6LiyIKk+fVu8UeR1u9k5/P/k782Rw\n",
353 353 "jER7R6SyJ0vg2a12vx/JZmSQL7oJjHdh4VX6rO9ZGDCkHxOUloqR/smT4Vg7AJvSV2ntANEFckX9\n",
354 354 "fMB9IeG1drz6AfieGKLO3nGSNwvpiyp9exvWej10frykz6L0jb1j4AtRX7+5mWT/hAFW0lcVxAUI\n",
355 355 "ofvV/JFN2dRF+k51LXIKl9fcZJW+bPZOTw/7JitR0udN2XS2YSF9e8BYtdI39o5BIERJ/8SJeJG+\n",
356 356 "yswdwL/mj2XptXdESd/N3uHN3PGaGyUSVpvIzSLiWTTcTs5iTRkVVfoigVwRpW9vo1rpm0CuQSBK\n",
357 357 "S4HGRv52zc3BefOqEIXSnzjRu+ZPTw+5uWR2OvopfZUnconYO25z4yFs2odzLrJPCqxPLU6fXae9\n",
358 358 "I6L0nSRulL5BqEgXpR8UyFXt6U+a5K30VZzQ5ZUdFFd7h5f03RYgnj7GjRtKpv39qZz1IMgofd4A\n",
359 359 "sIjSty8UOpW+ZcWryqYh/ZhAxtOPk9IP095RQfo5Oe6BYhnS12nvREH69vY8JSCc1hBrW6fSZwk8\n",
360 360 "i8QBZOwdHqVP6+6oymiThSH9mKCkRMzeiZunr9re8SvpLJu5A3iTvoyn76b0RewdGmi015bnfWKg\n",
361 361 "pG0/x4gne8dJ+jIlIHQGcp1Kn2WssJR+nPx8wJB+bCCashmm0p8yJfyUzXRU+uPGDbeMROwdt+Mc\n",
362 362 "eZV+RoZYLRsK51MLj9IX9fRFArnOhYJlLN1KnyczKEwY0o8Jpk0DWlvdS/L64cSJ0WvvqDiA3Y/0\n",
363 363 "RQO5OTnDvXgRewcY7uvzkC6FzMLhfGrhWbzclD5L27CUPm8g1/lkwFpPP05BXMCQfmyQmUnI2+Wg\n",
364 364 "Ml+M9Dx9SvpuxyyrUvpu+wBklL7bhjIRewcYTtgqDmuX8fTDsHfCUvoy9g6P0jf2joEneC2egQFS\n",
365 365 "bG3qVH1zsiOK7J2sLHJzumXYxNXeccsIErF3gOFKP2rSlwnkhrkjV7e9w1N7xyh9A0/wZvC0thKC\n",
366 366 "DesDNW5cqnCYF1QrfcA7bTOugVwv0ldh74jYTs4+wlT6op4+JdeBgeBTrYChqt2yolf6JpBrwARe\n",
367 367 "0g/TzwdIYDGo6JqOU7y8NmjpVvoynr6T9FXaO7KpnzLZO7yBXFmlT8k4KN3RrtppcbugIoRG6RtE\n",
368 368 "Dt60zTD9fIr8fGIpeaGlBcjLUzumVzBXJek7YwaqPX1V9o7IvJzEzZO940b6YaZsss7V3oZ1UdO5\n",
369 369 "I5cqfcsySt/AB7ylGMJW+gBR8S0t3r9vbVV/ipeXvaMie4eqSGd9GdWevqjSd/P0ZZU+Tx8y9o6o\n",
370 370 "p8+rwJ1tRBcXlUrfXrrZKH0DT1RUAPX17Nc3NZE6/GGioMBb6Q8MEOtH9YEuXvaOqvRQN4tHxtN3\n",
371 371 "s3dEn0pU2DsyTwvUS6dWRVj2jl21sx68Ym+jY3HhUfpAKm3T5OkbeGL6dOCjj9ivb2wEysr0zccN\n",
372 372 "fqR/+jQhNpkCaG7wsndOnyYZRbJwI33VSl806KzD3uFdOOztwwrkUjJmDYA7CTxqpQ+k0jaNvWPg\n",
373 373 "CUr6bjnpbmhsJJZQmPAjfR3WDuBdikFVplBurjvpiwZy3Tx9UaWvw97hXTjsG7TCDuSyvl5Rpa/L\n",
374 374 "0wdSpG/sHQNP0GMPg3LhKeJG+jqCuIC30m9vV2fvODdonTkjng7qpfTjQvoySp8nkCvj6dN2PGWc\n",
375 375 "eT19ndk7QGqxNErfwBc8Fk8cSV+X0veyd1SQ/sSJ7qQvuslMpafvtJ5E7B1nTX0RpS9i7zjr9ogo\n",
376 376 "fVZ7R0Tpy9o7LLuEz541St8gADyk39AQL9LXZe94BXJVkb6bfSRD+irtHSfpiyp9macFp9JntXcm\n",
377 377 "TBDbFGYfjzXrKWylz/IEQl+HUfoGvpg+HairC76uu5uQQViHolPEyd5RqfSd/cuQPj14xF4SOS6k\n",
378 378 "T2Ak9qMAAA6KSURBVHPHeZSnXbHz2Dt2a8qy2LNY7O10Kn0ZT59lXtTeMUrfwBcVFWxK/9gxovLD\n",
379 379 "PphhJNo7TqVvWcTuESX9RIIQgt3iidLesdtNdNHg+dw47R0epU/HpU8IGQyMY2/HqvRp0HRgQDw1\n",
380 380 "lIf0WeZF3zeTsmngC1alH4WfD8TH3kkmCTHIbs6i/dsXla4ucpPKpJ46M4JEUzZVKH17H7IpnzyL\n",
381 381 "F1XslsU3rlPps5B+IpGya0TsHZb3ldfesXv6hvQNPMHq6UdJ+i0t7mmluuwdN6Xf0UFIlEU5svRv\n",
382 382 "X1RkrB0K50IlqvRzc4cGmUWVPu1DdnMXz/iZmUSB9/SIkz7PfGkMQUTps5I+T4CZLpYi77lOGNKP\n",
383 383 "GaZPBz78MPi6qEh/7Fjy4XerQa/L3nEr6ayymqdT6asgfftCRe0iVfZO2Erf3p538aIEzvNUJqL0\n",
384 384 "AX7S51X6zv0KLPZOT48hfYMAlJeTmjp+5YuB6Egf8LZ4dNk7+fmkbzva2tTsxgX0KX1K+j09xCoS\n",
385 385 "sYucpC8Sa7D3IWsP8ZI+9ed5FhtnLIB1vjSOwkr69lRWlsWU9k93GQf9PY3SN2BCVhYwYwbwwQf+\n",
386 386 "19XXR0f6XpU2ddk7eXnDLSWVTxU6lL7d3pGpBuokfZG52eMLsvZQZydfe6q+ecbNzk7V0ecpVEcX\n",
387 387 "C1bSp6m1lsVGzPS1sD59UE9f9CwFXTCkH0NUVgKHD/tf89e/ArNmhTMfJ7yUvi57Z9w44g/bs2FU\n",
388 388 "jqVD6dvtnahJX1bpOxcNXnuHV+nT7CceggX47R26SPT2sj2J0dfCSuJ2pS9SYVUXDOnHEKykP3t2\n",
389 389 "OPNxYupU4OTJoT+zLH2kD5B+7SWdVVpJupQ+7VN2dy8l3P5+QmgynnzYnr6I0qfturr4FilKyqxz\n",
390 390 "pKmsrGPY58RC4sbTN2BGEOmfOUM+2GGXVaYoLh5+gHtHB8mkUZFC6Qanr69a6dsPfFcRJLbbO+3t\n",
391 391 "4uWm7YRLM5Z492ZE6emLKH3aTkTp85A+78LCOyfj6Rswo7ISOHTI+/fU2gl7YxaFG+nrru3vVPoq\n",
392 392 "4wc6FhS7vSMTdLYTrmgROLsnL2oPyXj6sqTPm7JJF0fWufEqfV5P35C+QSCClP6RI9H5+YD7Wb7H\n",
393 393 "j5PFQBdoMJdCpdJ3BopVWEd2e0dG6dOTvXp6xG0i+8LR3s6/AMl6+iL2Dn1CEAnk6lL69kAur6dv\n",
394 394 "SN/AFzNmkGJqziP8KKL084FoSF+npz9+/NBAsYoFxW7vyKaXTp5M+hIlfUpWAwNi1hVdNOjRfzxB\n",
395 395 "SVGlz5spA6QWGF2kTz36zk5j7xgoxpgxpAbPkSPuv49a6Udh70ydSg6Cp1CdHmpfVFT0rUrpA6Rt\n",
396 396 "a6s46WdkpIquiZJ+R0fK2uGxFWWUfnc3/47cri52e2fsWJJzf+YM2xiJBHkfW1v5ArkmZdOACeef\n",
397 397 "D7zzjvvvRqPSLyoiCwtFc7PaCqN20lfxFEGJGpBX+nl5cqQPpCwaEXuHKn2RWkcynn5XF998ee2d\n",
398 398 "RIK0OXWKL0OIlfTtnr5J2TQIxMKFwNtvu/8uaqVfUJAiAYpjx/SSfnHxUNI/fpwsPqrgVPqypD9t\n",
399 399 "Wmovg6zSV0H6NENJROnTBUNkv0FuLpm3qL3Ds2Da7R3WgDcv6U+YQD4fxtM3UA4v0u/uJn5/lKSf\n",
400 400 "kTG8RtCHH5JYhC7YLaX+fnKjFhaq658WkgMIwcraO/a9DHFQ+nRDnYzS583cAVKZUbykTy0lngXT\n",
401 401 "bu+wLk6U9HlKRLS0GE/fQAO8SH//fmDu3OgPZZg5cyjpHz0aHuk3NxMykSl97IS9tIQKpU9J37II\n",
402 402 "6avw9GXmRUlfVOmfOUPG57XU6ILFe54xXSx02ju0Da+9w0r6tMyDIX0DJlRUkCCQM2D6zjvAeedF\n",
403 403 "Myc7Zs4kRA+QrJC6uvBI/9gxtdYOQMisuZncoH194oeiU9CAZ1cXIS9Ze6etjRTiE326kVH6+fmp\n",
404 404 "8adO5W/b0kIWwGnT+No1NpLPlkjKpk5759gxtveQPj0a0jdgQiJB1P6+fUN//vbbJMgbNeykf/w4\n",
405 405 "uQl0frDz8lIbY3QEjSsqSBG7+npS6VTFxjeacSRbEZWqZZkMKfokI6L0s7LI3/fgQX7Sp3NvbuZr\n",
406 406 "W1BAYldTprD/Leh+C157p6GBL27w4YdsC1hBAVko+/rYTxsLA4b0Y4zFi4E//GHoz958E1iyJJr5\n",
407 407 "2DF7NiEBgGQTzZypd7xEIhVH0KH0KyrI00pdHSF9FZg6ldz0x4+rIX1Zpd/SIqb0ATLue+/xqXVg\n",
408 408 "qNLnJf2//pVvrsXF5ACijAx2+zMnh2yEZP08TZjAR/qNjfxprrohTPq//OUvce655yIzMxNvvfWW\n",
409 409 "53U7duzAvHnzMGfOHKxfv150uFGJyy8HXn899X1nJ/H0L7ooujlR2FNK3303HMtp7lyy0Bw8SHYt\n",
410 410 "qwQ9prKujiwAKjB1Kvl7TZkid1wetZ5OnBBX+gUFhNzGjBFLH6SkL6L0T54k9hBPPEKU9I8c4csw\n",
411 411 "Ki4mT6ysT47FxWThZCH9yZPJhjZVIkIVhEn/vPPOwzPPPINLL73U85pkMom1a9dix44d2L9/P7Zs\n",
412 412 "2YIDBw6IDjlqUFtbCwBYuhTYsye1yec3vyGEHwd/cM4corg7OojldMEFesah7wVASP/99wmRVlWp\n",
413 413 "HYceSK+S9CsqgN/9Tv6mp7WY6utrpZT+7t3kCU1EdRYWkvddxNM/cYJkHfEE3vPziRfuFQuxfy7s\n",
414 414 "c+zu5ost0SdUVtI/5xzyLwvpZ2SQ911nrEsEwqQ/b948zJ071/ea3bt3o7KyEjNnzkR2djZWrVqF\n",
415 415 "bdu2iQ45akA/0Lm5RO0/8wz5+dNPA9dfH9287MjKAubPB/buJaS/cKGecZykf/AgcOCAetLPzycl\n",
416 416 "Bt57Tx3pn38+8OKLQFmZXD9z5pDXfeZMrfCGtGnT5Db1FRYS1cpr71CBwpvfT1+nl9J3I/0xY0g7\n",
417 417 "ns8GJXEdpA+MMNJnQUNDAypsd1B5eTkaGhp0Djni8MUvAo88QlT1M88AN98c9YxSWLkS2LCBqNAw\n",
418 418 "LKfFi4GXXybvhep9CokE8PGPA7/8JXDJJWr6PP98EiSUtaLGjyeEO2aM+EHw9DWJLhrUmhGNTdTX\n",
419 419 "811P53nZZXztiouJGGEFL+nTz106k77vA9eyZctw3JkzCOCBBx7AtddeG9h5Ik7RizTF9dcD//mf\n",
420 420 "wIIFwJe/LK8aVeK224B584A1a/g37Yhg8WJiE1x3nZ59CjffTIJ0F16opj+aZfX1r8v3lZkJXHyx\n",
421 421 "eHuawii66Wz1arJwiMRuPvqI2HI8GD8e2LoVuOEGvnbl5XxznDWLvDesm95mzybZT6xPLsXF0ZZM\n",
422 422 "cYUlierqamvPnj2uv/v9739vLV++fPD7Bx54wFq3bp3rtbNnz7YAmC/zZb7Ml/ni+Jo9ezYXZyvZ\n",
423 423 "02jZT6y2YfHixTh06BCOHj2K0tJSbN26FVu2bHG99nDQ+YAGBgYGBtIQ9vSfeeYZVFRUYNeuXbj6\n",
424 424 "6quxYsUKAEBjYyOuvvpqAEBWVhY2bNiA5cuXo6qqCrfccgvm8xhuBgYGBgZKkbC8ZLqBgYGBwYhD\n",
425 425 "5DtyzeYtgrq6Olx++eU499xzsWDBAvzHf/xH1FOKHMlkEosWLWJKGhjJaGtrw4033oj58+ejqqoK\n",
426 426 "u3btinpKkeHBBx/Eueeei/POOw+f//zn0dPTE/WUQsNdd92FoqIinGeLVLe0tGDZsmWYO3currrq\n",
427 427 "KrS1tQX2Eynpm81bKWRnZ+Ohhx7Ce++9h127duG//uu/Ru17QfHII4+gqqpq1GeBffOb38TKlStx\n",
428 428 "4MABvPPOO6PWIj169Cgef/xxvPXWW3j33XeRTCbx1FNPRT2t0HDnnXdix44dQ362bt06LFu2DAcP\n",
429 429 "HsQVV1yBdevWBfYTKembzVspFBcXY+Hfdjjl5uZi/vz5aGxsjHhW0aG+vh4vvPACvvSlL3kmCowG\n",
430 430 "tLe3Y+fOnbjrrrsAkDjZZJni/GmMSZMmITs7G11dXejv70dXVxfK4pTDrBlLly5FniPndvv27Vi9\n",
431 431 "ejUAYPXq1Xj22WcD+4mU9M3mLXccPXoUe/fuxSWqdgmlIb71rW/hBz/4ATJEdyONEHzwwQeYNm0a\n",
432 432 "7rzzTlx44YW455570GU/smwUIT8/H3//93+P6dOno7S0FFOmTMGVV14Z9bQiRVNTE4r+VpCpqKgI\n",
433 433 "Tfbj5TwQ6R012h/b3dDR0YEbb7wRjzzyCHJli7qnKZ577jkUFhZi0aJFo1rlA0B/fz/eeustfPWr\n",
434 434 "X8Vbb72FnJwcpkf4kYgjR47g4YcfxtGjR9HY2IiOjg48+eSTUU8rNkgkEkycGinpl5WVoa6ubvD7\n",
435 435 "uro6lMetJF2I6Ovrww033IAvfOELuO6666KeTmR48803sX37dpxzzjm49dZb8frrr+OOO+6IelqR\n",
436 436 "oLy8HOXl5bj4b9txb7zxRt+qtiMZf/rTn7BkyRIUFBQgKysLn/vc5/Dmm29GPa1IUVRUNFg14dix\n",
437 437 "YyhkqMgXKenbN2/19vZi69atqKmpiXJKkcGyLNx9992oqqrC3/3d30U9nUjxwAMPoK6uDh988AGe\n",
438 438 "euopfPrTn8bmzZujnlYkKC4uRkVFBQ7+7fCCV199Feeee27Es4oG8+bNw65du9Dd3Q3LsvDqq6+i\n",
439 439 "SnXlvTRDTU0NNm3aBADYtGkTm1jk2r+rAS+88II1d+5ca/bs2dYDDzwQ9XQiw86dO61EImFdcMEF\n",
440 440 "1sKFC62FCxdaL774YtTTihy1tbXWtddeG/U0IsXbb79tLV682Dr//POt66+/3mpra4t6SpFh/fr1\n",
441 441 "VlVVlbVgwQLrjjvusHp7e6OeUmhYtWqVVVJSYmVnZ1vl5eXWT3/6U+vUqVPWFVdcYc2ZM8datmyZ\n",
442 442 "1draGtiP2ZxlYGBgMIowulMjDAwMDEYZDOkbGBgYjCIY0jcwMDAYRTCkb2BgYDCKYEjfwMDAYBTB\n",
443 443 "kL6BgYHBKIIhfQMDA4NRBEP6BgYGBqMI/x+3ghdT1LKwsgAAAABJRU5ErkJggg==\n"
444 444 ],
445 445 "text/plain": [
446 446 "<matplotlib.figure.Figure at 0x1084796d0>"
447 447 ]
448 448 },
449 449 "metadata": {},
450 450 "output_type": "display_data"
451 451 }
452 452 ],
453 453 "source": [
454 454 "x = np.linspace(0, 3*np.pi, 500)\n",
455 455 "plt.plot(x, np.sin(x**2))\n",
456 456 "plt.title('A simple chirp');"
457 457 ]
458 458 },
459 459 {
460 460 "cell_type": "markdown",
461 461 "metadata": {},
462 462 "source": [
463 463 "These images can be resized by dragging the handle in the lower right corner. Double clicking will return them to their original size."
464 464 ]
465 465 },
466 466 {
467 467 "cell_type": "markdown",
468 468 "metadata": {},
469 469 "source": [
470 470 "One thing to be aware of is that by default, the `Figure` object is cleared at the end of each cell, so you will need to issue all plotting commands for a single figure in a single cell."
471 471 ]
472 472 },
473 473 {
474 474 "cell_type": "markdown",
475 475 "metadata": {},
476 476 "source": [
477 477 "## Loading Matplotlib demos with %load"
478 478 ]
479 479 },
480 480 {
481 481 "cell_type": "markdown",
482 482 "metadata": {},
483 483 "source": [
484 484 "IPython's `%load` magic can be used to load any Matplotlib demo by its URL:"
485 485 ]
486 486 },
487 487 {
488 488 "cell_type": "code",
489 489 "execution_count": 4,
490 490 "metadata": {
491 491 "collapsed": false
492 492 },
493 493 "outputs": [],
494 494 "source": [
495 495 "%load http://matplotlib.org/mpl_examples/showcase/integral_demo.py"
496 496 ]
497 497 },
498 498 {
499 499 "cell_type": "code",
500 500 "execution_count": 5,
501 501 "metadata": {
502 502 "collapsed": false
503 503 },
504 504 "outputs": [
505 505 {
506 506 "data": {
507 507 "image/png": [
508 508 "iVBORw0KGgoAAAANSUhEUgAAAW8AAAEMCAYAAAALXDfgAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\n",
509 509 "AAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xl4FFW+xvFvp9NJCAphkdUECAgqLigG2UZgrsB4YQZQ\n",
510 510 "AZVFQQRxlAFFUQR1BMVxRAV0QMFxAUXUgRkXBrioiCJIhLAjO5KwG7ORpde6f5SJooGQpLuru/N+\n",
511 511 "nqefFElXnR+QvBxOnTrHZhiGgYiIhJUoqwsQEZHyU3iLiIQhhbeISBhSeIuIhCGFt4hIGFJ4i4iE\n",
512 512 "IYW3iEgYUniLiIShMsN727ZtTJ06lXXr1gFwxx13BLomEREpQ5nhXVBQgMPhwDAMdu7cyQUXXBCM\n",
513 513 "ukRE5CzKDO927dqxceNGOnTowLp16+jUqVMw6hIRkbM4pzHv+Ph4ANatW0eHDh0CWpCIiJTtnMI7\n",
514 514 "KSmJ999/nw0bNlC/fv1A1yQiImUoM7znzZtH165dufLKKxkwYMAZ3/fEE0/4sy4RETkLW1lLwi5f\n",
515 515 "vhyXy8Xx48cZPnw4UVGl573NZkOry4qIBEeZ4X3OF1J4i4gEjR7SEREJQwpvEZEwpPAWEQlDCm8R\n",
516 516 "kTCk8BYRCUMKbxGRMKTwFhGxSmFhhU9VeIuIWCEnBxITK3y6wltExArz5kFmZoVP1xOWIiLB5vFA\n",
517 517 "8+Zw6BBUMDfV8xYRCbYlS8zgbtGiwpdQeIuIBNsLL5gfx46t8CU0bCIiEkzffAPt20NCAqSnw3nn\n",
518 518 "Vegy6nmLiATTiy+aH0eOrHBwg3reIiLBk54OzZqZxwcOaKqgiEhYeOkl8Hqhf/9KBTeo5y0iEhyn\n",
519 519 "TpmBnZ1tjnu3a1epy6nnLSISDG++aQZ3x46VDm5QeIuIBJ7PBzNmmMfjxvnlkgpvEZFA++QT2LMH\n",
520 520 "mjSBvn39ckmFt4hIoBU/lDNmDERH++WSumEpIhJImzbBVVeZc7ozMqBmTb9cVj1vEZFAKn4oZ/hw\n",
521 521 "vwU3qOctIhI4GRnm6oFutznm3by53y6tnreISKA89xy4XHDzzX4NblDPW0QkME6cgKZNza3ONm2C\n",
522 522 "K6/06+XV8xYRCYQXXjCD+49/9Htwg3reIiL+l5VlzunOy4N16+Daa/3ehHreIiL+NmuWGdzXXx+Q\n",
523 523 "4Ab1vEVE/Csvz+x1Z2XBqlXQpUtAmlHPW0TEn+bMMYO7Uye47rqANaOet4iIvxQWmjNMTpyA//4X\n",
524 524 "/vCHgDWlnreIiL/Mm2cGd9u20LNnQJtSz1tExB9cLvNBnIwMWLwY+vULaHPqeYuI+MNbb5nB3bo1\n",
525 525 "9OkT8OYU3iIileXxwLRp5vHEiRAV+GhVeIuIVNaiRbB/P7RoAQMGBKVJhbeISGV4PDB1qnn8yCN+\n",
526 526 "22yhLApvEZHKmD8fvvsOmjWDwYOD1qxmm4iIVFRREbRsCenpsGABDBoUtKbV8xYRqajZs83gvuIK\n",
527 527 "uPXWoDatnreISEXk5kJyMmRmwscfQ69eQW1ePW8RkYqYPt0M7k6d4H//N+jNq+ctIlJeJ06Yve78\n",
528 528 "fPjyS+jcOeglqOctIlJeTz9tBnevXpYEN6jnLSJSPgcPQqtW5o7wmzaZNystoJ63iEh5PPGEuQjV\n",
529 529 "bbdZFtygnreIyLnbts0MbLsddu0yx70top63iMi5mjQJDANGjbI0uEE9bxGRc7N2LXTsCPHxsG8f\n",
530 530 "NGhgaTnqeYuIlMUwYPx483jcOMuDG9TzFhEp29tvm4tO1asHu3dDzZpWV6Set4jIWeXlwYMPmsd/\n",
531 531 "+1tIBDcovEVEzu6pp+DoUWjXDoYOtbqaEho2ERE5kz17zD0p3W745hszwEOEet4iImcybpwZ3MOG\n",
532 532 "hVRwg3reIiKl++QT6N0batQwb1LWr291RadRz1tE5NecThg71jx+4omQC25QeIuI/NaLL8LevXDJ\n",
533 533 "JXDvvVZXUyoNm4iI/NLhw+aqgfn5sGIFdO9udUWlUs9bROSXJkwwg7tfv5ANblDPW0TkZ199Bb/7\n",
534 534 "HcTGws6d0KyZ1RWdkXreIiJg3qQcOdI8fuihkA5uUHiLiJimTDF72y1bwsSJVldTJg2biIhs2gTX\n",
535 535 "XAM+H6xebdm+lOWhnreIVG1uNwwfDl4v/PnPYRHcoPAWkaruuecgLQ2aNIFp06yu5pxp2EREqq7v\n",
536 536 "voM2bcyblcuXQ48eVld0ztTzFpGqyeuFO+80g3vYsLAKblB4i0hV9fLL8PXX5pZm06dbXU25adhE\n",
537 537 "RKqeAwfgssugoACWLIG+fa2uqNzU8xaRqsUwcA8bZgb3gAFhGdyg8BaRKsb3j3/g+OILCqtXh1mz\n",
538 538 "rC6nwhTeIlJ1bN2KMW4cAKsHDjR3gw9TCm8RqRoKCnDdeCN2t5uTf/oT+9q2tbqiSlF4i0iV4Bkz\n",
539 539 "hpi9eyls0oQTjz5qdTmVpvAWkcj3/vtEv/YaXoeDU/PmYcTHW11RpSm8RSSyHTyI9847AcidPBlP\n",
540 540 "69YWF+QfCm8RiVxuN+4BA7Dn5ZHTrRtFP4V4JFB4i0jE8k6ejCM1laK6dSmcNQtsNqtL8huFt4hE\n",
541 541 "JOPTT4l69ll8Nhun5szBqF3b6pL8SuEtIpHn2DHct9yCzTDIGzMGd8eOVlfkdwpvEYksTieu3r2J\n",
542 542 "+eEHCtq2peCBB6yuKCAU3iISOQwDz4gRxGzYgLNePfL++U+Ijra6qoBQeItIxPC98ALRCxbgiYkh\n",
543 543 "d/58fBdcYHVJAaPwFpHIsHw5tgcfBCBnxgw8l19ucUGBpfAWkfC3axeem2/G5vORdd99uPr0sbqi\n",
544 544 "gFN4i0h4y87GfcMNRJ86Re7111M0YYLVFQWFwltEwpfXi+umm3AcOEBBixYUzJ4NUVUj1qrG71JE\n",
545 545 "IpLn/vuJ+ewzXDVrcurttzGqV7e6pKBReItIWPI++yzRM2fis9vJe/11vImJVpcUVApvEQk7vldf\n",
546 546 "xf7T2Hb288/jat/e4oqCT+EtImHFWLQI2913A5A1ZQrO/v0trsgaCm8RCR/LlmEMHozNMMi+//6I\n",
547 547 "WuK1vBTeIhIevvoKb9++RHk8ZA8fTmGErllyrhTeIhL6Nm3Ce8MN2J1Ocm68kcIpUyJqbe6KUHiL\n",
548 548 "SGjbvRv373+P/dQpcrt3p+DFF6t8cIPCW0RC2Y4duDp3xpGVxamOHcl/9dWIXSWwvBTeIhKaUlPx\n",
549 549 "dOxIzMmTFLRty6k334TYWKurChkKbxEJPatW4e3aleicHE5ddx05ixZVqacnz4XCW0RCy0cf4evZ\n",
550 550 "E3tBATm9epE3fz7Ex1tdVchReItIyDDmz8fXty9RLhfZt95KwZw54HBYXVZIUniLSEjwzZqFbehQ\n",
551 551 "onw+skePpvC558But7qskKXbtiJiLZ8Pz6RJRE+bBkD2xIkU3nuvxUWFPoW3iFgnNxf3rbfiWLoU\n",
552 552 "n81GzjPPUDRkiNVVhQWFt4hYY9cu3L164di3D/d555H7yiu4unWzuqqwofAWkeD75BO8AwfiyM+n\n",
553 553 "oHlzTs2fj7dpU6urCiu6YSkiwWMY+KZMwfjjH7Hn55PbvTu5y5YpuCtAPW8RCY68PNyDB+P48EMM\n",
554 554 "m42s8eMpGjdO65RUkMJbRAJv9WpcgwYRk5GBOz6e3NmzcXXvbnVVYU3DJiISOEVFeMeOxejalZiM\n",
555 555 "DAouvpisZcsU3H6gnreIBMa33+K+7TYce/bgi4oi5777zA0U9MSkXyi8RcS/3G68f/0rtmnTcPh8\n",
556 556 "FCQlUTBnDu42bayuLKIovEXEf9avx3nnncRu24Zhs5E9bBiFkyZBtWpWVxZxFN4iUnmHD+N56CGi\n",
557 557 "33mHWKCoYUPyZ83C1bGj1ZVFLIW3iFRcQQG+v/8d45lniC4qwhsdzakRIyi8/36M886zurqIpvAW\n",
558 558 "kfIzDIyFC/GMH4/j6FEAcrt3p+jJJ/E2aWJxcVWDwltEzp3PB0uX4nzsMWLT0nAA+S1bUjRtGq4O\n",
559 559 "HayurkpReItI2dxuePddXFOnErN7N7GAs1YtCiZOpOiWW7TutgUU3iJyZvn5GPPm4Xn2WRxHjhAD\n",
560 560 "OOvWpWj0aAqHDNG4toUU3lIxPh94PObL7f752G6HuDhzl+/oaK1bEa727sXz2msYs2fjyMnBARQk\n",
561 561 "JuIcO5aim26CmBirK6zyFN5icrng4EHYvx/278fIyMB94gTekycxfvgBW1YWUdnZ2HNysBcVYfP5\n",
562 562 "yrykYbPhi4nB+OnlO/98fAkJkJCArU4d7HXqYK9bl6i6daF+fWjQABo2ND8mJCj4gy0nB957D9e8\n",
563 563 "ecSsX18SDqcuuwzXuHE4e/aEKK2oESoU3lVNQQGkpWGkpuLesAHvnj1Eff89McePYzOMkrfZgLL6\n",
564 564 "Vj67HSM6GsNuL3nh9RLldhPlchHl82F3OsHpNE/IzDznMn0OB566dfE1aIAtMRF7cjLRzZpBUpL5\n",
565 565 "SkyEunUV8JXl9cLKlbjnziXqo4+wu1zEAJ7YWAr+8Afct9+O69pr9eccghTekczrNYN6/Xqca9Zg\n",
566 566 "pKYSt28fNp/vN+FsREVR1KAB7sREjKZNISkJo3ZtfAkJ+BISMGrVwlerlnkcH28Oj5T1A+3xYHO5\n",
567 567 "wOnEVlREVF4etuxsonJyiMrJwZadjS0nxwz1Y8ewnThB9IkTOH78keiCAmKOHoWjRyEtrfTfXlwc\n",
568 568 "7saNoWlT7BddRHSLFtiSk6FZM0hOhho1/PUnGVmOH4fly3F9+CFR//d/ROfmUrzaSF7btngGDcLZ\n",
569 569 "u7fGs0OcwjvSHD2KsWwZRUuW4Fi1iui8PGxA3E9f9kVFUXDRRXjbtMHXpg3eZs3wNmmC98IL/b9g\n",
570 570 "UHQ0RnQ0xMdjAL6GDc/5VFtBAVEnTmA/doyoI0ewZ2RAejqkp2M/fJiYY8dw5Odj37cP9u2DTz/9\n",
571 571 "zTXcNWviTUrC1rw5jlatiGrRwgz1Zs3Mnnt0Ffn2d7lg/Xp8S5fi+egjYrZtA37+x7vwwgtxDRyI\n",
572 572 "c8AAvImJ1tUp5VJFvnsjmM8Ha9bg/egj3B9/TNzOndiA4pUkCho3xp2SAm3b4r7yStyXXgrx8VZW\n",
573 573 "fE6M+Hi8TZuedYcVW04O9vR07OnpRB86BAcOwIEDRKenE3v0qHmjbetW2Lr1t9ePisLVoAFGkyZE\n",
574 574 "NW+Oo2VLs9fepIk5LNOoUXiGu8cDO3dCaire9evxrF2LY+dOcygLM7C9MTGcSknB6NED1//8D97k\n",
575 575 "ZKurlgoIw+9OAWDPHjyvvYbvrbeIOXoUO2AHvLGxFLZvj7dHD5zdukX09lJGzZp4atbEc9llOH/z\n",
576 576 "RYOokyexf/890YcOEXXwIMb+/UQdOIAjI4PYzExijxyBI0dg7drfXjsqCne9evgaN8aWlER0s2bY\n",
577 577 "ExPNm6m/vLFao0bwx4MNA06eNP/HsX8/xr59eHbvxrtjB44dO8z7DFDyPQFQ2KQJ7m7d8HTvjrN9\n",
578 578 "ey0UFQEU3uEkOxvfwoU4586lWlpayV9eUYMGuHr1wn399ebNpbi4s16mSrDZ8NWrh69ePfN/Hr/m\n",
579 579 "dGLPyCjptdsOHoQDB4jKyMBx7BgxP/5IzLFjcOwYbNhwxma8sbF46tTBKJ5FU7s2UT/NpImqUwdq\n",
580 580 "1jSnTRZPn/zlR5vt9KmWv/yYmws//oiRmYn35MmSWT9kZuI4cgR7YeHPv1XA8dMLoLBhQ5xXXAHX\n",
581 581 "XIO3TRvcl1+OofH/iKPwDgcbNuB+5hmi/vMf7G431QBPXByFvXrhuvVWXO3bawpXecXG4m3eHG/z\n",
582 582 "5rhK+7rLhf3YMeyHD2M/fJiow4cxjh2Do0eJOn4c+w8/EJOZSXRREfbiHnwA2DB/SH/9g+o+7zyc\n",
583 583 "jRvjadIEW3IyRnIy3iZNcLdujVG7dkBqkdCi8A5VhoGxciVFf/0r1daswYE5b/pU+/Z4bruNohtu\n",
584 584 "wKhe3eoqI1dMDN6kJLxJSWd9my0/n6iTJ0tmz5w2kyY7GyM3F6OoCKOoyJx143JhczqxOZ3m33F0\n",
585 585 "NNjtGA6HOYMnOhqbw2H2lGvXxla7Nr7atTF+mvXjS0jA27ix2dOXKk3hHWq8Xox//Qvnk08St327\n",
586 586 "2cuuVo38wYNx3nWXOStEQoZRvTre6tXxWl2IVDkK71Dh9WK88QbuJ58k5tAh4gBXQgJFo0ZRcPvt\n",
587 587 "6mmJyGkU3qHg889xjh5N7K5dxABFjRpRdO+9FA4cqFkBIlIqhbeV9u7FOWYMsf/9r7nEZv36FEya\n",
588 588 "RFGfPuE5x1hEgkYJYYWcHFxPPEH0Sy8R6/HgiYsjf8wYCkaNUk9bRM6JwjuYDAPjjTfwPPAAMVlZ\n",
589 589 "AOTddBMFjz6Kr0EDi4sTkXCi8A6Wo0dx3XEHMStWmFtHXX01hU89hfvKK62uTETCkMI7CHzvvot3\n",
590 590 "1ChicnNxn3ceeVOn4uzfX8tsikiFKbwD6ccfcY4YQeySJUQB+Z07c+rFF/E1amR1ZSIS5hTeAWIs\n",
591 591 "XYrn9tuJ/eEHPHFxnHr8cQqHDlVvW0T8QuHtb243nr/8hejZs82x7auuIv/llyN6dT8RCT6Ftz+d\n",
592 592 "OIGrTx9i1q3DGx1N3kMPUTh6tLlmhYiIHym8/WXDBujXj5j0dApr1SL/rbdwt21rdVUiEqG0jqg/\n",
593 593 "LFgAnTtDejrZl1zC2lmzFNwiElDqeVeGxwMTJsDzz5u/HjGC1D598GiYREQCTD3vivrxR/jDH8zg\n",
594 594 "jo6G2bPh1VcxYmLKPldEpJLU866II0egRw/Yvh3q14cPPjCHTUREgkThXV779kH37uZO5ZdeCsuW\n",
595 595 "QWKi1VWJSBWjYZPy2LrV7GEfOAApKbB6tYJbRCyh8D5X69ZBly7mbuLdusGnn0KdOlZXJSJVlML7\n",
596 596 "XKxcCddfD1lZ0KcPLF0K559vdVUiUoUpvMuyeDH06gX5+TBkiHlzMi7O6qpEpIpTeJ/N++9D//7g\n",
597 597 "csF998Ebb2h7MhEJCQrvM1m2DAYNAp8PHn0UZsyAKP1xhaLXX3+dli1bsnHjRqtLEQkapVFpvvoK\n",
598 598 "brwR3G4YNw6mTNFSriGsf//+xMXFcdVVV1ldikjQKLx/bdMm6N0bCgth2DCYPl3BHeLWrFlD+/bt\n",
599 599 "senvSaoQhfcv7d5tPjmZk2P2vF99VcEdBr744gtsNhuLFy9mwoQJ7Ny50+qSRAJO4V0sPd2cDnjy\n",
600 600 "pPkE5Tvv6OZkCJo3bx6tW7emZ8+e7Nu3D4Avv/ySkSNHcuONN9K9e3f+9re/WVylSOApvAFOnDAD\n",
601 601 "Oz0dOnSAJUsgNtbqquRX1qxZw5NPPslbb73FqVOneOCBBzh8+DCGYdD2pyV4T5w4QWZmpsWVigSe\n",
602 602 "wvvUKbjhBti1C664Aj75BKpXt7oqKcVTTz1F165dad26NYZh0KhRI7Zs2UK7du1K3vPFF1/w+9//\n",
603 603 "3sIqRYKjao8L+HzmgzcbN0Lz5rB8OdSqZXVVUoqNGzeyefNmZsyYQVxcHF9//TVgDpnUrFkTgP37\n",
604 604 "9/Pdd9/xwgsvWFmqSFBU7Z7344/Dv/8NNWuaj7w3aGB1RXIGH3zwAQDdunU77fOdO3fGZrPx3nvv\n",
605 605 "MXfuXN5//33i4+OtKFEkqKpuz3vRIpg61Xzw5r33oGVLqyuSs1ixYgWtWrWizq8WA7PZbDz22GMA\n",
606 606 "DBgwwIrSRCxRNXveGzeac7jBnMfdo4e19chZ7d+/n6NHj542ti1S1VW98D52zFwZsPghnL/8xeqK\n",
607 607 "pAxr1qwB0BOUIr9QtcLb6TQfvsnIgI4dzX0n9RBOyCsO7yuuuMLiSkRCR9UJb8OAu++GtWvN3W8W\n",
608 608 "L9Zc7jCxbt06YmNjaan7EiIlqk54z5hhLularRr85z/mxsES8vbt28fJkye5+OKLsdvtVpcjEjKq\n",
609 609 "Rnh//TWMH28ev/kmaOw0bKxbtw6A1q1bW1yJSGiJ/PDOyoJbbwWvFx580NxcQcLGN998A8All1xi\n",
610 610 "cSUioSWyw9sw4K674NAhc7f3qVOtrkjKacOGDUBohLfX663wuR6Px4+ViER6eM+dC//6l7lZ8Lvv\n",
611 611 "QkyM1RVJOWRmZnLw4EFsNhutWrWytJalS5eWPOVZETNnziQ1NdWPFUlVF7nhvX37z3O4X3kFkpOt\n",
612 612 "rUfK7dtvvwWgbt261K5dO+DtHThwgKFDhzJ16lQefvhhDMMAYO3ataxbt46BAwdW+Npjxoxh5syZ\n",
613 613 "7Nmz55zeP3z4cHr06EFKSkqF25TIFpnhXVgIAwdCURHccYc55i1hpzi8L7744oC35XK5uO222+jV\n",
614 614 "qxcnT55k4cKF5OXlkZeXx9SpU5k4cWKlrh8dHc20adMYM2bMOQ2hzJ07l/bt23PkyJFKtSuRKzLD\n",
615 615 "+/77zZ53q1Ywa5bV1UgFFW8oHIzx7lWrVnHo0CE6dOjAsGHDWLBgATVq1GDmzJn069ePuLi4Srdx\n",
616 616 "4YUX0qpVKxYtWlTme+12u2bYyFlF3sJUixfDnDnm+PbChXDeeVZXJBXg9XrZvHkzAJdeemnA21u7\n",
617 617 "di116tQhKSmJpKQkAAoKCnjnnXdKnvD0h+HDhzN69GgGDRrkt2tK1RRZPe9Dh+DOO83jZ5/VfO4w\n",
618 618 "tnfvXgoLC7HZbEEJ77S0NNq0aXPa51auXEliYiIJCQl+a+eyyy4jKyuLrVu3+u2aUjVFTs+7eGOF\n",
619 619 "7Gxz9/cxY6yuSCph06ZNgDlWHMjH4seOHcvJkydJTU2lRYsWDBo0iKSkJKZNm8bq1au55pprznju\n",
620 620 "li1b+OCDD7Db7aSnp/Pcc88xf/58cnNzOXbsGOPHj6dJkyannRMVFUVKSgqrVq3i8ssvL/n8rl27\n",
621 621 "mDlzJgkJCcTFxREbG3vWm7QVaVsiS+SE9+zZsHq1+dj7669rwakwVxzeF110EQ6HI2DtvPjiiyVj\n",
622 622 "3Q8//DA33HBDyde2b9/O4MGDSz3v+++/59133+Xpp58GzH8EevfuzYwZM/D5fPTr14/LL7+ckSNH\n",
623 623 "/ubc5ORkduzYUfLr1NRUhgwZwhtvvEH79u0ByM/PZ+DAgdhK+T6uTNsSOSJj2OT77+Hhh83jl1+G\n",
624 624 "unWtrUcqbcuWLQCn9U4DZdu2bYA5pPFL6enp1KhRo9Rz5syZw6RJk0p+XVBQQK1atWjbti2NGzdm\n",
625 625 "1KhRZ9wcIiEhgfT0dAB8Ph9jx46lU6dOJcENUL16dfr06VMyXdFfbUvkCP/wNgwYOdLcSPimm8yX\n",
626 626 "hDWv18vOnTuB4CwDu23bNmrUqEFiYuJpn8/LyztjeN9zzz2nbbe2YcMGfve73wHQqFEjJk+efMax\n",
627 627 "8lq1apGbmwuY0yEPHjxYrvnclWlbIkf4h/ebb8KKFebGwS+9ZHU14gd79+7F6XRis9m48sorA97e\n",
628 628 "9u3bS52WZ7PZSu35AqcF/d69ezl27BgdO3Y8p/Z8Pl/JdYvncZcnbCvTtkSO8A7vo0dh3DjzeMYM\n",
629 629 "bSAcIbZv3w6Aw+EIylznHTt2lNpOjRo1yMrKKvP8NWvWEBMTc9rNze+///6M78/Ozi7Z8b5hw4YA\n",
630 630 "FBYWlrfsCrUtkSN8w9sw4M9/NmeX3HADnOHGkoSf4vC++OKLiQnwejRZWVkcOXKk1OmISUlJpYZ3\n",
631 631 "YWEhU6ZM4bvvvgNg9erVXHrppSUP8vh8PmbPnn3GNrOzs0vmkl9zzTU0btyYtLS037yvtCcxK9u2\n",
632 632 "RI7wDe8PPoAlS8xFp155RbNLIkhxMAVjz8rim5WlhXdKSkqpa5F89tlnzJkzh127drFnzx4OHjx4\n",
633 633 "2j8yM2bMOOsNw927d5eM5dvtdp5//nlWrlx52gyU48ePlzyJeejQIb+1LZEjPKcKZmbCvfeax88+\n",
634 634 "a25rJhEjmOG9detWatasWeqwSbdu3Xj88cd/8/kOHTowYMAAtmzZwrZt2/joo4+YOHEiEyZMwOFw\n",
635 635 "0LNnT66++upS2/N4PHz77benzRbp3Lkzb7/9Ni+88AIXXngh8fHxxMTEcPPNN/OPf/yDIUOGMHLk\n",
636 636 "SAYNGlSptiWy2Iwz3ZEp74XOcnPH74YMgQULoEsX+OwziAqd/0CsWLECr9f7m6f15Nzk5ORw6aWX\n",
637 637 "YrPZWLVqFS1atAhoe6NHj8br9fLqq6/+5mtOp5Orr76aTz/9lAZ+up+SmprKQw89xOeff+6X60nF\n",
638 638 "ZGZmsnr1au655x6rS6mw0Em9c7V0qRnc1arBvHkhFdxSebt27QLM2ReBCu6XXnqJW265BYDNmzfT\n",
639 639 "q1evUt8XGxvLsGHDmDdvnt/anjt3LqNGjfLb9aTqCq/kKyw0b1ICTJkCAe6VSfDt3r0bgHbt2gWs\n",
640 640 "jcWLFxMTE8OOHTtwOBz07t37jO+95557+Pzzz8nOzq50u3v37uXw4cOVWhdcpFh4hff06XDwIFx+\n",
641 641 "+c8bLUhEKe55//JpQ3+7++67adCgATNnzmTevHln3ZU+Pj6e6dOn8+CDD1ZqWLCoqIhJkybx8ssv\n",
642 642 "l/rIu0h5hc8Ny/R0+GktB2bOhOjwKV3OXfGMi0D2vAcMGFCuGRlt2rRh8ODBvPbaa4wYMaJCbc6c\n",
643 643 "OZNHHnmEpk2bVuh8kV8LnwQcP94cNhkwALp2tboaCZCdO3cSHx8flDVNyqNLly506dKlwuc/9NBD\n",
644 644 "fqxGJFyGTVatgvfeM29S/v3vVlcjAZKRkUFOTg5XXXXVWYcyRCQcwtvj+Xlt7kcegZ+eTJPIU7yS\n",
645 645 "YKdOnSyuRCT0hX54v/IKbN0KzZrBgw9aXY0EUPEj4p07d7a4EpHQF9rh/cMPMHmyefz88+CHTWAl\n",
646 646 "dG3cuJHzzz8/KE9WioS70A7vSZMgKwu6d4c+fayuRgKosLCQtLQ0rrvuOqL04JVImUL3pyQtDV59\n",
647 647 "1ZwSOGOGFp6KcGvWrMHpdNKzZ0+rSxEJC6EZ3oYB991nfhwzBi65xOqKxM8mT57M9ddfX7Ls6ZIl\n",
648 648 "S0hISDjjo+oicrrQDO9334U1a6BePXjsMaurkQD48ssvKSwsxOv1cvjwYZYuXcpdd91Vsi61iJxd\n",
649 649 "6D2k43LBo4+ax08/DT/tOCKRJSUlhQsuuIDs7GzGjRtHcnIyfy5et0ZEyhR6Pe+5c+HAAXOo5Pbb\n",
650 650 "ra5GAuSRRx4hLS2Njh07EhcXx9tvv43D4Sj1vR6Ph2effZa33nqL1157jaFDh2qrL6nyQqvnfeqU\n",
651 651 "uVogwFNPaf2SCFa7dm0WLlx4Tu+dMGECl1xyCUOHDuXHH39k+vTpNGnSJMAVioS20Op5z5gBx49D\n",
652 652 "u3bQt6/V1UgI2LFjBx9++CFDhgwBzLVPArnioEi4CJ3wzsw0tzQDeOYZTQ0UwLyxee211xIbGwvA\n",
653 653 "V199RaeMRggBAAADwUlEQVROncjJybG4MhFrhU54P/MM5OZCjx7QrZvV1UiISEhI4IILLgAgPz+f\n",
654 654 "pUuXkpKSwuLFiy2uTMRaoTGonJEBs2aZx8VrdosAffv2Zf369fz73//G6XTSr18/Pvvss5BbMlYk\n",
655 655 "2EIjvP/6V3A6zbW627a1uhoJIbGxsUyfPt3qMkRCjvXDJt99B//8J9jtP880ERGRs7I+vCdPBp8P\n",
656 656 "7rwTWra0uhoRkbBgbXinpsIHH5hLveoxeBGRc2ZteE+caH4cMwYaN7a0FBGRcGJdeH/+Oaxcaa5d\n",
657 657 "MmGCZWWIiIQj68K7+Obk+PFQu7ZlZYiIhCNrwvvrr82ed40acO+9lpQgIhLOrAnvp54yP953HyQk\n",
658 658 "WFKCiEg4C354b9wIS5dCfDyMHRv05oNhy5YtVpcgImXYvXu31SVUSvDDu/jx97vvhrp1g958MCi8\n",
659 659 "RULfnj17rC6hUoIb3tu3w7/+BbGx8MADQW1aRCSSBHdtk2nTzI/Dh0OjRkFtOpiKioq004tICMvL\n",
660 660 "y7O6hMoz/KRLly4GoJdeeumlVzlejz/+eIUy12YYhoGIiIQV6xemEhGRclN4i4iEIYW3iEgYUniL\n",
661 661 "iIQhhbeIVClFRUXcfPPNzJ8/3+pSKiU09rCMEAsXLsTtdpORkUG9evUYMWKE1SWJyK/ExcVx4YUX\n",
662 662 "kpKSYnUplaKet5/s2rWL5cuXM3ToUOx2O5dddpnVJYnIGezcuZNWrVpZXUalKLz9ZMGCBfzpT38C\n",
663 663 "YPPmzVx11VUWVyQipXG73Rw6dIhPPvmEhx9+GJ/PZ3VJFaLw9pPs7GxatWqFy+UiLy+Pb7/91uqS\n",
664 664 "RKQUW7ZsoW/fvvTu3Ruv18vWrVutLqlCNObtJ0OHDmXFihXs2LGD5s2bc/ToUatLEpFSpKWl0aVL\n",
665 665 "FwB27NhB7TDdyUvh7ScpKSklN0D69+9vcTUicibZ2dlcd911ZGVlYbfbSUxMtLqkCtHaJiJSpezb\n",
666 666 "t4+PP/6Y7OxsRo0aRYMGDawuqUIU3iIiYUg3LEVEwpDCW0QkDOmGpYiIxbxeL4sWLWL//v0kJiay\n",
667 667 "fv16HnjgAZKTk894jnreIiIW27x5MzfddBPJycn4fD769+9Pw4YNz3qOwltExGJXX301sbGxrF27\n",
668 668 "lq5du9K1a1eqVat21nMU3iIiFktNTeWHH35g27ZtNGvWjC+//LLMczTmLSJisWXLllG/fn06derE\n",
669 669 "kiVLqFu3bpnnaJ63iEgY0rCJiEgYUniLiIQhhbeISBhSeIuIhCGFt4hIGFJ4i4iEIYW3iEgYUniL\n",
670 670 "iISh/weZPyRnS1m/IAAAAABJRU5ErkJggg==\n"
671 671 ],
672 672 "text/plain": [
673 673 "<matplotlib.figure.Figure at 0x10848fb10>"
674 674 ]
675 675 },
676 676 "metadata": {},
677 677 "output_type": "display_data"
678 678 }
679 679 ],
680 680 "source": [
681 681 "\"\"\"\n",
682 682 "Plot demonstrating the integral as the area under a curve.\n",
683 683 "\n",
684 684 "Although this is a simple example, it demonstrates some important tweaks:\n",
685 685 "\n",
686 686 " * A simple line plot with custom color and line width.\n",
687 687 " * A shaded region created using a Polygon patch.\n",
688 688 " * A text label with mathtext rendering.\n",
689 689 " * figtext calls to label the x- and y-axes.\n",
690 690 " * Use of axis spines to hide the top and right spines.\n",
691 691 " * Custom tick placement and labels.\n",
692 692 "\"\"\"\n",
693 693 "import numpy as np\n",
694 694 "import matplotlib.pyplot as plt\n",
695 695 "from matplotlib.patches import Polygon\n",
696 696 "\n",
697 697 "\n",
698 698 "def func(x):\n",
699 699 " return (x - 3) * (x - 5) * (x - 7) + 85\n",
700 700 "\n",
701 701 "\n",
702 702 "a, b = 2, 9 # integral limits\n",
703 703 "x = np.linspace(0, 10)\n",
704 704 "y = func(x)\n",
705 705 "\n",
706 706 "fig, ax = plt.subplots()\n",
707 707 "plt.plot(x, y, 'r', linewidth=2)\n",
708 708 "plt.ylim(ymin=0)\n",
709 709 "\n",
710 710 "# Make the shaded region\n",
711 711 "ix = np.linspace(a, b)\n",
712 712 "iy = func(ix)\n",
713 713 "verts = [(a, 0)] + list(zip(ix, iy)) + [(b, 0)]\n",
714 714 "poly = Polygon(verts, facecolor='0.9', edgecolor='0.5')\n",
715 715 "ax.add_patch(poly)\n",
716 716 "\n",
717 717 "plt.text(0.5 * (a + b), 30, r\"$\\int_a^b f(x)\\mathrm{d}x$\",\n",
718 718 " horizontalalignment='center', fontsize=20)\n",
719 719 "\n",
720 720 "plt.figtext(0.9, 0.05, '$x$')\n",
721 721 "plt.figtext(0.1, 0.9, '$y$')\n",
722 722 "\n",
723 723 "ax.spines['right'].set_visible(False)\n",
724 724 "ax.spines['top'].set_visible(False)\n",
725 725 "ax.xaxis.set_ticks_position('bottom')\n",
726 726 "\n",
727 727 "ax.set_xticks((a, b))\n",
728 728 "ax.set_xticklabels(('$a$', '$b$'))\n",
729 729 "ax.set_yticks([])\n",
730 730 "\n",
731 731 "plt.show()\n"
732 732 ]
733 733 }
734 734 ],
735 "metadata": {
736 "signature": "sha256:74dbf5caa25c937be70dfe2ab509783a01f4a2044850d7044e729300a8c3644d"
737 },
735 "metadata": {},
738 736 "nbformat": 4,
739 737 "nbformat_minor": 0
740 738 } No newline at end of file
@@ -1,158 +1,156
1 1 {
2 2 "cells": [
3 3 {
4 4 "cell_type": "markdown",
5 5 "metadata": {},
6 6 "source": [
7 7 "# Using `raw_input` and `%debug` in the Notebook"
8 8 ]
9 9 },
10 10 {
11 11 "cell_type": "markdown",
12 12 "metadata": {},
13 13 "source": [
14 14 "The Notebook has added support for `raw_input` and `%debug`, as of 1.0."
15 15 ]
16 16 },
17 17 {
18 18 "cell_type": "code",
19 19 "execution_count": 1,
20 20 "metadata": {
21 21 "collapsed": false
22 22 },
23 23 "outputs": [],
24 24 "source": [
25 25 "# Python 3 compat\n",
26 26 "import sys\n",
27 27 "if sys.version_info[0] >= 3:\n",
28 28 " raw_input = input"
29 29 ]
30 30 },
31 31 {
32 32 "cell_type": "code",
33 33 "execution_count": 2,
34 34 "metadata": {
35 35 "collapsed": false
36 36 },
37 37 "outputs": [
38 38 {
39 39 "name": "stdout",
40 40 "output_type": "stream",
41 41 "text": [
42 42 "What is your name? Sir Robin\n"
43 43 ]
44 44 },
45 45 {
46 46 "data": {
47 47 "text/plain": [
48 48 "'Sir Robin'"
49 49 ]
50 50 },
51 51 "execution_count": 2,
52 52 "metadata": {},
53 53 "output_type": "execute_result"
54 54 }
55 55 ],
56 56 "source": [
57 57 "name = raw_input(\"What is your name? \")\n",
58 58 "name"
59 59 ]
60 60 },
61 61 {
62 62 "cell_type": "markdown",
63 63 "metadata": {},
64 64 "source": [
65 65 "**Python 2-only**: the eval input works as well (`input` is just `eval(raw_input(prompt))`)"
66 66 ]
67 67 },
68 68 {
69 69 "cell_type": "code",
70 70 "execution_count": 3,
71 71 "metadata": {
72 72 "collapsed": false
73 73 },
74 74 "outputs": [
75 75 {
76 76 "name": "stdout",
77 77 "output_type": "stream",
78 78 "text": [
79 79 "How many fingers? 4\n"
80 80 ]
81 81 },
82 82 {
83 83 "data": {
84 84 "text/plain": [
85 85 "(4, int)"
86 86 ]
87 87 },
88 88 "execution_count": 3,
89 89 "metadata": {},
90 90 "output_type": "execute_result"
91 91 }
92 92 ],
93 93 "source": [
94 94 "fingers = input(\"How many fingers? \")\n",
95 95 "fingers, type(fingers)"
96 96 ]
97 97 },
98 98 {
99 99 "cell_type": "code",
100 100 "execution_count": 4,
101 101 "metadata": {
102 102 "collapsed": false
103 103 },
104 104 "outputs": [
105 105 {
106 106 "ename": "ZeroDivisionError",
107 107 "evalue": "integer division or modulo by zero",
108 108 "output_type": "error",
109 109 "traceback": [
110 110 "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mZeroDivisionError\u001b[0m Traceback (most recent call last)",
111 111 "\u001b[1;32m<ipython-input-4-a5097cc0c0c5>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mx\u001b[0m\u001b[1;33m/\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m \u001b[0mdiv\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1\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",
112 112 "\u001b[1;32m<ipython-input-4-a5097cc0c0c5>\u001b[0m in \u001b[0;36mdiv\u001b[1;34m(x, y)\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mdiv\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\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----> 2\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mx\u001b[0m\u001b[1;33m/\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 3\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[0mdiv\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1\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",
113 113 "\u001b[1;31mZeroDivisionError\u001b[0m: integer division or modulo by zero"
114 114 ]
115 115 }
116 116 ],
117 117 "source": [
118 118 "def div(x, y):\n",
119 119 " return x/y\n",
120 120 "\n",
121 121 "div(1,0)"
122 122 ]
123 123 },
124 124 {
125 125 "cell_type": "code",
126 126 "execution_count": 5,
127 127 "metadata": {
128 128 "collapsed": false
129 129 },
130 130 "outputs": [
131 131 {
132 132 "name": "stdout",
133 133 "output_type": "stream",
134 134 "text": [
135 135 "> \u001b[1;32m<ipython-input-4-a5097cc0c0c5>\u001b[0m(2)\u001b[0;36mdiv\u001b[1;34m()\u001b[0m\n",
136 136 "\u001b[1;32m 1 \u001b[1;33m\u001b[1;32mdef\u001b[0m \u001b[0mdiv\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\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",
137 137 "\u001b[0m\u001b[1;32m----> 2 \u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mx\u001b[0m\u001b[1;33m/\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
138 138 "\u001b[0m\u001b[1;32m 3 \u001b[1;33m\u001b[1;33m\u001b[0m\u001b[0m\n",
139 139 "\u001b[0m\n",
140 140 "ipdb> x\n",
141 141 "1\n",
142 142 "ipdb> y\n",
143 143 "0\n",
144 144 "ipdb> exit\n"
145 145 ]
146 146 }
147 147 ],
148 148 "source": [
149 149 "%debug"
150 150 ]
151 151 }
152 152 ],
153 "metadata": {
154 "signature": "sha256:ac5c21534f3dd013c78d4d201527f3ed4dea5b6fad4116b8d23c67ba107e48c3"
155 },
153 "metadata": {},
156 154 "nbformat": 4,
157 155 "nbformat_minor": 0
158 156 } No newline at end of file
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: 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: 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: 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: modified file
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