Commits

Mathieu D. committed 1d71c0f

remove forgotten 'src' folder

Comments (0)

Files changed (90)

src/.DS_Store

Binary file removed.

src/AppFrameworks.rst

-
-*******************************************************************************
-Building Application Frameworks
-*******************************************************************************
-
-An application framework allows you to inherit from a class or set of classes
-and create a new application, reusing most of the code in the existing classes
-and overriding one or more methods in order to customize the application to your
-needs. A fundamental concept in the application framework is the *Template
-Method* which is typically hidden beneath the covers and drives the application
-by calling the various methods in the base class (some of which you have
-overridden in order to create the application).
-
-For example, whenever you create an applet you're using an application
-framework: you inherit from **JApplet** and then override **init( )**. The
-applet mechanism (which is a *Template Method*) does the rest by drawing the
-screen, handling the event loop, resizing, etc.
-
-Template Method
-=======================================================================
-
-An important characteristic of the *Template Method* is that it is defined in
-the base class and cannot be changed. It's sometimes a **private** method but
-it's virtually always **final**. It calls other base-class methods (the ones you
-override) in order to do its job, but it is usually called only as part of an
-initialization process (and thus the client programmer isn't necessarily able to
-call it directly)::
-
-    # AppFrameworks/TemplateMethod.py
-    # Simple demonstration of Template Method.
-
-    class ApplicationFramework:
-        def __init__(self):
-            self.__templateMethod()
-        def __templateMethod(self):
-            for i in range(5):
-                self.customize1()
-                self.customize2()
-
-    # Create an "application":
-    class MyApp(ApplicationFramework):
-        def customize1(self):
-            print("Nudge, nudge, wink, wink! ",)
-        def customize2(self):
-            print("Say no more, Say no more!")
-
-    MyApp()
-
-
-
-The base-class constructor is responsible for performing the necessary
-initialization and then starting the "engine" (the template method) that runs
-the application (in a GUI application, this "engine" would be the main event
-loop). The client programmer simply provides definitions for **customize1( )**
-and **customize2( )** and the "application" is ready to run.
-
-We'll see *Template Method* numerous other times throughout the book.
-
-Exercises
-=======================================================================
-
-#.  Create a framework that takes a list of file names on the command line. It
-    opens each file except the last for reading, and the last for writing. The
-    framework will process each input file using an undetermined policy and
-    write the output to the last file. Inherit to customize this framework to
-    create two separate applications:
-
-        #. Converts all the letters in each file to uppercase.
-        #. Searches the files for words given in the first file.
-
-
-

src/CanonicalScript.rst

-..  index::
-    triple: script; command-line; canonical form
-
-****************************************************************************
-A Canonical Form for Command-Line Programs
-****************************************************************************
-
-Creating Python programs for command-line use involves a certain amount of
-repetitious coding, which can often be left off or forgotten. Here is a form
-which includes everthing.
-
-Note that if you are using Windows, you can add Python programs to your "File
-New" menu and automatically include the above text in the new file. `This
-article <http://articles.techrepublic.com.com/5100-10878_11-5034852.html>`_
-shows you how. Other operating systems have their own automation features.

src/ChangeInterface.rst

