Show More
This diff has been collapsed as it changes many lines, (605 lines changed) Show them Hide them | |||||
@@ -0,0 +1,605 b'' | |||||
|
1 | # -*- coding: utf-8 -*- | |||
|
2 | """Sphinx directive to support embedded IPython code. | |||
|
3 | ||||
|
4 | This directive allows pasting of entire interactive IPython sessions, prompts | |||
|
5 | and all, and their code will actually get re-executed at doc build time, with | |||
|
6 | all prompts renumbered sequentially. | |||
|
7 | ||||
|
8 | To enable this directive, simply list it in your Sphinx ``conf.py`` file | |||
|
9 | (making sure the directory where you placed it is visible to sphinx, as is | |||
|
10 | needed for all Sphinx directives). | |||
|
11 | ||||
|
12 | By default this directive assumes that your prompts are unchanged IPython ones, | |||
|
13 | but this can be customized. For example, the following code in your Sphinx | |||
|
14 | config file will configure this directive for the following input/output | |||
|
15 | prompts ``Yade [1]:`` and ``-> [1]:``:: | |||
|
16 | ||||
|
17 | import ipython_directive as id | |||
|
18 | id.rgxin =re.compile(r'(?:In |Yade )\[(\d+)\]:\s?(.*)\s*') | |||
|
19 | id.rgxout=re.compile(r'(?:Out| -> )\[(\d+)\]:\s?(.*)\s*') | |||
|
20 | id.fmtin ='Yade [%d]:' | |||
|
21 | id.fmtout=' -> [%d]:' | |||
|
22 | ||||
|
23 | id.rc_override=dict( | |||
|
24 | prompt_in1="Yade [\#]:", | |||
|
25 | prompt_in2=" .\D..", | |||
|
26 | prompt_out=" -> [\#]:" | |||
|
27 | ) | |||
|
28 | ||||
|
29 | import ipython_console_highlighting as ich | |||
|
30 | ich.IPythonConsoleLexer.input_prompt= | |||
|
31 | re.compile("(Yade \[[0-9]+\]: )|( \.\.\.+:)") | |||
|
32 | ich.IPythonConsoleLexer.output_prompt= | |||
|
33 | re.compile("(( -> )|(Out)\[[0-9]+\]: )|( \.\.\.+:)") | |||
|
34 | ich.IPythonConsoleLexer.continue_prompt=re.compile(" \.\.\.+:") | |||
|
35 | ||||
|
36 | ||||
|
37 | ToDo | |||
|
38 | ---- | |||
|
39 | ||||
|
40 | - Turn the ad-hoc test() function into a real test suite. | |||
|
41 | - Break up ipython-specific functionality from matplotlib stuff into better | |||
|
42 | separated code. | |||
|
43 | - Make sure %bookmarks used internally are removed on exit. | |||
|
44 | ||||
|
45 | ||||
|
46 | Authors | |||
|
47 | ------- | |||
|
48 | ||||
|
49 | - John D Hunter: orignal author. | |||
|
50 | - Fernando Perez: refactoring, documentation, cleanups. | |||
|
51 | - VΓ‘clavΕ milauer <eudoxos-AT-arcig.cz>: Prompt generatlizations. | |||
|
52 | """ | |||
|
53 | ||||
|
54 | #----------------------------------------------------------------------------- | |||
|
55 | # Imports | |||
|
56 | #----------------------------------------------------------------------------- | |||
|
57 | ||||
|
58 | # Stdlib | |||
|
59 | import cStringIO | |||
|
60 | import imp | |||
|
61 | import os | |||
|
62 | import re | |||
|
63 | import shutil | |||
|
64 | import sys | |||
|
65 | import warnings | |||
|
66 | ||||
|
67 | # To keep compatibility with various python versions | |||
|
68 | try: | |||
|
69 | from hashlib import md5 | |||
|
70 | except ImportError: | |||
|
71 | from md5 import md5 | |||
|
72 | ||||
|
73 | # Third-party | |||
|
74 | import matplotlib | |||
|
75 | import sphinx | |||
|
76 | from docutils.parsers.rst import directives | |||
|
77 | ||||
|
78 | matplotlib.use('Agg') | |||
|
79 | ||||
|
80 | # Our own | |||
|
81 | import IPython | |||
|
82 | from IPython.Shell import MatplotlibShell | |||
|
83 | ||||
|
84 | #----------------------------------------------------------------------------- | |||
|
85 | # Globals | |||
|
86 | #----------------------------------------------------------------------------- | |||
|
87 | ||||
|
88 | sphinx_version = sphinx.__version__.split(".") | |||
|
89 | # The split is necessary for sphinx beta versions where the string is | |||
|
90 | # '6b1' | |||
|
91 | sphinx_version = tuple([int(re.split('[a-z]', x)[0]) | |||
|
92 | for x in sphinx_version[:2]]) | |||
|
93 | ||||
|
94 | COMMENT, INPUT, OUTPUT = range(3) | |||
|
95 | rc_override = {} | |||
|
96 | rgxin = re.compile('In \[(\d+)\]:\s?(.*)\s*') | |||
|
97 | rgxout = re.compile('Out\[(\d+)\]:\s?(.*)\s*') | |||
|
98 | fmtin = 'In [%d]:' | |||
|
99 | fmtout = 'Out[%d]:' | |||
|
100 | ||||
|
101 | #----------------------------------------------------------------------------- | |||
|
102 | # Functions and class declarations | |||
|
103 | #----------------------------------------------------------------------------- | |||
|
104 | def block_parser(part): | |||
|
105 | """ | |||
|
106 | part is a string of ipython text, comprised of at most one | |||
|
107 | input, one ouput, comments, and blank lines. The block parser | |||
|
108 | parses the text into a list of:: | |||
|
109 | ||||
|
110 | blocks = [ (TOKEN0, data0), (TOKEN1, data1), ...] | |||
|
111 | ||||
|
112 | where TOKEN is one of [COMMENT | INPUT | OUTPUT ] and | |||
|
113 | data is, depending on the type of token:: | |||
|
114 | ||||
|
115 | COMMENT : the comment string | |||
|
116 | ||||
|
117 | INPUT: the (DECORATOR, INPUT_LINE, REST) where | |||
|
118 | DECORATOR: the input decorator (or None) | |||
|
119 | INPUT_LINE: the input as string (possibly multi-line) | |||
|
120 | REST : any stdout generated by the input line (not OUTPUT) | |||
|
121 | ||||
|
122 | ||||
|
123 | OUTPUT: the output string, possibly multi-line | |||
|
124 | """ | |||
|
125 | ||||
|
126 | block = [] | |||
|
127 | lines = part.split('\n') | |||
|
128 | N = len(lines) | |||
|
129 | i = 0 | |||
|
130 | decorator = None | |||
|
131 | while 1: | |||
|
132 | ||||
|
133 | if i==N: | |||
|
134 | # nothing left to parse -- the last line | |||
|
135 | break | |||
|
136 | ||||
|
137 | line = lines[i] | |||
|
138 | i += 1 | |||
|
139 | line_stripped = line.strip() | |||
|
140 | if line_stripped.startswith('#'): | |||
|
141 | block.append((COMMENT, line)) | |||
|
142 | continue | |||
|
143 | ||||
|
144 | if line_stripped.startswith('@'): | |||
|
145 | # we're assuming at most one decorator -- may need to | |||
|
146 | # rethink | |||
|
147 | decorator = line_stripped | |||
|
148 | continue | |||
|
149 | ||||
|
150 | # does this look like an input line? | |||
|
151 | matchin = rgxin.match(line) | |||
|
152 | if matchin: | |||
|
153 | lineno, inputline = int(matchin.group(1)), matchin.group(2) | |||
|
154 | ||||
|
155 | # the ....: continuation string | |||
|
156 | continuation = ' %s:'%''.join(['.']*(len(str(lineno))+2)) | |||
|
157 | Nc = len(continuation) | |||
|
158 | # input lines can continue on for more than one line, if | |||
|
159 | # we have a '\' line continuation char or a function call | |||
|
160 | # echo line 'print'. The input line can only be | |||
|
161 | # terminated by the end of the block or an output line, so | |||
|
162 | # we parse out the rest of the input line if it is | |||
|
163 | # multiline as well as any echo text | |||
|
164 | ||||
|
165 | rest = [] | |||
|
166 | while i<N: | |||
|
167 | ||||
|
168 | # look ahead; if the next line is blank, or a comment, or | |||
|
169 | # an output line, we're done | |||
|
170 | ||||
|
171 | nextline = lines[i] | |||
|
172 | matchout = rgxout.match(nextline) | |||
|
173 | #print "nextline=%s, continuation=%s, starts=%s"%(nextline, continuation, nextline.startswith(continuation)) | |||
|
174 | if matchout or nextline.startswith('#'): | |||
|
175 | break | |||
|
176 | elif nextline.startswith(continuation): | |||
|
177 | inputline += '\n' + nextline[Nc:] | |||
|
178 | else: | |||
|
179 | rest.append(nextline) | |||
|
180 | i+= 1 | |||
|
181 | ||||
|
182 | block.append((INPUT, (decorator, inputline, '\n'.join(rest)))) | |||
|
183 | continue | |||
|
184 | ||||
|
185 | # if it looks like an output line grab all the text to the end | |||
|
186 | # of the block | |||
|
187 | matchout = rgxout.match(line) | |||
|
188 | if matchout: | |||
|
189 | lineno, output = int(matchout.group(1)), matchout.group(2) | |||
|
190 | if i<N-1: | |||
|
191 | output = '\n'.join([output] + lines[i:]) | |||
|
192 | ||||
|
193 | block.append((OUTPUT, output)) | |||
|
194 | break | |||
|
195 | ||||
|
196 | return block | |||
|
197 | ||||
|
198 | ||||
|
199 | class EmbeddedSphinxShell(object): | |||
|
200 | """An embedded IPython instance to run inside Sphinx""" | |||
|
201 | ||||
|
202 | def __init__(self): | |||
|
203 | ||||
|
204 | self.cout = cStringIO.StringIO() | |||
|
205 | ||||
|
206 | IPython.Shell.Term.cout = self.cout | |||
|
207 | IPython.Shell.Term.cerr = self.cout | |||
|
208 | argv = ['-autocall', '0'] | |||
|
209 | self.user_ns = {} | |||
|
210 | self.user_glocal_ns = {} | |||
|
211 | ||||
|
212 | self.IP = IPython.ipmaker.make_IPython( | |||
|
213 | argv, self.user_ns, self.user_glocal_ns, embedded=True, | |||
|
214 | #shell_class=IPython.Shell.InteractiveShell, | |||
|
215 | shell_class=MatplotlibShell, | |||
|
216 | rc_override = dict(colors = 'NoColor'), **rc_override) | |||
|
217 | ||||
|
218 | self.input = '' | |||
|
219 | self.output = '' | |||
|
220 | ||||
|
221 | self.is_verbatim = False | |||
|
222 | self.is_doctest = False | |||
|
223 | self.is_suppress = False | |||
|
224 | ||||
|
225 | # on the first call to the savefig decorator, we'll import | |||
|
226 | # pyplot as plt so we can make a call to the plt.gcf().savefig | |||
|
227 | self._pyplot_imported = False | |||
|
228 | ||||
|
229 | # we need bookmark the current dir first so we can save | |||
|
230 | # relative to it | |||
|
231 | self.process_input_line('bookmark ipy_basedir') | |||
|
232 | self.cout.seek(0) | |||
|
233 | self.cout.truncate(0) | |||
|
234 | ||||
|
235 | def process_input_line(self, line): | |||
|
236 | """process the input, capturing stdout""" | |||
|
237 | #print "input='%s'"%self.input | |||
|
238 | stdout = sys.stdout | |||
|
239 | sys.stdout = self.cout | |||
|
240 | #self.IP.resetbuffer() | |||
|
241 | self.IP.push(self.IP.prefilter(line, 0)) | |||
|
242 | #self.IP.runlines(line) | |||
|
243 | sys.stdout = stdout | |||
|
244 | ||||
|
245 | # Callbacks for each type of token | |||
|
246 | def process_input(self, data, input_prompt, lineno): | |||
|
247 | """Process data block for INPUT token.""" | |||
|
248 | decorator, input, rest = data | |||
|
249 | image_file = None | |||
|
250 | #print 'INPUT:', data | |||
|
251 | is_verbatim = decorator=='@verbatim' or self.is_verbatim | |||
|
252 | is_doctest = decorator=='@doctest' or self.is_doctest | |||
|
253 | is_suppress = decorator=='@suppress' or self.is_suppress | |||
|
254 | is_savefig = decorator is not None and \ | |||
|
255 | decorator.startswith('@savefig') | |||
|
256 | ||||
|
257 | input_lines = input.split('\n') | |||
|
258 | ||||
|
259 | continuation = ' %s:'%''.join(['.']*(len(str(lineno))+2)) | |||
|
260 | Nc = len(continuation) | |||
|
261 | ||||
|
262 | if is_savefig: | |||
|
263 | saveargs = decorator.split(' ') | |||
|
264 | filename = saveargs[1] | |||
|
265 | outfile = os.path.join('_static/%s'%filename) | |||
|
266 | # build out an image directive like | |||
|
267 | # .. image:: somefile.png | |||
|
268 | # :width 4in | |||
|
269 | # | |||
|
270 | # from an input like | |||
|
271 | # savefig somefile.png width=4in | |||
|
272 | imagerows = ['.. image:: %s'%outfile] | |||
|
273 | ||||
|
274 | for kwarg in saveargs[2:]: | |||
|
275 | arg, val = kwarg.split('=') | |||
|
276 | arg = arg.strip() | |||
|
277 | val = val.strip() | |||
|
278 | imagerows.append(' :%s: %s'%(arg, val)) | |||
|
279 | ||||
|
280 | image_file = outfile | |||
|
281 | image_directive = '\n'.join(imagerows) | |||
|
282 | ||||
|
283 | # TODO: can we get "rest" from ipython | |||
|
284 | #self.process_input_line('\n'.join(input_lines)) | |||
|
285 | ||||
|
286 | ret = [] | |||
|
287 | is_semicolon = False | |||
|
288 | ||||
|
289 | for i, line in enumerate(input_lines): | |||
|
290 | if line.endswith(';'): | |||
|
291 | is_semicolon = True | |||
|
292 | ||||
|
293 | if i==0: | |||
|
294 | # process the first input line | |||
|
295 | if is_verbatim: | |||
|
296 | self.process_input_line('') | |||
|
297 | else: | |||
|
298 | # only submit the line in non-verbatim mode | |||
|
299 | self.process_input_line(line) | |||
|
300 | formatted_line = '%s %s'%(input_prompt, line) | |||
|
301 | else: | |||
|
302 | # process a continuation line | |||
|
303 | if not is_verbatim: | |||
|
304 | self.process_input_line(line) | |||
|
305 | ||||
|
306 | formatted_line = '%s %s'%(continuation, line) | |||
|
307 | ||||
|
308 | if not is_suppress: | |||
|
309 | ret.append(formatted_line) | |||
|
310 | ||||
|
311 | if not is_suppress: | |||
|
312 | if len(rest.strip()): | |||
|
313 | if is_verbatim: | |||
|
314 | # the "rest" is the standard output of the | |||
|
315 | # input, which needs to be added in | |||
|
316 | # verbatim mode | |||
|
317 | ret.append(rest) | |||
|
318 | ||||
|
319 | self.cout.seek(0) | |||
|
320 | output = self.cout.read() | |||
|
321 | if not is_suppress and not is_semicolon: | |||
|
322 | ret.append(output) | |||
|
323 | ||||
|
324 | self.cout.truncate(0) | |||
|
325 | return ret, input_lines, output, is_doctest, image_file | |||
|
326 | #print 'OUTPUT', output # dbg | |||
|
327 | ||||
|
328 | def process_output(self, data, output_prompt, | |||
|
329 | input_lines, output, is_doctest, image_file): | |||
|
330 | """Process data block for OUTPUT token.""" | |||
|
331 | if is_doctest: | |||
|
332 | submitted = data.strip() | |||
|
333 | found = output | |||
|
334 | if found is not None: | |||
|
335 | ind = found.find(output_prompt) | |||
|
336 | if ind<0: | |||
|
337 | raise RuntimeError('output prompt="%s" does not match out line=%s'%(output_prompt, found)) | |||
|
338 | found = found[len(output_prompt):].strip() | |||
|
339 | ||||
|
340 | if found!=submitted: | |||
|
341 | raise RuntimeError('doctest failure for input_lines="%s" with found_output="%s" and submitted output="%s"'%(input_lines, found, submitted)) | |||
|
342 | #print 'doctest PASSED for input_lines="%s" with found_output="%s" and submitted output="%s"'%(input_lines, found, submitted) | |||
|
343 | ||||
|
344 | def process_comment(self, data): | |||
|
345 | """Process data block for COMMENT token.""" | |||
|
346 | if not self.is_suppress: | |||
|
347 | return [data] | |||
|
348 | ||||
|
349 | def process_block(self, block): | |||
|
350 | """ | |||
|
351 | process block from the block_parser and return a list of processed lines | |||
|
352 | """ | |||
|
353 | ||||
|
354 | ret = [] | |||
|
355 | output = None | |||
|
356 | input_lines = None | |||
|
357 | ||||
|
358 | m = rgxin.match(str(self.IP.outputcache.prompt1).strip()) | |||
|
359 | lineno = int(m.group(1)) | |||
|
360 | ||||
|
361 | input_prompt = fmtin%lineno | |||
|
362 | output_prompt = fmtout%lineno | |||
|
363 | image_file = None | |||
|
364 | image_directive = None | |||
|
365 | # XXX - This needs a second refactor. There's too much state being | |||
|
366 | # held globally, which makes for a very awkward interface and large, | |||
|
367 | # hard to test functions. I've already broken this up at least into | |||
|
368 | # three separate processors to isolate the logic better, but this only | |||
|
369 | # serves to highlight the coupling. Next we need to clean it up... | |||
|
370 | for token, data in block: | |||
|
371 | if token==COMMENT: | |||
|
372 | out_data = self.process_comment(data) | |||
|
373 | elif token==INPUT: | |||
|
374 | out_data, input_lines, output, is_doctest, image_file= \ | |||
|
375 | self.process_input(data, input_prompt, lineno) | |||
|
376 | elif token==OUTPUT: | |||
|
377 | out_data = \ | |||
|
378 | self.process_output(data, output_prompt, | |||
|
379 | input_lines, output, is_doctest, | |||
|
380 | image_file) | |||
|
381 | if out_data: | |||
|
382 | ret.extend(out_data) | |||
|
383 | ||||
|
384 | if image_file is not None: | |||
|
385 | self.ensure_pyplot() | |||
|
386 | command = 'plt.gcf().savefig("%s")'%image_file | |||
|
387 | #print 'SAVEFIG', command # dbg | |||
|
388 | self.process_input_line('bookmark ipy_thisdir') | |||
|
389 | self.process_input_line('cd -b ipy_basedir') | |||
|
390 | self.process_input_line(command) | |||
|
391 | self.process_input_line('cd -b ipy_thisdir') | |||
|
392 | self.cout.seek(0) | |||
|
393 | self.cout.truncate(0) | |||
|
394 | return ret, image_directive | |||
|
395 | ||||
|
396 | def ensure_pyplot(self): | |||
|
397 | if self._pyplot_imported: | |||
|
398 | return | |||
|
399 | self.process_input_line('import matplotlib.pyplot as plt') | |||
|
400 | ||||
|
401 | # A global instance used below. XXX: not sure why this can't be created inside | |||
|
402 | # ipython_directive itself. | |||
|
403 | shell = EmbeddedSphinxShell() | |||
|
404 | ||||
|
405 | ||||
|
406 | def ipython_directive(name, arguments, options, content, lineno, | |||
|
407 | content_offset, block_text, state, state_machine, | |||
|
408 | ): | |||
|
409 | ||||
|
410 | debug = ipython_directive.DEBUG | |||
|
411 | shell.is_suppress = options.has_key('suppress') | |||
|
412 | shell.is_doctest = options.has_key('doctest') | |||
|
413 | shell.is_verbatim = options.has_key('verbatim') | |||
|
414 | ||||
|
415 | #print 'ipy', shell.is_suppress, options | |||
|
416 | parts = '\n'.join(content).split('\n\n') | |||
|
417 | lines = ['.. sourcecode:: ipython', ''] | |||
|
418 | ||||
|
419 | figures = [] | |||
|
420 | for part in parts: | |||
|
421 | block = block_parser(part) | |||
|
422 | ||||
|
423 | if len(block): | |||
|
424 | rows, figure = shell.process_block(block) | |||
|
425 | for row in rows: | |||
|
426 | lines.extend([' %s'%line for line in row.split('\n')]) | |||
|
427 | ||||
|
428 | if figure is not None: | |||
|
429 | figures.append(figure) | |||
|
430 | ||||
|
431 | for figure in figures: | |||
|
432 | lines.append('') | |||
|
433 | lines.extend(figure.split('\n')) | |||
|
434 | lines.append('') | |||
|
435 | ||||
|
436 | #print lines | |||
|
437 | if len(lines)>2: | |||
|
438 | if debug: | |||
|
439 | print '\n'.join(lines) | |||
|
440 | else: | |||
|
441 | #print 'INSERTING %d lines'%len(lines) | |||
|
442 | state_machine.insert_input( | |||
|
443 | lines, state_machine.input_lines.source(0)) | |||
|
444 | ||||
|
445 | return [] | |||
|
446 | ||||
|
447 | ipython_directive.DEBUG = False | |||
|
448 | ||||
|
449 | # Enable as a proper Sphinx directive | |||
|
450 | def setup(app): | |||
|
451 | setup.app = app | |||
|
452 | options = {'suppress': directives.flag, | |||
|
453 | 'doctest': directives.flag, | |||
|
454 | 'verbatim': directives.flag, | |||
|
455 | } | |||
|
456 | ||||
|
457 | app.add_directive('ipython', ipython_directive, True, (0, 2, 0), **options) | |||
|
458 | ||||
|
459 | ||||
|
460 | # Simple smoke test, needs to be converted to a proper automatic test. | |||
|
461 | def test(): | |||
|
462 | ||||
|
463 | examples = [ | |||
|
464 | r""" | |||
|
465 | In [9]: pwd | |||
|
466 | Out[9]: '/home/jdhunter/py4science/book' | |||
|
467 | ||||
|
468 | In [10]: cd bookdata/ | |||
|
469 | /home/jdhunter/py4science/book/bookdata | |||
|
470 | ||||
|
471 | In [2]: from pylab import * | |||
|
472 | ||||
|
473 | In [2]: ion() | |||
|
474 | ||||
|
475 | In [3]: im = imread('stinkbug.png') | |||
|
476 | ||||
|
477 | @savefig mystinkbug.png width=4in | |||
|
478 | In [4]: imshow(im) | |||
|
479 | Out[4]: <matplotlib.image.AxesImage object at 0x39ea850> | |||
|
480 | ||||
|
481 | """, | |||
|
482 | r""" | |||
|
483 | ||||
|
484 | In [1]: x = 'hello world' | |||
|
485 | ||||
|
486 | # string methods can be | |||
|
487 | # used to alter the string | |||
|
488 | @doctest | |||
|
489 | In [2]: x.upper() | |||
|
490 | Out[2]: 'HELLO WORLD' | |||
|
491 | ||||
|
492 | @verbatim | |||
|
493 | In [3]: x.st<TAB> | |||
|
494 | x.startswith x.strip | |||
|
495 | """, | |||
|
496 | r""" | |||
|
497 | ||||
|
498 | In [130]: url = 'http://ichart.finance.yahoo.com/table.csv?s=CROX\ | |||
|
499 | .....: &d=9&e=22&f=2009&g=d&a=1&br=8&c=2006&ignore=.csv' | |||
|
500 | ||||
|
501 | In [131]: print url.split('&') | |||
|
502 | ['http://ichart.finance.yahoo.com/table.csv?s=CROX', 'd=9', 'e=22', 'f=2009', 'g=d', 'a=1', 'b=8', 'c=2006', 'ignore=.csv'] | |||
|
503 | ||||
|
504 | In [60]: import urllib | |||
|
505 | ||||
|
506 | """, | |||
|
507 | r"""\ | |||
|
508 | ||||
|
509 | In [133]: import numpy.random | |||
|
510 | ||||
|
511 | @suppress | |||
|
512 | In [134]: numpy.random.seed(2358) | |||
|
513 | ||||
|
514 | @doctest | |||
|
515 | In [135]: np.random.rand(10,2) | |||
|
516 | Out[135]: | |||
|
517 | array([[ 0.64524308, 0.59943846], | |||
|
518 | [ 0.47102322, 0.8715456 ], | |||
|
519 | [ 0.29370834, 0.74776844], | |||
|
520 | [ 0.99539577, 0.1313423 ], | |||
|
521 | [ 0.16250302, 0.21103583], | |||
|
522 | [ 0.81626524, 0.1312433 ], | |||
|
523 | [ 0.67338089, 0.72302393], | |||
|
524 | [ 0.7566368 , 0.07033696], | |||
|
525 | [ 0.22591016, 0.77731835], | |||
|
526 | [ 0.0072729 , 0.34273127]]) | |||
|
527 | ||||
|
528 | """, | |||
|
529 | ||||
|
530 | r""" | |||
|
531 | In [106]: print x | |||
|
532 | jdh | |||
|
533 | ||||
|
534 | In [109]: for i in range(10): | |||
|
535 | .....: print i | |||
|
536 | .....: | |||
|
537 | .....: | |||
|
538 | 0 | |||
|
539 | 1 | |||
|
540 | 2 | |||
|
541 | 3 | |||
|
542 | 4 | |||
|
543 | 5 | |||
|
544 | 6 | |||
|
545 | 7 | |||
|
546 | 8 | |||
|
547 | 9 | |||
|
548 | ||||
|
549 | ||||
|
550 | """, | |||
|
551 | ||||
|
552 | r""" | |||
|
553 | ||||
|
554 | In [144]: from pylab import * | |||
|
555 | ||||
|
556 | In [145]: ion() | |||
|
557 | ||||
|
558 | # use a semicolon to suppress the output | |||
|
559 | @savefig test_hist.png width=4in | |||
|
560 | In [151]: hist(np.random.randn(10000), 100); | |||
|
561 | ||||
|
562 | ||||
|
563 | @savefig test_plot.png width=4in | |||
|
564 | In [151]: plot(np.random.randn(10000), 'o'); | |||
|
565 | """, | |||
|
566 | ||||
|
567 | r""" | |||
|
568 | # use a semicolon to suppress the output | |||
|
569 | In [151]: plt.clf() | |||
|
570 | ||||
|
571 | @savefig plot_simple.png width=4in | |||
|
572 | In [151]: plot([1,2,3]) | |||
|
573 | ||||
|
574 | @savefig hist_simple.png width=4in | |||
|
575 | In [151]: hist(np.random.randn(10000), 100); | |||
|
576 | ||||
|
577 | """, | |||
|
578 | r""" | |||
|
579 | # update the current fig | |||
|
580 | In [151]: ylabel('number') | |||
|
581 | ||||
|
582 | In [152]: title('normal distribution') | |||
|
583 | ||||
|
584 | ||||
|
585 | @savefig hist_with_text.png | |||
|
586 | In [153]: grid(True) | |||
|
587 | ||||
|
588 | """, | |||
|
589 | ] | |||
|
590 | ||||
|
591 | ||||
|
592 | ipython_directive.DEBUG = True | |||
|
593 | #options = dict(suppress=True) | |||
|
594 | options = dict() | |||
|
595 | for example in examples: | |||
|
596 | content = example.split('\n') | |||
|
597 | ipython_directive('debug', arguments=None, options=options, | |||
|
598 | content=content, lineno=0, | |||
|
599 | content_offset=None, block_text=None, | |||
|
600 | state=None, state_machine=None, | |||
|
601 | ) | |||
|
602 | ||||
|
603 | # Run test suite as a script | |||
|
604 | if __name__=='__main__': | |||
|
605 | test() |
General Comments 0
You need to be logged in to leave comments.
Login now