##// END OF EJS Templates
This updates to current main branch and adds my latest changes to demo.py and demoExerciser.py. Note demoExercizer.py is just a quick way to test things, just 'run' it in ipython....
Tom Fetherston -
Show More
@@ -0,0 +1,65 b''
1 from IPython.demo import Demo,IPythonDemo,LineDemo,IPythonLineDemo,ClearDemo,ClearIPDemo
2 import tempfile, os, StringIO, shutil
3
4 example1 = """
5 '''A simple interactive demo to illustrate the use of IPython's Demo class.'''
6
7 print 'Hello, welcome to an interactive IPython demo.'
8
9 # The mark below defines a block boundary, which is a point where IPython will
10 # stop execution and return to the interactive prompt. The dashes are actually
11 # optional and used only as a visual aid to clearly separate blocks while
12 # editing the demo code.
13 # <demo> stop
14
15 x = 1
16 y = 2
17
18 # <demo> stop
19
20 # the mark below makes this block as silent
21 # <demo> silent
22
23 print 'This is a silent block, which gets executed but not printed.'
24
25 # <demo> stop
26 # <demo> auto
27 print 'This is an automatic block.'
28 print 'It is executed without asking for confirmation, but printed.'
29 z = x+y
30
31 print 'z=',x
32
33 # <demo> stop
34 # This is just another normal block.
35 print 'z is now:', z
36
37 print 'bye!'
38 """
39 fp = tempfile.mkdtemp(prefix = 'DemoTmp')
40 fd, filename = tempfile.mkstemp(prefix = 'demoExample1File', suffix = '.py', dir = fp)
41 f = os.fdopen(fd, 'wt')
42
43 f.write(example1)
44 f.close()
45
46 my_d = Demo(filename)
47 my_cd = ClearDemo(filename)
48
49 fobj = StringIO.StringIO(example1)
50 str_d = Demo(fobj, title='via stringio')
51 #~ def tmpcleanup():
52 #~ global my_d, my_cd, fp
53 #~ del my_d
54 #~ del my_cd
55 #~ shutil.rmtree(fp, False)
56
57 print '''
58 The following demos should now be available to use:
59 my_d -- created from a file
60 my_cd -- created from a file, a ClearDemo
61 str_d -- same as above, but created via a stringi\o object
62
63 '''
64 # call tmpcleanup to delete the temporary files created. -not implemented
65
@@ -125,7 +125,7 b" print 'Hello, welcome to an interactive IPython demo.'"
125 # The mark below defines a block boundary, which is a point where IPython will
125 # The mark below defines a block boundary, which is a point where IPython will
126 # stop execution and return to the interactive prompt. The dashes are actually
126 # stop execution and return to the interactive prompt. The dashes are actually
127 # optional and used only as a visual aid to clearly separate blocks while
127 # optional and used only as a visual aid to clearly separate blocks while
128 editing the demo code.
128 # editing the demo code.
129 # <demo> stop
129 # <demo> stop
130
130
131 x = 1
131 x = 1
@@ -170,6 +170,7 b' import sys'
170
170
171 from IPython.PyColorize import Parser
171 from IPython.PyColorize import Parser
172 from IPython.genutils import marquee, file_read, file_readlines
172 from IPython.genutils import marquee, file_read, file_readlines
173 from genutils import Term
173
174
174 __all__ = ['Demo','IPythonDemo','LineDemo','IPythonLineDemo','DemoError']
175 __all__ = ['Demo','IPythonDemo','LineDemo','IPythonLineDemo','DemoError']
175
176
@@ -185,7 +186,7 b' class Demo(object):'
185 re_auto = re_mark('auto')
186 re_auto = re_mark('auto')
186 re_auto_all = re_mark('auto_all')
187 re_auto_all = re_mark('auto_all')
187
188
188 def __init__(self,fname,arg_str='',auto_all=None):
189 def __init__(self,src,title='',arg_str='',auto_all=None):
189 """Make a new demo object. To run the demo, simply call the object.
190 """Make a new demo object. To run the demo, simply call the object.
190
191
191 See the module docstring for full details and an example (you can use
192 See the module docstring for full details and an example (you can use
@@ -193,9 +194,14 b' class Demo(object):'
193
194
194 Inputs:
195 Inputs:
195
196
196 - fname = filename.
197 - src is either a file, or file-like object, or a
198 string that can be resolved to a filename.
197
199
198 Optional inputs:
200 Optional inputs:
201
202 - title: a string to use as the demo name. Of most use when the demo
203 you are making comes from an object that has no filename, or if you
204 want an alternate denotation distinct from the filename.
199
205
200 - arg_str(''): a string of arguments, internally converted to a list
206 - arg_str(''): a string of arguments, internally converted to a list
201 just like sys.argv, so the demo script can see a similar
207 just like sys.argv, so the demo script can see a similar
@@ -207,9 +213,24 b' class Demo(object):'
207 can be changed at runtime simply by reassigning it to a boolean
213 can be changed at runtime simply by reassigning it to a boolean
208 value.
214 value.
209 """
215 """
210
216 if hasattr(src, "read"):
211 self.fname = fname
217 # It seems to be a file or a file-like object
212 self.sys_argv = [fname] + shlex.split(arg_str)
218 self.fobj = src
219 self.fname = "from a file-like object"
220 if title == '':
221 self.title = "from a file-like object"
222 else:
223 self.title = title
224 else:
225 # Assume it's a string or something that can be converted to one
226 self.fobj = open(src)
227 self.fname = src
228 if title == '':
229 (filepath, filename) = os.path.split(src)
230 self.title = filename
231 else:
232 self.title = title
233 self.sys_argv = [src] + shlex.split(arg_str)
213 self.auto_all = auto_all
234 self.auto_all = auto_all
214
235
215 # get a few things from ipython. While it's a bit ugly design-wise,
236 # get a few things from ipython. While it's a bit ugly design-wise,
@@ -228,7 +249,7 b' class Demo(object):'
228 def reload(self):
249 def reload(self):
229 """Reload source from disk and initialize state."""
250 """Reload source from disk and initialize state."""
230 # read data and parse into blocks
251 # read data and parse into blocks
231 self.src = file_read(self.fname)
252 self.src = self.fobj.read()
232 src_b = [b.strip() for b in self.re_stop.split(self.src) if b]
253 src_b = [b.strip() for b in self.re_stop.split(self.src) if b]
233 self._silent = [bool(self.re_silent.findall(b)) for b in src_b]
254 self._silent = [bool(self.re_silent.findall(b)) for b in src_b]
234 self._auto = [bool(self.re_auto.findall(b)) for b in src_b]
255 self._auto = [bool(self.re_auto.findall(b)) for b in src_b]
@@ -277,7 +298,7 b' class Demo(object):'
277
298
278 if index is None:
299 if index is None:
279 if self.finished:
300 if self.finished:
280 print 'Demo finished. Use reset() if you want to rerun it.'
301 print >>Term.cout, 'Demo finished. Use <demo_name>.reset() if you want to rerun it.'
281 return None
302 return None
282 index = self.block_index
303 index = self.block_index
283 else:
304 else:
@@ -346,26 +367,27 b' class Demo(object):'
346 if index is None:
367 if index is None:
347 return
368 return
348
369
349 print self.marquee('<%s> block # %s (%s remaining)' %
370 print >>Term.cout, self.marquee('<%s> block # %s (%s remaining)' %
350 (self.fname,index,self.nblocks-index-1))
371 (self.title,index,self.nblocks-index-1))
351 sys.stdout.write(self.src_blocks_colored[index])
372 print >>Term.cout,(self.src_blocks_colored[index])
352 sys.stdout.flush()
373 sys.stdout.flush()
353
374
354 def show_all(self):
375 def show_all(self):
355 """Show entire demo on screen, block by block"""
376 """Show entire demo on screen, block by block"""
356
377
357 fname = self.fname
378 fname = self.title
379 title = self.title
358 nblocks = self.nblocks
380 nblocks = self.nblocks
359 silent = self._silent
381 silent = self._silent
360 marquee = self.marquee
382 marquee = self.marquee
361 for index,block in enumerate(self.src_blocks_colored):
383 for index,block in enumerate(self.src_blocks_colored):
362 if silent[index]:
384 if silent[index]:
363 print marquee('<%s> SILENT block # %s (%s remaining)' %
385 print >>Term.cout, marquee('<%s> SILENT block # %s (%s remaining)' %
364 (fname,index,nblocks-index-1))
386 (title,index,nblocks-index-1))
365 else:
387 else:
366 print marquee('<%s> block # %s (%s remaining)' %
388 print >>Term.cout, marquee('<%s> block # %s (%s remaining)' %
367 (fname,index,nblocks-index-1))
389 (title,index,nblocks-index-1))
368 print block,
390 print >>Term.cout, block,
369 sys.stdout.flush()
391 sys.stdout.flush()
370
392
371 def runlines(self,source):
393 def runlines(self,source):
@@ -390,18 +412,18 b' class Demo(object):'
390 next_block = self.src_blocks[index]
412 next_block = self.src_blocks[index]
391 self.block_index += 1
413 self.block_index += 1
392 if self._silent[index]:
414 if self._silent[index]:
393 print marquee('Executing silent block # %s (%s remaining)' %
415 print >>Term.cout, marquee('Executing silent block # %s (%s remaining)' %
394 (index,self.nblocks-index-1))
416 (index,self.nblocks-index-1))
395 else:
417 else:
396 self.pre_cmd()
418 self.pre_cmd()
397 self.show(index)
419 self.show(index)
398 if self.auto_all or self._auto[index]:
420 if self.auto_all or self._auto[index]:
399 print marquee('output:')
421 print >>Term.cout, marquee('output:')
400 else:
422 else:
401 print marquee('Press <q> to quit, <Enter> to execute...'),
423 print >>Term.cout, marquee('Press <q> to quit, <Enter> to execute...'),
402 ans = raw_input().strip()
424 ans = raw_input().strip()
403 if ans:
425 if ans:
404 print marquee('Block NOT executed')
426 print >>Term.cout, marquee('Block NOT executed')
405 return
427 return
406 try:
428 try:
407 save_argv = sys.argv
429 save_argv = sys.argv
@@ -419,10 +441,10 b' class Demo(object):'
419 if self.block_index == self.nblocks:
441 if self.block_index == self.nblocks:
420 mq1 = self.marquee('END OF DEMO')
442 mq1 = self.marquee('END OF DEMO')
421 if mq1:
443 if mq1:
422 # avoid spurious prints if empty marquees are used
444 # avoid spurious print >>Term.cout,s if empty marquees are used
423 print
445 print >>Term.cout
424 print mq1
446 print >>Term.cout, mq1
425 print self.marquee('Use reset() if you want to rerun it.')
447 print >>Term.cout, self.marquee('Use <demo_name>.reset() if you want to rerun it.')
426 self.finished = True
448 self.finished = True
427
449
428 # These methods are meant to be overridden by subclasses who may wish to
450 # These methods are meant to be overridden by subclasses who may wish to
@@ -471,9 +493,9 b' class LineDemo(Demo):'
471 def reload(self):
493 def reload(self):
472 """Reload source from disk and initialize state."""
494 """Reload source from disk and initialize state."""
473 # read data and parse into blocks
495 # read data and parse into blocks
474 src_b = [l for l in file_readlines(self.fname) if l.strip()]
496 src_b = [l for l in self.fobj.readline() if l.strip()]
475 nblocks = len(src_b)
497 nblocks = len(src_b)
476 self.src = os.linesep.join(file_readlines(self.fname))
498 self.src = os.linesep.join(self.fobj.readlines())
477 self._silent = [False]*nblocks
499 self._silent = [False]*nblocks
478 self._auto = [True]*nblocks
500 self._auto = [True]*nblocks
479 self.auto_all = True
501 self.auto_all = True
@@ -494,28 +516,32 b' class IPythonLineDemo(IPythonDemo,LineDemo):'
494
516
495 class ClearMixin(object):
517 class ClearMixin(object):
496 """Use this mixin to make Demo classes with less visual clutter.
518 """Use this mixin to make Demo classes with less visual clutter.
497
519
498 Demos using this mixin will clear the screen before every block and use
520 Demos using this mixin will clear the screen before every block and use
499 blank marquees.
521 blank marquees.
500
522
501 Note that in order for the methods defined here to actually override those
523 Note that in order for the methods defined here to actually override those
502 of the classes it's mixed with, it must go /first/ in the inheritance
524 of the classes it's mixed with, it must go /first/ in the inheritance
503 tree. For example:
525 tree. For example:
504
526
505 class ClearIPDemo(ClearMixin,IPythonDemo): pass
527 class ClearIPDemo(ClearMixin,IPythonDemo): pass
506
528
507 will provide an IPythonDemo class with the mixin's features.
529 will provide an IPythonDemo class with the mixin's features.
508 """
530 """
509
531
510 def marquee(self,txt='',width=78,mark='*'):
532 def marquee(self,txt='',width=78,mark='*'):
511 """Blank marquee that returns '' no matter what the input."""
533 """Blank marquee that returns '' no matter what the input."""
512 return ''
534 return ''
513
535
514 def pre_cmd(self):
536 def pre_cmd(self):
515 """Method called before executing each block.
537 """Method called before executing each block.
516
538
517 This one simply clears the screen."""
539 This one simply clears the screen."""
518 os.system('clear')
540 if sys.platform == "win32":
541 os.system('cls')
542 else:
543 os.system('clear')
544
519
545
520
546
521 class ClearDemo(ClearMixin,Demo):
547 class ClearDemo(ClearMixin,Demo):
General Comments 0
You need to be logged in to leave comments. Login now