-
-********************************************************************************
-Changing the Interface
-********************************************************************************
-
-Sometimes the problem that you're solving is as simple as "I don't have the
-interface that I want." Two of the patterns in *Design Patterns* solve this
-problem: *Adapter* takes one type and produces an interface to some other type.
-*Façade* creates an interface to a set of classes, simply to provide a more
-comfortable way to deal with a library or bundle of resources.
-
-Adapter
-=======================================================================
-
-When you've got *this*, and you need *that*, *Adapter* solves the problem. The
-only requirement is to produce a *that*, and there are a number of ways you can
-accomplish this adaptation::
-
-    # ChangeInterface/Adapter.py
-    # Variations on the Adapter pattern.
-
-    class WhatIHave:
-        def g(self): pass
-        def h(self): pass
-
-    class WhatIWant:
-        def f(self): pass
-
-    class ProxyAdapter(WhatIWant):
-        def __init__(self, whatIHave):
-            self.whatIHave = whatIHave
-
-        def f(self):
-            # Implement behavior using
-            # methods in WhatIHave:
-            self.whatIHave.g()
-            self.whatIHave.h()
-
-    class WhatIUse:
-        def op(self, whatIWant):
-            whatIWant.f()
-
-    # Approach 2: build adapter use into op():
-    class WhatIUse2(WhatIUse):
-        def op(self, whatIHave):
-            ProxyAdapter(whatIHave).f()
-
-    # Approach 3: build adapter into WhatIHave:
-    class WhatIHave2(WhatIHave, WhatIWant):
-        def f(self):
-            self.g()
-            self.h()
-
-    # Approach 4: use an inner class:
-    class WhatIHave3(WhatIHave):
-        class InnerAdapter(WhatIWant):
-            def __init__(self, outer):
-                self.outer = outer
-            def f(self):
-                self.outer.g()
-                self.outer.h()
-
-        def whatIWant(self):
-            return WhatIHave3.InnerAdapter(self)
-
-    whatIUse = WhatIUse()
-    whatIHave = WhatIHave()
-    adapt= ProxyAdapter(whatIHave)
-    whatIUse2 = WhatIUse2()
-    whatIHave2 = WhatIHave2()
-    whatIHave3 = WhatIHave3()
-    whatIUse.op(adapt)
-    # Approach 2:
-    whatIUse2.op(whatIHave)
-    # Approach 3:
-    whatIUse.op(whatIHave2)
-    # Approach 4:
-    whatIUse.op(whatIHave3.whatIWant())
-
-I'm taking liberties with the term "proxy" here, because in *Design Patterns*
-they assert that a proxy must have an identical interface with the object that
-it is a surrogate for. However, if you have the two words together: "proxy
-adapter," it is perhaps more reasonable.
-
-Façade
-=======================================================================
-
-A general principle that I apply when I'm casting about trying to mold
-requirements into a first-cut object is "If something is ugly, hide it inside an
-object." This is basically what *Façade* accomplishes. If you have a rather
-confusing collection of classes and interactions that the client programmer
-doesn't really need to see, then you can create an interface that is useful for
-the client programmer and that only presents what's necessary.
-
-Façade is often implemented as singleton abstract factory. Of course, you can
-easily get this effect by creating a class containing **static** factory
-methods::
-
-    # ChangeInterface/Facade.py
-    class A:
-        def __init__(self, x): pass
-    class B:
-        def __init__(self, x): pass
-    class C:
-        def __init__(self, x): pass
-
-    # Other classes that aren't exposed by the
-    # facade go here ...
-
-    class Facade:
-        def makeA(x): return A(x)
-        makeA = staticmethod(makeA)
-        def makeB(x): return B(x)
-        makeB = staticmethod(makeB)
-        def makeC(x): return C(x)
-        makeC = staticmethod(makeC)
-
-    # The client programmer gets the objects
-    # by calling the static methods:
-    a = Facade.makeA(1);
-    b = Facade.makeB(1);
-    c = Facade.makeC(1.0);
-
-[rewrite this section using research from Larman's book]
-
-Example for Facade (?): my "nicer" version of the XML library.
-
-Exercises
-=======================================================================
-
-#.  Create an adapter class that automatically loads a two-dimensional array of
-    objects into a dictionary as key-value pairs.
-
-
-

src/CodeManager.py

-# CodeManager.py
-"""
-Extracts, displays, checks and updates code examples in restructured text (.rst)
-files.
-
-You can just put in the codeMarker and the (indented) first line (containing the
-file path) into your restructured text file, then run the update program to
-automatically insert the rest of the file.
-"""
-import os, re, sys, shutil, inspect, difflib
-
-restFiles = [os.path.join(d[0], f) for d in os.walk(".") if not "_test" in d[0]
-             for f in d[2] if f.endswith(".rst")]
-
-class Languages:
-    "Strategy design pattern"
-
-    class Python:
-        codeMarker = "::\n\n"
-        commentTag = "#"
-        listings = re.compile("::\n\n( {4}#.*(?:\n+ {4}.*)*)")
-
-    class Java:
-        codeMarker = "..  code-block:: java\n\n"
-        commentTag = "//"
-        listings = \
-            re.compile(".. *code-block:: *java\n\n( {4}//.*(?:\n+ {4}.*)*)")
-
-def shift(listing):
-    "Shift the listing left by 4 spaces"
-    return [x[4:] if x.startswith("    ") else x for x in listing.splitlines()]
-
-def difference(listing1, listing2):
-    "Is there any difference between these two code listings?"
-    if type(listing1) is not list:
-        listing1 = listing1.splitlines()
-    if type(listing2) is not list:
-        listing2 = listing2.splitlines()
-    for line1, line2 in zip(listing1, listing2):
-        if line1 != line2:
-            return True
-    return False
-
-class Commands:
-    """
-    Each static method can be called from the command line. Add a new static
-    method here to add a new command to the program.
-    """
-
-    @staticmethod
-    def display(language):
-        """
-        Print all the code listings in the .rst files.
-        """
-        for f in restFiles:
-            listings = language.listings.findall(open(f).read())
-            if not listings: continue
-            print('=' * 60 + "\n" + f + "\n" + '=' * 60)
-            for n, l in enumerate(listings):
-                print("\n".join(shift(l)))
-                if n < len(listings) - 1:
-                    print('-' * 60)
-
-    @staticmethod
-    def extract(language):
-        """
-        Pull the code listings from the .rst files and write each listing into
-        its own file. Will not overwrite if code files and .rst files disagree
-        unless you say "extract -force".
-        """
-        force = len(sys.argv) == 3 and sys.argv[2] == '-force'
-        paths = set()
-        for listing in [shift(listing) for f in restFiles
-                    for listing in language.listings.findall(open(f).read())]:
-            path = listing[0][len(language.commentTag):].strip()
-            if path in paths:
-                print("ERROR: Duplicate file name: %s" % path)
-                sys.exit(1)
-            else:
-                paths.add(path)
-            path = os.path.join("..", "code", path)
-            dirname = os.path.dirname(path)
-            if dirname and not os.path.exists(dirname):
-                os.makedirs(dirname)
-            if os.path.exists(path) and not force:
-                if difference(open(path).read(), listing):
-                    print("ERROR: Existing file different from .rst")
-                    print("Use 'extract -force' to force overwrite")
-                    Commands.check(language)
-                    return
-            file(path, 'w').write("\n".join(listing))
-
-    @staticmethod
-    def check(language, verbose=True):
-        """
-        Ensure that external code files exist and check which external files
-        have changed from what's in the .rst files. Generate files in the
-        _deltas subdirectory showing what has changed.
-        """
-        class Result: # Messenger
-            def __init__(self, **kwargs):
-                self.__dict__ = kwargs
-        result = Result(missing = [], deltas = [])
-        listings = [Result(code = shift(code), file = f)
-                    for f in restFiles for code in
-                    language.listings.findall(open(f).read())]
-        paths = [os.path.normpath(os.path.join("..", "code", path)) for path in
-                    [listing.code[0].strip()[len(language.commentTag):].strip()
-                     for listing in listings]]
-        if os.path.exists("_deltas"):
-            shutil.rmtree("_deltas")
-        for path, listing in zip(paths, listings):
-            if not os.path.exists(path):
-                result.missing.append(path)
-            else:
-                code = open(path).read().splitlines()
-                if difference(listing.code, code):
-                    d = difflib.HtmlDiff()
-                    if not os.path.exists("_deltas"):
-                        os.makedirs("_deltas")
-                    html = os.path.join("_deltas",
-                        os.path.basename(path).split('.')[0] + ".html")
-                    open(html, 'w').write(
-                        "<html><h1>Left: %s<br>Right: %s</h1>" %
-                        (listing.file, path) +
-                        d.make_file(listing.code, code))
-                    result.deltas.append(Result(file = listing.file,
-                        path = path, html = html, code = code))
-        if result.missing:
-            print("Missing %s files:\n%s" %
-                  (language.__name__, "\n".join(result.missing)))
-        if verbose:
-            for delta in result.deltas:
-                print("%s <==> %s; see %s" %
-                    (delta.file, delta.path, delta.html))
-        return result
-
-    changed = False # Whether .rst file has changed
-
-    @staticmethod
-    def update(language):
-        """
-        Refresh external code files into .rst files.
-        """
-        force = len(sys.argv) == 3 and sys.argv[2] == '-force'
-        check_result = Commands.check(language, verbose=False)
-        if check_result.missing:
-            print(language.__name__, "update aborted")
-            return
-        if not force and check_result.deltas:
-            print("The following files will be updated when you add -force:")
-            for delta in check_result.deltas:
-                print("%s via %s" % (delta.file, delta.path))
-            print("For details, see corresponding files in _deltas")
-            return
-        def _update(matchobj):
-            listing = shift(matchobj.group(1))
-            path = os.path.join("..", "code",
-                listing[0].strip()[len(language.commentTag):].strip())
-            code = open(path).read().splitlines()
-            if difference(listing, code):
-                Commands.changed = True
-            return language.codeMarker + \
-                "\n".join([("    " + line).rstrip() for line in code])
-        for f in restFiles:
-            Commands.changed = False
-            updated = language.listings.sub(_update, open(f).read())
-            if Commands.changed:
-                print("updating %s" % f)
-                open(f, 'w').write(updated)
-
-if __name__ == "__main__":
-    commands = dict(inspect.getmembers(Commands, inspect.isfunction))
-    if len(sys.argv) < 2 or sys.argv[1] not in commands:
-        print("Command line options:\n")
-        for name in commands:
-            print(name + ": " + commands[name].__doc__)
-    else:
-        for language in inspect.getmembers(Languages, inspect.isclass):
-            commands[sys.argv[1]](language[1])

src/Comprehensions.rst

-.. index::
-   pair: list; comprehension
-   pair: generator; comprehension
-
-********************************************************************************
-Comprehensions
-********************************************************************************
-
-History: where did they come from?
-
-They require a mind shift.
-
-What makes them so compelling (once you 'get it')?
-
-..  Todo history: from functional programming (Haskell) via set builder 
-
-Comprehensions are constructs that allow sequences to be built from other sequences. Python 2.0 introduced list comprehensions and Python 3.0 comes with dictionary and set comprehensions.
-
-List Comprehensions
-=======================================================================
-
-A list comprehension consists of the following parts:
-
-- An Input Sequence.
-- A Variable representing members of the input sequence.
-- An Optional Predicate expression.
-- An Output Expression producing elements of the output list from members of the Input Sequence that satisfy the predicate.
-
-Say we need to obtain a list of all the integers in a sequence and then square them::
-
-    a_list = [1, ‘4’, 9, ‘a’, 0, 4]
-    squared_ints = [ e**2 for e in a_list if type(e) == types.IntType ] 
-    print squared_ints 
-    # [ 1, 81, 0, 16 ]
-    
-.. image:: _images/listComprehensions.*
-
-- The iterator part iterates through each member **e** of the input sequence **a_list**.
-- The predicate checks if the member is an integer. 
-- If the member is an integer then it is passed to the output expression, squared, to become a member of the output list.
-
-Much the same results can be achieved using the built in functions, **map**, **filter** and the anonymous **lambda** function. 
-
-The filter function applies a predicate to a sequence::
-
-    filter(lambda e: type(e) == types.IntType, a_list)
-    
-Map modifies each member of a sequence::
-
-    map(lambda e: e**2, a_list)
-
-The two can be combined::
-
-    map(lambda e: e**2, filter(lambda e: type(e) == types.IntType, a_list))
-    
-The above example involves function calls to **map**, **filter**, **type** and two calls to **lambda**. Function calls in Python are expensive. Furthermore the input sequence is traversed through twice and an intermediate list is produced by filter.
-
-The list comprehension is enclosed within a list so, it is immediately evident that a list is being produced. There is only one function call to **type** and no call to the cryptic **lambda** instead the list comprehension uses a conventional iterator, an expression and an if expression for the optional predicate.
-
-
-Nested Comprehensions
-=======================================================================
-
-An identity matrix of size n is an n by n square matrix with ones on the main diagonal and zeros elsewhere. A 3 by 3 identity matrix is:
-
-.. insert picture of 3x3 matrix here.
-.. image:: _images/idMatrix.*
-
-In python we can represent such a matrix by a list of lists, where each sub-list represents a row. A 3 by 3 matrix would be represented by the following list::
-
-    [ [ 1, 0, 1 ],
-      [ 0, 1, 0 ],
-      [ 0, 0, 1 ] ]
-
-
-.. Would be more efficient to represent the structure as a tuple of tuples, but the whole point of this
-.. example is to use lists.
-
-  
-The above matrix can be generated by the following comprehension::
-
-    [ [ 1 if item_idx == row_idx else 0 for item_idx in range(0, 3) ] for row_idx in range(0, 3) ]
-
-
-Techniques
-==============================================================================
-
-Using ``zip()`` and dealing with two or more elements at a time::
-
-    ['%s=%s' % (n, v) for n, v in zip(self.all_names, self)]
-
-Multiple types (auto unpacking of a tuple)::
-
-    [f(v) for (n, f), v in zip(cls.all_slots, values)]
-
-A two-level list comprehension using ``os.walk()``::
-
-    # Comprehensions/os_walk_comprehension.py
-    import os
-    restFiles = [os.path.join(d[0], f) for d in os.walk(".")
-                 for f in d[2] if f.endswith(".rst")]
-    for r in restFiles:
-        print(r)
-
-
-A More Complex Example
-==============================================================================
-
-..  note:: This will get a full description of all parts.
-
-::
-
-    # CodeManager.py
-    """
-    TODO: Break check into two pieces?
-    TODO: update() is still only in test mode; doesn't actually work yet.
-
-    Extracts, displays, checks and updates code examples in restructured text (.rst)
-    files.
-
-    You can just put in the codeMarker and the (indented) first line (containing the
-    file path) into your restructured text file, then run the update program to
-    automatically insert the rest of the file.
-    """
-    import os, re, sys, shutil, inspect, difflib
-
-    restFiles = [os.path.join(d[0], f) for d in os.walk(".") if not "_test" in d[0]
-                 for f in d[2] if f.endswith(".rst")]
-
-    class Languages:
-        "Strategy design pattern"
-
-        class Python:
-            codeMarker = "::\n\n"
-            commentTag = "#"
-            listings = re.compile("::\n\n( {4}#.*(?:\n+ {4}.*)*)")
-
-        class Java:
-            codeMarker = "..  code-block:: java\n\n"
-            commentTag = "//"
-            listings = \
-                re.compile(".. *code-block:: *java\n\n( {4}//.*(?:\n+ {4}.*)*)")
-
-    def shift(listing):
-        "Shift the listing left by 4 spaces"
-        return [x[4:] if x.startswith("    ") else x for x in listing.splitlines()]
-
-    # TEST - makes duplicates of the rst files in a test directory to test update():
-    dirs = set([os.path.join("_test", os.path.dirname(f)) for f in restFiles])
-    if [os.makedirs(d) for d in dirs if not os.path.exists(d)]:
-        [shutil.copy(f, os.path.join("_test", f)) for f in restFiles]
-    testFiles = [os.path.join(d[0], f) for d in os.walk("_test")
-                 for f in d[2] if f.endswith(".rst")]
-
-    class Commands:
-        """
-        Each static method can be called from the command line. Add a new static
-        method here to add a new command to the program.
-        """
-
-        @staticmethod
-        def display(language):
-            """
-            Print all the code listings in the .rst files.
-            """
-            for f in restFiles:
-                listings = language.listings.findall(open(f).read())
-                if not listings: continue
-                print('=' * 60 + "\n" + f + "\n" + '=' * 60)
-                for n, l in enumerate(listings):
-                    print("\n".join(shift(l)))
-                    if n < len(listings) - 1:
-                        print('-' * 60)
-
-        @staticmethod
-        def extract(language):
-            """
-            Pull the code listings from the .rst files and write each listing into
-            its own file. Will not overwrite if code files and .rst files disagree
-            unless you say "extract -force".
-            """
-            force = len(sys.argv) == 3 and sys.argv[2] == '-force'
-            paths = set()
-            for listing in [shift(listing) for f in restFiles
-                        for listing in language.listings.findall(open(f).read())]:
-                path = listing[0][len(language.commentTag):].strip()
-                if path in paths:
-                    print("ERROR: Duplicate file name: %s" % path)
-                    sys.exit(1)
-                else:
-                    paths.add(path)
-                path = os.path.join("..", "code", path)
-                dirname = os.path.dirname(path)
-                if dirname and not os.path.exists(dirname):
-                    os.makedirs(dirname)
-                if os.path.exists(path) and not force:
-                    for i in difflib.ndiff(open(path).read().splitlines(), listing):
-                        if i.startswith("+ ") or i.startswith("- "):
-                            print("ERROR: Existing file different from .rst")
-                            print("Use 'extract -force' to force overwrite")
-                            Commands.check(language)
-                            return
-                file(path, 'w').write("\n".join(listing))
-
-        @staticmethod
-        def check(language):
-            """
-            Ensure that external code files exist and check which external files
-            have changed from what's in the .rst files. Generate files in the
-            _deltas subdirectory showing what has changed.
-            """
-            class Result: # Messenger
-                def __init__(self, **kwargs):
-                    self.__dict__ = kwargs
-            result = Result(missing = [], deltas = [])
-            listings = [Result(code = shift(code), file = f)
-                        for f in restFiles for code in
-                        language.listings.findall(open(f).read())]
-            paths = [os.path.normpath(os.path.join("..", "code", path)) for path in
-                        [listing.code[0].strip()[len(language.commentTag):].strip()
-                         for listing in listings]]
-            if os.path.exists("_deltas"):
-                shutil.rmtree("_deltas")
-            for path, listing in zip(paths, listings):
-                if not os.path.exists(path):
-                    result.missing.append(path)
-                else:
-                    code = open(path).read().splitlines()
-                    for i in difflib.ndiff(listing.code, code):
-                        if i.startswith("+ ") or i.startswith("- "):
-                            d = difflib.HtmlDiff()
-                            if not os.path.exists("_deltas"):
-                                os.makedirs("_deltas")
-                            html = os.path.join("_deltas",
-                                os.path.basename(path).split('.')[0] + ".html")
-                            open(html, 'w').write(
-                                "<html><h1>Left: %s<br>Right: %s</h1>" %
-                                (listing.file, path) +
-                                d.make_file(listing.code, code))
-                            result.deltas.append(Result(file = listing.file,
-                                path = path, html = html, code = code))
-                            break
-            if result.missing:
-                print("Missing %s files:\n%s" %
-                      (language.__name__, "\n".join(result.missing)))
-            for delta in result.deltas:
-                print("%s changed in %s; see %s" %
-                      (delta.file, delta.path, delta.html))
-            return result
-
-        @staticmethod
-        def update(language): # Test until it is trustworthy
-            """
-            Refresh external code files into .rst files.
-            """
-            check_result = Commands.check(language)
-            if check_result.missing:
-                print(language.__name__, "update aborted")
-                return
-            changed = False
-            def _update(matchobj):
-                listing = shift(matchobj.group(1))
-                path = listing[0].strip()[len(language.commentTag):].strip()
-                filename = os.path.basename(path).split('.')[0]
-                path = os.path.join("..", "code", path)
-                code = open(path).read().splitlines()
-                return language.codeMarker + \
-                    "\n".join([("    " + line).rstrip() for line in listing])
-            for f in testFiles:
-                updated = language.listings.sub(_update, open(f).read())
-                open(f, 'w').write(updated)
-
-    if __name__ == "__main__":
-        commands = dict(inspect.getmembers(Commands, inspect.isfunction))
-        if len(sys.argv) < 2 or sys.argv[1] not in commands:
-            print("Command line options:\n")
-            for name in commands:
-                print(name + ": " + commands[name].__doc__)
-        else:
-            for language in inspect.getmembers(Languages, inspect.isclass):
-                commands[sys.argv[1]](language[1])
-                
-Set Comprehensions
-=======================================================================
-
-Set comprehensions allow sets to be constructed using the same principles as list comprehensions, the only difference is that resulting sequence is a set.
-
-Say we have a list of names. The list can contain names which only differ in the case used to represent them,   duplicates and names consisting of only one character. We are only interested in names longer then one character and wish to represent all names in the same format: The first letter should be capitalised, all other characters should be lower case.
-
-Given the list::
-
-    names = [ 'Bob', 'JOHN', 'alice', 'bob', 'ALICE', 'J', 'Bob' ]
-
-We require the set::
-
-    { 'Bob', 'John', 'Alice' }
-
-.. no need to include this if sets are defined else where in the document.
-
-Note the new syntax for denoting a set. Members are enclosed in curly braces. 
-
-The following set comprehension accomplishes this::
-
-    { name[0].upper() + name[1:].lower() for name in names if len(name) > 1 }
-
-
-.. the same could be achieved by embedding a list comprehension in a set:
-.. 
-..    set( [ name[0].upper() + name[1:].lower() for name in names if len(name) > 1 ] )    
-
-  
-
-                
-Dictionary Comprehensions
-=======================================================================
-
-Say we have a dictionary the keys of which are characters and the values of which map to the number of times that character appears in some text. The dictionary currently distinguishes between upper and lower case characters. 
-
-
-.. The following is inefficient: If both a lower case and upper case 
-.. character exists then the entry in the new dictionary is updated twice
-
-We require a dictionary in which the occurrences of upper and lower case characters are combined::
-
-    mcase = {'a':10, 'b': 34, 'A': 7, 'Z':3}
-
-    mcase_frequency = { k.lower() : mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0) for k in mcase.keys() }
-
-    # mcase_frequency == {'a': 17, 'z': 3, 'b': 34}
-
-
-.. Might be a good idea to mention that the comprehensions are eagerly evaluated and that 
-.. generators get around this problem
-
-.. note:: Contributions by Michael Charlton, 3/23/09 
-
-.. EOF

