From f5f9ce72982012d83efa53cf432cbfbb4b4cb47f Mon Sep 17 00:00:00 2001 From: Michele Simionato Date: Wed, 26 Jan 2011 13:49:15 +0100 Subject: Various fixes/improvements to the monitor mechanism --- plac/doc/importer_ui.py | 1 + plac/doc/plac.html | 68 +- plac/doc/plac.pdf | 3507 ++++++++++++++++++++++++----------------------- plac/doc/plac_adv.txt | 40 +- plac/doc/test_runp.py | 12 +- plac/plac.py | 6 +- plac/plac_ext.py | 38 +- 7 files changed, 1933 insertions(+), 1739 deletions(-) diff --git a/plac/doc/importer_ui.py b/plac/doc/importer_ui.py index a4592b0..0a5cc9c 100644 --- a/plac/doc/importer_ui.py +++ b/plac/doc/importer_ui.py @@ -1,3 +1,4 @@ +from __future__ import with_statement from Tkinter import * from importer3 import FakeImporter diff --git a/plac/doc/plac.html b/plac/doc/plac.html index a81cf24..8dc043e 100644 --- a/plac/doc/plac.html +++ b/plac/doc/plac.html @@ -474,10 +474,11 @@ h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
  • Threaded commands
  • Running commands as external processes
  • Managing the output of concurrent commands
  • -
  • Parallel computing with plac
  • -
  • The plac server
  • -
  • Summary
  • -
  • Appendix: custom annotation objects
  • +
  • Monitor support
  • +
  • Parallel computing with plac
  • +
  • The plac server
  • +
  • Summary
  • +
  • Appendix: custom annotation objects
  • @@ -2676,11 +2677,10 @@ task runs and more values are yielded. Accessing the .result property which waits for the task to finish and returns the last yielded -value or raises an exception.

    -

    Here is some example code to visualize the output of the FakeImporter -in Tkinter (I chose Tkinter because it is easy to use and it is -in the standard library, but you can use any GUI):

    +value or raises an exception. The code below provides an example of +how you could implement a GUI over the importer example:

    +from __future__ import with_statement
     from Tkinter import *
     from importer3 import FakeImporter
     
    @@ -2713,8 +2713,47 @@ if __name__ == '__main__':
     
     
    +
    +

    Monitor support

    +

    Starting from release 0.8 plac provides builtin support for monitoring the +output of concurrent commands, at least for platforms where multiprocessing +is fully supported. You can define your own monitor +class, simply by inheriting from plac.Monitor and by +overriding the methods add_listener(self, no), +del_listener(self, taskno), notify_listener(self, taskno, msg), +schedule(self, seconds, func, arg) and run(self). +Then, you can a monitor object to any plac.Interpreter object +by simply calling the add_monitor method. +For convenience, +plac comes with a very simple TkMonitor based on Tkinter +(I chose Tkinter because it is easy to use and it is +in the standard library, but you can use any GUI): you can just +look at how the TkMonitor is implemented in plac_tk.py +and adapt it. Here is an example of usage of the TkMonitor:

    +
    +from __future__ import with_statement
    +import plac
    +
    +class Hello(object):
    +    mpcommands = ['hello']
    +    def hello(self):
    +        yield 'hello'
    +
    +if __name__ == '__main__':
    +    i = plac.Interpreter(Hello())
    +    i.add_monitor(plac.TkMonitor('tkmon'))
    +    with i:
    +        i.interact()
    +        
    +
    +
    +

    Try to give the hello command from the interactive interpreter: +each time a new text widget will be added displaying the output +of the command. Notice that if Tkinter is not installed correctly +on your system the TkMonitor class will not be available.

    +
    -

    Parallel computing with plac

    +

    Parallel computing with plac

    plac is certainly not intended as a tool for parallel computing, but still you can use it to launch a set of commands and to collect the results, similarly to the MapReduce pattern popularized by @@ -2836,7 +2875,7 @@ $ python picalculator.py -mS 10000000 # sequential mode is some 20% slower than the sequential mode.

    Since the pattern submit a bunch of tasks, starts them and collect the results is so common, plac provides an utility function -runp(genseq, mode='p', start=True) to start +runp(genseq, mode='p', monitors=(), start=True) to start a bunch a generators and return a list of task objects. By default runp use processes, but you can use threads by passing mode='t'. If you do not wont to start the tasks, you can say so (start=False). @@ -2844,9 +2883,12 @@ With runp the parallel pi calculation becomes

     sum(task.result for task in plac.runp(calc_pi(N) for i in range(ncpus)))/ncpus
     
    +

    The file test_runp in the doc directory of the plac distribution +shows another couple of examples of usage, including how to show the +results of the running computation on a TkMonitor.

    -

    The plac server

    +

    The plac server

    A command-line oriented interface can be easily converted into a socket-based interface. Starting from release 0.7 plac features a builtin server which is able to accept commands from multiple @@ -2892,7 +2934,7 @@ Connection closed by foreign host.

    -

    Summary

    +

    Summary

    Once plac claimed to be the easiest command-line arguments parser in the world. Having read this document you may think that it is not so easy after all. But it is a false impression. Actually the @@ -2918,7 +2960,7 @@ given port number (default 2199)


    -

    Appendix: custom annotation objects

    +

    Appendix: custom annotation objects

    Internally plac uses an Annotation class to convert the tuples in the function signature into annotation objects, i.e. objects with six attributes help, kind, short, type, choices, metavar.

    diff --git a/plac/doc/plac.pdf b/plac/doc/plac.pdf index 04d9797..b2652b5 100644 --- a/plac/doc/plac.pdf +++ b/plac/doc/plac.pdf @@ -6,7 +6,7 @@ << /F1 2 0 R /F2 3 0 R /F3 7 0 R - /F4 94 0 R >> + /F4 96 0 R >> endobj % 'F1': class PDFType1Font 2 0 obj @@ -86,12 +86,12 @@ endobj << /Annots [ 4 0 R 5 0 R 6 0 R ] - /Contents 341 0 R + /Contents 346 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -144,7 +144,7 @@ endobj 0 0 ] /Contents () - /Dest [ 95 0 R + /Dest [ 97 0 R /XYZ 62.69291 765.0236 @@ -162,7 +162,7 @@ endobj 0 0 ] /Contents () - /Dest [ 95 0 R + /Dest [ 97 0 R /XYZ 62.69291 765.0236 @@ -180,7 +180,7 @@ endobj 0 0 ] /Contents () - /Dest [ 95 0 R + /Dest [ 97 0 R /XYZ 62.69291 411.0236 @@ -198,7 +198,7 @@ endobj 0 0 ] /Contents () - /Dest [ 95 0 R + /Dest [ 97 0 R /XYZ 62.69291 411.0236 @@ -216,7 +216,7 @@ endobj 0 0 ] /Contents () - /Dest [ 109 0 R + /Dest [ 111 0 R /XYZ 62.69291 765.0236 @@ -234,7 +234,7 @@ endobj 0 0 ] /Contents () - /Dest [ 109 0 R + /Dest [ 111 0 R /XYZ 62.69291 765.0236 @@ -252,7 +252,7 @@ endobj 0 0 ] /Contents () - /Dest [ 119 0 R + /Dest [ 121 0 R /XYZ 62.69291 741.0236 @@ -270,7 +270,7 @@ endobj 0 0 ] /Contents () - /Dest [ 119 0 R + /Dest [ 121 0 R /XYZ 62.69291 741.0236 @@ -288,7 +288,7 @@ endobj 0 0 ] /Contents () - /Dest [ 123 0 R + /Dest [ 125 0 R /XYZ 62.69291 765.0236 @@ -306,7 +306,7 @@ endobj 0 0 ] /Contents () - /Dest [ 123 0 R + /Dest [ 125 0 R /XYZ 62.69291 765.0236 @@ -324,7 +324,7 @@ endobj 0 0 ] /Contents () - /Dest [ 123 0 R + /Dest [ 125 0 R /XYZ 62.69291 265.7299 @@ -342,7 +342,7 @@ endobj 0 0 ] /Contents () - /Dest [ 123 0 R + /Dest [ 125 0 R /XYZ 62.69291 265.7299 @@ -360,7 +360,7 @@ endobj 0 0 ] /Contents () - /Dest [ 131 0 R + /Dest [ 133 0 R /XYZ 62.69291 522.6236 @@ -378,7 +378,7 @@ endobj 0 0 ] /Contents () - /Dest [ 131 0 R + /Dest [ 133 0 R /XYZ 62.69291 522.6236 @@ -396,7 +396,7 @@ endobj 0 0 ] /Contents () - /Dest [ 136 0 R + /Dest [ 138 0 R /XYZ 62.69291 552.6236 @@ -414,7 +414,7 @@ endobj 0 0 ] /Contents () - /Dest [ 136 0 R + /Dest [ 138 0 R /XYZ 62.69291 552.6236 @@ -432,7 +432,7 @@ endobj 0 0 ] /Contents () - /Dest [ 139 0 R + /Dest [ 141 0 R /XYZ 62.69291 513.8236 @@ -450,7 +450,7 @@ endobj 0 0 ] /Contents () - /Dest [ 139 0 R + /Dest [ 141 0 R /XYZ 62.69291 513.8236 @@ -468,7 +468,7 @@ endobj 0 0 ] /Contents () - /Dest [ 141 0 R + /Dest [ 143 0 R /XYZ 62.69291 493.4236 @@ -486,7 +486,7 @@ endobj 0 0 ] /Contents () - /Dest [ 141 0 R + /Dest [ 143 0 R /XYZ 62.69291 493.4236 @@ -504,7 +504,7 @@ endobj 0 0 ] /Contents () - /Dest [ 160 0 R + /Dest [ 162 0 R /XYZ 62.69291 422.6236 @@ -522,7 +522,7 @@ endobj 0 0 ] /Contents () - /Dest [ 160 0 R + /Dest [ 162 0 R /XYZ 62.69291 422.6236 @@ -540,7 +540,7 @@ endobj 0 0 ] /Contents () - /Dest [ 211 0 R + /Dest [ 213 0 R /XYZ 62.69291 765.0236 @@ -558,7 +558,7 @@ endobj 0 0 ] /Contents () - /Dest [ 211 0 R + /Dest [ 213 0 R /XYZ 62.69291 765.0236 @@ -576,7 +576,7 @@ endobj 0 0 ] /Contents () - /Dest [ 211 0 R + /Dest [ 213 0 R /XYZ 62.69291 495.0236 @@ -594,7 +594,7 @@ endobj 0 0 ] /Contents () - /Dest [ 211 0 R + /Dest [ 213 0 R /XYZ 62.69291 495.0236 @@ -612,7 +612,7 @@ endobj 0 0 ] /Contents () - /Dest [ 211 0 R + /Dest [ 213 0 R /XYZ 62.69291 291.0236 @@ -630,7 +630,7 @@ endobj 0 0 ] /Contents () - /Dest [ 211 0 R + /Dest [ 213 0 R /XYZ 62.69291 291.0236 @@ -648,7 +648,7 @@ endobj 0 0 ] /Contents () - /Dest [ 225 0 R + /Dest [ 227 0 R /XYZ 62.69291 681.0236 @@ -666,7 +666,7 @@ endobj 0 0 ] /Contents () - /Dest [ 225 0 R + /Dest [ 227 0 R /XYZ 62.69291 681.0236 @@ -684,7 +684,7 @@ endobj 0 0 ] /Contents () - /Dest [ 225 0 R + /Dest [ 227 0 R /XYZ 62.69291 648.0236 @@ -702,7 +702,7 @@ endobj 0 0 ] /Contents () - /Dest [ 225 0 R + /Dest [ 227 0 R /XYZ 62.69291 648.0236 @@ -720,7 +720,7 @@ endobj 0 0 ] /Contents () - /Dest [ 225 0 R + /Dest [ 227 0 R /XYZ 62.69291 426.0236 @@ -738,7 +738,7 @@ endobj 0 0 ] /Contents () - /Dest [ 225 0 R + /Dest [ 227 0 R /XYZ 62.69291 426.0236 @@ -756,7 +756,7 @@ endobj 0 0 ] /Contents () - /Dest [ 228 0 R + /Dest [ 230 0 R /XYZ 62.69291 629.8236 @@ -774,7 +774,7 @@ endobj 0 0 ] /Contents () - /Dest [ 228 0 R + /Dest [ 230 0 R /XYZ 62.69291 629.8236 @@ -792,7 +792,7 @@ endobj 0 0 ] /Contents () - /Dest [ 231 0 R + /Dest [ 233 0 R /XYZ 62.69291 609.0236 @@ -810,7 +810,7 @@ endobj 0 0 ] /Contents () - /Dest [ 231 0 R + /Dest [ 233 0 R /XYZ 62.69291 609.0236 @@ -828,7 +828,7 @@ endobj 0 0 ] /Contents () - /Dest [ 242 0 R + /Dest [ 244 0 R /XYZ 62.69291 299.8485 @@ -846,7 +846,7 @@ endobj 0 0 ] /Contents () - /Dest [ 242 0 R + /Dest [ 244 0 R /XYZ 62.69291 299.8485 @@ -864,7 +864,7 @@ endobj 0 0 ] /Contents () - /Dest [ 247 0 R + /Dest [ 249 0 R /XYZ 62.69291 378.6236 @@ -882,7 +882,7 @@ endobj 0 0 ] /Contents () - /Dest [ 247 0 R + /Dest [ 249 0 R /XYZ 62.69291 378.6236 @@ -900,7 +900,7 @@ endobj 0 0 ] /Contents () - /Dest [ 252 0 R + /Dest [ 254 0 R /XYZ 62.69291 330.0679 @@ -918,7 +918,7 @@ endobj 0 0 ] /Contents () - /Dest [ 252 0 R + /Dest [ 254 0 R /XYZ 62.69291 330.0679 @@ -936,7 +936,7 @@ endobj 0 0 ] /Contents () - /Dest [ 258 0 R + /Dest [ 260 0 R /XYZ 62.69291 717.0236 @@ -954,7 +954,7 @@ endobj 0 0 ] /Contents () - /Dest [ 258 0 R + /Dest [ 260 0 R /XYZ 62.69291 717.0236 @@ -972,7 +972,7 @@ endobj 0 0 ] /Contents () - /Dest [ 271 0 R + /Dest [ 273 0 R /XYZ 62.69291 204.6236 @@ -990,7 +990,7 @@ endobj 0 0 ] /Contents () - /Dest [ 271 0 R + /Dest [ 273 0 R /XYZ 62.69291 204.6236 @@ -1008,7 +1008,7 @@ endobj 0 0 ] /Contents () - /Dest [ 275 0 R + /Dest [ 277 0 R /XYZ 62.69291 371.4236 @@ -1026,7 +1026,7 @@ endobj 0 0 ] /Contents () - /Dest [ 275 0 R + /Dest [ 277 0 R /XYZ 62.69291 371.4236 @@ -1044,7 +1044,7 @@ endobj 0 0 ] /Contents () - /Dest [ 278 0 R + /Dest [ 280 0 R /XYZ 62.69291 348.6236 @@ -1062,7 +1062,7 @@ endobj 0 0 ] /Contents () - /Dest [ 278 0 R + /Dest [ 280 0 R /XYZ 62.69291 348.6236 @@ -1080,7 +1080,7 @@ endobj 0 0 ] /Contents () - /Dest [ 282 0 R + /Dest [ 284 0 R /XYZ 62.69291 175.4236 @@ -1098,7 +1098,7 @@ endobj 0 0 ] /Contents () - /Dest [ 282 0 R + /Dest [ 284 0 R /XYZ 62.69291 175.4236 @@ -1116,7 +1116,7 @@ endobj 0 0 ] /Contents () - /Dest [ 285 0 R + /Dest [ 287 0 R /XYZ 62.69291 282.6236 @@ -1134,7 +1134,7 @@ endobj 0 0 ] /Contents () - /Dest [ 285 0 R + /Dest [ 287 0 R /XYZ 62.69291 282.6236 @@ -1152,7 +1152,7 @@ endobj 0 0 ] /Contents () - /Dest [ 289 0 R + /Dest [ 291 0 R /XYZ 62.69291 383.8236 @@ -1170,7 +1170,7 @@ endobj 0 0 ] /Contents () - /Dest [ 289 0 R + /Dest [ 291 0 R /XYZ 62.69291 383.8236 @@ -1188,7 +1188,7 @@ endobj 0 0 ] /Contents () - /Dest [ 291 0 R + /Dest [ 293 0 R /XYZ 62.69291 575.8236 @@ -1206,7 +1206,7 @@ endobj 0 0 ] /Contents () - /Dest [ 291 0 R + /Dest [ 293 0 R /XYZ 62.69291 575.8236 @@ -1224,14 +1224,14 @@ endobj 0 0 ] /Contents () - /Dest [ 293 0 R + /Dest [ 296 0 R /XYZ 62.69291 703.8236 0 ] /Rect [ 82.69291 165.7736 - 206.6229 + 152.1629 177.7736 ] /Subtype /Link /Type /Annot >> @@ -1242,7 +1242,7 @@ endobj 0 0 ] /Contents () - /Dest [ 293 0 R + /Dest [ 296 0 R /XYZ 62.69291 703.8236 @@ -1260,14 +1260,14 @@ endobj 0 0 ] /Contents () - /Dest [ 297 0 R + /Dest [ 296 0 R /XYZ 62.69291 - 573.2159 + 338.6236 0 ] /Rect [ 82.69291 147.7736 - 151.6029 + 206.6229 159.7736 ] /Subtype /Link /Type /Annot >> @@ -1278,10 +1278,10 @@ endobj 0 0 ] /Contents () - /Dest [ 297 0 R + /Dest [ 296 0 R /XYZ 62.69291 - 573.2159 + 338.6236 0 ] /Rect [ 521.4627 147.7736 @@ -1296,14 +1296,14 @@ endobj 0 0 ] /Contents () - /Dest [ 300 0 R + /Dest [ 302 0 R /XYZ 62.69291 765.0236 0 ] /Rect [ 82.69291 129.7736 - 125.4729 + 151.6029 141.7736 ] /Subtype /Link /Type /Annot >> @@ -1314,7 +1314,7 @@ endobj 0 0 ] /Contents () - /Dest [ 300 0 R + /Dest [ 302 0 R /XYZ 62.69291 765.0236 @@ -1332,14 +1332,14 @@ endobj 0 0 ] /Contents () - /Dest [ 300 0 R + /Dest [ 302 0 R /XYZ 62.69291 - 454.6772 + 294.6236 0 ] /Rect [ 82.69291 111.7736 - 246.1129 + 125.4729 123.7736 ] /Subtype /Link /Type /Annot >> @@ -1350,10 +1350,10 @@ endobj 0 0 ] /Contents () - /Dest [ 300 0 R + /Dest [ 302 0 R /XYZ 62.69291 - 454.6772 + 294.6236 0 ] /Rect [ 521.4627 111.7736 @@ -1362,8 +1362,44 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Page2': class PDFPage +% 'Annot.NUMBER74': class LinkAnnotation 79 0 obj +<< /Border [ 0 + 0 + 0 ] + /Contents () + /Dest [ 304 0 R + /XYZ + 62.69291 + 652.6772 + 0 ] + /Rect [ 82.69291 + 93.77362 + 246.1129 + 105.7736 ] + /Subtype /Link + /Type /Annot >> +endobj +% 'Annot.NUMBER75': class LinkAnnotation +80 0 obj +<< /Border [ 0 + 0 + 0 ] + /Contents () + /Dest [ 304 0 R + /XYZ + 62.69291 + 652.6772 + 0 ] + /Rect [ 521.4627 + 93.77362 + 532.5827 + 105.7736 ] + /Subtype /Link + /Type /Annot >> +endobj +% 'Page2': class PDFPage +81 0 obj % Page dictionary << /Annots [ 9 0 R 10 0 R @@ -1434,13 +1470,15 @@ endobj 75 0 R 76 0 R 77 0 R - 78 0 R ] - /Contents 342 0 R + 78 0 R + 79 0 R + 80 0 R ] + /Contents 347 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -1451,8 +1489,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER74': class PDFDictionary -80 0 obj +% 'Annot.NUMBER76': class PDFDictionary +82 0 obj << /A << /S /URI /Type /Action /URI (http://docs.python.org/library/getopt.html) >> @@ -1466,8 +1504,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER75': class PDFDictionary -81 0 obj +% 'Annot.NUMBER77': class PDFDictionary +83 0 obj << /A << /S /URI /Type /Action /URI (http://docs.python.org/library/optparse.html) >> @@ -1481,8 +1519,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER76': class PDFDictionary -82 0 obj +% 'Annot.NUMBER78': class PDFDictionary +84 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -1496,8 +1534,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER77': class PDFDictionary -83 0 obj +% 'Annot.NUMBER79': class PDFDictionary +85 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -1511,8 +1549,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER78': class PDFDictionary -84 0 obj +% 'Annot.NUMBER80': class PDFDictionary +86 0 obj << /A << /S /URI /Type /Action /URI (http://www.welton.it/articles/scalable_systems) >> @@ -1526,8 +1564,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER79': class PDFDictionary -85 0 obj +% 'Annot.NUMBER81': class PDFDictionary +87 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -1541,8 +1579,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER80': class PDFDictionary -86 0 obj +% 'Annot.NUMBER82': class PDFDictionary +88 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -1556,8 +1594,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER81': class PDFDictionary -87 0 obj +% 'Annot.NUMBER83': class PDFDictionary +89 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -1571,8 +1609,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER82': class PDFDictionary -88 0 obj +% 'Annot.NUMBER84': class PDFDictionary +90 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -1586,8 +1624,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER83': class PDFDictionary -89 0 obj +% 'Annot.NUMBER85': class PDFDictionary +91 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -1601,8 +1639,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER84': class PDFDictionary -90 0 obj +% 'Annot.NUMBER86': class PDFDictionary +92 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -1616,8 +1654,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER85': class PDFDictionary -91 0 obj +% 'Annot.NUMBER87': class PDFDictionary +93 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -1631,8 +1669,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER86': class PDFDictionary -92 0 obj +% 'Annot.NUMBER88': class PDFDictionary +94 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -1646,8 +1684,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER87': class PDFDictionary -93 0 obj +% 'Annot.NUMBER89': class PDFDictionary +95 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -1662,7 +1700,7 @@ endobj /Type /Annot >> endobj % 'F4': class PDFType1Font -94 0 obj +96 0 obj % Font Helvetica-Oblique << /BaseFont /Helvetica-Oblique /Encoding /WinAnsiEncoding @@ -1671,11 +1709,9 @@ endobj /Type /Font >> endobj % 'Page3': class PDFPage -95 0 obj +97 0 obj % Page dictionary -<< /Annots [ 80 0 R - 81 0 R - 82 0 R +<< /Annots [ 82 0 R 83 0 R 84 0 R 85 0 R @@ -1686,13 +1722,15 @@ endobj 90 0 R 91 0 R 92 0 R - 93 0 R ] - /Contents 343 0 R + 93 0 R + 94 0 R + 95 0 R ] + /Contents 348 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -1703,8 +1741,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER88': class PDFDictionary -96 0 obj +% 'Annot.NUMBER90': class PDFDictionary +98 0 obj << /A << /S /URI /Type /Action /URI (http://docs.python.org/library/getopt.html) >> @@ -1718,8 +1756,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER89': class PDFDictionary -97 0 obj +% 'Annot.NUMBER91': class PDFDictionary +99 0 obj << /A << /S /URI /Type /Action /URI (http://docs.python.org/library/optparse.html) >> @@ -1733,8 +1771,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER90': class PDFDictionary -98 0 obj +% 'Annot.NUMBER92': class PDFDictionary +100 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -1748,8 +1786,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER91': class PDFDictionary -99 0 obj +% 'Annot.NUMBER93': class PDFDictionary +101 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -1763,8 +1801,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER92': class PDFDictionary -100 0 obj +% 'Annot.NUMBER94': class PDFDictionary +102 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -1778,8 +1816,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER93': class PDFDictionary -101 0 obj +% 'Annot.NUMBER95': class PDFDictionary +103 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -1793,8 +1831,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER94': class PDFDictionary -102 0 obj +% 'Annot.NUMBER96': class PDFDictionary +104 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -1808,8 +1846,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER95': class PDFDictionary -103 0 obj +% 'Annot.NUMBER97': class PDFDictionary +105 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -1823,8 +1861,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER96': class PDFDictionary -104 0 obj +% 'Annot.NUMBER98': class PDFDictionary +106 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -1839,23 +1877,23 @@ endobj /Type /Annot >> endobj % 'Page4': class PDFPage -105 0 obj +107 0 obj % Page dictionary -<< /Annots [ 96 0 R - 97 0 R - 98 0 R +<< /Annots [ 98 0 R 99 0 R 100 0 R 101 0 R 102 0 R 103 0 R - 104 0 R ] - /Contents 344 0 R + 104 0 R + 105 0 R + 106 0 R ] + /Contents 349 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -1866,8 +1904,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER97': class PDFDictionary -106 0 obj +% 'Annot.NUMBER99': class PDFDictionary +108 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -1881,8 +1919,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER98': class PDFDictionary -107 0 obj +% 'Annot.NUMBER100': class PDFDictionary +109 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -1896,8 +1934,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER99': class PDFDictionary -108 0 obj +% 'Annot.NUMBER101': class PDFDictionary +110 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -1912,17 +1950,17 @@ endobj /Type /Annot >> endobj % 'Page5': class PDFPage -109 0 obj +111 0 obj % Page dictionary -<< /Annots [ 106 0 R - 107 0 R - 108 0 R ] - /Contents 345 0 R +<< /Annots [ 108 0 R + 109 0 R + 110 0 R ] + /Contents 350 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -1933,8 +1971,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER100': class PDFDictionary -110 0 obj +% 'Annot.NUMBER102': class PDFDictionary +112 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -1948,8 +1986,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER101': class PDFDictionary -111 0 obj +% 'Annot.NUMBER103': class PDFDictionary +113 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -1963,8 +2001,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER102': class PDFDictionary -112 0 obj +% 'Annot.NUMBER104': class PDFDictionary +114 0 obj << /A << /S /URI /Type /Action /URI (http://code.activestate.com/recipes/278844-parsing-the-command-line/) >> @@ -1979,17 +2017,17 @@ endobj /Type /Annot >> endobj % 'Page6': class PDFPage -113 0 obj +115 0 obj % Page dictionary -<< /Annots [ 110 0 R - 111 0 R - 112 0 R ] - /Contents 346 0 R +<< /Annots [ 112 0 R + 113 0 R + 114 0 R ] + /Contents 351 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -2000,8 +2038,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER103': class PDFDictionary -114 0 obj +% 'Annot.NUMBER105': class PDFDictionary +116 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -2015,8 +2053,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER104': class PDFDictionary -115 0 obj +% 'Annot.NUMBER106': class PDFDictionary +117 0 obj << /A << /S /URI /Type /Action /URI (http://code.activestate.com/recipes/278844-parsing-the-command-line/) >> @@ -2030,8 +2068,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER105': class PDFDictionary -116 0 obj +% 'Annot.NUMBER107': class PDFDictionary +118 0 obj << /A << /S /URI /Type /Action /URI (http://code.activestate.com/recipes/278844-parsing-the-command-line/) >> @@ -2045,8 +2083,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER106': class PDFDictionary -117 0 obj +% 'Annot.NUMBER108': class PDFDictionary +119 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -2060,8 +2098,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER107': class PDFDictionary -118 0 obj +% 'Annot.NUMBER109': class PDFDictionary +120 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -2076,19 +2114,19 @@ endobj /Type /Annot >> endobj % 'Page7': class PDFPage -119 0 obj +121 0 obj % Page dictionary -<< /Annots [ 114 0 R - 115 0 R - 116 0 R +<< /Annots [ 116 0 R 117 0 R - 118 0 R ] - /Contents 347 0 R + 118 0 R + 119 0 R + 120 0 R ] + /Contents 352 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -2100,14 +2138,14 @@ endobj /Type /Page >> endobj % 'Page8': class PDFPage -120 0 obj +122 0 obj % Page dictionary -<< /Contents 348 0 R +<< /Contents 353 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -2118,8 +2156,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER108': class PDFDictionary -121 0 obj +% 'Annot.NUMBER110': class PDFDictionary +123 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -2133,8 +2171,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER109': class PDFDictionary -122 0 obj +% 'Annot.NUMBER111': class PDFDictionary +124 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -2149,16 +2187,16 @@ endobj /Type /Annot >> endobj % 'Page9': class PDFPage -123 0 obj +125 0 obj % Page dictionary -<< /Annots [ 121 0 R - 122 0 R ] - /Contents 349 0 R +<< /Annots [ 123 0 R + 124 0 R ] + /Contents 354 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -2169,8 +2207,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER110': class PDFDictionary -124 0 obj +% 'Annot.NUMBER112': class PDFDictionary +126 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -2184,8 +2222,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER111': class PDFDictionary -125 0 obj +% 'Annot.NUMBER113': class PDFDictionary +127 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -2199,8 +2237,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER112': class PDFDictionary -126 0 obj +% 'Annot.NUMBER114': class PDFDictionary +128 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -2214,8 +2252,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER113': class PDFDictionary -127 0 obj +% 'Annot.NUMBER115': class PDFDictionary +129 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -2229,8 +2267,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER114': class PDFDictionary -128 0 obj +% 'Annot.NUMBER116': class PDFDictionary +130 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -2244,8 +2282,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER115': class PDFDictionary -129 0 obj +% 'Annot.NUMBER117': class PDFDictionary +131 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -2259,8 +2297,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER116': class PDFDictionary -130 0 obj +% 'Annot.NUMBER118': class PDFDictionary +132 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -2275,21 +2313,21 @@ endobj /Type /Annot >> endobj % 'Page10': class PDFPage -131 0 obj +133 0 obj % Page dictionary -<< /Annots [ 124 0 R - 125 0 R - 126 0 R +<< /Annots [ 126 0 R 127 0 R 128 0 R 129 0 R - 130 0 R ] - /Contents 350 0 R + 130 0 R + 131 0 R + 132 0 R ] + /Contents 355 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -2301,14 +2339,14 @@ endobj /Type /Page >> endobj % 'Page11': class PDFPage -132 0 obj +134 0 obj % Page dictionary -<< /Contents 351 0 R +<< /Contents 356 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -2319,8 +2357,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER117': class PDFDictionary -133 0 obj +% 'Annot.NUMBER119': class PDFDictionary +135 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -2334,8 +2372,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER118': class PDFDictionary -134 0 obj +% 'Annot.NUMBER120': class PDFDictionary +136 0 obj << /A << /S /URI /Type /Action /URI (http://www.sqlalchemy.org/) >> @@ -2349,8 +2387,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER119': class PDFDictionary -135 0 obj +% 'Annot.NUMBER121': class PDFDictionary +137 0 obj << /A << /S /URI /Type /Action /URI (http://www.sqlalchemy.org/docs/reference/ext/sqlsoup.html) >> @@ -2365,17 +2403,17 @@ endobj /Type /Annot >> endobj % 'Page12': class PDFPage -136 0 obj +138 0 obj % Page dictionary -<< /Annots [ 133 0 R - 134 0 R - 135 0 R ] - /Contents 352 0 R +<< /Annots [ 135 0 R + 136 0 R + 137 0 R ] + /Contents 357 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -2386,8 +2424,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER120': class PDFDictionary -137 0 obj +% 'Annot.NUMBER122': class PDFDictionary +139 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -2401,8 +2439,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER121': class PDFDictionary -138 0 obj +% 'Annot.NUMBER123': class PDFDictionary +140 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -2417,16 +2455,16 @@ endobj /Type /Annot >> endobj % 'Page13': class PDFPage -139 0 obj +141 0 obj % Page dictionary -<< /Annots [ 137 0 R - 138 0 R ] - /Contents 353 0 R +<< /Annots [ 139 0 R + 140 0 R ] + /Contents 358 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -2437,8 +2475,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER122': class PDFDictionary -140 0 obj +% 'Annot.NUMBER124': class PDFDictionary +142 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -2453,15 +2491,15 @@ endobj /Type /Annot >> endobj % 'Page14': class PDFPage -141 0 obj +143 0 obj % Page dictionary -<< /Annots [ 140 0 R ] - /Contents 354 0 R +<< /Annots [ 142 0 R ] + /Contents 359 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -2472,8 +2510,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER123': class PDFDictionary -142 0 obj +% 'Annot.NUMBER125': class PDFDictionary +144 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -2487,8 +2525,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER124': class PDFDictionary -143 0 obj +% 'Annot.NUMBER126': class PDFDictionary +145 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -2503,16 +2541,16 @@ endobj /Type /Annot >> endobj % 'Page15': class PDFPage -144 0 obj +146 0 obj % Page dictionary -<< /Annots [ 142 0 R - 143 0 R ] - /Contents 355 0 R +<< /Annots [ 144 0 R + 145 0 R ] + /Contents 360 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -2523,8 +2561,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER125': class PDFDictionary -145 0 obj +% 'Annot.NUMBER127': class PDFDictionary +147 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -2538,8 +2576,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER126': class PDFDictionary -146 0 obj +% 'Annot.NUMBER128': class PDFDictionary +148 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -2553,8 +2591,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER127': class PDFDictionary -147 0 obj +% 'Annot.NUMBER129': class PDFDictionary +149 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -2568,8 +2606,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER128': class PDFDictionary -148 0 obj +% 'Annot.NUMBER130': class PDFDictionary +150 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -2583,8 +2621,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER129': class PDFDictionary -149 0 obj +% 'Annot.NUMBER131': class PDFDictionary +151 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -2598,8 +2636,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER130': class PDFDictionary -150 0 obj +% 'Annot.NUMBER132': class PDFDictionary +152 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -2613,8 +2651,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER131': class PDFDictionary -151 0 obj +% 'Annot.NUMBER133': class PDFDictionary +153 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -2628,8 +2666,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER132': class PDFDictionary -152 0 obj +% 'Annot.NUMBER134': class PDFDictionary +154 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -2643,8 +2681,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER133': class PDFDictionary -153 0 obj +% 'Annot.NUMBER135': class PDFDictionary +155 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -2658,8 +2696,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER134': class PDFDictionary -154 0 obj +% 'Annot.NUMBER136': class PDFDictionary +156 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -2673,8 +2711,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER135': class PDFDictionary -155 0 obj +% 'Annot.NUMBER137': class PDFDictionary +157 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -2688,8 +2726,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER136': class PDFDictionary -156 0 obj +% 'Annot.NUMBER138': class PDFDictionary +158 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -2703,8 +2741,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER137': class PDFDictionary -157 0 obj +% 'Annot.NUMBER139': class PDFDictionary +159 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -2718,8 +2756,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER138': class PDFDictionary -158 0 obj +% 'Annot.NUMBER140': class PDFDictionary +160 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -2733,8 +2771,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER139': class PDFDictionary -159 0 obj +% 'Annot.NUMBER141': class PDFDictionary +161 0 obj << /A << /S /URI /Type /Action /URI (file:///home/msimionato/Dropbox/md/gcodedev/plac/doc/in-writing) >> @@ -2749,11 +2787,9 @@ endobj /Type /Annot >> endobj % 'Page16': class PDFPage -160 0 obj +162 0 obj % Page dictionary -<< /Annots [ 145 0 R - 146 0 R - 147 0 R +<< /Annots [ 147 0 R 148 0 R 149 0 R 150 0 R @@ -2765,13 +2801,15 @@ endobj 156 0 R 157 0 R 158 0 R - 159 0 R ] - /Contents 356 0 R + 159 0 R + 160 0 R + 161 0 R ] + /Contents 361 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -2782,8 +2820,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER140': class PDFDictionary -161 0 obj +% 'Annot.NUMBER142': class PDFDictionary +163 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -2797,8 +2835,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER141': class PDFDictionary -162 0 obj +% 'Annot.NUMBER143': class PDFDictionary +164 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -2812,8 +2850,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER142': class PDFDictionary -163 0 obj +% 'Annot.NUMBER144': class PDFDictionary +165 0 obj << /A << /S /URI /Type /Action /URI (file:///home/msimionato/Dropbox/md/gcodedev/plac/doc/in-writing) >> @@ -2827,8 +2865,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER143': class PDFDictionary -164 0 obj +% 'Annot.NUMBER145': class PDFDictionary +166 0 obj << /A << /S /URI /Type /Action /URI (file:///home/msimionato/Dropbox/md/gcodedev/plac/doc/in-writing) >> @@ -2842,8 +2880,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER144': class PDFDictionary -165 0 obj +% 'Annot.NUMBER146': class PDFDictionary +167 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -2857,8 +2895,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER145': class PDFDictionary -166 0 obj +% 'Annot.NUMBER147': class PDFDictionary +168 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -2872,8 +2910,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER146': class PDFDictionary -167 0 obj +% 'Annot.NUMBER148': class PDFDictionary +169 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com/svn/tags/r11/doc/other-utilities.html?highlight=filetype#FileType) >> @@ -2887,8 +2925,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER147': class PDFDictionary -168 0 obj +% 'Annot.NUMBER149': class PDFDictionary +170 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -2902,8 +2940,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER148': class PDFDictionary -169 0 obj +% 'Annot.NUMBER150': class PDFDictionary +171 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com/svn/tags/r11/doc/ArgumentParser.html) >> @@ -2917,8 +2955,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER149': class PDFDictionary -170 0 obj +% 'Annot.NUMBER151': class PDFDictionary +172 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -2932,8 +2970,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER150': class PDFDictionary -171 0 obj +% 'Annot.NUMBER152': class PDFDictionary +173 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -2947,8 +2985,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER151': class PDFDictionary -172 0 obj +% 'Annot.NUMBER153': class PDFDictionary +174 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -2963,11 +3001,9 @@ endobj /Type /Annot >> endobj % 'Page17': class PDFPage -173 0 obj +175 0 obj % Page dictionary -<< /Annots [ 161 0 R - 162 0 R - 163 0 R +<< /Annots [ 163 0 R 164 0 R 165 0 R 166 0 R @@ -2976,13 +3012,15 @@ endobj 169 0 R 170 0 R 171 0 R - 172 0 R ] - /Contents 357 0 R + 172 0 R + 173 0 R + 174 0 R ] + /Contents 362 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -2993,8 +3031,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER152': class PDFDictionary -174 0 obj +% 'Annot.NUMBER154': class PDFDictionary +176 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3008,8 +3046,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER153': class PDFDictionary -175 0 obj +% 'Annot.NUMBER155': class PDFDictionary +177 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3023,8 +3061,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER154': class PDFDictionary -176 0 obj +% 'Annot.NUMBER156': class PDFDictionary +178 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/opterator) >> @@ -3038,8 +3076,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER155': class PDFDictionary -177 0 obj +% 'Annot.NUMBER157': class PDFDictionary +179 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/CLIArgs) >> @@ -3053,8 +3091,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER156': class PDFDictionary -178 0 obj +% 'Annot.NUMBER158': class PDFDictionary +180 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/commandline) >> @@ -3068,8 +3106,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER157': class PDFDictionary -179 0 obj +% 'Annot.NUMBER159': class PDFDictionary +181 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -3083,8 +3121,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER158': class PDFDictionary -180 0 obj +% 'Annot.NUMBER160': class PDFDictionary +182 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3098,8 +3136,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER159': class PDFDictionary -181 0 obj +% 'Annot.NUMBER161': class PDFDictionary +183 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/Clap/0.7) >> @@ -3113,8 +3151,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER160': class PDFDictionary -182 0 obj +% 'Annot.NUMBER162': class PDFDictionary +184 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3128,8 +3166,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER161': class PDFDictionary -183 0 obj +% 'Annot.NUMBER163': class PDFDictionary +185 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/Clap/0.7) >> @@ -3143,8 +3181,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER162': class PDFDictionary -184 0 obj +% 'Annot.NUMBER164': class PDFDictionary +186 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3158,8 +3196,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER163': class PDFDictionary -185 0 obj +% 'Annot.NUMBER165': class PDFDictionary +187 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3173,8 +3211,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER164': class PDFDictionary -186 0 obj +% 'Annot.NUMBER166': class PDFDictionary +188 0 obj << /A << /S /URI /Type /Action /URI (http://docs.python.org/library/cmd.html) >> @@ -3188,8 +3226,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER165': class PDFDictionary -187 0 obj +% 'Annot.NUMBER167': class PDFDictionary +189 0 obj << /A << /S /URI /Type /Action /URI (http://packages.python.org/cmd2/) >> @@ -3203,8 +3241,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER166': class PDFDictionary -188 0 obj +% 'Annot.NUMBER168': class PDFDictionary +190 0 obj << /A << /S /URI /Type /Action /URI (http://packages.python.org/cmd2/) >> @@ -3218,8 +3256,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER167': class PDFDictionary -189 0 obj +% 'Annot.NUMBER169': class PDFDictionary +191 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3233,8 +3271,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER168': class PDFDictionary -190 0 obj +% 'Annot.NUMBER170': class PDFDictionary +192 0 obj << /A << /S /URI /Type /Action /URI (https://github.com/pulp/marrow.script) >> @@ -3248,8 +3286,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER169': class PDFDictionary -191 0 obj +% 'Annot.NUMBER171': class PDFDictionary +193 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3263,8 +3301,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER170': class PDFDictionary -192 0 obj +% 'Annot.NUMBER172': class PDFDictionary +194 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -3278,8 +3316,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER171': class PDFDictionary -193 0 obj +% 'Annot.NUMBER173': class PDFDictionary +195 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3293,8 +3331,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER172': class PDFDictionary -194 0 obj +% 'Annot.NUMBER174': class PDFDictionary +196 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -3308,8 +3346,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER173': class PDFDictionary -195 0 obj +% 'Annot.NUMBER175': class PDFDictionary +197 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -3323,8 +3361,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER174': class PDFDictionary -196 0 obj +% 'Annot.NUMBER176': class PDFDictionary +198 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3338,8 +3376,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER175': class PDFDictionary -197 0 obj +% 'Annot.NUMBER177': class PDFDictionary +199 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3353,8 +3391,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER176': class PDFDictionary -198 0 obj +% 'Annot.NUMBER178': class PDFDictionary +200 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3368,8 +3406,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER177': class PDFDictionary -199 0 obj +% 'Annot.NUMBER179': class PDFDictionary +201 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3383,8 +3421,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER178': class PDFDictionary -200 0 obj +% 'Annot.NUMBER180': class PDFDictionary +202 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3398,8 +3436,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER179': class PDFDictionary -201 0 obj +% 'Annot.NUMBER181': class PDFDictionary +203 0 obj << /A << /S /URI /Type /Action /URI (file:///home/msimionato/Dropbox/md/gcodedev/plac/doc/in-writing) >> @@ -3413,8 +3451,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER180': class PDFDictionary -202 0 obj +% 'Annot.NUMBER182': class PDFDictionary +204 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3428,8 +3466,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER181': class PDFDictionary -203 0 obj +% 'Annot.NUMBER183': class PDFDictionary +205 0 obj << /A << /S /URI /Type /Action /URI (http://code.activestate.com/recipes/278844-parsing-the-command-line/) >> @@ -3443,8 +3481,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER182': class PDFDictionary -204 0 obj +% 'Annot.NUMBER184': class PDFDictionary +206 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3458,8 +3496,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER183': class PDFDictionary -205 0 obj +% 'Annot.NUMBER185': class PDFDictionary +207 0 obj << /A << /S /URI /Type /Action /URI (http://docs.python.org/library/optparse.html?highlight=optionparser#optparse.OptionParser) >> @@ -3473,8 +3511,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER184': class PDFDictionary -206 0 obj +% 'Annot.NUMBER186': class PDFDictionary +208 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -3488,8 +3526,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER185': class PDFDictionary -207 0 obj +% 'Annot.NUMBER187': class PDFDictionary +209 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -3503,8 +3541,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER186': class PDFDictionary -208 0 obj +% 'Annot.NUMBER188': class PDFDictionary +210 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com/svn/tags/r11/doc/ArgumentParser.html) >> @@ -3518,8 +3556,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER187': class PDFDictionary -209 0 obj +% 'Annot.NUMBER189': class PDFDictionary +211 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -3533,8 +3571,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER188': class PDFDictionary -210 0 obj +% 'Annot.NUMBER190': class PDFDictionary +212 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -3549,11 +3587,9 @@ endobj /Type /Annot >> endobj % 'Page18': class PDFPage -211 0 obj +213 0 obj % Page dictionary -<< /Annots [ 174 0 R - 175 0 R - 176 0 R +<< /Annots [ 176 0 R 177 0 R 178 0 R 179 0 R @@ -3587,13 +3623,15 @@ endobj 207 0 R 208 0 R 209 0 R - 210 0 R ] - /Contents 358 0 R + 210 0 R + 211 0 R + 212 0 R ] + /Contents 363 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -3604,8 +3642,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER189': class PDFDictionary -212 0 obj +% 'Annot.NUMBER191': class PDFDictionary +214 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/Clap/0.7) >> @@ -3619,8 +3657,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER190': class PDFDictionary -213 0 obj +% 'Annot.NUMBER192': class PDFDictionary +215 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3634,8 +3672,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER191': class PDFDictionary -214 0 obj +% 'Annot.NUMBER193': class PDFDictionary +216 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3649,8 +3687,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER192': class PDFDictionary -215 0 obj +% 'Annot.NUMBER194': class PDFDictionary +217 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3664,8 +3702,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER193': class PDFDictionary -216 0 obj +% 'Annot.NUMBER195': class PDFDictionary +218 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3679,8 +3717,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER194': class PDFDictionary -217 0 obj +% 'Annot.NUMBER196': class PDFDictionary +219 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3694,8 +3732,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER195': class PDFDictionary -218 0 obj +% 'Annot.NUMBER197': class PDFDictionary +220 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3709,8 +3747,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER196': class PDFDictionary -219 0 obj +% 'Annot.NUMBER198': class PDFDictionary +221 0 obj << /A << /S /URI /Type /Action /URI (http://twill.idyll.org/) >> @@ -3724,8 +3762,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER197': class PDFDictionary -220 0 obj +% 'Annot.NUMBER199': class PDFDictionary +222 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3739,8 +3777,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER198': class PDFDictionary -221 0 obj +% 'Annot.NUMBER200': class PDFDictionary +223 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3754,8 +3792,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER199': class PDFDictionary -222 0 obj +% 'Annot.NUMBER201': class PDFDictionary +224 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3769,8 +3807,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER200': class PDFDictionary -223 0 obj +% 'Annot.NUMBER202': class PDFDictionary +225 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3784,8 +3822,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER201': class PDFDictionary -224 0 obj +% 'Annot.NUMBER203': class PDFDictionary +226 0 obj << /A << /S /URI /Type /Action /URI (http://micheles.googlecode.com/hg/plac/doc/plac.html) >> @@ -3800,11 +3838,9 @@ endobj /Type /Annot >> endobj % 'Page19': class PDFPage -225 0 obj +227 0 obj % Page dictionary -<< /Annots [ 212 0 R - 213 0 R - 214 0 R +<< /Annots [ 214 0 R 215 0 R 216 0 R 217 0 R @@ -3814,13 +3850,15 @@ endobj 221 0 R 222 0 R 223 0 R - 224 0 R ] - /Contents 359 0 R + 224 0 R + 225 0 R + 226 0 R ] + /Contents 364 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -3832,14 +3870,14 @@ endobj /Type /Page >> endobj % 'Page20': class PDFPage -226 0 obj +228 0 obj % Page dictionary -<< /Contents 360 0 R +<< /Contents 365 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -3850,8 +3888,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER202': class PDFDictionary -227 0 obj +% 'Annot.NUMBER204': class PDFDictionary +229 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3866,15 +3904,15 @@ endobj /Type /Annot >> endobj % 'Page21': class PDFPage -228 0 obj +230 0 obj % Page dictionary -<< /Annots [ 227 0 R ] - /Contents 361 0 R +<< /Annots [ 229 0 R ] + /Contents 366 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -3885,8 +3923,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER203': class PDFDictionary -229 0 obj +% 'Annot.NUMBER205': class PDFDictionary +231 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3900,8 +3938,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER204': class PDFDictionary -230 0 obj +% 'Annot.NUMBER206': class PDFDictionary +232 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3916,16 +3954,16 @@ endobj /Type /Annot >> endobj % 'Page22': class PDFPage -231 0 obj +233 0 obj % Page dictionary -<< /Annots [ 229 0 R - 230 0 R ] - /Contents 362 0 R +<< /Annots [ 231 0 R + 232 0 R ] + /Contents 367 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -3936,8 +3974,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER205': class PDFDictionary -232 0 obj +% 'Annot.NUMBER207': class PDFDictionary +234 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3951,8 +3989,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER206': class PDFDictionary -233 0 obj +% 'Annot.NUMBER208': class PDFDictionary +235 0 obj << /A << /S /URI /Type /Action /URI (http://docs.python.org/library/shlex.html) >> @@ -3966,8 +4004,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER207': class PDFDictionary -234 0 obj +% 'Annot.NUMBER209': class PDFDictionary +236 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -3981,8 +4019,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER208': class PDFDictionary -235 0 obj +% 'Annot.NUMBER210': class PDFDictionary +237 0 obj << /A << /S /URI /Type /Action /URI (http://docs.python.org/library/shlex.html) >> @@ -3996,8 +4034,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER209': class PDFDictionary -236 0 obj +% 'Annot.NUMBER211': class PDFDictionary +238 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4011,8 +4049,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER210': class PDFDictionary -237 0 obj +% 'Annot.NUMBER212': class PDFDictionary +239 0 obj << /A << /S /URI /Type /Action /URI (http://docs.python.org/library/shlex.html) >> @@ -4026,8 +4064,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER211': class PDFDictionary -238 0 obj +% 'Annot.NUMBER213': class PDFDictionary +240 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4041,8 +4079,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER212': class PDFDictionary -239 0 obj +% 'Annot.NUMBER214': class PDFDictionary +241 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4056,8 +4094,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER213': class PDFDictionary -240 0 obj +% 'Annot.NUMBER215': class PDFDictionary +242 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4071,8 +4109,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER214': class PDFDictionary -241 0 obj +% 'Annot.NUMBER216': class PDFDictionary +243 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4087,24 +4125,24 @@ endobj /Type /Annot >> endobj % 'Page23': class PDFPage -242 0 obj +244 0 obj % Page dictionary -<< /Annots [ 232 0 R - 233 0 R - 234 0 R +<< /Annots [ 234 0 R 235 0 R 236 0 R 237 0 R 238 0 R 239 0 R 240 0 R - 241 0 R ] - /Contents 363 0 R + 241 0 R + 242 0 R + 243 0 R ] + /Contents 368 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -4115,8 +4153,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER215': class PDFDictionary -243 0 obj +% 'Annot.NUMBER217': class PDFDictionary +245 0 obj << /A << /S /URI /Type /Action /URI (http://micheles.googlecode.com/hg/plac/doc/plac.html) >> @@ -4130,8 +4168,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER216': class PDFDictionary -244 0 obj +% 'Annot.NUMBER218': class PDFDictionary +246 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4145,8 +4183,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER217': class PDFDictionary -245 0 obj +% 'Annot.NUMBER219': class PDFDictionary +247 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4160,8 +4198,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER218': class PDFDictionary -246 0 obj +% 'Annot.NUMBER220': class PDFDictionary +248 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4176,18 +4214,18 @@ endobj /Type /Annot >> endobj % 'Page24': class PDFPage -247 0 obj +249 0 obj % Page dictionary -<< /Annots [ 243 0 R - 244 0 R - 245 0 R - 246 0 R ] - /Contents 364 0 R +<< /Annots [ 245 0 R + 246 0 R + 247 0 R + 248 0 R ] + /Contents 369 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -4198,8 +4236,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER219': class PDFDictionary -248 0 obj +% 'Annot.NUMBER221': class PDFDictionary +250 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4213,8 +4251,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER220': class PDFDictionary -249 0 obj +% 'Annot.NUMBER222': class PDFDictionary +251 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4228,8 +4266,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER221': class PDFDictionary -250 0 obj +% 'Annot.NUMBER223': class PDFDictionary +252 0 obj << /A << /S /URI /Type /Action /URI (http://docs.python.org/library/cmd.html) >> @@ -4244,17 +4282,17 @@ endobj /Type /Annot >> endobj % 'Page25': class PDFPage -251 0 obj +253 0 obj % Page dictionary -<< /Annots [ 248 0 R - 249 0 R - 250 0 R ] - /Contents 365 0 R +<< /Annots [ 250 0 R + 251 0 R + 252 0 R ] + /Contents 370 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -4266,14 +4304,14 @@ endobj /Type /Page >> endobj % 'Page26': class PDFPage -252 0 obj +254 0 obj % Page dictionary -<< /Contents 366 0 R +<< /Contents 371 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -4285,14 +4323,14 @@ endobj /Type /Page >> endobj % 'Page27': class PDFPage -253 0 obj +255 0 obj % Page dictionary -<< /Contents 367 0 R +<< /Contents 372 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -4303,8 +4341,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER222': class PDFDictionary -254 0 obj +% 'Annot.NUMBER224': class PDFDictionary +256 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4318,8 +4356,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER223': class PDFDictionary -255 0 obj +% 'Annot.NUMBER225': class PDFDictionary +257 0 obj << /A << /S /URI /Type /Action /URI (http://freshmeat.net/projects/rlwrap/) >> @@ -4333,8 +4371,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER224': class PDFDictionary -256 0 obj +% 'Annot.NUMBER226': class PDFDictionary +258 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4348,8 +4386,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER225': class PDFDictionary -257 0 obj +% 'Annot.NUMBER227': class PDFDictionary +259 0 obj << /A << /S /URI /Type /Action /URI (http://ipython.scipy.org/moin/PyReadline/Intro) >> @@ -4364,18 +4402,18 @@ endobj /Type /Annot >> endobj % 'Page28': class PDFPage -258 0 obj +260 0 obj % Page dictionary -<< /Annots [ 254 0 R - 255 0 R - 256 0 R - 257 0 R ] - /Contents 368 0 R +<< /Annots [ 256 0 R + 257 0 R + 258 0 R + 259 0 R ] + /Contents 373 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -4386,8 +4424,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER226': class PDFDictionary -259 0 obj +% 'Annot.NUMBER228': class PDFDictionary +261 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4401,8 +4439,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER227': class PDFDictionary -260 0 obj +% 'Annot.NUMBER229': class PDFDictionary +262 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4416,8 +4454,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER228': class PDFDictionary -261 0 obj +% 'Annot.NUMBER230': class PDFDictionary +263 0 obj << /A << /S /URI /Type /Action /URI (http://docs.python.org/library/cmd.html) >> @@ -4431,8 +4469,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER229': class PDFDictionary -262 0 obj +% 'Annot.NUMBER231': class PDFDictionary +264 0 obj << /A << /S /URI /Type /Action /URI (http://docs.python.org/library/cmd.html) >> @@ -4446,8 +4484,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER230': class PDFDictionary -263 0 obj +% 'Annot.NUMBER232': class PDFDictionary +265 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -4461,8 +4499,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER231': class PDFDictionary -264 0 obj +% 'Annot.NUMBER233': class PDFDictionary +266 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4476,8 +4514,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER232': class PDFDictionary -265 0 obj +% 'Annot.NUMBER234': class PDFDictionary +267 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -4491,8 +4529,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER233': class PDFDictionary -266 0 obj +% 'Annot.NUMBER235': class PDFDictionary +268 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4506,8 +4544,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER234': class PDFDictionary -267 0 obj +% 'Annot.NUMBER236': class PDFDictionary +269 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4521,8 +4559,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER235': class PDFDictionary -268 0 obj +% 'Annot.NUMBER237': class PDFDictionary +270 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4536,8 +4574,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER236': class PDFDictionary -269 0 obj +% 'Annot.NUMBER238': class PDFDictionary +271 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4551,8 +4589,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER237': class PDFDictionary -270 0 obj +% 'Annot.NUMBER239': class PDFDictionary +272 0 obj << /A << /S /URI /Type /Action /URI (http://docs.python.org/distutils/) >> @@ -4567,11 +4605,9 @@ endobj /Type /Annot >> endobj % 'Page29': class PDFPage -271 0 obj +273 0 obj % Page dictionary -<< /Annots [ 259 0 R - 260 0 R - 261 0 R +<< /Annots [ 261 0 R 262 0 R 263 0 R 264 0 R @@ -4580,13 +4616,15 @@ endobj 267 0 R 268 0 R 269 0 R - 270 0 R ] - /Contents 369 0 R + 270 0 R + 271 0 R + 272 0 R ] + /Contents 374 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -4598,14 +4636,14 @@ endobj /Type /Page >> endobj % 'Page30': class PDFPage -272 0 obj +274 0 obj % Page dictionary -<< /Contents 370 0 R +<< /Contents 375 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -4616,8 +4654,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER238': class PDFDictionary -273 0 obj +% 'Annot.NUMBER240': class PDFDictionary +275 0 obj << /A << /S /URI /Type /Action /URI (http://argparse.googlecode.com) >> @@ -4631,8 +4669,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER239': class PDFDictionary -274 0 obj +% 'Annot.NUMBER241': class PDFDictionary +276 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4647,16 +4685,16 @@ endobj /Type /Annot >> endobj % 'Page31': class PDFPage -275 0 obj +277 0 obj % Page dictionary -<< /Annots [ 273 0 R - 274 0 R ] - /Contents 371 0 R +<< /Annots [ 275 0 R + 276 0 R ] + /Contents 376 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -4668,14 +4706,14 @@ endobj /Type /Page >> endobj % 'Page32': class PDFPage -276 0 obj +278 0 obj % Page dictionary -<< /Contents 372 0 R +<< /Contents 377 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -4686,8 +4724,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER240': class PDFDictionary -277 0 obj +% 'Annot.NUMBER242': class PDFDictionary +279 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4702,15 +4740,15 @@ endobj /Type /Annot >> endobj % 'Page33': class PDFPage -278 0 obj +280 0 obj % Page dictionary -<< /Annots [ 277 0 R ] - /Contents 373 0 R +<< /Annots [ 279 0 R ] + /Contents 378 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -4721,8 +4759,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER241': class PDFDictionary -279 0 obj +% 'Annot.NUMBER243': class PDFDictionary +281 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4736,8 +4774,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER242': class PDFDictionary -280 0 obj +% 'Annot.NUMBER244': class PDFDictionary +282 0 obj << /A << /S /URI /Type /Action /URI (http://docs.python.org/library/multiprocessing.html) >> @@ -4751,8 +4789,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER243': class PDFDictionary -281 0 obj +% 'Annot.NUMBER245': class PDFDictionary +283 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4767,17 +4805,17 @@ endobj /Type /Annot >> endobj % 'Page34': class PDFPage -282 0 obj +284 0 obj % Page dictionary -<< /Annots [ 279 0 R - 280 0 R - 281 0 R ] - /Contents 374 0 R +<< /Annots [ 281 0 R + 282 0 R + 283 0 R ] + /Contents 379 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -4788,8 +4826,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER244': class PDFDictionary -283 0 obj +% 'Annot.NUMBER246': class PDFDictionary +285 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4803,8 +4841,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER245': class PDFDictionary -284 0 obj +% 'Annot.NUMBER247': class PDFDictionary +286 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4819,16 +4857,16 @@ endobj /Type /Annot >> endobj % 'Page35': class PDFPage -285 0 obj +287 0 obj % Page dictionary -<< /Annots [ 283 0 R - 284 0 R ] - /Contents 375 0 R +<< /Annots [ 285 0 R + 286 0 R ] + /Contents 380 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -4840,14 +4878,14 @@ endobj /Type /Page >> endobj % 'Page36': class PDFPage -286 0 obj +288 0 obj % Page dictionary -<< /Contents 376 0 R +<< /Contents 381 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -4858,8 +4896,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER246': class PDFDictionary -287 0 obj +% 'Annot.NUMBER248': class PDFDictionary +289 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4873,8 +4911,8 @@ endobj /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER247': class PDFDictionary -288 0 obj +% 'Annot.NUMBER249': class PDFDictionary +290 0 obj << /A << /S /URI /Type /Action /URI (http://docs.python.org/library/multiprocessing.html) >> @@ -4889,16 +4927,16 @@ endobj /Type /Annot >> endobj % 'Page37': class PDFPage -289 0 obj +291 0 obj % Page dictionary -<< /Annots [ 287 0 R - 288 0 R ] - /Contents 377 0 R +<< /Annots [ 289 0 R + 290 0 R ] + /Contents 382 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -4909,8 +4947,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER248': class PDFDictionary -290 0 obj +% 'Annot.NUMBER250': class PDFDictionary +292 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -4925,15 +4963,15 @@ endobj /Type /Annot >> endobj % 'Page38': class PDFPage -291 0 obj +293 0 obj % Page dictionary -<< /Annots [ 290 0 R ] - /Contents 378 0 R +<< /Annots [ 292 0 R ] + /Contents 383 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -4944,31 +4982,47 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER249': class PDFDictionary -292 0 obj +% 'Annot.NUMBER251': class PDFDictionary +294 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> /Border [ 0 0 0 ] - /Rect [ 62.69291 + /Rect [ 176.9371 668.5736 - 84.98766 + 198.5507 680.5736 ] /Subtype /Link /Type /Annot >> endobj +% 'Annot.NUMBER252': class PDFDictionary +295 0 obj +<< /A << /S /URI + /Type /Action + /URI (http://pypi.python.org/pypi/plac) >> + /Border [ 0 + 0 + 0 ] + /Rect [ 62.69291 + 303.3736 + 84.98766 + 315.3736 ] + /Subtype /Link + /Type /Annot >> +endobj % 'Page39': class PDFPage -293 0 obj +296 0 obj % Page dictionary -<< /Annots [ 292 0 R ] - /Contents 379 0 R +<< /Annots [ 294 0 R + 295 0 R ] + /Contents 384 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -4980,14 +5034,14 @@ endobj /Type /Page >> endobj % 'Page40': class PDFPage -294 0 obj +297 0 obj % Page dictionary -<< /Contents 380 0 R +<< /Contents 385 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -4998,8 +5052,8 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER250': class PDFDictionary -295 0 obj +% 'Annot.NUMBER253': class PDFDictionary +298 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -5007,38 +5061,22 @@ endobj 0 0 ] /Rect [ 473.5049 - 666.5736 + 319.3736 494.7927 - 678.5736 ] - /Subtype /Link - /Type /Annot >> -endobj -% 'Annot.NUMBER251': class PDFDictionary -296 0 obj -<< /A << /S /URI - /Type /Action - /URI (http://pypi.python.org/pypi/plac) >> - /Border [ 0 - 0 - 0 ] - /Rect [ 172.4311 - 453.9659 - 194.7087 - 465.9659 ] + 331.3736 ] /Subtype /Link /Type /Annot >> endobj % 'Page41': class PDFPage -297 0 obj +299 0 obj % Page dictionary -<< /Annots [ 295 0 R - 296 0 R ] - /Contents 381 0 R +<< /Annots [ 298 0 R ] + /Contents 386 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -5049,8 +5087,23 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Annot.NUMBER252': class PDFDictionary -298 0 obj +% 'Annot.NUMBER254': class PDFDictionary +300 0 obj +<< /A << /S /URI + /Type /Action + /URI (http://pypi.python.org/pypi/plac) >> + /Border [ 0 + 0 + 0 ] + /Rect [ 172.4311 + 645.7736 + 194.7087 + 657.7736 ] + /Subtype /Link + /Type /Annot >> +endobj +% 'Annot.NUMBER255': class PDFDictionary +301 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -5058,14 +5111,35 @@ endobj 0 0 ] /Rect [ 91.57623 - 729.7736 + 259.3736 114.8995 - 741.7736 ] + 271.3736 ] /Subtype /Link /Type /Annot >> endobj -% 'Annot.NUMBER253': class PDFDictionary -299 0 obj +% 'Page42': class PDFPage +302 0 obj +% Page dictionary +<< /Annots [ 300 0 R + 301 0 R ] + /Contents 387 0 R + /MediaBox [ 0 + 0 + 595.2756 + 841.8898 ] + /Parent 345 0 R + /Resources << /Font 1 0 R + /ProcSet [ /PDF + /Text + /ImageB + /ImageC + /ImageI ] >> + /Rotate 0 + /Trans << >> + /Type /Page >> +endobj +% 'Annot.NUMBER256': class PDFDictionary +303 0 obj << /A << /S /URI /Type /Action /URI (http://pypi.python.org/pypi/plac) >> @@ -5073,23 +5147,22 @@ endobj 0 0 ] /Rect [ 106.6216 - 419.4272 + 617.4272 128.3202 - 431.4272 ] + 629.4272 ] /Subtype /Link /Type /Annot >> endobj -% 'Page42': class PDFPage -300 0 obj +% 'Page43': class PDFPage +304 0 obj % Page dictionary -<< /Annots [ 298 0 R - 299 0 R ] - /Contents 382 0 R +<< /Annots [ 303 0 R ] + /Contents 388 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -5100,15 +5173,15 @@ endobj /Trans << >> /Type /Page >> endobj -% 'Page43': class PDFPage -301 0 obj +% 'Page44': class PDFPage +305 0 obj % Page dictionary -<< /Contents 383 0 R +<< /Contents 389 0 R /MediaBox [ 0 0 595.2756 841.8898 ] - /Parent 340 0 R + /Parent 345 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text @@ -5119,503 +5192,516 @@ endobj /Trans << >> /Type /Page >> endobj -% 'R302': class PDFCatalog -302 0 obj +% 'R306': class PDFCatalog +306 0 obj % Document Root -<< /Outlines 304 0 R - /PageLabels 384 0 R +<< /Outlines 308 0 R + /PageLabels 390 0 R /PageMode /UseNone - /Pages 340 0 R + /Pages 345 0 R /Type /Catalog >> endobj -% 'R303': class PDFInfo -303 0 obj +% 'R307': class PDFInfo +307 0 obj << /Author () - /CreationDate (D:20110113123534-01'00') + /CreationDate (D:20110126134857-01'00') /Creator (\(unspecified\)) /Keywords () /Producer (ReportLab PDF Library - www.reportlab.com) /Subject (\(unspecified\)) /Title () >> endobj -% 'R304': class PDFOutlines -304 0 obj -<< /Count 37 - /First 305 0 R - /Last 320 0 R +% 'R308': class PDFOutlines +308 0 obj +<< /Count 38 + /First 309 0 R + /Last 324 0 R /Type /Outlines >> endobj % 'Outline.0': class OutlineEntryObject -305 0 obj +309 0 obj << /Count 14 /Dest [ 8 0 R /XYZ 62.69291 765.0236 0 ] - /First 306 0 R - /Last 319 0 R - /Next 320 0 R - /Parent 304 0 R + /First 310 0 R + /Last 323 0 R + /Next 324 0 R + /Parent 308 0 R /Title (Plac: Parsing the Command Line the Easy Way) >> endobj -% 'Outline.36.0': class OutlineEntryObject -306 0 obj -<< /Dest [ 95 0 R +% 'Outline.37.0': class OutlineEntryObject +310 0 obj +<< /Dest [ 97 0 R /XYZ 62.69291 765.0236 0 ] - /Next 307 0 R - /Parent 305 0 R + /Next 311 0 R + /Parent 309 0 R /Title (The importance of scaling down) >> endobj -% 'Outline.36.1': class OutlineEntryObject -307 0 obj -<< /Dest [ 95 0 R +% 'Outline.37.1': class OutlineEntryObject +311 0 obj +<< /Dest [ 97 0 R /XYZ 62.69291 411.0236 0 ] - /Next 308 0 R - /Parent 305 0 R - /Prev 306 0 R + /Next 312 0 R + /Parent 309 0 R + /Prev 310 0 R /Title (Scripts with required arguments) >> endobj -% 'Outline.36.2': class OutlineEntryObject -308 0 obj -<< /Dest [ 109 0 R +% 'Outline.37.2': class OutlineEntryObject +312 0 obj +<< /Dest [ 111 0 R /XYZ 62.69291 765.0236 0 ] - /Next 309 0 R - /Parent 305 0 R - /Prev 307 0 R + /Next 313 0 R + /Parent 309 0 R + /Prev 311 0 R /Title (Scripts with default arguments) >> endobj -% 'Outline.36.3': class OutlineEntryObject -309 0 obj -<< /Dest [ 119 0 R +% 'Outline.37.3': class OutlineEntryObject +313 0 obj +<< /Dest [ 121 0 R /XYZ 62.69291 741.0236 0 ] - /Next 310 0 R - /Parent 305 0 R - /Prev 308 0 R + /Next 314 0 R + /Parent 309 0 R + /Prev 312 0 R /Title (Scripts with options \(and smart options\)) >> endobj -% 'Outline.36.4': class OutlineEntryObject -310 0 obj -<< /Dest [ 123 0 R +% 'Outline.37.4': class OutlineEntryObject +314 0 obj +<< /Dest [ 125 0 R /XYZ 62.69291 765.0236 0 ] - /Next 311 0 R - /Parent 305 0 R - /Prev 309 0 R + /Next 315 0 R + /Parent 309 0 R + /Prev 313 0 R /Title (Scripts with flags) >> endobj -% 'Outline.36.5': class OutlineEntryObject -311 0 obj -<< /Dest [ 123 0 R +% 'Outline.37.5': class OutlineEntryObject +315 0 obj +<< /Dest [ 125 0 R /XYZ 62.69291 265.7299 0 ] - /Next 312 0 R - /Parent 305 0 R - /Prev 310 0 R + /Next 316 0 R + /Parent 309 0 R + /Prev 314 0 R /Title (plac for Python 2.X users) >> endobj -% 'Outline.36.6': class OutlineEntryObject -312 0 obj -<< /Dest [ 131 0 R +% 'Outline.37.6': class OutlineEntryObject +316 0 obj +<< /Dest [ 133 0 R /XYZ 62.69291 522.6236 0 ] - /Next 313 0 R - /Parent 305 0 R - /Prev 311 0 R + /Next 317 0 R + /Parent 309 0 R + /Prev 315 0 R /Title (More features) >> endobj -% 'Outline.36.7': class OutlineEntryObject -313 0 obj -<< /Dest [ 136 0 R +% 'Outline.37.7': class OutlineEntryObject +317 0 obj +<< /Dest [ 138 0 R /XYZ 62.69291 552.6236 0 ] - /Next 314 0 R - /Parent 305 0 R - /Prev 312 0 R + /Next 318 0 R + /Parent 309 0 R + /Prev 316 0 R /Title (A realistic example) >> endobj -% 'Outline.36.8': class OutlineEntryObject -314 0 obj -<< /Dest [ 139 0 R +% 'Outline.37.8': class OutlineEntryObject +318 0 obj +<< /Dest [ 141 0 R /XYZ 62.69291 513.8236 0 ] - /Next 315 0 R - /Parent 305 0 R - /Prev 313 0 R + /Next 319 0 R + /Parent 309 0 R + /Prev 317 0 R /Title (Keyword arguments) >> endobj -% 'Outline.36.9': class OutlineEntryObject -315 0 obj -<< /Dest [ 141 0 R +% 'Outline.37.9': class OutlineEntryObject +319 0 obj +<< /Dest [ 143 0 R /XYZ 62.69291 493.4236 0 ] - /Next 316 0 R - /Parent 305 0 R - /Prev 314 0 R + /Next 320 0 R + /Parent 309 0 R + /Prev 318 0 R /Title (Final example: a shelve interface) >> endobj -% 'Outline.36.10': class OutlineEntryObject -316 0 obj -<< /Dest [ 160 0 R +% 'Outline.37.10': class OutlineEntryObject +320 0 obj +<< /Dest [ 162 0 R /XYZ 62.69291 422.6236 0 ] - /Next 317 0 R - /Parent 305 0 R - /Prev 315 0 R + /Next 321 0 R + /Parent 309 0 R + /Prev 319 0 R /Title (plac vs argparse) >> endobj -% 'Outline.36.11': class OutlineEntryObject -317 0 obj -<< /Dest [ 211 0 R +% 'Outline.37.11': class OutlineEntryObject +321 0 obj +<< /Dest [ 213 0 R /XYZ 62.69291 765.0236 0 ] - /Next 318 0 R - /Parent 305 0 R - /Prev 316 0 R + /Next 322 0 R + /Parent 309 0 R + /Prev 320 0 R /Title (plac vs the rest of the world) >> endobj -% 'Outline.36.12': class OutlineEntryObject -318 0 obj -<< /Dest [ 211 0 R +% 'Outline.37.12': class OutlineEntryObject +322 0 obj +<< /Dest [ 213 0 R /XYZ 62.69291 495.0236 0 ] - /Next 319 0 R - /Parent 305 0 R - /Prev 317 0 R + /Next 323 0 R + /Parent 309 0 R + /Prev 321 0 R /Title (The future) >> endobj -% 'Outline.36.13': class OutlineEntryObject -319 0 obj -<< /Dest [ 211 0 R +% 'Outline.37.13': class OutlineEntryObject +323 0 obj +<< /Dest [ 213 0 R /XYZ 62.69291 291.0236 0 ] - /Parent 305 0 R - /Prev 318 0 R + /Parent 309 0 R + /Prev 322 0 R /Title (Trivia: the story behind the name) >> endobj % 'Outline.1': class OutlineEntryObject -320 0 obj -<< /Count 19 - /Dest [ 225 0 R +324 0 obj +<< /Count 20 + /Dest [ 227 0 R /XYZ 62.69291 681.0236 0 ] - /First 321 0 R - /Last 339 0 R - /Parent 304 0 R - /Prev 305 0 R + /First 325 0 R + /Last 344 0 R + /Parent 308 0 R + /Prev 309 0 R /Title (Advanced usages of plac) >> endobj -% 'Outline.37.0': class OutlineEntryObject -321 0 obj -<< /Dest [ 225 0 R +% 'Outline.38.0': class OutlineEntryObject +325 0 obj +<< /Dest [ 227 0 R /XYZ 62.69291 648.0236 0 ] - /Next 322 0 R - /Parent 320 0 R + /Next 326 0 R + /Parent 324 0 R /Title (Introduction) >> endobj -% 'Outline.37.1': class OutlineEntryObject -322 0 obj -<< /Dest [ 225 0 R +% 'Outline.38.1': class OutlineEntryObject +326 0 obj +<< /Dest [ 227 0 R /XYZ 62.69291 426.0236 0 ] - /Next 323 0 R - /Parent 320 0 R - /Prev 321 0 R + /Next 327 0 R + /Parent 324 0 R + /Prev 325 0 R /Title (From scripts to interactive applications) >> endobj -% 'Outline.37.2': class OutlineEntryObject -323 0 obj -<< /Dest [ 228 0 R +% 'Outline.38.2': class OutlineEntryObject +327 0 obj +<< /Dest [ 230 0 R /XYZ 62.69291 629.8236 0 ] - /Next 324 0 R - /Parent 320 0 R - /Prev 322 0 R + /Next 328 0 R + /Parent 324 0 R + /Prev 326 0 R /Title (Testing a plac application) >> endobj -% 'Outline.37.3': class OutlineEntryObject -324 0 obj -<< /Dest [ 231 0 R +% 'Outline.38.3': class OutlineEntryObject +328 0 obj +<< /Dest [ 233 0 R /XYZ 62.69291 609.0236 0 ] - /Next 325 0 R - /Parent 320 0 R - /Prev 323 0 R + /Next 329 0 R + /Parent 324 0 R + /Prev 327 0 R /Title (Plac easy tests) >> endobj -% 'Outline.37.4': class OutlineEntryObject -325 0 obj -<< /Dest [ 242 0 R +% 'Outline.38.4': class OutlineEntryObject +329 0 obj +<< /Dest [ 244 0 R /XYZ 62.69291 299.8485 0 ] - /Next 326 0 R - /Parent 320 0 R - /Prev 324 0 R + /Next 330 0 R + /Parent 324 0 R + /Prev 328 0 R /Title (Plac batch scripts) >> endobj -% 'Outline.37.5': class OutlineEntryObject -326 0 obj -<< /Dest [ 247 0 R +% 'Outline.38.5': class OutlineEntryObject +330 0 obj +<< /Dest [ 249 0 R /XYZ 62.69291 378.6236 0 ] - /Next 327 0 R - /Parent 320 0 R - /Prev 325 0 R + /Next 331 0 R + /Parent 324 0 R + /Prev 329 0 R /Title (Implementing subcommands) >> endobj -% 'Outline.37.6': class OutlineEntryObject -327 0 obj -<< /Dest [ 252 0 R +% 'Outline.38.6': class OutlineEntryObject +331 0 obj +<< /Dest [ 254 0 R /XYZ 62.69291 330.0679 0 ] - /Next 328 0 R - /Parent 320 0 R - /Prev 326 0 R + /Next 332 0 R + /Parent 324 0 R + /Prev 330 0 R /Title (plac.Interpreter.call) >> endobj -% 'Outline.37.7': class OutlineEntryObject -328 0 obj -<< /Dest [ 258 0 R +% 'Outline.38.7': class OutlineEntryObject +332 0 obj +<< /Dest [ 260 0 R /XYZ 62.69291 717.0236 0 ] - /Next 329 0 R - /Parent 320 0 R - /Prev 327 0 R + /Next 333 0 R + /Parent 324 0 R + /Prev 331 0 R /Title (Readline support) >> endobj -% 'Outline.37.8': class OutlineEntryObject -329 0 obj -<< /Dest [ 271 0 R +% 'Outline.38.8': class OutlineEntryObject +333 0 obj +<< /Dest [ 273 0 R /XYZ 62.69291 204.6236 0 ] - /Next 330 0 R - /Parent 320 0 R - /Prev 328 0 R + /Next 334 0 R + /Parent 324 0 R + /Prev 332 0 R /Title (The plac runner) >> endobj -% 'Outline.37.9': class OutlineEntryObject -330 0 obj -<< /Dest [ 275 0 R +% 'Outline.38.9': class OutlineEntryObject +334 0 obj +<< /Dest [ 277 0 R /XYZ 62.69291 371.4236 0 ] - /Next 331 0 R - /Parent 320 0 R - /Prev 329 0 R + /Next 335 0 R + /Parent 324 0 R + /Prev 333 0 R /Title (A non class-based example) >> endobj -% 'Outline.37.10': class OutlineEntryObject -331 0 obj -<< /Dest [ 278 0 R +% 'Outline.38.10': class OutlineEntryObject +335 0 obj +<< /Dest [ 280 0 R /XYZ 62.69291 348.6236 0 ] - /Next 332 0 R - /Parent 320 0 R - /Prev 330 0 R + /Next 336 0 R + /Parent 324 0 R + /Prev 334 0 R /Title (Writing your own plac runner) >> endobj -% 'Outline.37.11': class OutlineEntryObject -332 0 obj -<< /Dest [ 282 0 R +% 'Outline.38.11': class OutlineEntryObject +336 0 obj +<< /Dest [ 284 0 R /XYZ 62.69291 175.4236 0 ] - /Next 333 0 R - /Parent 320 0 R - /Prev 331 0 R + /Next 337 0 R + /Parent 324 0 R + /Prev 335 0 R /Title (Long running commands) >> endobj -% 'Outline.37.12': class OutlineEntryObject -333 0 obj -<< /Dest [ 285 0 R +% 'Outline.38.12': class OutlineEntryObject +337 0 obj +<< /Dest [ 287 0 R /XYZ 62.69291 282.6236 0 ] - /Next 334 0 R - /Parent 320 0 R - /Prev 332 0 R + /Next 338 0 R + /Parent 324 0 R + /Prev 336 0 R /Title (Threaded commands) >> endobj -% 'Outline.37.13': class OutlineEntryObject -334 0 obj -<< /Dest [ 289 0 R +% 'Outline.38.13': class OutlineEntryObject +338 0 obj +<< /Dest [ 291 0 R /XYZ 62.69291 383.8236 0 ] - /Next 335 0 R - /Parent 320 0 R - /Prev 333 0 R + /Next 339 0 R + /Parent 324 0 R + /Prev 337 0 R /Title (Running commands as external processes) >> endobj -% 'Outline.37.14': class OutlineEntryObject -335 0 obj -<< /Dest [ 291 0 R +% 'Outline.38.14': class OutlineEntryObject +339 0 obj +<< /Dest [ 293 0 R /XYZ 62.69291 575.8236 0 ] - /Next 336 0 R - /Parent 320 0 R - /Prev 334 0 R + /Next 340 0 R + /Parent 324 0 R + /Prev 338 0 R /Title (Managing the output of concurrent commands) >> endobj -% 'Outline.37.15': class OutlineEntryObject -336 0 obj -<< /Dest [ 293 0 R +% 'Outline.38.15': class OutlineEntryObject +340 0 obj +<< /Dest [ 296 0 R /XYZ 62.69291 703.8236 0 ] - /Next 337 0 R - /Parent 320 0 R - /Prev 335 0 R + /Next 341 0 R + /Parent 324 0 R + /Prev 339 0 R + /Title (Monitor support) >> +endobj +% 'Outline.38.16': class OutlineEntryObject +341 0 obj +<< /Dest [ 296 0 R + /XYZ + 62.69291 + 338.6236 + 0 ] + /Next 342 0 R + /Parent 324 0 R + /Prev 340 0 R /Title (Parallel computing with plac) >> endobj -% 'Outline.37.16': class OutlineEntryObject -337 0 obj -<< /Dest [ 297 0 R +% 'Outline.38.17': class OutlineEntryObject +342 0 obj +<< /Dest [ 302 0 R /XYZ 62.69291 - 573.2159 + 765.0236 0 ] - /Next 338 0 R - /Parent 320 0 R - /Prev 336 0 R + /Next 343 0 R + /Parent 324 0 R + /Prev 341 0 R /Title (The plac server) >> endobj -% 'Outline.37.17': class OutlineEntryObject -338 0 obj -<< /Dest [ 300 0 R +% 'Outline.38.18': class OutlineEntryObject +343 0 obj +<< /Dest [ 302 0 R /XYZ 62.69291 - 765.0236 + 294.6236 0 ] - /Next 339 0 R - /Parent 320 0 R - /Prev 337 0 R + /Next 344 0 R + /Parent 324 0 R + /Prev 342 0 R /Title (Summary) >> endobj -% 'Outline.37.18': class OutlineEntryObject -339 0 obj -<< /Dest [ 300 0 R +% 'Outline.38.19': class OutlineEntryObject +344 0 obj +<< /Dest [ 304 0 R /XYZ 62.69291 - 454.6772 + 652.6772 0 ] - /Parent 320 0 R - /Prev 338 0 R + /Parent 324 0 R + /Prev 343 0 R /Title (Appendix: custom annotation objects) >> endobj -% 'R340': class PDFPages -340 0 obj +% 'R345': class PDFPages +345 0 obj % page tree -<< /Count 43 +<< /Count 44 /Kids [ 8 0 R - 79 0 R - 95 0 R - 105 0 R - 109 0 R - 113 0 R - 119 0 R - 120 0 R - 123 0 R - 131 0 R - 132 0 R - 136 0 R - 139 0 R + 81 0 R + 97 0 R + 107 0 R + 111 0 R + 115 0 R + 121 0 R + 122 0 R + 125 0 R + 133 0 R + 134 0 R + 138 0 R 141 0 R - 144 0 R - 160 0 R - 173 0 R - 211 0 R - 225 0 R - 226 0 R + 143 0 R + 146 0 R + 162 0 R + 175 0 R + 213 0 R + 227 0 R 228 0 R - 231 0 R - 242 0 R - 247 0 R - 251 0 R - 252 0 R + 230 0 R + 233 0 R + 244 0 R + 249 0 R 253 0 R - 258 0 R - 271 0 R - 272 0 R - 275 0 R - 276 0 R + 254 0 R + 255 0 R + 260 0 R + 273 0 R + 274 0 R + 277 0 R 278 0 R - 282 0 R - 285 0 R - 286 0 R - 289 0 R + 280 0 R + 284 0 R + 287 0 R + 288 0 R 291 0 R 293 0 R - 294 0 R + 296 0 R 297 0 R - 300 0 R - 301 0 R ] + 299 0 R + 302 0 R + 304 0 R + 305 0 R ] /Type /Pages >> endobj -% 'R341': class PDFStream -341 0 obj +% 'R346': class PDFStream +346 0 obj % page stream << /Length 2944 >> stream @@ -5810,10 +5896,10 @@ Q endstream endobj -% 'R342': class PDFStream -342 0 obj +% 'R347': class PDFStream +347 0 obj % page stream -<< /Length 9380 >> +<< /Length 9629 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q @@ -5823,17 +5909,17 @@ BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Contents) Tj T* ET Q Q q -1 0 0 1 62.69291 108.0236 cm +1 0 0 1 62.69291 90.02362 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q -1 0 0 1 0 615 cm +1 0 0 1 0 633 cm q BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (Plac: Parsing the Command Line the Easy Way) Tj T* ET Q Q q -1 0 0 1 397.8898 615 cm +1 0 0 1 397.8898 633 cm q 0 0 .501961 rg 0 0 .501961 RG @@ -5841,13 +5927,13 @@ BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 66.44 0 Td (1) Tj T* -66.44 0 Td ET Q Q q -1 0 0 1 0 597 cm +1 0 0 1 0 615 cm q BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (The importance of scaling down) Tj T* ET Q Q q -1 0 0 1 397.8898 597 cm +1 0 0 1 397.8898 615 cm q 0 0 .501961 rg 0 0 .501961 RG @@ -5855,13 +5941,13 @@ BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 66.44 0 Td (3) Tj T* -66.44 0 Td ET Q Q q -1 0 0 1 0 579 cm +1 0 0 1 0 597 cm q BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Scripts with required arguments) Tj T* ET Q Q q -1 0 0 1 397.8898 579 cm +1 0 0 1 397.8898 597 cm q 0 0 .501961 rg 0 0 .501961 RG @@ -5869,13 +5955,13 @@ BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 66.44 0 Td (3) Tj T* -66.44 0 Td ET Q Q q -1 0 0 1 0 561 cm +1 0 0 1 0 579 cm q BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Scripts with default arguments) Tj T* ET Q Q q -1 0 0 1 397.8898 561 cm +1 0 0 1 397.8898 579 cm q 0 0 .501961 rg 0 0 .501961 RG @@ -5883,13 +5969,13 @@ BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 66.44 0 Td (5) Tj T* -66.44 0 Td ET Q Q q -1 0 0 1 0 543 cm +1 0 0 1 0 561 cm q BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Scripts with options \(and smart options\)) Tj T* ET Q Q q -1 0 0 1 397.8898 543 cm +1 0 0 1 397.8898 561 cm q 0 0 .501961 rg 0 0 .501961 RG @@ -5897,13 +5983,13 @@ BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 66.44 0 Td (7) Tj T* -66.44 0 Td ET Q Q q -1 0 0 1 0 525 cm +1 0 0 1 0 543 cm q BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Scripts with flags) Tj T* ET Q Q q -1 0 0 1 397.8898 525 cm +1 0 0 1 397.8898 543 cm q 0 0 .501961 rg 0 0 .501961 RG @@ -5911,13 +5997,13 @@ BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 66.44 0 Td (9) Tj T* -66.44 0 Td ET Q Q q -1 0 0 1 0 507 cm +1 0 0 1 0 525 cm q BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (plac for Python 2.X users) Tj T* ET Q Q q -1 0 0 1 397.8898 507 cm +1 0 0 1 397.8898 525 cm q 0 0 .501961 rg 0 0 .501961 RG @@ -5925,13 +6011,13 @@ BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 66.44 0 Td (9) Tj T* -66.44 0 Td ET Q Q q -1 0 0 1 0 489 cm +1 0 0 1 0 507 cm q BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (More features) Tj T* ET Q Q q -1 0 0 1 397.8898 489 cm +1 0 0 1 397.8898 507 cm q 0 0 .501961 rg 0 0 .501961 RG @@ -5939,13 +6025,13 @@ BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (10) Tj T* -60.88 0 Td ET Q Q q -1 0 0 1 0 471 cm +1 0 0 1 0 489 cm q BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (A realistic example) Tj T* ET Q Q q -1 0 0 1 397.8898 471 cm +1 0 0 1 397.8898 489 cm q 0 0 .501961 rg 0 0 .501961 RG @@ -5953,13 +6039,13 @@ BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (12) Tj T* -60.88 0 Td ET Q Q q -1 0 0 1 0 453 cm +1 0 0 1 0 471 cm q BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Keyword arguments) Tj T* ET Q Q q -1 0 0 1 397.8898 453 cm +1 0 0 1 397.8898 471 cm q 0 0 .501961 rg 0 0 .501961 RG @@ -5967,13 +6053,13 @@ BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (13) Tj T* -60.88 0 Td ET Q Q q -1 0 0 1 0 435 cm +1 0 0 1 0 453 cm q BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Final example: a shelve interface) Tj T* ET Q Q q -1 0 0 1 397.8898 435 cm +1 0 0 1 397.8898 453 cm q 0 0 .501961 rg 0 0 .501961 RG @@ -5981,13 +6067,13 @@ BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (14) Tj T* -60.88 0 Td ET Q Q q -1 0 0 1 0 417 cm +1 0 0 1 0 435 cm q BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (plac vs argparse) Tj T* ET Q Q q -1 0 0 1 397.8898 417 cm +1 0 0 1 397.8898 435 cm q 0 0 .501961 rg 0 0 .501961 RG @@ -5995,12 +6081,26 @@ BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (16) Tj T* -60.88 0 Td ET Q Q q -1 0 0 1 0 399 cm +1 0 0 1 0 417 cm q BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (plac vs the rest of the world) Tj T* ET Q Q q +1 0 0 1 397.8898 417 cm +q +0 0 .501961 rg +0 0 .501961 RG +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (18) Tj T* -60.88 0 Td ET +Q +Q +q +1 0 0 1 0 399 cm +q +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (The future) Tj T* ET +Q +Q +q 1 0 0 1 397.8898 399 cm q 0 0 .501961 rg @@ -6011,7 +6111,7 @@ Q q 1 0 0 1 0 381 cm q -BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (The future) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Trivia: the story behind the name) Tj T* ET Q Q q @@ -6025,7 +6125,7 @@ Q q 1 0 0 1 0 363 cm q -BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Trivia: the story behind the name) Tj T* ET +BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (Advanced usages of plac) Tj T* ET Q Q q @@ -6033,13 +6133,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (18) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 60.88 0 Td (19) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 345 cm q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (Advanced usages of plac) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Introduction) Tj T* ET Q Q q @@ -6047,13 +6147,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 60.88 0 Td (19) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (19) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 327 cm q -BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Introduction) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (From scripts to interactive applications) Tj T* ET Q Q q @@ -6067,7 +6167,7 @@ Q q 1 0 0 1 0 309 cm q -BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (From scripts to interactive applications) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Testing a plac application) Tj T* ET Q Q q @@ -6075,13 +6175,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (19) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (21) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 291 cm q -BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Testing a plac application) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Plac easy tests) Tj T* ET Q Q q @@ -6089,13 +6189,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (21) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (22) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 273 cm q -BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Plac easy tests) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Plac batch scripts) Tj T* ET Q Q q @@ -6103,13 +6203,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (22) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (23) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 255 cm q -BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Plac batch scripts) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Implementing subcommands) Tj T* ET Q Q q @@ -6117,13 +6217,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (23) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (24) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 237 cm q -BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Implementing subcommands) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (plac.Interpreter.call) Tj T* ET Q Q q @@ -6131,13 +6231,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (24) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (26) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 219 cm q -BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (plac.Interpreter.call) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Readline support) Tj T* ET Q Q q @@ -6145,13 +6245,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (26) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (28) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 201 cm q -BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Readline support) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (The plac runner) Tj T* ET Q Q q @@ -6159,13 +6259,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (28) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (29) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 183 cm q -BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (The plac runner) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (A non class-based example) Tj T* ET Q Q q @@ -6173,13 +6273,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (29) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (31) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 165 cm q -BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (A non class-based example) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Writing your own plac runner) Tj T* ET Q Q q @@ -6187,13 +6287,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (31) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (33) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 147 cm q -BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Writing your own plac runner) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Long running commands) Tj T* ET Q Q q @@ -6201,13 +6301,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (33) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (34) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 129 cm q -BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Long running commands) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Threaded commands) Tj T* ET Q Q q @@ -6215,13 +6315,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (34) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (35) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 111 cm q -BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Threaded commands) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Running commands as external processes) Tj T* ET Q Q q @@ -6229,13 +6329,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (35) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (37) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 93 cm q -BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Running commands as external processes) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Managing the output of concurrent commands) Tj T* ET Q Q q @@ -6243,13 +6343,13 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (37) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (38) Tj T* -60.88 0 Td ET Q Q q 1 0 0 1 0 75 cm q -BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Managing the output of concurrent commands) Tj T* ET +BT 1 0 0 1 20 2 Tm 12 TL /F1 10 Tf 0 0 .501961 rg (Monitor support) Tj T* ET Q Q q @@ -6257,7 +6357,7 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (38) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (39) Tj T* -60.88 0 Td ET Q Q q @@ -6285,7 +6385,7 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (41) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (42) Tj T* -60.88 0 Td ET Q Q q @@ -6313,7 +6413,7 @@ q q 0 0 .501961 rg 0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (42) Tj T* -60.88 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 60.88 0 Td (43) Tj T* -60.88 0 Td ET Q Q q @@ -6329,8 +6429,8 @@ Q endstream endobj -% 'R343': class PDFStream -343 0 obj +% 'R348': class PDFStream +348 0 obj % page stream << /Length 5956 >> stream @@ -6414,8 +6514,8 @@ Q endstream endobj -% 'R344': class PDFStream -344 0 obj +% 'R349': class PDFStream +349 0 obj % page stream << /Length 4418 >> stream @@ -6545,8 +6645,8 @@ Q endstream endobj -% 'R345': class PDFStream -345 0 obj +% 'R350': class PDFStream +350 0 obj % page stream << /Length 4021 >> stream @@ -6676,8 +6776,8 @@ Q endstream endobj -% 'R346': class PDFStream -346 0 obj +% 'R351': class PDFStream +351 0 obj % page stream << /Length 3872 >> stream @@ -6807,8 +6907,8 @@ Q endstream endobj -% 'R347': class PDFStream -347 0 obj +% 'R352': class PDFStream +352 0 obj % page stream << /Length 4986 >> stream @@ -6944,8 +7044,8 @@ Q endstream endobj -% 'R348': class PDFStream -348 0 obj +% 'R353': class PDFStream +353 0 obj % page stream << /Length 4279 >> stream @@ -7139,8 +7239,8 @@ Q endstream endobj -% 'R349': class PDFStream -349 0 obj +% 'R354': class PDFStream +354 0 obj % page stream << /Length 4877 >> stream @@ -7288,8 +7388,8 @@ Q endstream endobj -% 'R350': class PDFStream -350 0 obj +% 'R355': class PDFStream +355 0 obj % page stream << /Length 6131 >> stream @@ -7442,8 +7542,8 @@ Q endstream endobj -% 'R351': class PDFStream -351 0 obj +% 'R356': class PDFStream +356 0 obj % page stream << /Length 4220 >> stream @@ -7598,8 +7698,8 @@ Q endstream endobj -% 'R352': class PDFStream -352 0 obj +% 'R357': class PDFStream +357 0 obj % page stream << /Length 4269 >> stream @@ -7714,8 +7814,8 @@ Q endstream endobj -% 'R353': class PDFStream -353 0 obj +% 'R358': class PDFStream +358 0 obj % page stream << /Length 3533 >> stream @@ -7832,8 +7932,8 @@ Q endstream endobj -% 'R354': class PDFStream -354 0 obj +% 'R359': class PDFStream +359 0 obj % page stream << /Length 4268 >> stream @@ -7963,8 +8063,8 @@ Q endstream endobj -% 'R355': class PDFStream -355 0 obj +% 'R360': class PDFStream +360 0 obj % page stream << /Length 6251 >> stream @@ -8230,8 +8330,8 @@ Q endstream endobj -% 'R356': class PDFStream -356 0 obj +% 'R361': class PDFStream +361 0 obj % page stream << /Length 6569 >> stream @@ -8427,8 +8527,8 @@ Q endstream endobj -% 'R357': class PDFStream -357 0 obj +% 'R362': class PDFStream +362 0 obj % page stream << /Length 7017 >> stream @@ -8595,8 +8695,8 @@ Q endstream endobj -% 'R358': class PDFStream -358 0 obj +% 'R363': class PDFStream +363 0 obj % page stream << /Length 8625 >> stream @@ -8817,8 +8917,8 @@ Q endstream endobj -% 'R359': class PDFStream -359 0 obj +% 'R364': class PDFStream +364 0 obj % page stream << /Length 5814 >> stream @@ -8933,8 +9033,8 @@ Q endstream endobj -% 'R360': class PDFStream -360 0 obj +% 'R365': class PDFStream +365 0 obj % page stream << /Length 3534 >> stream @@ -9073,8 +9173,8 @@ Q endstream endobj -% 'R361': class PDFStream -361 0 obj +% 'R366': class PDFStream +366 0 obj % page stream << /Length 5533 >> stream @@ -9200,8 +9300,8 @@ Q endstream endobj -% 'R362': class PDFStream -362 0 obj +% 'R367': class PDFStream +367 0 obj % page stream << /Length 6041 >> stream @@ -9345,8 +9445,8 @@ Q endstream endobj -% 'R363': class PDFStream -363 0 obj +% 'R368': class PDFStream +368 0 obj % page stream << /Length 6421 >> stream @@ -9457,8 +9557,8 @@ Q endstream endobj -% 'R364': class PDFStream -364 0 obj +% 'R369': class PDFStream +369 0 obj % page stream << /Length 4398 >> stream @@ -9578,8 +9678,8 @@ Q endstream endobj -% 'R365': class PDFStream -365 0 obj +% 'R370': class PDFStream +370 0 obj % page stream << /Length 4327 >> stream @@ -9634,8 +9734,8 @@ Q endstream endobj -% 'R366': class PDFStream -366 0 obj +% 'R371': class PDFStream +371 0 obj % page stream << /Length 4207 >> stream @@ -9742,8 +9842,8 @@ Q endstream endobj -% 'R367': class PDFStream -367 0 obj +% 'R372': class PDFStream +372 0 obj % page stream << /Length 4686 >> stream @@ -9877,8 +9977,8 @@ Q endstream endobj -% 'R368': class PDFStream -368 0 obj +% 'R373': class PDFStream +373 0 obj % page stream << /Length 5046 >> stream @@ -9970,8 +10070,8 @@ Q endstream endobj -% 'R369': class PDFStream -369 0 obj +% 'R374': class PDFStream +374 0 obj % page stream << /Length 4970 >> stream @@ -10074,8 +10174,8 @@ Q endstream endobj -% 'R370': class PDFStream -370 0 obj +% 'R375': class PDFStream +375 0 obj % page stream << /Length 4210 >> stream @@ -10225,8 +10325,8 @@ Q endstream endobj -% 'R371': class PDFStream -371 0 obj +% 'R376': class PDFStream +376 0 obj % page stream << /Length 5294 >> stream @@ -10416,8 +10516,8 @@ Q endstream endobj -% 'R372': class PDFStream -372 0 obj +% 'R377': class PDFStream +377 0 obj % page stream << /Length 3670 >> stream @@ -10526,8 +10626,8 @@ Q endstream endobj -% 'R373': class PDFStream -373 0 obj +% 'R378': class PDFStream +378 0 obj % page stream << /Length 5393 >> stream @@ -10745,8 +10845,8 @@ Q endstream endobj -% 'R374': class PDFStream -374 0 obj +% 'R379': class PDFStream +379 0 obj % page stream << /Length 4842 >> stream @@ -10873,8 +10973,8 @@ Q endstream endobj -% 'R375': class PDFStream -375 0 obj +% 'R380': class PDFStream +380 0 obj % page stream << /Length 4152 >> stream @@ -11030,8 +11130,8 @@ Q endstream endobj -% 'R376': class PDFStream -376 0 obj +% 'R381': class PDFStream +381 0 obj % page stream << /Length 4636 >> stream @@ -11239,8 +11339,8 @@ Q endstream endobj -% 'R377': class PDFStream -377 0 obj +% 'R382': class PDFStream +382 0 obj % page stream << /Length 4830 >> stream @@ -11376,10 +11476,10 @@ Q endstream endobj -% 'R378': class PDFStream -378 0 obj +% 'R383': class PDFStream +383 0 obj % page stream -<< /Length 4749 >> +<< /Length 4604 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q @@ -11429,20 +11529,13 @@ BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Managing the output of concurrent co Q Q q -1 0 0 1 62.69291 455.8236 cm -q -BT 1 0 0 1 0 86 Tm 1.895542 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (acts as a command-line task launcher and can be used as the base to build a GUI-based task) Tj T* 0 Tw .38561 Tw (launcher and task monitor. To this aim the interpreter class provides a ) Tj /F3 10 Tf (.submit ) Tj /F1 10 Tf (method which returns a) Tj T* 0 Tw 1.792339 Tw (task object and a ) Tj /F3 10 Tf (.tasks ) Tj /F1 10 Tf (method returning the list of all the tasks submitted to the interpreter. The) Tj T* 0 Tw .373516 Tw /F3 10 Tf (submit ) Tj /F1 10 Tf (method does not start the task and thus it is nonblocking. Each task has an ) Tj /F3 10 Tf (.outlist ) Tj /F1 10 Tf (attribute) Tj T* 0 Tw .106098 Tw (which is a list storing the value yielded by the generator underlying the task \(the ) Tj /F3 10 Tf (None ) Tj /F1 10 Tf (values are skipped) Tj T* 0 Tw .633318 Tw (though\): the ) Tj /F3 10 Tf (.outlist ) Tj /F1 10 Tf (grows as the task runs and more values are yielded. Accessing the ) Tj /F3 10 Tf (.outlist) Tj T* 0 Tw 1.051654 Tw /F1 10 Tf (is nonblocking and can be done freely. Finally there is a ) Tj /F3 10 Tf (.result ) Tj /F1 10 Tf (property which waits for the task to) Tj T* 0 Tw (finish and returns the last yielded value or raises an exception.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 425.8236 cm +1 0 0 1 62.69291 443.8236 cm q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .014692 Tw (Here is some example code to visualize the output of the FakeImporter in Tkinter \(I chose Tkinter because) Tj T* 0 Tw (it is easy to use and it is in the standard library, but you can use any GUI\):) Tj T* ET +BT 1 0 0 1 0 98 Tm 1.895542 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (acts as a command-line task launcher and can be used as the base to build a GUI-based task) Tj T* 0 Tw .38561 Tw (launcher and task monitor. To this aim the interpreter class provides a ) Tj /F3 10 Tf (.submit ) Tj /F1 10 Tf (method which returns a) Tj T* 0 Tw 1.792339 Tw (task object and a ) Tj /F3 10 Tf (.tasks ) Tj /F1 10 Tf (method returning the list of all the tasks submitted to the interpreter. The) Tj T* 0 Tw .373516 Tw /F3 10 Tf (submit ) Tj /F1 10 Tf (method does not start the task and thus it is nonblocking. Each task has an ) Tj /F3 10 Tf (.outlist ) Tj /F1 10 Tf (attribute) Tj T* 0 Tw .106098 Tw (which is a list storing the value yielded by the generator underlying the task \(the ) Tj /F3 10 Tf (None ) Tj /F1 10 Tf (values are skipped) Tj T* 0 Tw .633318 Tw (though\): the ) Tj /F3 10 Tf (.outlist ) Tj /F1 10 Tf (grows as the task runs and more values are yielded. Accessing the ) Tj /F3 10 Tf (.outlist) Tj T* 0 Tw 1.051654 Tw /F1 10 Tf (is nonblocking and can be done freely. Finally there is a ) Tj /F3 10 Tf (.result ) Tj /F1 10 Tf (property which waits for the task to) Tj T* 0 Tw .830574 Tw (finish and returns the last yielded value or raises an exception. The code below provides an example of) Tj T* 0 Tw (how you could implement a GUI over the importer example:) Tj T* ET Q Q q -1 0 0 1 62.69291 92.62362 cm +1 0 0 1 62.69291 98.62362 cm q q 1 0 0 1 0 0 cm @@ -11452,11 +11545,11 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .862745 rg -n -6 -6 468.6898 324 re B* +n -6 -6 468.6898 336 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 302 Tm /F3 10 Tf 12 TL (from Tkinter import *) Tj T* (from importer3 import FakeImporter) Tj T* T* (def taskwidget\(root, task, tick=500\):) Tj T* ( "A Label widget showing the output of a task every 500 ms") Tj T* ( sv = StringVar\(root\)) Tj T* ( lb = Label\(root, textvariable=sv\)) Tj T* ( def show_outlist\(\):) Tj T* ( try:) Tj T* ( out = task.outlist[-1]) Tj T* ( except IndexError: # no output yet) Tj T* ( out = '') Tj T* ( sv.set\('%s %s' % \(task, out\)\)) Tj T* ( root.after\(tick, show_outlist\)) Tj T* ( root.after\(0, show_outlist\)) Tj T* ( return lb) Tj T* T* (def monitor\(tasks\):) Tj T* ( root = Tk\(\)) Tj T* ( for task in tasks:) Tj T* ( task.run\(\)) Tj T* ( taskwidget\(root, task\).pack\(\)) Tj T* ( root.mainloop\(\)) Tj T* T* (if __name__ == '__main__':) Tj T* ( import plac) Tj T* ET +BT 1 0 0 1 0 314 Tm /F3 10 Tf 12 TL (from __future__ import with_statement) Tj T* (from Tkinter import *) Tj T* (from importer3 import FakeImporter) Tj T* T* (def taskwidget\(root, task, tick=500\):) Tj T* ( "A Label widget showing the output of a task every 500 ms") Tj T* ( sv = StringVar\(root\)) Tj T* ( lb = Label\(root, textvariable=sv\)) Tj T* ( def show_outlist\(\):) Tj T* ( try:) Tj T* ( out = task.outlist[-1]) Tj T* ( except IndexError: # no output yet) Tj T* ( out = '') Tj T* ( sv.set\('%s %s' % \(task, out\)\)) Tj T* ( root.after\(tick, show_outlist\)) Tj T* ( root.after\(0, show_outlist\)) Tj T* ( return lb) Tj T* T* (def monitor\(tasks\):) Tj T* ( root = Tk\(\)) Tj T* ( for task in tasks:) Tj T* ( task.run\(\)) Tj T* ( taskwidget\(root, task\).pack\(\)) Tj T* ( root.mainloop\(\)) Tj T* T* (if __name__ == '__main__':) Tj T* ( import plac) Tj T* ET Q Q Q @@ -11472,10 +11565,10 @@ Q endstream endobj -% 'R379': class PDFStream -379 0 obj +% 'R384': class PDFStream +384 0 obj % page stream -<< /Length 4807 >> +<< /Length 5571 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q @@ -11502,17 +11595,17 @@ Q q 1 0 0 1 62.69291 685.8236 cm q -BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Parallel computing with plac) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Monitor support) Tj T* ET Q Q q 1 0 0 1 62.69291 571.8236 cm q -BT 1 0 0 1 0 98 Tm 1.174751 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is certainly not intended as a tool for parallel computing, but still you can use it to launch a set of) Tj T* 0 Tw .497984 Tw (commands and to collect the results, similarly to the MapReduce pattern popularized by Google. In order) Tj T* 0 Tw .669431 Tw (to give an example, I will consider the "Hello World" of parallel computing, i.e. the computation of pi with) Tj T* 0 Tw .537633 Tw (independent processes. There is a huge number of algorithms to compute pi; here I will describe a trivial) Tj T* 0 Tw .101567 Tw (one chosen for simplicity, not per efficienty. The trick is to consider the first quadrant of a circle with radius) Tj T* 0 Tw .602488 Tw (1 and to extract a number of points ) Tj /F3 10 Tf (\(x, y\) ) Tj /F1 10 Tf (with ) Tj /F3 10 Tf (x ) Tj /F1 10 Tf (and ) Tj /F3 10 Tf (y ) Tj /F1 10 Tf (random variables in the interval ) Tj /F3 10 Tf ([0,1]) Tj /F1 10 Tf (. The) Tj T* 0 Tw .928876 Tw (probability of extracting a number inside the quadrant \(i.e. with ) Tj /F3 10 Tf (x^2 + y^2 < 1) Tj /F1 10 Tf (\) is proportional to the) Tj T* 0 Tw .433145 Tw (area of the quadrant \(i.e. ) Tj /F3 10 Tf (pi/4) Tj /F1 10 Tf (\). The value of ) Tj /F3 10 Tf (pi ) Tj /F1 10 Tf (therefore can be extracted by multiplying by 4 the ratio) Tj T* 0 Tw (between the number of points in the quadrant versus the total number of points ) Tj /F3 10 Tf (N) Tj /F1 10 Tf (, for ) Tj /F3 10 Tf (N ) Tj /F1 10 Tf (large:) Tj T* ET +BT 1 0 0 1 0 98 Tm .493555 Tw 12 TL /F1 10 Tf 0 0 0 rg (Starting from release 0.8 ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (provides builtin support for monitoring the output of concurrent commands,) Tj T* 0 Tw 1.277318 Tw (at least for platforms where multiprocessing is fully supported. You can define your own monitor class,) Tj T* 0 Tw .839979 Tw (simply by inheriting from ) Tj /F3 10 Tf (plac.Monitor ) Tj /F1 10 Tf (and by overriding the methods ) Tj /F3 10 Tf (add_listener\(self, no\)) Tj /F1 10 Tf (,) Tj T* 0 Tw 2.953953 Tw /F3 10 Tf (del_listener\(self, taskno\)) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (notify_listener\(self, taskno, msg\)) Tj /F1 10 Tf (, ) Tj /F3 10 Tf (schedule\(self,) Tj T* 0 Tw .367674 Tw (seconds, func, arg\) ) Tj /F1 10 Tf (and ) Tj /F3 10 Tf (run\(self\)) Tj /F1 10 Tf (. Then, you can a monitor object to any ) Tj /F3 10 Tf (plac.Interpreter) Tj T* 0 Tw 1.149983 Tw /F1 10 Tf (object by simply calling the ) Tj /F3 10 Tf (add_monitor ) Tj /F1 10 Tf (method. For convenience, ) Tj /F3 10 Tf (plac ) Tj /F1 10 Tf (comes with a very simple) Tj T* 0 Tw .82683 Tw /F3 10 Tf (TkMonitor ) Tj /F1 10 Tf (based on Tkinter \(I chose Tkinter because it is easy to use and it is in the standard library,) Tj T* 0 Tw .08332 Tw (but you can use any GUI\): you can just look at how the ) Tj /F3 10 Tf (TkMonitor ) Tj /F1 10 Tf (is implemented in ) Tj /F3 10 Tf (plac_tk.py ) Tj /F1 10 Tf (and) Tj T* 0 Tw (adapt it. Here is an example of usage of the ) Tj /F3 10 Tf (TkMonitor) Tj /F1 10 Tf (:) Tj T* ET Q Q q -1 0 0 1 62.69291 466.6236 cm +1 0 0 1 62.69291 394.6236 cm q q 1 0 0 1 0 0 cm @@ -11522,30 +11615,36 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .862745 rg -n -6 -6 468.6898 96 re B* +n -6 -6 468.6898 168 re B* Q q -BT 1 0 0 1 0 74 Tm 12 TL /F3 10 Tf 0 0 0 rg (def calc_pi\(N\):) Tj T* ( inside = 0) Tj T* ( for j in xrange\(N\):) Tj T* ( x, y = random\(\), random\(\)) Tj T* ( if x*x + y*y ) Tj (<) Tj ( 1:) Tj T* ( inside += 1) Tj T* ( return \(4.0 * inside\) / N) Tj T* ET +0 0 0 rg +BT 1 0 0 1 0 146 Tm /F3 10 Tf 12 TL (from __future__ import with_statement) Tj T* (import plac) Tj T* T* (class Hello\(object\):) Tj T* ( mpcommands = ['hello']) Tj T* ( def hello\(self\):) Tj T* ( yield 'hello') Tj T* T* (if __name__ == '__main__':) Tj T* ( i = plac.Interpreter\(Hello\(\)\)) Tj T* ( i.add_monitor\(plac.TkMonitor\('tkmon'\)\)) Tj T* ( with i:) Tj T* ( i.interact\(\)) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 398.6236 cm +1 0 0 1 62.69291 350.6236 cm q -0 0 0 rg -BT 1 0 0 1 0 50 Tm /F1 10 Tf 12 TL .046654 Tw (The algorithm is trivially parallelizable: if you have n CPUs, you can compute pi n times with N/n iterations,) Tj T* 0 Tw 1.122488 Tw (sum the results and divide the total by n. I have a Macbook with two cores, therefore I would expect a) Tj T* 0 Tw 2.347984 Tw (speedup factor of 2 with respect to a sequential computation. Moreover, I would expect a threaded) Tj T* 0 Tw 2.827984 Tw (computation to be even slower than a sequential computation, due to the GIL and the scheduling) Tj T* 0 Tw (overhead.) Tj T* ET +BT 1 0 0 1 0 26 Tm 1.657633 Tw 12 TL /F1 10 Tf 0 0 0 rg (Try to give the ) Tj /F3 10 Tf (hello ) Tj /F1 10 Tf (command from the interactive interpreter: each time a new text widget will be) Tj T* 0 Tw 1.321235 Tw (added displaying the output of the command. Notice that if ) Tj /F3 10 Tf (Tkinter ) Tj /F1 10 Tf (is not installed correctly on your) Tj T* 0 Tw (system the ) Tj /F3 10 Tf (TkMonitor ) Tj /F1 10 Tf (class will not be available.) Tj T* ET Q Q q -1 0 0 1 62.69291 368.6236 cm +1 0 0 1 62.69291 320.6236 cm q -BT 1 0 0 1 0 14 Tm .313984 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here is a script implementing the algorithm and working in three different modes \(parallel mode, threaded) Tj T* 0 Tw (mode and sequential mode\) depending on a ) Tj /F3 10 Tf (mode ) Tj /F1 10 Tf (option:) Tj T* ET +BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Parallel computing with plac) Tj T* ET Q Q q -1 0 0 1 62.69291 95.42362 cm +1 0 0 1 62.69291 206.6236 cm +q +BT 1 0 0 1 0 98 Tm 1.174751 Tw 12 TL /F1 10 Tf 0 0 .501961 rg (plac ) Tj 0 0 0 rg (is certainly not intended as a tool for parallel computing, but still you can use it to launch a set of) Tj T* 0 Tw .497984 Tw (commands and to collect the results, similarly to the MapReduce pattern popularized by Google. In order) Tj T* 0 Tw .669431 Tw (to give an example, I will consider the "Hello World" of parallel computing, i.e. the computation of pi with) Tj T* 0 Tw .537633 Tw (independent processes. There is a huge number of algorithms to compute pi; here I will describe a trivial) Tj T* 0 Tw .101567 Tw (one chosen for simplicity, not per efficienty. The trick is to consider the first quadrant of a circle with radius) Tj T* 0 Tw .602488 Tw (1 and to extract a number of points ) Tj /F3 10 Tf (\(x, y\) ) Tj /F1 10 Tf (with ) Tj /F3 10 Tf (x ) Tj /F1 10 Tf (and ) Tj /F3 10 Tf (y ) Tj /F1 10 Tf (random variables in the interval ) Tj /F3 10 Tf ([0,1]) Tj /F1 10 Tf (. The) Tj T* 0 Tw .928876 Tw (probability of extracting a number inside the quadrant \(i.e. with ) Tj /F3 10 Tf (x^2 + y^2 < 1) Tj /F1 10 Tf (\) is proportional to the) Tj T* 0 Tw .433145 Tw (area of the quadrant \(i.e. ) Tj /F3 10 Tf (pi/4) Tj /F1 10 Tf (\). The value of ) Tj /F3 10 Tf (pi ) Tj /F1 10 Tf (therefore can be extracted by multiplying by 4 the ratio) Tj T* 0 Tw (between the number of points in the quadrant versus the total number of points ) Tj /F3 10 Tf (N) Tj /F1 10 Tf (, for ) Tj /F3 10 Tf (N ) Tj /F1 10 Tf (large:) Tj T* ET +Q +Q +q +1 0 0 1 62.69291 101.4236 cm q q 1 0 0 1 0 0 cm @@ -11555,10 +11654,10 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .862745 rg -n -6 -6 468.6898 264 re B* +n -6 -6 468.6898 96 re B* Q q -BT 1 0 0 1 0 242 Tm 12 TL /F3 10 Tf 0 0 0 rg (from __future__ import with_statement) Tj T* (from random import random) Tj T* (import multiprocessing) Tj T* (import plac) Tj T* T* (class PiCalculator\(object\):) Tj T* ( """Compute pi in parallel with threads or processes""") Tj T* ( ) Tj T* ( @plac.annotations\() Tj T* ( npoints=\('number of integration points', 'positional', None, int\),) Tj T* ( mode=\('sequential|parallel|threaded', 'option', 'm', str, 'SPT'\)\)) Tj T* ( def __init__\(self, npoints, mode='S'\):) Tj T* ( self.npoints = npoints) Tj T* ( if mode == 'P':) Tj T* ( self.mpcommands = ['calc_pi']) Tj T* ( elif mode == 'T':) Tj T* ( self.thcommands = ['calc_pi']) Tj T* ( elif mode == 'S':) Tj T* ( self.commands = ['calc_pi']) Tj T* ( self.n_cpu = multiprocessing.cpu_count\(\)) Tj T* ( ) Tj T* ET +BT 1 0 0 1 0 74 Tm 12 TL /F3 10 Tf 0 0 0 rg (def calc_pi\(N\):) Tj T* ( inside = 0) Tj T* ( for j in xrange\(N\):) Tj T* ( x, y = random\(\), random\(\)) Tj T* ( if x*x + y*y ) Tj (<) Tj ( 1:) Tj T* ( inside += 1) Tj T* ( return \(4.0 * inside\) / N) Tj T* ET Q Q Q @@ -11574,14 +11673,27 @@ Q endstream endobj -% 'R380': class PDFStream -380 0 obj +% 'R385': class PDFStream +385 0 obj % page stream -<< /Length 3511 >> +<< /Length 3219 >> stream 1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 62.69291 247.8236 cm +1 0 0 1 62.69291 705.0236 cm +q +0 0 0 rg +BT 1 0 0 1 0 50 Tm /F1 10 Tf 12 TL .046654 Tw (The algorithm is trivially parallelizable: if you have n CPUs, you can compute pi n times with N/n iterations,) Tj T* 0 Tw 1.122488 Tw (sum the results and divide the total by n. I have a Macbook with two cores, therefore I would expect a) Tj T* 0 Tw 2.347984 Tw (speedup factor of 2 with respect to a sequential computation. Moreover, I would expect a threaded) Tj T* 0 Tw 2.827984 Tw (computation to be even slower than a sequential computation, due to the GIL and the scheduling) Tj T* 0 Tw (overhead.) Tj T* ET +Q +Q +q +1 0 0 1 62.69291 675.0236 cm +q +BT 1 0 0 1 0 14 Tm .313984 Tw 12 TL /F1 10 Tf 0 0 0 rg (Here is a script implementing the algorithm and working in three different modes \(parallel mode, threaded) Tj T* 0 Tw (mode and sequential mode\) depending on a ) Tj /F3 10 Tf (mode ) Tj /F1 10 Tf (option:) Tj T* ET +Q +Q +q +1 0 0 1 62.69291 89.82362 cm q q 1 0 0 1 0 0 cm @@ -11591,30 +11703,33 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .862745 rg -n -6 -6 468.6898 516 re B* +n -6 -6 468.6898 576 re B* Q q -BT 1 0 0 1 0 494 Tm 12 TL /F3 10 Tf 0 0 0 rg ( def submit_tasks\(self\):) Tj T* ( self.i = plac.Interpreter\(self\).__enter__\(\) ) Tj T* ( return [self.i.submit\('calc_pi %d' % \(self.npoints / self.n_cpu\)\)) Tj T* ( for _ in range\(self.n_cpu\)]) Tj T* T* ( def close\(self\):) Tj T* ( self.i.close\(\)) Tj T* T* ( @plac.annotations\() Tj T* ( npoints=\('npoints', 'positional', None, int\)\)) Tj T* ( def calc_pi\(self, npoints\):) Tj T* ( counts = 0) Tj T* ( for j in xrange\(npoints\):) Tj T* ( n, r = divmod\(j, 1000000\)) Tj T* ( if r == 0:) Tj T* ( yield '%dM iterations' % n) Tj T* ( x, y = random\(\), random\(\)) Tj T* ( if x*x + y*y ) Tj (<) Tj ( 1:) Tj T* ( counts += 1) Tj T* ( yield \(4.0 * counts\)/npoints) Tj T* T* ( def run\(self\):) Tj T* ( tasks = self.i.tasks\(\)) Tj T* ( for t in tasks:) Tj T* ( t.run\(\)) Tj T* ( try:) Tj T* ( total = 0) Tj T* ( for task in tasks:) Tj T* ( total += task.result) Tj T* ( except: # the task was killed) Tj T* ( print tasks) Tj T* ( return) Tj T* ( return total / self.n_cpu) Tj T* T* (if __name__ == '__main__':) Tj T* ( pc = plac.call\(PiCalculator\)) Tj T* ( pc.submit_tasks\(\)) Tj T* ( try:) Tj T* ( import time; t0 = time.time\(\)) Tj T* ( print '%f in %f seconds ' % \(pc.run\(\), time.time\(\) - t0\)) Tj T* ( finally:) Tj T* ( pc.close\(\)) Tj T* ET -Q -Q +BT 1 0 0 1 0 554 Tm 12 TL /F3 10 Tf 0 0 0 rg (from __future__ import with_statement) Tj T* (from random import random) Tj T* (import multiprocessing) Tj T* (import plac) Tj T* T* (class PiCalculator\(object\):) Tj T* ( """Compute pi in parallel with threads or processes""") Tj T* ( ) Tj T* ( @plac.annotations\() Tj T* ( npoints=\('number of integration points', 'positional', None, int\),) Tj T* ( mode=\('sequential|parallel|threaded', 'option', 'm', str, 'SPT'\)\)) Tj T* ( def __init__\(self, npoints, mode='S'\):) Tj T* ( self.npoints = npoints) Tj T* ( if mode == 'P':) Tj T* ( self.mpcommands = ['calc_pi']) Tj T* ( elif mode == 'T':) Tj T* ( self.thcommands = ['calc_pi']) Tj T* ( elif mode == 'S':) Tj T* ( self.commands = ['calc_pi']) Tj T* ( self.n_cpu = multiprocessing.cpu_count\(\)) Tj T* ( ) Tj T* ( def submit_tasks\(self\):) Tj T* ( self.i = plac.Interpreter\(self\).__enter__\(\) ) Tj T* ( return [self.i.submit\('calc_pi %d' % \(self.npoints / self.n_cpu\)\)) Tj T* ( for _ in range\(self.n_cpu\)]) Tj T* T* ( def close\(self\):) Tj T* ( self.i.close\(\)) Tj T* T* ( @plac.annotations\() Tj T* ( npoints=\('npoints', 'positional', None, int\)\)) Tj T* ( def calc_pi\(self, npoints\):) Tj T* ( counts = 0) Tj T* ( for j in xrange\(npoints\):) Tj T* ( n, r = divmod\(j, 1000000\)) Tj T* ( if r == 0:) Tj T* ( yield '%dM iterations' % n) Tj T* ( x, y = random\(\), random\(\)) Tj T* ( if x*x + y*y ) Tj (<) Tj ( 1:) Tj T* ( counts += 1) Tj T* ( yield \(4.0 * counts\)/npoints) Tj T* T* ( def run\(self\):) Tj T* ( tasks = self.i.tasks\(\)) Tj T* ( for t in tasks:) Tj T* ( t.run\(\)) Tj T* ( try:) Tj T* ET Q Q Q -q -1 0 0 1 62.69291 167.8236 cm -q -BT 1 0 0 1 0 62 Tm .381797 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice the ) Tj /F3 10 Tf (submit_tasks ) Tj /F1 10 Tf (method, which instantiates and initializes a ) Tj /F3 10 Tf (plac.Interpreter ) Tj /F1 10 Tf (object and) Tj T* 0 Tw 3.38152 Tw (submits a number of commands corresponding to the number of available CPUs. The ) Tj /F3 10 Tf (calc_pi) Tj T* 0 Tw 3.796651 Tw /F1 10 Tf (command yield a log message every million of interactions, just to monitor the progress of the) Tj T* 0 Tw 1.751318 Tw (computation. The ) Tj /F3 10 Tf (run ) Tj /F1 10 Tf (method starts all the submitted commands in parallel and sums the results. It) Tj T* 0 Tw 1.17104 Tw (returns the average value of ) Tj /F3 10 Tf (pi ) Tj /F1 10 Tf (after the slowest CPU has finished its job \(if the CPUs are equal and) Tj T* 0 Tw (equally busy they should finish more or less at the same time\).) Tj T* ET Q Q q -1 0 0 1 62.69291 149.8236 cm +1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Here are the results on my old Macbook with Ubuntu 10.04 and Python 2.6, for 10 million of iterations:) Tj T* ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (40) Tj T* -235.3849 0 Td ET Q Q + +endstream +endobj +% 'R386': class PDFStream +386 0 obj +% page stream +<< /Length 4480 >> +stream +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 62.69291 92.62362 cm +1 0 0 1 62.69291 559.8236 cm q q 1 0 0 1 0 0 cm @@ -11624,34 +11739,30 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .862745 rg -n -6 -6 468.6898 48 re B* +n -6 -6 468.6898 204 re B* Q q -0 0 0 rg -BT 1 0 0 1 0 26 Tm /F3 10 Tf 12 TL ($ python picalculator.py -mP 10000000 # two processes) Tj T* (3.141904 in 5.744545 seconds) Tj T* ($ python picalculator.py -mT 10000000 # two threads) Tj T* ET +BT 1 0 0 1 0 182 Tm 12 TL /F3 10 Tf 0 0 0 rg ( total = 0) Tj T* ( for task in tasks:) Tj T* ( total += task.result) Tj T* ( except: # the task was killed) Tj T* ( print tasks) Tj T* ( return) Tj T* ( return total / self.n_cpu) Tj T* T* (if __name__ == '__main__':) Tj T* ( pc = plac.call\(PiCalculator\)) Tj T* ( pc.submit_tasks\(\)) Tj T* ( try:) Tj T* ( import time; t0 = time.time\(\)) Tj T* ( print '%f in %f seconds ' % \(pc.run\(\), time.time\(\) - t0\)) Tj T* ( finally:) Tj T* ( pc.close\(\)) Tj T* ET Q Q Q Q Q q -1 0 0 1 56.69291 56.69291 cm +1 0 0 1 62.69291 479.8236 cm +q +BT 1 0 0 1 0 62 Tm .381797 Tw 12 TL /F1 10 Tf 0 0 0 rg (Notice the ) Tj /F3 10 Tf (submit_tasks ) Tj /F1 10 Tf (method, which instantiates and initializes a ) Tj /F3 10 Tf (plac.Interpreter ) Tj /F1 10 Tf (object and) Tj T* 0 Tw 3.38152 Tw (submits a number of commands corresponding to the number of available CPUs. The ) Tj /F3 10 Tf (calc_pi) Tj T* 0 Tw 3.796651 Tw /F1 10 Tf (command yield a log message every million of interactions, just to monitor the progress of the) Tj T* 0 Tw 1.751318 Tw (computation. The ) Tj /F3 10 Tf (run ) Tj /F1 10 Tf (method starts all the submitted commands in parallel and sums the results. It) Tj T* 0 Tw 1.17104 Tw (returns the average value of ) Tj /F3 10 Tf (pi ) Tj /F1 10 Tf (after the slowest CPU has finished its job \(if the CPUs are equal and) Tj T* 0 Tw (equally busy they should finish more or less at the same time\).) Tj T* ET +Q +Q +q +1 0 0 1 62.69291 461.8236 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (40) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Here are the results on my old Macbook with Ubuntu 10.04 and Python 2.6, for 10 million of iterations:) Tj T* ET Q Q - -endstream -endobj -% 'R381': class PDFStream -381 0 obj -% page stream -<< /Length 4777 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 62.69291 715.8236 cm +1 0 0 1 62.69291 368.6236 cm q q 1 0 0 1 0 0 cm @@ -11661,31 +11772,31 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .862745 rg -n -6 -6 468.6898 48 re B* +n -6 -6 468.6898 84 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 26 Tm /F3 10 Tf 12 TL (3.141272 in 13.875645 seconds) Tj T* ($ python picalculator.py -mS 10000000 # sequential) Tj T* (3.141586 in 11.353841 seconds) Tj T* ET +BT 1 0 0 1 0 62 Tm /F3 10 Tf 12 TL ($ python picalculator.py -mP 10000000 # two processes) Tj T* (3.141904 in 5.744545 seconds) Tj T* ($ python picalculator.py -mT 10000000 # two threads) Tj T* (3.141272 in 13.875645 seconds) Tj T* ($ python picalculator.py -mS 10000000 # sequential) Tj T* (3.141586 in 11.353841 seconds) Tj T* ET Q Q Q Q Q q -1 0 0 1 62.69291 683.8236 cm +1 0 0 1 62.69291 336.6236 cm q 0 0 0 rg BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 1.711751 Tw (As you see using processes one gets a 2x speedup indeed, where the threaded mode is some 20%) Tj T* 0 Tw (slower than the sequential mode.) Tj T* ET Q Q q -1 0 0 1 62.69291 617.8236 cm +1 0 0 1 62.69291 270.6236 cm q -BT 1 0 0 1 0 50 Tm .167765 Tw 12 TL /F1 10 Tf 0 0 0 rg (Since the pattern submit a bunch of tasks, starts them and collect the results is so common, ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (provides) Tj T* 0 Tw .493828 Tw (an utility function ) Tj /F3 10 Tf (runp\(genseq, mode='p', start=True\) ) Tj /F1 10 Tf (to start a bunch a generators and return) Tj T* 0 Tw .587765 Tw (a list of task objects. By default ) Tj /F3 10 Tf (runp ) Tj /F1 10 Tf (use processes, but you can use threads by passing ) Tj /F3 10 Tf (mode='t') Tj /F1 10 Tf (. If) Tj T* 0 Tw .422765 Tw (you do not wont to start the tasks, you can say so \() Tj /F3 10 Tf (start=False) Tj /F1 10 Tf (\). With ) Tj /F3 10 Tf (runp ) Tj /F1 10 Tf (the parallel pi calculation) Tj T* 0 Tw (becomes a one-liner:) Tj T* ET +BT 1 0 0 1 0 50 Tm .167765 Tw 12 TL /F1 10 Tf 0 0 0 rg (Since the pattern submit a bunch of tasks, starts them and collect the results is so common, ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (provides) Tj T* 0 Tw 2.487251 Tw (an utility function ) Tj /F3 10 Tf (runp\(genseq, mode='p', monitors=\(\), start=True\) ) Tj /F1 10 Tf (to start a bunch a) Tj T* 0 Tw .598876 Tw (generators and return a list of task objects. By default ) Tj /F3 10 Tf (runp ) Tj /F1 10 Tf (use processes, but you can use threads by) Tj T* 0 Tw .225542 Tw (passing ) Tj /F3 10 Tf (mode='t') Tj /F1 10 Tf (. If you do not wont to start the tasks, you can say so \() Tj /F3 10 Tf (start=False) Tj /F1 10 Tf (\). With ) Tj /F3 10 Tf (runp ) Tj /F1 10 Tf (the) Tj T* 0 Tw (parallel pi calculation becomes a one-liner:) Tj T* ET Q Q q -1 0 0 1 62.69291 585.2159 cm +1 0 0 1 62.69291 238.0159 cm q q .976496 0 0 .976496 0 0 cm @@ -11706,19 +11817,41 @@ Q Q Q q -1 0 0 1 62.69291 555.2159 cm +1 0 0 1 62.69291 206.0159 cm +q +BT 1 0 0 1 0 14 Tm 1.05186 Tw 12 TL /F1 10 Tf 0 0 0 rg (The file ) Tj /F3 10 Tf (test_runp ) Tj /F1 10 Tf (in the ) Tj /F3 10 Tf (doc ) Tj /F1 10 Tf (directory of the plac distribution shows another couple of examples of) Tj T* 0 Tw (usage, including how to show the results of the running computation on a ) Tj /F3 10 Tf (TkMonitor) Tj /F1 10 Tf (.) Tj T* ET +Q +Q +q +1 0 0 1 56.69291 56.69291 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (41) Tj T* -235.3849 0 Td ET +Q +Q + +endstream +endobj +% 'R387': class PDFStream +387 0 obj +% page stream +<< /Length 6179 >> +stream +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +q +1 0 0 1 62.69291 747.0236 cm q BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (The plac server) Tj T* ET Q Q q -1 0 0 1 62.69291 441.2159 cm +1 0 0 1 62.69291 633.0236 cm q BT 1 0 0 1 0 98 Tm 1.258443 Tw 12 TL /F1 10 Tf 0 0 0 rg (A command-line oriented interface can be easily converted into a socket-based interface. Starting from) Tj T* 0 Tw .930574 Tw (release 0.7 plac features a builtin server which is able to accept commands from multiple clients and to) Tj T* 0 Tw .994692 Tw (execute them. The server works by instantiating a separate interpreter for each client, so that if a client) Tj T* 0 Tw 1.08784 Tw (interpreter dies for any reason the other interpreters keep working. To avoid external dependencies the) Tj T* 0 Tw .872209 Tw (server is based on the ) Tj /F3 10 Tf (asynchat ) Tj /F1 10 Tf (module in the standard library, but it would not be difficult to replace) Tj T* 0 Tw 2.386412 Tw (the server with a different one \(for instance, a Twisted server\). Since ) Tj /F3 10 Tf (asynchat) Tj /F1 10 Tf (-based servers are) Tj T* 0 Tw .755984 Tw (asynchronous, any blocking command in the interpreter should be run in a separated process or thread.) Tj T* 0 Tw 1.157633 Tw (The default port for the ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (server is 2199, and the command to signal end-of-connection is EOF. For) Tj T* 0 Tw (instance, here is how you could manage remote import on a database \(say a SQLite db\):) Tj T* ET Q Q q -1 0 0 1 62.69291 312.0159 cm +1 0 0 1 62.69291 503.8236 cm q q 1 0 0 1 0 0 cm @@ -11739,13 +11872,13 @@ Q Q Q q -1 0 0 1 62.69291 292.0159 cm +1 0 0 1 62.69291 483.8236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (You can connect to the server with ) Tj /F3 10 Tf (telnet ) Tj /F1 10 Tf (on port 2199, as follows:) Tj T* ET Q Q q -1 0 0 1 62.69291 114.8159 cm +1 0 0 1 62.69291 306.6236 cm q q 1 0 0 1 0 0 cm @@ -11765,41 +11898,25 @@ Q Q Q q -1 0 0 1 56.69291 56.69291 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (41) Tj T* -235.3849 0 Td ET -Q -Q - -endstream -endobj -% 'R382': class PDFStream -382 0 obj -% page stream -<< /Length 6758 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 747.0236 cm +1 0 0 1 62.69291 276.6236 cm q BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Summary) Tj T* ET Q Q q -1 0 0 1 62.69291 705.0236 cm +1 0 0 1 62.69291 234.6236 cm q BT 1 0 0 1 0 26 Tm 2.203318 Tw 12 TL /F1 10 Tf 0 0 0 rg (Once ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (claimed to be the easiest command-line arguments parser in the world. Having read this) Tj T* 0 Tw .673322 Tw (document you may think that it is not so easy after all. But it is a false impression. Actually the rules are) Tj T* 0 Tw (quite simple:) Tj T* ET Q Q q -1 0 0 1 62.69291 699.0236 cm +1 0 0 1 62.69291 228.6236 cm Q q -1 0 0 1 62.69291 699.0236 cm +1 0 0 1 62.69291 228.6236 cm Q q -1 0 0 1 62.69291 687.0236 cm +1 0 0 1 62.69291 216.6236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q @@ -11819,10 +11936,10 @@ q Q Q q -1 0 0 1 62.69291 681.0236 cm +1 0 0 1 62.69291 210.6236 cm Q q -1 0 0 1 62.69291 633.0236 cm +1 0 0 1 62.69291 162.6236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q @@ -11894,10 +12011,10 @@ q Q Q q -1 0 0 1 62.69291 627.0236 cm +1 0 0 1 62.69291 156.6236 cm Q q -1 0 0 1 62.69291 603.0236 cm +1 0 0 1 62.69291 132.6236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q @@ -11917,10 +12034,10 @@ q Q Q q -1 0 0 1 62.69291 597.0236 cm +1 0 0 1 62.69291 126.6236 cm Q q -1 0 0 1 62.69291 573.0236 cm +1 0 0 1 62.69291 102.6236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q @@ -11940,10 +12057,26 @@ q Q Q q -1 0 0 1 62.69291 567.0236 cm +1 0 0 1 62.69291 96.62362 cm Q q -1 0 0 1 62.69291 543.0236 cm +1 0 0 1 56.69291 56.69291 cm +q +0 0 0 rg +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (42) Tj T* -235.3849 0 Td ET +Q +Q + +endstream +endobj +% 'R388': class PDFStream +388 0 obj +% page stream +<< /Length 4337 >> +stream +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET +q +1 0 0 1 62.69291 741.0236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q @@ -11963,10 +12096,10 @@ q Q Q q -1 0 0 1 62.69291 537.0236 cm +1 0 0 1 62.69291 735.0236 cm Q q -1 0 0 1 62.69291 513.0236 cm +1 0 0 1 62.69291 711.0236 cm 0 0 0 rg BT /F1 10 Tf 12 TL ET q @@ -11986,39 +12119,39 @@ q Q Q q -1 0 0 1 62.69291 513.0236 cm +1 0 0 1 62.69291 711.0236 cm Q q -1 0 0 1 62.69291 495.0236 cm +1 0 0 1 62.69291 693.0236 cm q BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Moreover, remember that ) Tj /F3 10 Tf (plac_runner.py ) Tj /F1 10 Tf (is your friend.) Tj T* ET Q Q q -1 0 0 1 62.69291 466.6772 cm +1 0 0 1 62.69291 664.6772 cm n 0 14.17323 m 469.8898 14.17323 l S Q q -1 0 0 1 62.69291 436.6772 cm +1 0 0 1 62.69291 634.6772 cm q BT 1 0 0 1 0 3 Tm 18 TL /F2 15 Tf 0 0 0 rg (Appendix: custom annotation objects) Tj T* ET Q Q q -1 0 0 1 62.69291 406.6772 cm +1 0 0 1 62.69291 604.6772 cm q BT 1 0 0 1 0 14 Tm .578651 Tw 12 TL /F1 10 Tf 0 0 0 rg (Internally ) Tj 0 0 .501961 rg (plac ) Tj 0 0 0 rg (uses an ) Tj /F3 10 Tf (Annotation ) Tj /F1 10 Tf (class to convert the tuples in the function signature into annotation) Tj T* 0 Tw (objects, i.e. objects with six attributes ) Tj /F3 10 Tf (help, kind, short, type, choices, metavar) Tj /F1 10 Tf (.) Tj T* ET Q Q q -1 0 0 1 62.69291 376.6772 cm +1 0 0 1 62.69291 574.6772 cm q 0 0 0 rg BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .083735 Tw (Advanced users can implement their own annotation objects. For instance, here is an example of how you) Tj T* 0 Tw (could implement annotations for positional arguments:) Tj T* ET Q Q q -1 0 0 1 62.69291 247.4772 cm +1 0 0 1 62.69291 445.4772 cm q q 1 0 0 1 0 0 cm @@ -12039,14 +12172,14 @@ Q Q Q q -1 0 0 1 62.69291 227.4772 cm +1 0 0 1 62.69291 425.4772 cm q 0 0 0 rg BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (You can use such annotations objects as follows:) Tj T* ET Q Q q -1 0 0 1 62.69291 98.27717 cm +1 0 0 1 62.69291 248.2772 cm q q 1 0 0 1 0 0 cm @@ -12056,34 +12189,25 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .862745 rg -n -6 -6 468.6898 120 re B* +n -6 -6 468.6898 168 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 98 Tm /F3 10 Tf 12 TL (# example11.py) Tj T* (import plac) Tj T* (from annotations import Positional) Tj T* T* (@plac.annotations\() Tj T* ( i=Positional\("This is an int", int\),) Tj T* ( n=Positional\("This is a float", float\),) Tj T* ( rest=Positional\("Other arguments"\)\)) Tj T* (def main\(i, n, *rest\):) Tj T* ET +BT 1 0 0 1 0 146 Tm /F3 10 Tf 12 TL (# example11.py) Tj T* (import plac) Tj T* (from annotations import Positional) Tj T* T* (@plac.annotations\() Tj T* ( i=Positional\("This is an int", int\),) Tj T* ( n=Positional\("This is a float", float\),) Tj T* ( rest=Positional\("Other arguments"\)\)) Tj T* (def main\(i, n, *rest\):) Tj T* ( print\(i, n, rest\)) Tj T* T* (if __name__ == '__main__':) Tj T* ( import plac; plac.call\(main\)) Tj T* ET Q Q Q Q Q q -1 0 0 1 56.69291 56.69291 cm +1 0 0 1 62.69291 228.2772 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (42) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Here is the usage message you get:) Tj T* ET Q Q - -endstream -endobj -% 'R383': class PDFStream -383 0 obj -% page stream -<< /Length 1709 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 62.69291 703.8236 cm +1 0 0 1 62.69291 99.07717 cm q q 1 0 0 1 0 0 cm @@ -12093,46 +12217,34 @@ q .662745 .662745 .662745 RG .5 w .960784 .960784 .862745 rg -n -6 -6 468.6898 60 re B* +n -6 -6 468.6898 120 re B* Q q 0 0 0 rg -BT 1 0 0 1 0 38 Tm /F3 10 Tf 12 TL ( print\(i, n, rest\)) Tj T* T* (if __name__ == '__main__':) Tj T* ( import plac; plac.call\(main\)) Tj T* ET -Q -Q +BT 1 0 0 1 0 98 Tm /F3 10 Tf 12 TL (usage: example11.py [-h] i n [rest [rest ...]]) Tj T* T* (positional arguments:) Tj T* ( i This is an int) Tj T* ( n This is a float) Tj T* ( rest Other arguments) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ET Q Q Q -q -1 0 0 1 62.69291 683.8236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Here is the usage message you get:) Tj T* ET Q Q q -1 0 0 1 62.69291 554.6236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 120 re B* -Q +1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 98 Tm /F3 10 Tf 12 TL (usage: example11.py [-h] i n [rest [rest ...]]) Tj T* T* (positional arguments:) Tj T* ( i This is an int) Tj T* ( n This is a float) Tj T* ( rest Other arguments) Tj T* T* (optional arguments:) Tj T* ( -h, --help show this help message and exit) Tj T* ET -Q -Q -Q +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (43) Tj T* -235.3849 0 Td ET Q Q + +endstream +endobj +% 'R389': class PDFStream +389 0 obj +% page stream +<< /Length 693 >> +stream +1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET q -1 0 0 1 62.69291 510.6236 cm +1 0 0 1 62.69291 729.0236 cm q BT 1 0 0 1 0 26 Tm .713516 Tw 12 TL /F1 10 Tf 0 0 0 rg (You can go on and define ) Tj /F3 10 Tf (Option ) Tj /F1 10 Tf (and ) Tj /F3 10 Tf (Flag ) Tj /F1 10 Tf (classes, if you like. Using custom annotation objects you) Tj T* 0 Tw .17528 Tw (could do advanced things like extracting the annotations from a configuration file or from a database, but I) Tj T* 0 Tw (expect such use cases to be quite rare: the default mechanism should work pretty well for most users.) Tj T* ET Q @@ -12141,362 +12253,370 @@ q 1 0 0 1 56.69291 56.69291 cm q 0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (43) Tj T* -235.3849 0 Td ET +BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 235.3849 0 Td (44) Tj T* -235.3849 0 Td ET Q Q endstream endobj -% 'R384': class PDFPageLabels -384 0 obj +% 'R390': class PDFPageLabels +390 0 obj % Document Root << /Nums [ 0 - 385 0 R + 391 0 R 1 - 386 0 R + 392 0 R 2 - 387 0 R + 393 0 R 3 - 388 0 R + 394 0 R 4 - 389 0 R + 395 0 R 5 - 390 0 R + 396 0 R 6 - 391 0 R + 397 0 R 7 - 392 0 R + 398 0 R 8 - 393 0 R + 399 0 R 9 - 394 0 R + 400 0 R 10 - 395 0 R + 401 0 R 11 - 396 0 R + 402 0 R 12 - 397 0 R + 403 0 R 13 - 398 0 R + 404 0 R 14 - 399 0 R + 405 0 R 15 - 400 0 R + 406 0 R 16 - 401 0 R + 407 0 R 17 - 402 0 R + 408 0 R 18 - 403 0 R + 409 0 R 19 - 404 0 R + 410 0 R 20 - 405 0 R + 411 0 R 21 - 406 0 R + 412 0 R 22 - 407 0 R + 413 0 R 23 - 408 0 R + 414 0 R 24 - 409 0 R + 415 0 R 25 - 410 0 R + 416 0 R 26 - 411 0 R + 417 0 R 27 - 412 0 R + 418 0 R 28 - 413 0 R + 419 0 R 29 - 414 0 R + 420 0 R 30 - 415 0 R + 421 0 R 31 - 416 0 R + 422 0 R 32 - 417 0 R + 423 0 R 33 - 418 0 R + 424 0 R 34 - 419 0 R + 425 0 R 35 - 420 0 R + 426 0 R 36 - 421 0 R + 427 0 R 37 - 422 0 R + 428 0 R 38 - 423 0 R + 429 0 R 39 - 424 0 R + 430 0 R 40 - 425 0 R + 431 0 R 41 - 426 0 R + 432 0 R 42 - 427 0 R ] >> -endobj -% 'R385': class PDFPageLabel -385 0 obj -% None -<< /S /D - /St 1 >> -endobj -% 'R386': class PDFPageLabel -386 0 obj -% None -<< /S /D - /St 2 >> -endobj -% 'R387': class PDFPageLabel -387 0 obj -% None -<< /S /D - /St 3 >> -endobj -% 'R388': class PDFPageLabel -388 0 obj -% None -<< /S /D - /St 4 >> -endobj -% 'R389': class PDFPageLabel -389 0 obj -% None -<< /S /D - /St 5 >> -endobj -% 'R390': class PDFPageLabel -390 0 obj -% None -<< /S /D - /St 6 >> + 433 0 R + 43 + 434 0 R ] >> endobj % 'R391': class PDFPageLabel 391 0 obj % None << /S /D - /St 7 >> + /St 1 >> endobj % 'R392': class PDFPageLabel 392 0 obj % None << /S /D - /St 8 >> + /St 2 >> endobj % 'R393': class PDFPageLabel 393 0 obj % None << /S /D - /St 9 >> + /St 3 >> endobj % 'R394': class PDFPageLabel 394 0 obj % None << /S /D - /St 10 >> + /St 4 >> endobj % 'R395': class PDFPageLabel 395 0 obj % None << /S /D - /St 11 >> + /St 5 >> endobj % 'R396': class PDFPageLabel 396 0 obj % None << /S /D - /St 12 >> + /St 6 >> endobj % 'R397': class PDFPageLabel 397 0 obj % None << /S /D - /St 13 >> + /St 7 >> endobj % 'R398': class PDFPageLabel 398 0 obj % None << /S /D - /St 14 >> + /St 8 >> endobj % 'R399': class PDFPageLabel 399 0 obj % None << /S /D - /St 15 >> + /St 9 >> endobj % 'R400': class PDFPageLabel 400 0 obj % None << /S /D - /St 16 >> + /St 10 >> endobj % 'R401': class PDFPageLabel 401 0 obj % None << /S /D - /St 17 >> + /St 11 >> endobj % 'R402': class PDFPageLabel 402 0 obj % None << /S /D - /St 18 >> + /St 12 >> endobj % 'R403': class PDFPageLabel 403 0 obj % None << /S /D - /St 19 >> + /St 13 >> endobj % 'R404': class PDFPageLabel 404 0 obj % None << /S /D - /St 20 >> + /St 14 >> endobj % 'R405': class PDFPageLabel 405 0 obj % None << /S /D - /St 21 >> + /St 15 >> endobj % 'R406': class PDFPageLabel 406 0 obj % None << /S /D - /St 22 >> + /St 16 >> endobj % 'R407': class PDFPageLabel 407 0 obj % None << /S /D - /St 23 >> + /St 17 >> endobj % 'R408': class PDFPageLabel 408 0 obj % None << /S /D - /St 24 >> + /St 18 >> endobj % 'R409': class PDFPageLabel 409 0 obj % None << /S /D - /St 25 >> + /St 19 >> endobj % 'R410': class PDFPageLabel 410 0 obj % None << /S /D - /St 26 >> + /St 20 >> endobj % 'R411': class PDFPageLabel 411 0 obj % None << /S /D - /St 27 >> + /St 21 >> endobj % 'R412': class PDFPageLabel 412 0 obj % None << /S /D - /St 28 >> + /St 22 >> endobj % 'R413': class PDFPageLabel 413 0 obj % None << /S /D - /St 29 >> + /St 23 >> endobj % 'R414': class PDFPageLabel 414 0 obj % None << /S /D - /St 30 >> + /St 24 >> endobj % 'R415': class PDFPageLabel 415 0 obj % None << /S /D - /St 31 >> + /St 25 >> endobj % 'R416': class PDFPageLabel 416 0 obj % None << /S /D - /St 32 >> + /St 26 >> endobj % 'R417': class PDFPageLabel 417 0 obj % None << /S /D - /St 33 >> + /St 27 >> endobj % 'R418': class PDFPageLabel 418 0 obj % None << /S /D - /St 34 >> + /St 28 >> endobj % 'R419': class PDFPageLabel 419 0 obj % None << /S /D - /St 35 >> + /St 29 >> endobj % 'R420': class PDFPageLabel 420 0 obj % None << /S /D - /St 36 >> + /St 30 >> endobj % 'R421': class PDFPageLabel 421 0 obj % None << /S /D - /St 37 >> + /St 31 >> endobj % 'R422': class PDFPageLabel 422 0 obj % None << /S /D - /St 38 >> + /St 32 >> endobj % 'R423': class PDFPageLabel 423 0 obj % None << /S /D - /St 39 >> + /St 33 >> endobj % 'R424': class PDFPageLabel 424 0 obj % None << /S /D - /St 40 >> + /St 34 >> endobj % 'R425': class PDFPageLabel 425 0 obj % None << /S /D - /St 41 >> + /St 35 >> endobj % 'R426': class PDFPageLabel 426 0 obj % None << /S /D - /St 42 >> + /St 36 >> endobj % 'R427': class PDFPageLabel 427 0 obj % None +<< /S /D + /St 37 >> +endobj +% 'R428': class PDFPageLabel +428 0 obj +% None +<< /S /D + /St 38 >> +endobj +% 'R429': class PDFPageLabel +429 0 obj +% None +<< /S /D + /St 39 >> +endobj +% 'R430': class PDFPageLabel +430 0 obj +% None +<< /S /D + /St 40 >> +endobj +% 'R431': class PDFPageLabel +431 0 obj +% None +<< /S /D + /St 41 >> +endobj +% 'R432': class PDFPageLabel +432 0 obj +% None +<< /S /D + /St 42 >> +endobj +% 'R433': class PDFPageLabel +433 0 obj +% None << /S /D /St 43 >> endobj +% 'R434': class PDFPageLabel +434 0 obj +% None +<< /S /D + /St 44 >> +endobj xref -0 428 +0 435 0000000000 65535 f 0000000113 00000 n 0000000246 00000 n @@ -12576,363 +12696,370 @@ xref 0000018183 00000 n 0000018427 00000 n 0000018671 00000 n -0000018899 00000 n -0000019837 00000 n -0000020099 00000 n -0000020362 00000 n -0000020612 00000 n -0000020861 00000 n -0000021127 00000 n -0000021379 00000 n -0000021629 00000 n -0000021881 00000 n -0000022131 00000 n -0000022383 00000 n -0000022633 00000 n -0000022885 00000 n -0000023136 00000 n -0000023375 00000 n -0000023555 00000 n -0000023990 00000 n -0000024251 00000 n -0000024515 00000 n -0000024764 00000 n -0000025016 00000 n -0000025269 00000 n -0000025521 00000 n -0000025772 00000 n -0000026025 00000 n -0000026263 00000 n -0000026659 00000 n -0000026909 00000 n -0000027162 00000 n -0000027400 00000 n -0000027741 00000 n -0000027995 00000 n -0000028249 00000 n -0000028521 00000 n -0000028862 00000 n -0000029116 00000 n -0000029406 00000 n -0000029696 00000 n -0000029950 00000 n -0000030188 00000 n -0000030533 00000 n -0000030832 00000 n -0000031086 00000 n -0000031324 00000 n -0000031655 00000 n -0000031909 00000 n -0000032163 00000 n -0000032415 00000 n -0000032667 00000 n -0000032919 00000 n -0000033173 00000 n -0000033410 00000 n -0000033776 00000 n -0000034075 00000 n -0000034329 00000 n -0000034577 00000 n +0000018915 00000 n +0000019159 00000 n +0000019387 00000 n +0000020343 00000 n +0000020605 00000 n +0000020868 00000 n +0000021118 00000 n +0000021367 00000 n +0000021633 00000 n +0000021885 00000 n +0000022135 00000 n +0000022387 00000 n +0000022637 00000 n +0000022889 00000 n +0000023139 00000 n +0000023391 00000 n +0000023642 00000 n +0000023881 00000 n +0000024061 00000 n +0000024496 00000 n +0000024757 00000 n +0000025021 00000 n +0000025271 00000 n +0000025524 00000 n +0000025777 00000 n +0000026029 00000 n +0000026280 00000 n +0000026533 00000 n +0000026771 00000 n +0000027169 00000 n +0000027420 00000 n +0000027674 00000 n +0000027912 00000 n +0000028253 00000 n +0000028507 00000 n +0000028761 00000 n +0000029033 00000 n +0000029374 00000 n +0000029628 00000 n +0000029918 00000 n +0000030208 00000 n +0000030462 00000 n +0000030700 00000 n +0000031045 00000 n +0000031344 00000 n +0000031598 00000 n +0000031836 00000 n +0000032167 00000 n +0000032421 00000 n +0000032675 00000 n +0000032927 00000 n +0000033179 00000 n +0000033431 00000 n +0000033685 00000 n +0000033922 00000 n +0000034288 00000 n +0000034587 00000 n 0000034841 00000 n -0000035182 00000 n -0000035436 00000 n -0000035674 00000 n -0000036005 00000 n -0000036244 00000 n -0000036565 00000 n -0000036817 00000 n -0000037056 00000 n -0000037387 00000 n -0000037640 00000 n -0000037892 00000 n -0000038144 00000 n -0000038396 00000 n -0000038650 00000 n -0000038902 00000 n -0000039154 00000 n -0000039408 00000 n -0000039662 00000 n -0000039914 00000 n -0000040168 00000 n -0000040420 00000 n -0000040673 00000 n -0000040927 00000 n -0000041197 00000 n -0000041658 00000 n -0000041912 00000 n -0000042166 00000 n -0000042450 00000 n -0000042735 00000 n -0000042989 00000 n -0000043241 00000 n -0000043559 00000 n -0000043813 00000 n -0000044102 00000 n -0000044354 00000 n -0000044606 00000 n -0000044845 00000 n -0000045276 00000 n -0000045530 00000 n -0000045784 00000 n -0000046043 00000 n -0000046300 00000 n -0000046561 00000 n -0000046813 00000 n -0000047067 00000 n +0000035089 00000 n +0000035353 00000 n +0000035694 00000 n +0000035948 00000 n +0000036186 00000 n +0000036517 00000 n +0000036756 00000 n +0000037077 00000 n +0000037329 00000 n +0000037568 00000 n +0000037899 00000 n +0000038152 00000 n +0000038404 00000 n +0000038656 00000 n +0000038908 00000 n +0000039162 00000 n +0000039414 00000 n +0000039666 00000 n +0000039920 00000 n +0000040174 00000 n +0000040426 00000 n +0000040680 00000 n +0000040932 00000 n +0000041185 00000 n +0000041439 00000 n +0000041709 00000 n +0000042170 00000 n +0000042424 00000 n +0000042678 00000 n +0000042962 00000 n +0000043247 00000 n +0000043501 00000 n +0000043753 00000 n +0000044071 00000 n +0000044325 00000 n +0000044614 00000 n +0000044866 00000 n +0000045118 00000 n +0000045357 00000 n +0000045788 00000 n +0000046042 00000 n +0000046296 00000 n +0000046555 00000 n +0000046812 00000 n +0000047073 00000 n 0000047325 00000 n -0000047577 00000 n -0000047835 00000 n +0000047579 00000 n +0000047837 00000 n 0000048089 00000 n -0000048342 00000 n -0000048603 00000 n -0000048857 00000 n -0000049111 00000 n -0000049365 00000 n -0000049624 00000 n -0000049878 00000 n -0000050130 00000 n -0000050384 00000 n -0000050636 00000 n -0000050888 00000 n -0000051141 00000 n -0000051395 00000 n -0000051649 00000 n -0000051903 00000 n -0000052157 00000 n -0000052442 00000 n -0000052695 00000 n -0000052985 00000 n -0000053239 00000 n -0000053550 00000 n -0000053802 00000 n -0000054054 00000 n -0000054343 00000 n -0000054595 00000 n -0000054832 00000 n -0000055513 00000 n -0000055771 00000 n +0000048347 00000 n +0000048601 00000 n +0000048854 00000 n +0000049115 00000 n +0000049369 00000 n +0000049623 00000 n +0000049877 00000 n +0000050136 00000 n +0000050390 00000 n +0000050642 00000 n +0000050896 00000 n +0000051148 00000 n +0000051400 00000 n +0000051653 00000 n +0000051907 00000 n +0000052161 00000 n +0000052415 00000 n +0000052669 00000 n +0000052954 00000 n +0000053207 00000 n +0000053497 00000 n +0000053751 00000 n +0000054062 00000 n +0000054314 00000 n +0000054566 00000 n +0000054855 00000 n +0000055107 00000 n +0000055344 00000 n 0000056025 00000 n -0000056279 00000 n -0000056533 00000 n -0000056787 00000 n -0000057041 00000 n -0000057295 00000 n -0000057540 00000 n -0000057794 00000 n -0000058048 00000 n -0000058302 00000 n -0000058556 00000 n -0000058815 00000 n -0000059241 00000 n -0000059540 00000 n -0000059779 00000 n -0000060100 00000 n -0000060354 00000 n -0000060593 00000 n -0000060924 00000 n -0000061178 00000 n -0000061440 00000 n -0000061694 00000 n -0000061957 00000 n -0000062210 00000 n -0000062473 00000 n -0000062727 00000 n -0000062981 00000 n -0000063234 00000 n -0000063472 00000 n -0000063883 00000 n -0000064157 00000 n -0000064411 00000 n -0000064665 00000 n -0000064904 00000 n -0000065255 00000 n -0000065509 00000 n -0000065763 00000 n -0000066009 00000 n -0000066335 00000 n -0000066619 00000 n -0000066918 00000 n -0000067172 00000 n +0000056283 00000 n +0000056537 00000 n +0000056791 00000 n +0000057045 00000 n +0000057299 00000 n +0000057553 00000 n +0000057807 00000 n +0000058052 00000 n +0000058306 00000 n +0000058560 00000 n +0000058814 00000 n +0000059068 00000 n +0000059327 00000 n +0000059753 00000 n +0000060052 00000 n +0000060291 00000 n +0000060612 00000 n +0000060866 00000 n +0000061105 00000 n +0000061436 00000 n +0000061690 00000 n +0000061952 00000 n +0000062206 00000 n +0000062469 00000 n +0000062722 00000 n +0000062985 00000 n +0000063239 00000 n +0000063493 00000 n +0000063746 00000 n +0000063984 00000 n +0000064395 00000 n +0000064669 00000 n +0000064923 00000 n +0000065177 00000 n +0000065416 00000 n +0000065767 00000 n +0000066021 00000 n +0000066275 00000 n +0000066521 00000 n +0000066847 00000 n +0000067131 00000 n 0000067430 00000 n 0000067684 00000 n -0000067937 00000 n -0000068288 00000 n -0000068542 00000 n -0000068796 00000 n -0000069057 00000 n -0000069318 00000 n -0000069570 00000 n -0000069823 00000 n -0000070075 00000 n -0000070329 00000 n -0000070583 00000 n -0000070837 00000 n -0000071091 00000 n -0000071331 00000 n -0000071747 00000 n -0000072046 00000 n -0000072298 00000 n -0000072537 00000 n -0000072853 00000 n -0000073152 00000 n -0000073390 00000 n -0000073711 00000 n -0000073965 00000 n -0000074238 00000 n +0000067942 00000 n +0000068196 00000 n +0000068449 00000 n +0000068800 00000 n +0000069054 00000 n +0000069308 00000 n +0000069569 00000 n +0000069830 00000 n +0000070082 00000 n +0000070335 00000 n +0000070587 00000 n +0000070841 00000 n +0000071095 00000 n +0000071349 00000 n +0000071603 00000 n +0000071843 00000 n +0000072259 00000 n +0000072558 00000 n +0000072810 00000 n +0000073049 00000 n +0000073365 00000 n +0000073664 00000 n +0000073902 00000 n +0000074223 00000 n 0000074477 00000 n -0000074818 00000 n -0000075072 00000 n -0000075311 00000 n -0000075627 00000 n -0000075926 00000 n -0000076180 00000 n +0000074750 00000 n +0000074989 00000 n +0000075330 00000 n +0000075584 00000 n +0000075823 00000 n +0000076139 00000 n 0000076438 00000 n -0000076769 00000 n -0000077008 00000 n -0000077329 00000 n -0000077568 00000 n -0000077874 00000 n -0000078173 00000 n -0000078427 00000 n -0000078666 00000 n -0000078997 00000 n -0000079251 00000 n -0000079490 00000 n -0000079806 00000 n -0000080091 00000 n -0000080255 00000 n -0000080505 00000 n -0000080634 00000 n -0000080888 00000 n -0000081085 00000 n -0000081299 00000 n -0000081513 00000 n -0000081739 00000 n -0000081941 00000 n -0000082150 00000 n -0000082347 00000 n -0000082550 00000 n -0000082751 00000 n -0000082969 00000 n -0000083170 00000 n -0000083384 00000 n -0000083579 00000 n -0000083777 00000 n -0000084013 00000 n -0000084193 00000 n -0000084417 00000 n -0000084627 00000 n -0000084826 00000 n -0000085028 00000 n -0000085236 00000 n -0000085441 00000 n -0000085641 00000 n -0000085840 00000 n -0000086050 00000 n -0000086263 00000 n -0000086469 00000 n -0000086671 00000 n -0000086894 00000 n -0000087121 00000 n -0000087334 00000 n -0000087534 00000 n -0000087726 00000 n -0000087911 00000 n -0000088439 00000 n -0000091484 00000 n -0000100965 00000 n -0000107022 00000 n -0000111541 00000 n -0000115663 00000 n -0000119636 00000 n -0000124723 00000 n -0000129103 00000 n -0000134081 00000 n -0000140313 00000 n -0000144634 00000 n -0000149004 00000 n -0000152638 00000 n -0000157007 00000 n -0000163359 00000 n -0000170029 00000 n -0000177147 00000 n -0000185873 00000 n -0000191788 00000 n -0000195423 00000 n -0000201057 00000 n -0000207199 00000 n -0000213721 00000 n -0000218220 00000 n -0000222648 00000 n -0000226956 00000 n -0000231743 00000 n -0000236890 00000 n -0000241961 00000 n -0000246272 00000 n -0000251667 00000 n -0000255438 00000 n -0000260932 00000 n -0000265875 00000 n -0000270128 00000 n -0000274865 00000 n -0000279796 00000 n -0000284646 00000 n -0000289554 00000 n -0000293166 00000 n -0000298044 00000 n -0000304903 00000 n -0000306717 00000 n -0000307434 00000 n -0000307513 00000 n -0000307592 00000 n -0000307671 00000 n -0000307750 00000 n -0000307829 00000 n -0000307908 00000 n -0000307987 00000 n -0000308066 00000 n -0000308145 00000 n -0000308225 00000 n -0000308305 00000 n -0000308385 00000 n -0000308465 00000 n -0000308545 00000 n -0000308625 00000 n -0000308705 00000 n -0000308785 00000 n -0000308865 00000 n -0000308945 00000 n -0000309025 00000 n -0000309105 00000 n -0000309185 00000 n -0000309265 00000 n -0000309345 00000 n -0000309425 00000 n -0000309505 00000 n -0000309585 00000 n -0000309665 00000 n -0000309745 00000 n -0000309825 00000 n -0000309905 00000 n -0000309985 00000 n -0000310065 00000 n -0000310145 00000 n -0000310225 00000 n -0000310305 00000 n -0000310385 00000 n -0000310465 00000 n -0000310545 00000 n -0000310625 00000 n -0000310705 00000 n -0000310785 00000 n +0000076692 00000 n +0000076950 00000 n +0000077281 00000 n +0000077520 00000 n +0000077841 00000 n +0000078095 00000 n +0000078334 00000 n +0000078650 00000 n +0000078949 00000 n +0000079188 00000 n +0000079509 00000 n +0000079763 00000 n +0000080002 00000 n +0000080333 00000 n +0000080572 00000 n +0000080878 00000 n +0000081163 00000 n +0000081327 00000 n +0000081577 00000 n +0000081706 00000 n +0000081960 00000 n +0000082157 00000 n +0000082371 00000 n +0000082585 00000 n +0000082811 00000 n +0000083013 00000 n +0000083222 00000 n +0000083419 00000 n +0000083622 00000 n +0000083823 00000 n +0000084041 00000 n +0000084242 00000 n +0000084456 00000 n +0000084651 00000 n +0000084849 00000 n +0000085085 00000 n +0000085265 00000 n +0000085489 00000 n +0000085699 00000 n +0000085898 00000 n +0000086100 00000 n +0000086308 00000 n +0000086513 00000 n +0000086713 00000 n +0000086912 00000 n +0000087122 00000 n +0000087335 00000 n +0000087541 00000 n +0000087743 00000 n +0000087966 00000 n +0000088193 00000 n +0000088393 00000 n +0000088606 00000 n +0000088806 00000 n +0000088998 00000 n +0000089183 00000 n +0000089721 00000 n +0000092766 00000 n +0000102496 00000 n +0000108553 00000 n +0000113072 00000 n +0000117194 00000 n +0000121167 00000 n +0000126254 00000 n +0000130634 00000 n +0000135612 00000 n +0000141844 00000 n +0000146165 00000 n +0000150535 00000 n +0000154169 00000 n +0000158538 00000 n +0000164890 00000 n +0000171560 00000 n +0000178678 00000 n +0000187404 00000 n +0000193319 00000 n +0000196954 00000 n +0000202588 00000 n +0000208730 00000 n +0000215252 00000 n +0000219751 00000 n +0000224179 00000 n +0000228487 00000 n +0000233274 00000 n +0000238421 00000 n +0000243492 00000 n +0000247803 00000 n +0000253198 00000 n +0000256969 00000 n +0000262463 00000 n +0000267406 00000 n +0000271659 00000 n +0000276396 00000 n +0000281327 00000 n +0000286032 00000 n +0000291704 00000 n +0000295024 00000 n +0000299605 00000 n +0000305885 00000 n +0000310323 00000 n +0000311120 00000 n +0000311852 00000 n +0000311931 00000 n +0000312010 00000 n +0000312089 00000 n +0000312168 00000 n +0000312247 00000 n +0000312326 00000 n +0000312405 00000 n +0000312484 00000 n +0000312563 00000 n +0000312643 00000 n +0000312723 00000 n +0000312803 00000 n +0000312883 00000 n +0000312963 00000 n +0000313043 00000 n +0000313123 00000 n +0000313203 00000 n +0000313283 00000 n +0000313363 00000 n +0000313443 00000 n +0000313523 00000 n +0000313603 00000 n +0000313683 00000 n +0000313763 00000 n +0000313843 00000 n +0000313923 00000 n +0000314003 00000 n +0000314083 00000 n +0000314163 00000 n +0000314243 00000 n +0000314323 00000 n +0000314403 00000 n +0000314483 00000 n +0000314563 00000 n +0000314643 00000 n +0000314723 00000 n +0000314803 00000 n +0000314883 00000 n +0000314963 00000 n +0000315043 00000 n +0000315123 00000 n +0000315203 00000 n +0000315283 00000 n trailer << /ID % ReportLab generated PDF document -- digest (http://www.reportlab.com) - [(\260\201\222\340\217\207\014\373\005\024\270z\002Q\314\373) (\260\201\222\340\217\207\014\373\005\024\270z\002Q\314\373)] + [(\264*\221\021\265;\202\277\256k\312\271\011\200e&) (\264*\221\021\265;\202\277\256k\312\271\011\200e&)] - /Info 303 0 R - /Root 302 0 R - /Size 428 >> + /Info 307 0 R + /Root 306 0 R + /Size 435 >> startxref -310834 +315332 %%EOF diff --git a/plac/doc/plac_adv.txt b/plac/doc/plac_adv.txt index e4c251b..4477781 100644 --- a/plac/doc/plac_adv.txt +++ b/plac/doc/plac_adv.txt @@ -1018,15 +1018,39 @@ task runs and more values are yielded. Accessing the ``.outlist`` is nonblocking and can be done freely. Finally there is a ``.result`` property which waits for the task to finish and returns the last yielded -value or raises an exception. - -Here is some example code to visualize the output of the FakeImporter -in Tkinter (I chose Tkinter because it is easy to use and it is -in the standard library, but you can use any GUI): +value or raises an exception. The code below provides an example of +how you could implement a GUI over the importer example: .. include:: importer_ui.py :literal: +Monitor support +-------------------------------- + +Starting from release 0.8 plac_ provides builtin support for monitoring the +output of concurrent commands, at least for platforms where multiprocessing +is fully supported. You can define your own monitor +class, simply by inheriting from ``plac.Monitor`` and by +overriding the methods ``add_listener(self, no)``, +``del_listener(self, taskno)``, ``notify_listener(self, taskno, msg)``, +``schedule(self, seconds, func, arg)`` and ``run(self)``. +Then, you can a monitor object to any ``plac.Interpreter`` object +by simply calling the ``add_monitor`` method. +For convenience, +``plac`` comes with a very simple ``TkMonitor`` based on Tkinter +(I chose Tkinter because it is easy to use and it is +in the standard library, but you can use any GUI): you can just +look at how the ``TkMonitor`` is implemented in ``plac_tk.py`` +and adapt it. Here is an example of usage of the ``TkMonitor``: + +.. include:: tkmon.py + :literal: + +Try to give the ``hello`` command from the interactive interpreter: +each time a new text widget will be added displaying the output +of the command. Notice that if ``Tkinter`` is not installed correctly +on your system the ``TkMonitor`` class will not be available. + Parallel computing with plac --------------------------------------------- @@ -1092,7 +1116,7 @@ mode is some 20% slower than the sequential mode. Since the pattern submit a bunch of tasks, starts them and collect the results is so common, plac_ provides an utility function -``runp(genseq, mode='p', start=True)`` to start +``runp(genseq, mode='p', monitors=(), start=True)`` to start a bunch a generators and return a list of task objects. By default ``runp`` use processes, but you can use threads by passing ``mode='t'``. If you do not wont to start the tasks, you can say so (``start=False``). @@ -1100,6 +1124,10 @@ With ``runp`` the parallel pi calculation becomes a one-liner:: sum(task.result for task in plac.runp(calc_pi(N) for i in range(ncpus)))/ncpus +The file ``test_runp`` in the ``doc`` directory of the plac distribution +shows another couple of examples of usage, including how to show the +results of the running computation on a ``TkMonitor``. + The plac server ------------------------------------------------------- diff --git a/plac/doc/test_runp.py b/plac/doc/test_runp.py index 65980f8..619fc1f 100644 --- a/plac/doc/test_runp.py +++ b/plac/doc/test_runp.py @@ -14,13 +14,11 @@ def test(): tasks = plac.runp([gen(3), gen(5), gen(10)]) for t in tasks: t.result + t.man.stop() def test_tkmonitor(): mon = plac_tk.TkMonitor('tkmon') - i = plac.Interpreter.from_gen([gen(3), gen(5), gen(10)], 'p', [mon]) - with i: - for t in i.tasks(): - t.run() - for t in i.tasks(): - t.result - i.man.stop() + tasks = plac.runp([gen(3), gen(5), gen(10)], monitors=[mon]) + for t in tasks: + t.result + t.man.stop() diff --git a/plac/plac.py b/plac/plac.py index 8296500..c762cca 100644 --- a/plac/plac.py +++ b/plac/plac.py @@ -32,4 +32,8 @@ __version__ = '0.8.0' from plac_core import * if sys.version >= '2.5': - from plac_ext import Interpreter, import_main, ReadlineInput, stdout, runp, Manager + from plac_ext import Interpreter, import_main, ReadlineInput, stdout, runp, Monitor + try: + from plac_tk import TkMonitor + except ImportError: + pass diff --git a/plac/plac_ext.py b/plac/plac_ext.py index a7596c3..4429aec 100644 --- a/plac/plac_ext.py +++ b/plac/plac_ext.py @@ -357,7 +357,7 @@ class MPTask(BaseTask): return [] def notify(self, msg): - self.man.send('notify_task %d %r' % (self.no, msg)) + self.man.send('notify_listener %d %r' % (self.no, msg)) def __init__(self, no, arglist, genobj, manager): """ @@ -567,17 +567,17 @@ plac.Interpreter(plac.import_main(*%s)).interact(prompt='i>\\n') class Monitor(object): """ - Base monitor class with methods add_task/del_task/notify_task + Base monitor class with methods add_listener/del_listener/notify_listener and start/stop/schedule/slave. """ - commands = 'add_task', 'del_task', 'notify_task' + commands = 'add_listener', 'del_listener', 'notify_listener' def __init__(self, name): self.name = name - def add_task(self, taskno): + def add_listener(self, taskno): pass - def del_task(self, taskno): + def del_listener(self, taskno): pass - def notify_task(self, taskno, msg): + def notify_listener(self, taskno, msg): pass def start(self): pass @@ -622,7 +622,7 @@ class SlaveProcess(object): with Interpreter(self.mon) as i: # .schedule() must be invoked inside the with block self.mon.schedule(.1, self._sendline, i) - self.mon.start() + self.mon.run() class StartStopObject(object): started = False @@ -814,7 +814,7 @@ class Interpreter(object): if not plac_core._match_cmd(arglist[0], self.tm.specialcommands): self.tm.registry[task.no] = task if m: - m.send('add_task %d' % task.no) + m.send('add_listener %d' % task.no) return task def send(self, line): @@ -1006,18 +1006,6 @@ class Interpreter(object): else: i.parser.print_usage() - @classmethod - def from_gen(cls, genseq, mode='p', monitors=()): - "Returns an interpreter object able to run the tasks in the sequence" - assert mode in 'pt', mode - launcher = _TaskLauncher(genseq, mode) - self = cls(launcher).__enter__() - for mon in monitors: - self.add_monitor(mon) - for i in range(len(launcher.genlist)): - self.submit('rungen %d' % (i + 1)) - return self - #################################### runp ##################################### class _TaskLauncher(object): @@ -1034,12 +1022,18 @@ class _TaskLauncher(object): for out in self.genlist[int(i) - 1]: yield out -def runp(genseq, mode='p', start=True): +def runp(genseq, mode='p', monitors=(), start=True): """Run a sequence of generators in parallel. Mode can be 'p' (use processes) or 't' (use threads). Return a list of running task objects. If start is False, the tasks are only submitted and not automatically started. """ - inter = Interpreter.from_gen(genseq, mode) + assert mode in 'pt', mode + launcher = _TaskLauncher(genseq, mode) + inter = Interpreter(launcher).__enter__() + for mon in monitors: # must be added before submit + inter.add_monitor(mon) + for i in range(len(launcher.genlist)): + inter.submit('rungen %d' % (i + 1)) if start: for task in inter.tasks(): task.run() -- cgit v1.2.1