src/Contributors.rst

-*******************************************************************************
-Contributors
-*******************************************************************************
-
-List of contributors.
-
-..  Note::  This needs some thought. I want to include everyone who makes a
-            contribution, but I'd also like to indicate people who have made
-            larger contributions -- there's no automatic way to do this now
-            that we have moved to BitBucket and are using Wikis to allow people
-            to make contributions more simply in the beginning.
-
-Thanks To
-===============================================================================
-
-  * BitBucket.org and the creators of Mercurial
-
-  * Creator(s) of Sphinx
-
-  * And of course, Guido and the team for their incessant improvement of Python,
-    especially for taking the risk in breaking backward compatibility in Python
-    3.0 to refactor the language.
- 
-
-===============================================================================
-
-.. todo:: Yarko (example label of ToDo):
-
-    - update CSS styles for todo's & todo lists;
-    - look at http://sphinx.pocoo.org/ext/coverage.html for example.
-    - Autogenerated ToDoLists do not appear in LaTeX output - debug, fix;
-    - DONE:
-      - ToDo does not appear to be created by make dependencies (it's autogenerated);
-      - update Makefile to always re-generate todo lists;
-     
-
-

src/CoroutinesAndConcurrency.rst

-.. index::
-   coroutines
-   concurrency
-   threads
-   parallelism
-   multiprocessing
-   GIL: Global Interpreter Lock
-
-********************************************************************************
-Coroutines, Concurrency & Distributed Systems
-********************************************************************************
-
-[[ Will probably need to expand this to multiple chapters:
-
-1. Concurrency Concepts
-2. Coroutines
-3. Processes
-4. Threads
-
-(this isn't final; may need different organization or finer grained. However, it should start
-with simpler concepts and progress to the more difficult ones, as above.)
-
-]]
-
-Primary focus should be on:
-
-1) Using ``yield`` to create coroutines
-
-2) Using the new ``multiprocessing`` module
-
-and then showing some alternative techniques.
-
-foo bar :func:`input` baz.
-
-The GIL
-===============================================================================
-
-The GIL prevents context switches from
-happening in the middle of C code. Basically, it makes any C
-code into a critical section, except when that C code explicitly releases
-the GIL. This greatly simplifies the task of writing extension
-modules as well the Python core. 
-
-The designers of Python made a design decision
-that extension writers would not have to take care of locking.
-Thus, Python is intended to be simple/easy to integrate with any C
-library.  In order to remove the GIL, you'd have to go into all existing
-C code and write explicit locking/unlocking code, and you'd have to do this with
-every new C library as well.
-
-[[ Description of how it supports/impacts reference-counted garbage collection]]
-
-Multiprocessing
-===============================================================================
-
-Example by Michele Simionato in comp lang python.
-Here is an example of using multiprocessing (which is included
-in Python 2.6 and easy_installable in older Python versions)
-to print a spin bar while a computation is running::
-
-    import sys, time
-    import multiprocessing
-    DELAY = 0.1
-    DISPLAY = [ '|', '/', '-', '\\' ]
-    def spinner_func(before='', after=''):
-        write, flush = sys.stdout.write, sys.stdout.flush
-        pos = -1
-        while True:
-            pos = (pos + 1) % len(DISPLAY)
-            msg = before + DISPLAY[pos] + after
-            write(msg); flush()
-            write('\x08' * len(msg))
-            time.sleep(DELAY)
-    def long_computation():
-        # emulate a long computation
-        time.sleep(3)
-    if __name__ == '__main__':
-        spinner = multiprocessing.Process(
-            None, spinner_func, args=('Please wait ... ', ''))
-        spinner.start()
-        try:
-            long_computation()
-            print 'Computation done'
-        finally:
-            spinner.terminate()
-
-
-On the Erlang mail list, four years ago, Erlang expert Joe Armstrong posted this:
-
-    In Concurrency Oriented (CO) programming you concentrate on the concurrency and the messages between the processes. There is no sharing of data.
-
-    [A program] should be thought of thousands of little black boxes all doing things in parallel - these black boxes can send and receive messages. Black boxes can detect errors in other black boxes - that's all.
-    ...
-    Erlang uses a simple functional language inside the [black boxes] - this is not particularly interesting - *any* language that does the job would do - the important bit is the concurrency.
-
-On the Squeak mail list in 1998, Alan Kay had this to say:
-
-    ...Smalltalk is not only NOT its syntax or the class library, it is not even about classes. I'm sorry that I long ago coined the term "objects" for this topic because it gets many people to focus on the lesser idea.
-
-    The big idea is "messaging" -- that is what the kernal of Smalltalk/Squeak is all about... The key in making great and growable systems is much more to design how its modules communicate rather than what their internal properties and behaviors should be. Think of the internet -- to live, it (a) has to allow many different kinds of ideas and realizations that are beyond any single standard and (b) to allow varying degrees of safe interoperability between these ideas.
-
-    If you focus on just messaging -- and realize that a good metasystem can late bind the various 2nd level architectures used in objects -- then much of the language-, UI-, and OS based discussions on this thread are really quite moot.
-
-
-Further Reading
-================================================================================
-
-    `This article
-    <http://guidewiredevelopment.wordpress.com/2008/10/06/a-more-clearly-stated-version-of-my-argument/>`_
-    argues that large-scale parallelism -- which is what
-    ``multiprocessing`` supports -- is the more important problem to solve, and
-    that functional languages don't help that much with this problem.
-
-    http://jessenoller.com/2009/02/01/python-threads-and-the-global-interpreter-lock/
-
-.. Good introduction to Twisted:
-.. http://jessenoller.com/2009/02/11/twisted-hello-asynchronous-programming/
-
-.. Also
-.. http://jessenoller.com/2009/02/02/an-interview-with-adam-olsen-author-of-safe-threading-completely-different/
-
-.. Generators and coroutines:
-.. http://groups.google.com/group/comp.lang.python/browse_thread/thread/aacd809829d6b6ce/
-
-.. ShowMeDo: Scientific and Parallel Computing Using IPython:
-.. http://blog.showmedo.com/2009/05/05/scientific-and-parallel-computing-using-ipython/

src/Decorator.rst

-********************************************************************************
-Decorator: Dynamic Type Selection
-********************************************************************************
-
-..  note:: I think we can rewrite this chapter to use Python decorators as
-           implementation (thus the decorators chapter should precede this one).
-
-The use of layered objects to dynamically and transparently add responsibilities
-to individual objects is referred to as the *decorator* pattern.
-
-Used when subclassing creates too many (& inflexible) classes
-
-All decorators that wrap around the original object must have the same basic
-interface
-
-Dynamic proxy/surrogate?
-
-This accounts for the odd inheritance structure
-
-Tradeoff: coding is more complicated when using decorators
-
-Basic Decorator Structure
-=======================================================================
-
-.. image:: _images/decorator.*
-
-
-A Coffee Example
-=======================================================================
-
-Consider going down to the local coffee shop, *BeanMeUp*, for a coffee.  There
-are typically many different drinks on offer -- espressos, lattes, teas, iced
-coffees, hot chocolate to name a few, as well as a number of extras (which cost
-extra too) such as whipped cream or an extra shot of espresso. You can also make
-certain changes to your drink at no extra cost, such as asking for decaf coffee
-instead of regular coffee.
-
-Quite clearly if we are going to model all these drinks and combinations, there
-will be sizeable class diagrams. So for clarity we will only consider a subset
-of the coffees: Espresso, Espresso Con Panna, Café Late, Cappuccino and Café
-Mocha. We'll include 2 extras - whipped cream ("whipped") and an extra shot of
-espresso; and three changes - decaf, steamed milk ("wet") and foamed milk
-("dry").
-
-Class for Each Combination
-=======================================================================
-
-One solution is to create an individual class for every combination. Each class
-describes the drink and is responsible for the cost etc. The resulting menu is
-huge, and a part of the class diagram would look something like this:
-
-.. image:: _images/coffeeExplosion.*
-
-The key to using this method is to find the particular combination you want.
-So, once you've found the drink you would like, here is how you would use it, as
-shown in the **CoffeeShop** class in the following code::
-
-    # Decorator/nodecorators/CoffeeShop.py
-    # Coffee example with no decorators
-
-    class Espresso: pass
-    class DoubleEspresso: pass
-    class EspressoConPanna: pass
-
-    class Cappuccino:
-        def __init__(self):
-            self.cost = 1
-            self.description = "Cappucino"
-        def getCost(self):
-            return self.cost
-        def getDescription(self):
-            return self.description
-
-    class CappuccinoDecaf: pass
-    class CappuccinoDecafWhipped: pass
-    class CappuccinoDry: pass
-    class CappuccinoDryWhipped: pass
-    class CappuccinoExtraEspresso: pass
-    class CappuccinoExtraEspressoWhipped: pass
-    class CappuccinoWhipped: pass
-
-    class CafeMocha: pass
-    class CafeMochaDecaf: pass
-    class CafeMochaDecafWhipped:
-        def __init__(self):
-            self.cost = 1.25
-            self.description = \
-              "Cafe Mocha decaf whipped cream"
-        def getCost(self):
-            return self.cost
-        def getDescription(self):
-            return self.description
-
-    class CafeMochaExtraEspresso: pass
-    class CafeMochaExtraEspressoWhipped: pass
-    class CafeMochaWet: pass
-    class CafeMochaWetWhipped: pass
-    class CafeMochaWhipped: pass
-
-    class CafeLatte: pass
-    class CafeLatteDecaf: pass
-    class CafeLatteDecafWhipped: pass
-    class CafeLatteExtraEspresso: pass
-    class CafeLatteExtraEspressoWhipped: pass
-    class CafeLatteWet: pass
-    class CafeLatteWetWhipped: pass
-    class CafeLatteWhipped: pass
-
-    cappuccino = Cappuccino()
-    print((cappuccino.getDescription() + ": $" +
-      `cappuccino.getCost()`))
-
-    cafeMocha = CafeMochaDecafWhipped()
-    print((cafeMocha.getDescription()
-      + ": $" + `cafeMocha.getCost()`))
-
-
-
-And here is the corresponding output::
-
-    Cappucino: $1.0
-    Cafe Mocha decaf whipped cream: $1.25
-
-You can see that creating the particular combination you want is easy, since you
-are just creating an instance of a class. However, there are a number of
-problems with this approach. Firstly, the combinations are fixed statically so
-that any combination a customer may wish to order needs to be created up front.
-Secondly, the resulting menu is so huge that finding your particular combination
-is difficult and time consuming.
-
-The Decorator Approach
-=======================================================================
-
-Another approach would be to break the drinks down into the various components
-such as espresso and foamed milk, and then let the customer combine the
-components to describe a particular coffee.
-
-In order to do this programmatically, we use the Decorator pattern.  A Decorator
-adds responsibility to a component by wrapping it, but the Decorator conforms to
-the interface of the component it encloses, so the wrapping is transparent.
-Decorators can also be nested without the loss of this transparency.
-
-.. image:: _images/decoratedCoffee.*
-
-
-Methods invoked on the Decorator can in turn invoke methods in the component,
-and can of course perform processing before or after the invocation.
-
-So if we added **getTotalCost()** and **getDescription()** methods to the
-**DrinkComponent** interface, an Espresso looks like this::
-
-    # Decorator/alldecorators/EspressoDecorator.py
-
-    class Espresso(Decorator):
-        cost = 0.75f
-        description = " espresso"
-        def __init__(DrinkComponent):
-            Decorator.__init__(self, component)
-
-        def getTotalCost(self):
-            return self.component.getTotalCost() + cost
-
-        def getDescription(self):
-            return self.component.getDescription() +
-                description
-
-
-You combine the components to create a drink as follows, as shown in the code
-below::
-
-    # Decorator/alldecorators/CoffeeShop.py
-    # Coffee example using decorators
-
-    class DrinkComponent:
-        def getDescription(self):
-            return self.__class__.__name__
-        def getTotalCost(self):
-            return self.__class__.cost
-
-    class Mug(DrinkComponent):
-        cost = 0.0
-
-    class Decorator(DrinkComponent):
-        def __init__(self, drinkComponent):
-            self.component = drinkComponent
-        def getTotalCost(self):
-            return self.component.getTotalCost() + \
-              DrinkComponent.getTotalCost(self)
-        def getDescription(self):
-            return self.component.getDescription() + \
-              ' ' + DrinkComponent.getDescription(self)
-
-    class Espresso(Decorator):
-        cost = 0.75
-        def __init__(self, drinkComponent):
-            Decorator.__init__(self, drinkComponent)
-
-    class Decaf(Decorator):
-        cost = 0.0
-        def __init__(self, drinkComponent):
-            Decorator.__init__(self, drinkComponent)
-
-    class FoamedMilk(Decorator):
-        cost = 0.25
-        def __init__(self, drinkComponent):
-            Decorator.__init__(self, drinkComponent)
-
-    class SteamedMilk(Decorator):
-        cost = 0.25
-        def __init__(self, drinkComponent):
-            Decorator.__init__(self, drinkComponent)
-
-    class Whipped(Decorator):
-        cost = 0.25
-        def __init__(self, drinkComponent):
-            Decorator.__init__(self, drinkComponent)
-
-    class Chocolate(Decorator):
-        cost = 0.25
-        def __init__(self, drinkComponent):
-            Decorator.__init__(self, drinkComponent)
-
-    cappuccino = Espresso(FoamedMilk(Mug()))
-    print(cappuccino.getDescription().strip() + \)
-      ": $" + `cappuccino.getTotalCost()`
-
-    cafeMocha = Espresso(SteamedMilk(Chocolate(
-      Whipped(Decaf(Mug())))))
-
-    print(cafeMocha.getDescription().strip() + \)
-      ": $" + `cafeMocha.getTotalCost()`
-
-
-
-This approach would certainly provide the most flexibility and the smallest
-menu. You have a small number of components to choose from, but assembling the
-description of the coffee then becomes rather arduous.
-
-If you want to describe a plain cappuccino, you create it with::
-
-    plainCap = Espresso(FoamedMilk(Mug()))
-
-Creating a decaf Cafe Mocha with whipped cream requires an even longer
-description.
-
-Compromise
-=======================================================================
-
-The previous approach takes too long to describe a coffee. There will also be
-certain combinations that you will describe regularly, and it would be
-convenient to have a quick way of describing them.
-
-The 3rd approach is a mixture of the first 2 approaches, and combines
-flexibility with ease of use. This compromise is achieved by creating a
-reasonably sized menu of basic selections, which would often work exactly as
-they are, but if you wanted to decorate them (whipped cream, decaf etc.) then
-you would use decorators to make the modifications. This is the type of menu you
-are presented with in most coffee shops.
-
-.. image:: _images/compromiseDecoration.*
-
-Here is how to create a basic selection, as well as a decorated selection::
-
-    # Decorator/compromise/CoffeeShop.py
-    # Coffee example with a compromise of basic
-    # combinations and decorators
-
-    class DrinkComponent:
-        def getDescription(self):
-            return self.__class__.__name__
-        def getTotalCost(self):
-            return self.__class__.cost
-
-    class Espresso(DrinkComponent):
-        cost = 0.75
-
-    class EspressoConPanna(DrinkComponent):
-        cost = 1.0
-
-    class Cappuccino(DrinkComponent):
-        cost = 1.0
-
-    class CafeLatte(DrinkComponent):
-        cost = 1.0
-
-    class CafeMocha(DrinkComponent):
-        cost = 1.25
-
-    class Decorator(DrinkComponent):
-        def __init__(self, drinkComponent):
-            self.component = drinkComponent
-        def getTotalCost(self):
-            return self.component.getTotalCost() + \
-              DrinkComponent.getTotalCost(self)
-        def getDescription(self):
-            return self.component.getDescription() + \
-              ' ' + DrinkComponent.getDescription(self)
-
-    class ExtraEspresso(Decorator):
-        cost = 0.75
-        def __init__(self, drinkComponent):
-            Decorator.__init__(self, drinkComponent)
-
-    class Whipped(Decorator):
-        cost = 0.50
-        def __init__(self, drinkComponent):
-            Decorator.__init__(self, drinkComponent)
-
-    class Decaf(Decorator):
-        cost = 0.0
-        def __init__(self, drinkComponent):
-            Decorator.__init__(self, drinkComponent)
-
-    class Dry(Decorator):
-        cost = 0.0
-        def __init__(self, drinkComponent):
-            Decorator.__init__(self, drinkComponent)
-
-    class Wet(Decorator):
-        cost = 0.0
-        def __init__(self, drinkComponent):
-            Decorator.__init__(self, drinkComponent)
-
-    cappuccino = Cappuccino()
-    print(cappuccino.getDescription() + ": $" + \)
-      `cappuccino.getTotalCost()`
-
-    cafeMocha = Whipped(Decaf(CafeMocha()))
-    print(cafeMocha.getDescription() + ": $" + \)
-      `cafeMocha.getTotalCost()`
-
-
-
-You can see that creating a basic selection is quick and easy, which makes sense
-since they will be described regularly.  Describing a decorated drink is more
-work than when using a class per combination, but clearly less work than when
-only using decorators.
-
-The final result is not too many classes, but not too many decorators either.
-Most of the time it's possible to get away without using any decorators at all,
-so we have the benefits of both approaches.
-
-Other Considerations
-=======================================================================
-
-What happens if we decide to change the menu at a later stage, such as by adding
-a new type of drink? If we had used the class per combination approach, the
-effect of adding an extra such as syrup would be an exponential growth in the
-number of classes. However, the implications to the all decorator or compromise
-approaches are the same - one extra class is created.
-
-How about the effect of changing the cost of steamed milk and foamed milk, when
-the price of milk goes up? Having a class for each combination means that you
-need to change a method in each class, and thus maintain many classes. By using
-decorators, maintenance is reduced by defining the logic in one place.
-
-Further Reading
-=======================================================================
-
-
-Exercises
-=======================================================================
-
-#.  Add a Syrup class to the decorator approach described above. Then create a
-    Café Latte (you'll need to use steamed milk with an espresso) with syrup.
-
-#.  Repeat Exercise 1 for the compromise approach.
-
-#.  Implement the decorator pattern to create a Pizza restaurant, which has a
-    set menu of choices as well as the option to design your own pizza.  Follow
-    the compromise approach to create a menu consisting of a Margherita,
-    Hawaiian, Regina, and Vegetarian pizzas, with toppings (decorators) of
-    Garlic, Olives, Spinach, Avocado, Feta and Pepperdews. Create a Hawaiian
-    pizza, as well as a Margherita decorated with Spinach, Feta, Pepperdews and
-    Olives.

src/DeveloperGuide.rst

-*******************************************************************************
-Developer Guide
-*******************************************************************************
-
-Details for people participating in the book development process.
-
-.. Great article with ideas for document automation, including paver and cog:
-.. http://feedproxy.google.com/~r/DougHellmann/~3/JOnbNzmhSNU/writing-technical-documentation-with.html
-
-Getting Started: The Easiest Approach
-===============================================================================
-
-If all of the details are a little overwhelming at first, there's an easy way
-for you to make contributions without learning about distributed version control
-and Sphinx:
-
-1.  Create an account at http://www.BitBucket.org.
-
-2.  In your account, you get a wiki. In your wiki, create a page for your
-    contribution. Just add your code and descriptions using plain text.
-
-3.  Point us to your wiki via the `newsgroup
-    <http://groups.google.com/group/python3patterns/>`_.
-
-4.  We'll take your contribution and do the necessary formatting.
-
-If you want to take another step, you can learn how to format your wiki page
-using Sphinx by looking at the source for pages in the book. You can try it
-right now -- on the left side of this page (in the HTML book) you'll see a
-header that says **This Page** and underneath it **Show Source**. Click on
-**Show Source** and you'll see the Sphinx source for this page. Just look at
-the page sources and imitate that.
-
-When you're ready, you can learn more about Sphinx and Mercurial and begin
-making contributions that way.
-
-The following sections are for those who are ready to build the book on their
-own machines.
-
-For Windows Users
-===============================================================================
-
-You need to install Cygwin; go to:
-
-    http://www.cygwin.com
-
-You need to install at least the ``make`` utility, but I find that ``chere``
-(command prompt here) is also very useful.
-
-Also install ``openssh`` (under **Net**), so you can create your RSA key
-for Mercurial.
-
-I've discovered that it's best if you *don't* install Python as part of
-Cygwin; instead use a single Python installation under windows. Cygwin will
-find the installation if it is on your Windows PATH.
-
-Because of this, you shouldn't select "mercurial" when you're
-installing Cygwin because that will cause Python to be installed. Instead,
-install them as standalone Windows applications (see below).
-
-Installing Sphinx
-===============================================================================
-
-Because we are sometimes pushing the boundaries of Sphinx, you'll need to get
-the very latest development version (a.k.a. the "tip").
-
-#. Get mercurial:
-
-    http://www.selenic.com/mercurial
-
-    Avoid installing the tortoiseHG part - it has caused trouble w/ Python
-    debuggers.
-
-#. To get the Sphinx trunk, start with:
-
-    ``$ hg clone http://www.bitbucket.org/birkenfeld/sphinx/``
-
-    and to update, use:
-
-    ``$ hg pull``
-
-    Once you update, run
-
-    ``$ python setup.py install``
-
-    (You can repeat this step whenever you need to update).
-
-    We may talk about minimum version numbers to process the book. Check your
-    version with:
-
-    ``$ hg identify -n``
-
-The full anouncement from Georg (Sphinx creator) is here:
-
-    http://groups.google.com/group/sphinx-dev/browse_thread/thread/6dd415847e5cbf7c
-
-Mercurial Cheat sheets & quick starts should be enough to answer your questions:
-
-    - http://edong.net/2008v1/docs/dongwoo-Hg-120dpi.png
-    - http://www.ivy.fr/mercurial/ref/v1.0/
-
-Getting the Development Branch of the Book
-===============================================================================
-
-This book uses BitBucket.org tools, and additional tools if necessary.
-
-#.  Sign up for an account at http://BitBucket.org.
-
-#.  You must create an rsa key. Under OSX and Linux, and if you installed
-    ``openssh with`` Cygwin under windows, you run ``ssh-keygen`` to generate
-    the key, and then add it to your BitBucket account.
-
-#.  Go to http://www.bitbucket.org/BruceEckel/python-3-patterns-idioms/, and
-    you'll see instructions for getting a branch for development.
-
-#.  Work on your branch and make local commits and commits to your BitBucket
-    account.
-
-Building the Book
-===============================================================================
-
-To ensure you have Cygwin installed correctly (if you're using windows) and
-to see what the options are, type:
-
-    ``make``
-
-at a shell prompt. Then you can use ``make html`` to build the HTML version of
-the book, or ``make htmlhelp`` to make the windows help version, etc.
-
-You can also use the ``build`` system I've created (as a book example; it is
-part of the distribution). This will call ``make`` and it simplifies many of the
-tasks involved. Type:
-
-    ``build help``
-
-to see the options.
-
-.. todo::   The remainder of this document needs rewriting. Rewrite this section
-            for BitBucket & Mercurial; make some project specific diagrams;
-
-Building the PDF
-===============================================================================
-
-In order to build the Acrobat PDF verion of the book, you must install some
-additional software:
-
-**Mac OSX**: Install the http://www.tug.org/mactex/ distribution. Although this is
-a Mac installer, it installs all the necessary command-line binaries to create the
-PDF of the book, and modifies your PATH variable.
-
-**Windows**: Install following these instructions:
-http://www.tug.org/texlive/windows.html
-
-**Linux**: Your Linux install may already have support, but if not, install following
-these instructions:
-http://www.tug.org/texlive/quickinstall.html
-
-Once TeX is installed, move to this book's **src** directory and run ``make latex``.
-When that command runs successfully, it will give you instructions as to how to finish.
-
-Setting up Mercurial
-===============================================================================
-
-It's easier if you put a configuration file called **.hgrc** in your
-home directory.  Here's one that sets up the user name and configures
-**kdiff3** as the diff tool for Mercurial to use when showing you
-differences between files::
-
-    # This is a Mercurial configuration file.
-    [ui]
-    username = Firstname Lastname <email@mailer.net>
-
-    [merge-tools]
-    # Override stock tool location
-    kdiff3.executable = /usr/bin/kdiff3
-    # Specify command line
-    kdiff3.args = $base $local $other -o $output
-    # Give higher priority
-    kdiff3.priority = 1
-
-In addition, you can change the editor that Mercurial uses via an
-environment variable. For example, on OSX and Linux (and Windows with
-cygwin) you add this to your **.bash_profile** to set **emacs** as the
-default editor::
-
-	 export set EDITOR=/usr/bin/emacs
-
-
-Working with BitBucket and Mercurial
-===============================================================================
-
-.. note:: Adapted from a posting by Yarko Tymciurak
-
-
-This assumes that you have created a local branch on your private machine where
-you do work, and keep it merged with the trunk.
-
-That is, you've done:
-
-   - Forked a branch of http://www.bitbucket.org/BruceEckel/python-3-patterns-idioms/
-     (the main trunk; this fork will provide a place for review and comment)
-   - cloned the trunk to your local machine:
-     - hg clone https://my_login@bitbucket.org/BruceEckel/python-3-patterns-idioms/
-   - cloned your local copy of trunk to create a working directory:
-     - hg clone python-3-patterns-idioms devel
-
-.. ToDo:: This section still work in progress:
-
-   - ``hg branch lp:python3patterns``
-   - ``hg commit -m 'initial checkout'``
-   - (hack, hack, hack....)
-   - ``hg merge``   (pull new updates)
-   - ``hg commit -m 'checkin after merge...'``
-   - ... and so on...
-
-When you have a new function idea, or think you've found a bug, ask Bruce
-on the group.
-
-   -  If you have a new feature, create a wiki page on BitBucket and
-      describe what you're going to do.
-   -  If you have found a bug, make a bug report on BitBucket (later assign
-      it to yourself, and link your branch to it);
-   -  If you want to work on a project, look for an unassigned bug and try to
-      work it out - then proceed as below...
-
-When you are ready to share your work have others review, register a branch.
-
-
-.. note:: You can re-use one branch for multiple bug fixes.
-
-1.  Sign up for an account on BitBucket.org
-
-2.  Go to the project and select "register branch"
-    (``https://code.BitBucket.org/python3patterns/+addbranch``). Suggest you
-    create a hosted branch, then you can work locally, and pull/push as you make
-    progress (see
-    http://doc.Mercurial-vcs.org/latest/en/user-guide/index.html#organizing).
-
-3.  Once you have registered your branch, BitBucket will provide you with
-    instructions on how to pull and push to your personal development copy.
-
-4.  Link your bug report or blueprint to your branch.
-
-5.  Merge from your "parent" (the trunk, or others you are working with) as needed.
-
-6.  Push your working copy to BitBucket as your work is ready for others to
-    review or test.
-
-7.  Once you are done making your changes, have completed testing, and are
-    ready for the project team to inspect & test, please select "propose for
-    merging"
-
-8.  Somebody on the core team will make a test merge (it may include
-    merging with other patches). Once tests pass, and your branch is accepted,
-    it will be merged into the trunk.
-
-A Simple Overview Of Editing and Merging
-===============================================================================
-
-#.  ``hg pull http://www.bitbucket.org/BruceEckel/python-3-patterns-idioms/``
-
-#.  ``hg merge`` This brought up kdiff3 (note: this requires a separate
-    installation     of **kdiff3**)on any file's w/ conflicts, and you get to
-    just visually look - left-to-right at A:base, B:mine, and C:yours.... the
-    NICE thing is when you want BOTH the other and yours, you can click BOTH B &
-    C buttons --- sweeet! you can also review the "automatic" merges, choose
-    which - conflicts only, or any merge.
-
-#.  ... ``make html;  make latex`` ...... look at outputs (simultaneously,
-    comparatively)... make any changes.... repeat....
-
-#.  ``hg ci`` without a message, it brought up an editor with a list of all
-    changed files - so you can comment individually.
-
-Emacs for Editing Restructured Text
-===============================================================================
-
-If you want an editing system with support for restructured text, one choice is
-the free text editor *emacs*, which has an add-on mode for restructured text.
-Emacs has a long and venerable history, and is an extremely powerful editor.
-Emacs also has versions that are customized for operating systems to make it
-much more familiar.
-
-Here's a `simple introduction to emacs <http://lowfatlinux.com/linux-editor-emacs.html>`_
-and a `useful introductory help guide <http://www.linuxhelp.net/guides/emacs/>`_.
-For Windows, there's `a special FAQ <http://www.gnu.org/software/emacs/windows/ntemacs.html>`_.
-
-**Mac OSX**: Comes with built-in emacs which you can invoke from the command line. For a nicer
-version, install `Aquamacs <http://aquamacs.org/>`_, which looks and feels like a native
-Mac application.
-
-**Windows**: You can download the latest windows installer `here (choose the
-highest numbered zip file with "bin" in the name) <http://ftp.gnu.org/pub/gnu/emacs/windows/>`_.
-`This blog <http://www.arunrocks.com/blog/archives/2008/02/20/5-indespensible-tips-for-emacs-on-windows/>`_
-gives useful tips to make emacs on Windows even friendlier (in particular, it
-puts emacs on the right-click menu and improves the startup settings).
-
-**Linux**: It's virtually guaranteed that you already have emacs preinstalled
-on your Linux distribution, which you can start from a command prompt. However,
-there may also be more "windowy" versions that you can install separately.
-
-.. ToDo:: Someone who knows more about emacs for Linux please add more specific information about the windowed version(s).
-
-Finally, `here's the documentation for installing and using the emacs
-restructured-text mode <http://docutils.sourceforge.net/docs/user/emacs.html>`_.
-The elisp code it refers to is in the file `rst.el <http://docutils.sourceforge.net/tools/editors/emacs/rst.el>`_.
-
-To customize your emacs, you need to open the ``.emacs`` file. The above Windows
-FAQ tells you how to put your ``.emacs`` file somewhere else, but the easiest
-thing to do is just open emacs and inside it type ``C-x C-f ~/.emacs``, which
-will open your default ``.emacs`` file if you have one, or create a new one if you don't.
-
-You'll need to install **rst.el** someplace emacs will find it. Here's an example **.emacs**
-file which adds a local directory called **~/emacs/** to the search path,
-(so you can put **.el** files there) and also automatically
-starts **rst** mode for files with extensions of **rst** and **.rest**::
-
-     (require 'cl)
-     (defvar emacs-directory "~/emacs/"
-     	     "The directory containing the emacs configuration files.")
-     (pushnew (expand-file-name emacs-directory) load-path)
-     (require 'rst)
-     (setq auto-mode-alist
-     	    (append '(("\\.rst$" . rst-mode)
-            	      ("\\.rest$" . rst-mode)) auto-mode-alist))
-
-

src/Factory.rst

-
-
-********************************************************************************
-Factory: Encapsulating Object Creation
-********************************************************************************
-
-When you discover that you need to add new types to a system, the most sensible
-first step is to use polymorphism to create a common interface to those new
-types. This separates the rest of the code in your system from the knowledge of
-the specific types that you are adding. New types may be added without
-disturbing existing code ... or so it seems. At first it would appear that the
-only place you need to change the code in such a design is the place where you
-inherit a new type, but this is not quite true. You must still create an object
-of your new type, and at the point of creation you must specify the exact
-constructor to use. Thus, if the code that creates objects is distributed
-throughout your application, you have the same problem when adding new types-you
-must still chase down all the points of your code where type matters. It happens
-to be the *creation* of the type that matters in this case rather than the *use*
-of the type (which is taken care of by polymorphism), but the effect is the
-same: adding a new type can cause problems.
-
-The solution is to force the creation of objects to occur through a common
-*factory* rather than to allow the creational code to be spread throughout your
-system. If all the code in your program must go through this factory whenever it
-needs to create one of your objects, then all you must do when you add a new
-object is to modify the factory.
-
-Since every object-oriented program creates objects, and since it's very likely
-you will extend your program by adding new types, I suspect that factories may
-be the most universally useful kinds of design patterns.
-
-Simple Factory Method
-=======================================================================
-
-As an example, let's revisit the **Shape** system.
-
-One approach is to make the factory a **static** method of the base class::
-
-    # Factory/shapefact1/ShapeFactory1.py
-    # A simple static factory method.
-    from __future__ import generators
-    import random
-
-    class Shape(object):
-        # Create based on class name:
-        def factory(type):
-            #return eval(type + "()")
-            if type == "Circle": return Circle()
-            if type == "Square": return Square()
-            assert 0, "Bad shape creation: " + type
-        factory = staticmethod(factory)
-
-    class Circle(Shape):
-        def draw(self): print("Circle.draw")
-        def erase(self): print("Circle.erase")
-
-    class Square(Shape):
-        def draw(self): print("Square.draw")
-        def erase(self): print("Square.erase")
-
-    # Generate shape name strings:
-    def shapeNameGen(n):
-        types = Shape.__subclasses__()
-        for i in range(n):
-            yield random.choice(types).__name__
-
-    shapes = \
-      [ Shape.factory(i) for i in shapeNameGen(7)]
-
-    for shape in shapes:
-        shape.draw()
-        shape.erase()
-
-
-
-The **factory( )** takes an argument that allows it to determine what type of
-**Shape** to create; it happens to be a **String** in this case but it could be
-any set of data. The **factory( )** is now the only other code in the system
-that needs to be changed when a new type of **Shape** is added (the
-initialization data for the objects will presumably come from somewhere outside
-the system, and not be a hard-coded array as in the above example).
-
-Note that this example also shows the new Python 2.2 **staticmethod( )**
-technique for creating static methods in a class.
-
-I have also used a tool which is new in Python 2.2 called a *generator*. A
-generator is a special case of a factory: it's a factory that takes no arguments
-in order to create a new object. Normally you hand some information to a factory
-in order to tell it what kind of object to create and how to create it, but a
-generator has some kind of internal algorithm that tells it what and how to
-build. It "generates out of thin air" rather than being told what to create.
-
-Now, this may not look consistent with the code you see above::
-
-    for i in shapeNameGen(7)
-
-looks like there's an initialization taking place. This is where a generator is
-a bit strange - when you call a function that contains a **yield** statement
-(**yield** is a new keyword that determines that a function is a generator),
-that function actually returns a generator object that has an iterator. This
-iterator is implicitly used in the **for** statement above, so it appears that
-you are iterating through the generator function, not what it returns. This was
-done for convenience of use.
-
-Thus, the code that you write is actually a kind of factory, that creates the
-generator objects that do the actual generation. You can use the generator
-explicitly if you want, for example::
-
-    gen = shapeNameGen(7)
-    print(gen.next())
-
-So **next( )** is the iterator method that's actually called to generate the
-next object, and it takes no arguments. **shapeNameGen( )** is the factory, and
-**gen** is the generator.
-
-Inside the generator-factory, you can see the call to **__subclasses__( )**,
-which produces a list of references to each of the subclasses of **Shape**
-(which must be inherited from **object** for this to work). You should be aware,
-however, that this only works for the first level of inheritance from **Item**,
-so if you were to inherit a new class from **Circle**, it wouldn't show up in
-the list generated by **__subclasses__( )**. If you need to create a deeper
-hierarchy this way, you must recurse the **__subclasses__( )** list.
-
-Also note that in **shapeNameGen( )** the statement::
-
-    types = Shape.__subclasses__()
-
-Is only executed when the generator object is produced; each time the **next(
-)** method of this generator object is called (which, as noted above, may happen
-implicitly), only the code in the **for** loop will be executed, so you don't
-have wasteful execution (as you would if this were an ordinary function).
-
-Preventing direct creation
---------------------------------------------------------------------------------
-
-To disallow direct access to the classes, you can nest the classes within the
-factory method, like this::
-
-    # Factory/shapefact1/NestedShapeFactory.py
-    import random
-
-    class Shape(object):
-        types = []
-
-    def factory(type):
-        class Circle(Shape):
-            def draw(self): print("Circle.draw")
-            def erase(self): print("Circle.erase")
-
-        class Square(Shape):
-            def draw(self): print("Square.draw")
-            def erase(self): print("Square.erase")
-
-        if type == "Circle": return Circle()
-        if type == "Square": return Square()
-        assert 0, "Bad shape creation: " + type
-
-    def shapeNameGen(n):
-        for i in range(n):
-            yield factory(random.choice(["Circle", "Square"]))
-
-    # Circle() # Not defined
-
-    for shape in shapeNameGen(7):
-        shape.draw()
-        shape.erase()
-
-
-
-
-Polymorphic Factories
-=======================================================================
-
-The static **factory( )** method in the previous example forces all the creation
-operations to be focused in one spot, so that's the only place you need to
-change the code. This is certainly a reasonable solution, as it throws a box
-around the process of creating objects. However, the *Design Patterns* book
-emphasizes that the reason for the *Factory Method* pattern is so that different
-types of factories can be subclassed from the basic factory (the above design is
-mentioned as a special case). However, the book does not provide an example, but
-instead just repeats the example used for the *Abstract Factory* (you'll see an
-example of this in the next section). Here is **ShapeFactory1.py** modified so
-the factory methods are in a separate class as virtual functions. Notice also
-that the specific **Shape** classes are dynamically loaded on demand::
-
-    # Factory/shapefact2/ShapeFactory2.py
-    # Polymorphic factory methods.
-    from __future__ import generators
-    import random
-
-    class ShapeFactory:
-        factories = {}
-        def addFactory(id, shapeFactory):
-            ShapeFactory.factories.put[id] = shapeFactory
-        addFactory = staticmethod(addFactory)
-        # A Template Method:
-        def createShape(id):
-            if not ShapeFactory.factories.has_key(id):
-                ShapeFactory.factories[id] = \
-                  eval(id + '.Factory()')
-            return ShapeFactory.factories[id].create()
-        createShape = staticmethod(createShape)
-
-    class Shape(object): pass
-
-    class Circle(Shape):
-        def draw(self): print("Circle.draw")
-        def erase(self): print("Circle.erase")
-        class Factory:
-            def create(self): return Circle()
-
-    class Square(Shape):
-        def draw(self):
-            print("Square.draw")
-        def erase(self):
-            print("Square.erase")
-        class Factory:
-            def create(self): return Square()
-
-    def shapeNameGen(n):
-        types = Shape.__subclasses__()
-        for i in range(n):
-            yield random.choice(types).__name__
-
-    shapes = [ ShapeFactory.createShape(i)
-               for i in shapeNameGen(7)]
-
-    for shape in shapes:
-        shape.draw()
-        shape.erase()
-
-
-
-Now the factory method appears in its own class, **ShapeFactory**, as the
-**create( )** method. The different types of shapes must each create their own
-factory with a **create( )** method to create an object of their own type. The
-actual creation of shapes is performed by calling **ShapeFactory.createShape(
-)**, which is a static method that uses the dictionary in **ShapeFactory** to
-find the appropriate factory object based on an identifier that you pass it. The
-factory is immediately used to create the shape object, but you could imagine a
-more complex problem where the appropriate factory object is returned and then
-used by the caller to create an object in a more sophisticated way. However, it
-seems that much of the time you don't need the intricacies of the polymorphic
-factory method, and a single static method in the base class (as shown in
-**ShapeFactory1.py**) will work fine.
-
-Notice that the **ShapeFactory** must be initialized by loading its dictionary
-with factory objects, which takes place in the static initialization clause of
-each of the shape implementations.
-
-Abstract Factories
-=======================================================================
-
-The *Abstract Factory* pattern looks like the factory objects we've seen
-previously, with not one but several factory methods. Each of the factory
-methods creates a different kind of object. The idea is that at the point of
-creation of the factory object, you decide how all the objects created by that
-factory will be used. The example given in *Design Patterns* implements
-portability across various graphical user interfaces (GUIs): you create a
-factory object appropriate to the GUI that you're working with, and from then on
-when you ask it for a menu, button, slider, etc. it will automatically create
-the appropriate version of that item for the GUI. Thus you're able to isolate,
-in one place, the effect of changing from one GUI to another.
-
-As another example suppose you are creating a general-purpose gaming environment
-and you want to be able to support different types of games. Here's how it might
-look using an abstract factory::
-
-    # Factory/Games.py
-    # An example of the Abstract Factory pattern.
-
-    class Obstacle:
-        def action(self): pass
-
-    class Character:
-        def interactWith(self, obstacle): pass
-
-    class Kitty(Character):
-        def interactWith(self, obstacle):
-            print("Kitty has encountered a",
-            obstacle.action())
-
-    class KungFuGuy(Character):
-        def interactWith(self, obstacle):
-            print("KungFuGuy now battles a",
-            obstacle.action())
-
-    class Puzzle(Obstacle):
-        def action(self):
-            print("Puzzle")
-
-    class NastyWeapon(Obstacle):
-        def action(self):
-            print("NastyWeapon")
-
-    # The Abstract Factory:
-    class GameElementFactory:
-        def makeCharacter(self): pass
-        def makeObstacle(self): pass
-
-    # Concrete factories:
-    class KittiesAndPuzzles(GameElementFactory):
-        def makeCharacter(self): return Kitty()
-        def makeObstacle(self): return Puzzle()
-
-    class KillAndDismember(GameElementFactory):
-        def makeCharacter(self): return KungFuGuy()
-        def makeObstacle(self): return NastyWeapon()
-
-    class GameEnvironment:
-        def __init__(self, factory):
-            self.factory = factory
-            self.p = factory.makeCharacter()
-            self.ob = factory.makeObstacle()
-        def play(self):
-            self.p.interactWith(self.ob)
-
-    g1 = GameEnvironment(KittiesAndPuzzles())
-    g2 = GameEnvironment(KillAndDismember())
-    g1.play()
-    g2.play()
-
-
-
-In this environment, **Character** objects interact with **Obstacle** objects,
-but there are different types of Characters and obstacles depending on what kind
-of game you're playing. You determine the kind of game by choosing a particular
-**GameElementFactory**, and then the **GameEnvironment** controls the setup and
-play of the game. In this example, the setup and play is very simple, but those
-activities (the *initial conditions* and the *state change*) can determine much
-of the game's outcome. Here, **GameEnvironment** is not designed to be
-inherited, although it could very possibly make sense to do that.
-
-This also contains examples of *Double Dispatching* and the *Factory Method*,
-both of which will be explained later.
-
-Of course, the above scaffolding of **Obstacle**, **Character** and
-**GameElementFactory** (which was translated from the Java version of this
-example) is unnecessary - it's only required for languages that have static type
-checking. As long as the concrete Python classes follow the form of the required
-classes, we don't need any base classes::
-
-    # Factory/Games2.py
-    # Simplified Abstract Factory.
-
-    class Kitty:
-        def interactWith(self, obstacle):
-            print("Kitty has encountered a",
-            obstacle.action())
-
-    class KungFuGuy:
-        def interactWith(self, obstacle):
-            print("KungFuGuy now battles a",
-            obstacle.action())
-
-    class Puzzle:
-        def action(self): print("Puzzle")
-
-    class NastyWeapon:
-        def action(self): print("NastyWeapon")
-
-    # Concrete factories:
-    class KittiesAndPuzzles:
-        def makeCharacter(self): return Kitty()
-        def makeObstacle(self): return Puzzle()
-
-    class KillAndDismember:
-        def makeCharacter(self): return KungFuGuy()
-        def makeObstacle(self): return NastyWeapon()
-
-    class GameEnvironment:
-        def __init__(self, factory):
-            self.factory = factory
-            self.p = factory.makeCharacter()
-            self.ob = factory.makeObstacle()
-        def play(self):
-            self.p.interactWith(self.ob)
-
-    g1 = GameEnvironment(KittiesAndPuzzles())
-    g2 = GameEnvironment(KillAndDismember())
-    g1.play()
-    g2.play()
-
-
-Another way to put this is that all inheritance in Python is implementation
-inheritance; since Python does its type-checking at runtime, there's no need to
-use interface inheritance so that you can upcast to the base type.
-
-You might want to study the two examples for comparison, however. Does the first
-one add enough useful information about the pattern that it's worth keeping some
-aspect of it? Perhaps all you need is "tagging classes" like this::
-
-    class Obstacle: pass
-    class Character: pass
-    class GameElementFactory: pass
-
-Then the inheritance serves only to indicate the type of the derived classes.