Commits

Anonymous committed 94d3219

Modified directory names for code files so they are all capitalized. More work on CodeManager.py.

  • Participants
  • Parent commits 192aa7d

Comments (0)

Files changed (238)

File code/AppFrameworks/TemplateMethod.py

+# 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()

File code/ChangeInterface/Adapter.py

+# 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())

File code/ChangeInterface/Facade.py

+# 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);

File code/CodeManager.py

-# CodeManager.py
-"""
-TODO: update() is still only in test mode; doesn't actually work yet.
-
-Extracts, checks and updates code examples in ReST files.
-
-You can just put in the codeMarker and the (indented) first line (containing the
-file path) into your ReST 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.
-        """
-        paths = set()
-        for f in restFiles:
-            for listing in language.listings.findall(open(f).read()):
-                listing = shift(listing)
-                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:
-                    if not os.path.exists(dirname):
-                        os.makedirs(dirname)
-                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.
-        """
-        missing = []
-        listings = [shift(code) 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[0].strip()[len(language.commentTag):].strip()
-                     for listing in listings]]
-        for path, listing in zip(paths, listings):
-            if not os.path.exists(path):
-                missing.append(path)
-            else:
-                code = open(path).read().splitlines()
-                for i in difflib.ndiff(listing, 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(d.make_file(listing, code))
-                        print("change in %s; see %s" % (path, html))
-                        break
-        if missing:
-            print("Missing", language.__name__, "files:\n", "\n".join(missing))
-        return missing
-
-    @staticmethod
-    def update(language): # Test until it is trustworthy
-        """
-        Refresh external code files into ReST files.
-        """
-        if Commands.check(language):
-            print(language.__name__, "update aborted")
-            return
-        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])
-
-       

File code/Comprehensions/CodeManager.py

-# comprehensions/CodeManager.py
-"""
-TODO: update() is still only in test mode; doesn't actually work yet.
-TODO: check() should generate deltas
-
-Extracts, checks and updates code examples in ReST files.
-
-You can just put in the codeMarker and the (indented) first line (containing the
-file path) into your ReST 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"
-        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 ReST files and write each
-        listing into its own file"""
-        paths = set()
-        for f in restFiles:
-            for listing in language.listings.findall(open(f).read()):
-                listing = shift(listing)
-                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:
-                    if not os.path.exists(dirname):
-                        os.makedirs(dirname)
-                file(path, 'w').write("\n".join(listing))
-
-    @staticmethod
-    def check(language):
-        "Ensure that external code files exist"
-        missing = []
-        for path in [code.splitlines()[0] for f in restFiles for code in
-                     language.listings.findall(open(f).read())]:
-            path = path.strip()[len(language.commentTag):].strip()
-            path = os.path.normpath(os.path.join("..", "code", path))
-            if not os.path.exists(path):
-                missing.append(path)
-        if missing:
-            print("Missing", language.__name__, "files:")
-            for p in missing:
-                print(p)
-        return missing
-
-    @staticmethod
-    def update(language): # Test until it is trustworthy
-        "Refresh external code files into ReST files"
-        if Commands.check(language):
-            print(language.__name__, "update aborted")
-            return
-        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()
-            for i in difflib.ndiff(listing, code):
-                if i.startswith("+ ") or i.startswith("- "):
-                    d = difflib.HtmlDiff()
-                    if not os.path.exists("_deltas"):
-                        os.makedirs("_deltas")
-                    open(os.path.join("_deltas", filename + ".html"), 'w')\
-                        .write(d.make_file(listing, code))
-                    break
-            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:")
-        for name in commands:
-            print(name + ": " + commands[name].__doc__)
-    else:
-        for language in inspect.getmembers(Languages, inspect.isclass):
-            commands[sys.argv[1]](language[1])
-
-       

File code/Comprehensions/os_walk_comprehension.py

-# 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)

File code/Decorator/alldecorators/CoffeeShop.py

+# 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()`

File code/Decorator/alldecorators/EspressoDecorator.py

+# 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

File code/Decorator/compromise/CoffeeShop.py

+# 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()`

File code/Decorator/nodecorators/CoffeeShop.py

+# 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()`))

File code/Factory/Games.py

+# 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()

File code/Factory/Games2.py

+# 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()

File code/Factory/shapefact1/NestedShapeFactory.py

+# 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()

File code/Factory/shapefact1/ShapeFactory1.py

+# 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()

File code/Factory/shapefact2/ShapeFactory2.py

+# 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()

File code/Fronting/ProxyDemo.py

+# Fronting/ProxyDemo.py
+# Simple demonstration of the Proxy pattern.
+
+class Implementation:
+    def f(self):
+        print("Implementation.f()")
+    def g(self):
+        print("Implementation.g()")
+    def h(self):
+        print("Implementation.h()")
+
+class Proxy:
+    def __init__(self):
+        self.__implementation = Implementation()
+    # Pass method calls to the implementation:
+    def f(self): self.__implementation.f()
+    def g(self): self.__implementation.g()
+    def h(self): self.__implementation.h()
+
+p = Proxy()
+p.f(); p.g(); p.h()

File code/Fronting/ProxyDemo2.py

+# Fronting/ProxyDemo2.py
+# Simple demonstration of the Proxy pattern.
+
+class Implementation2:
+    def f(self):
+        print("Implementation.f()")
+    def g(self):
+        print("Implementation.g()")
+    def h(self):
+        print("Implementation.h()")
+
+class Proxy2:
+    def __init__(self):
+        self.__implementation = Implementation2()
+    def __getattr__(self, name):
+        return getattr(self.__implementation, name)
+
+p = Proxy2()
+p.f(); p.g(); p.h();

File code/Fronting/StateDemo.py

+# Fronting/StateDemo.py
+# Simple demonstration of the State pattern.
+
+class State_d:
+    def __init__(self, imp):
+        self.__implementation = imp
+    def changeImp(self, newImp):
+        self.__implementation = newImp
+    # Delegate calls to the implementation:
+    def __getattr__(self, name):
+        return getattr(self.__implementation, name)
+
+class Implementation1:
+    def f(self):
+        print("Fiddle de dum, Fiddle de dee,")
+    def g(self):
+        print("Eric the half a bee.")
+    def h(self):
+        print("Ho ho ho, tee hee hee,")
+
+class Implementation2:
+    def f(self):
+        print("We're Knights of the Round Table.")
+    def g(self):
+        print("We dance whene'er we're able.")
+    def h(self):
+        print("We do routines and chorus scenes")
+
+def run(b):
+    b.f()
+    b.g()
+    b.h()
+    b.g()
+
+b = State_d(Implementation1())
+run(b)
+b.changeImp(Implementation2())
+run(b)

File code/FunctionObjects/ChainOfResponsibility.py

+# FunctionObjects/ChainOfResponsibility.py
+
+# Carry the information into the strategy:
+class Messenger: pass
+
+# The Result object carries the result data and
+# whether the strategy was successful:
+class Result:
+    def __init__(self):
+        self.succeeded = 0
+    def isSuccessful(self):
+        return self.succeeded
+    def setSuccessful(self, succeeded):
+        self.succeeded = succeeded
+
+class Strategy:
+    def __call__(messenger): pass
+    def __str__(self):
+        return "Trying " + self.__class__.__name__ \
+          + " algorithm"
+
+# Manage the movement through the chain and
+# find a successful result:
+class ChainLink:
+    def __init__(self, chain, strategy):
+        self.strategy = strategy
+        self.chain = chain
+        self.chain.append(self)
+
+    def next(self):
+        # Where this link is in the chain:
+        location = self.chain.index(self)
+        if not self.end():
+            return self.chain[location + 1]
+
+    def end(self):
+        return (self.chain.index(self) + 1 >=
+                len(self.chain))
+
+    def __call__(self, messenger):
+        r = self.strategy(messenger)
+        if r.isSuccessful() or self.end(): return r
+        return self.next()(messenger)
+
+# For this example, the Messenger
+# and Result can be the same type:
+class LineData(Result, Messenger):
+    def __init__(self, data):
+        self.data = data
+    def __str__(self): return `self.data`
+
+class LeastSquares(Strategy):
+    def __call__(self, messenger):
+        print(self)
+        linedata = messenger
+        # [ Actual test/calculation here ]
+        result = LineData([1.1, 2.2]) # Dummy data
+        result.setSuccessful(0)
+        return result
+
+class NewtonsMethod(Strategy):
+    def __call__(self, messenger):
+        print(self)
+        linedata = messenger
+        # [ Actual test/calculation here ]
+        result = LineData([3.3, 4.4]) # Dummy data
+        result.setSuccessful(0)
+        return result
+
+class Bisection(Strategy):
+    def __call__(self, messenger):
+        print(self)
+        linedata = messenger
+        # [ Actual test/calculation here ]
+        result = LineData([5.5, 6.6]) # Dummy data
+        result.setSuccessful(1)
+        return result
+
+class ConjugateGradient(Strategy):
+    def __call__(self, messenger):
+        print(self)
+        linedata = messenger
+        # [ Actual test/calculation here ]
+        result = LineData([7.7, 8.8]) # Dummy data
+        result.setSuccessful(1)
+        return result
+
+solutions = []
+ChainLink(solutions, LeastSquares()),
+ChainLink(solutions, NewtonsMethod()),
+ChainLink(solutions, Bisection()),
+ChainLink(solutions, ConjugateGradient())
+
+line = LineData([
+  1.0, 2.0, 1.0, 2.0, -1.0,
+  3.0, 4.0, 5.0, 4.0
+])
+
+print(solutions[0](line))

File code/FunctionObjects/CommandPattern.py

+# FunctionObjects/CommandPattern.py
+
+class Command:
+    def execute(self): pass
+
+class Loony(Command):
+    def execute(self):
+        print("You're a loony.")
+
+class NewBrain(Command):
+    def execute(self):
+        print("You might even need a new brain.")
+
+class Afford(Command):
+    def execute(self):
+        print("I couldn't afford a whole new brain.")
+
+# An object that holds commands:
+class Macro:
+    def __init__(self):
+        self.commands = []
+    def add(self, command):
+        self.commands.append(command)
+    def run(self):
+        for c in self.commands:
+            c.execute()
+
+macro = Macro()
+macro.add(Loony())
+macro.add(NewBrain())
+macro.add(Afford())
+macro.run()

File code/FunctionObjects/StrategyPattern.py

+# FunctionObjects/StrategyPattern.py
+
+# The strategy interface:
+class FindMinima:
+    # Line is a sequence of points:
+    def algorithm(self, line) : pass
+
+# The various strategies:
+class LeastSquares(FindMinima):
+    def algorithm(self, line):
+        return [ 1.1, 2.2 ] # Dummy
+
+class NewtonsMethod(FindMinima):
+    def algorithm(self, line):
+        return [ 3.3, 4.4 ]  # Dummy
+
+class Bisection(FindMinima):
+    def algorithm(self, line):
+        return [ 5.5, 6.6 ] # Dummy
+
+class ConjugateGradient(FindMinima):
+    def algorithm(self, line):
+        return [ 3.3, 4.4 ] # Dummy
+
+# The "Context" controls the strategy:
+class MinimaSolver:
+    def __init__(self, strategy):
+        self.strategy = strategy
+
+    def minima(self, line):
+        return self.strategy.algorithm(line)
+
+    def changeAlgorithm(self, newAlgorithm):
+        self.strategy = newAlgorithm
+
+solver = MinimaSolver(LeastSquares())
+line = [1.0, 2.0, 1.0, 2.0, -1.0, 3.0, 4.0, 5.0, 4.0]
+print(solver.minima(line))
+solver.changeAlgorithm(Bisection())
+print(solver.minima(line))

File code/MachineDiscovery/detect_CPUs.py

+# MachineDiscovery/detect_CPUs.py
+def detect_CPUs():
+    """
+    Detects the number of CPUs on a system. Cribbed from pp.
+    """
+    # Linux, Unix and MacOS:
+    if hasattr(os, "sysconf"):
+        if os.sysconf_names.has_key("SC_NPROCESSORS_ONLN"):
+            # Linux & Unix:
+            ncpus = os.sysconf("SC_NPROCESSORS_ONLN")
+            if isinstance(ncpus, int) and ncpus > 0:
+                return ncpus
+        else: # OSX:
+            return int(os.popen2("sysctl -n hw.ncpu")[1].read())
+    # Windows:
+    if os.environ.has_key("NUMBER_OF_PROCESSORS"):
+            ncpus = int(os.environ["NUMBER_OF_PROCESSORS"]);
+            if ncpus > 0:
+                return ncpus
+    return 1 # Default
+    

File code/Messenger/MessengerIdiom.py

+# Messenger/MessengerIdiom.py
+
+class Messenger:
+    def __init__(self, **kwargs):
+        self.__dict__ = kwargs
+
+m = Messenger(info="some information", b=['a', 'list'])
+m.more = 11
+print m.info, m.b, m.more

File code/MultipleDispatching/PaperScissorsRock.py

+# MultipleDispatching/PaperScissorsRock.py
+# Demonstration of multiple dispatching.
+from __future__ import generators
+import random
+
+# An enumeration type:
+class Outcome:
+    def __init__(self, value, name):
+        self.value = value
+        self.name = name
+    def __str__(self): return self.name
+    def __eq__(self, other):
+        return self.value == other.value
+
+Outcome.WIN = Outcome(0, "win")
+Outcome.LOSE = Outcome(1, "lose")
+Outcome.DRAW = Outcome(2, "draw")
+
+class Item(object):
+    def __str__(self):
+        return self.__class__.__name__
+
+class Paper(Item):
+    def compete(self, item):
+        # First dispatch: self was Paper
+        return item.evalPaper(self)
+    def evalPaper(self, item):
+        # Item was Paper, we're in Paper
+        return Outcome.DRAW
+    def evalScissors(self, item):
+        # Item was Scissors, we're in Paper
+        return Outcome.WIN
+    def evalRock(self, item):
+        # Item was Rock, we're in Paper
+        return Outcome.LOSE
+
+class Scissors(Item):
+    def compete(self, item):
+        # First dispatch: self was Scissors
+        return item.evalScissors(self)
+    def evalPaper(self, item):
+        # Item was Paper, we're in Scissors
+        return Outcome.LOSE
+    def evalScissors(self, item):
+        # Item was Scissors, we're in Scissors
+        return Outcome.DRAW
+    def evalRock(self, item):
+        # Item was Rock, we're in Scissors
+        return Outcome.WIN
+
+class Rock(Item):
+    def compete(self, item):
+        # First dispatch: self was Rock
+        return item.evalRock(self)
+    def evalPaper(self, item):
+        # Item was Paper, we're in Rock
+        return Outcome.WIN
+    def evalScissors(self, item):
+        # Item was Scissors, we're in Rock
+        return Outcome.LOSE
+    def evalRock(self, item):
+        # Item was Rock, we're in Rock
+        return Outcome.DRAW
+
+def match(item1, item2):
+    print("%s <--> %s : %s" % (
+      item1, item2, item1.compete(item2)))
+
+# Generate the items:
+def itemPairGen(n):
+    # Create a list of instances of all Items:
+    Items = Item.__subclasses__()
+    for i in range(n):
+        yield (random.choice(Items)(),
+               random.choice(Items)())
+
+for item1, item2 in itemPairGen(20):
+    match(item1, item2)

File code/MultipleDispatching/PaperScissorsRock2.py

+# MultipleDispatching/PaperScissorsRock2.py
+# Multiple dispatching using a table
+from __future__ import generators
+import random
+
+class Outcome:
+    def __init__(self, value, name):
+        self.value = value
+        self.name = name
+    def __str__(self): return self.name
+    def __eq__(self, other):
+        return self.value == other.value
+
+Outcome.WIN = Outcome(0, "win")
+Outcome.LOSE = Outcome(1, "lose")
+Outcome.DRAW = Outcome(2, "draw")
+
+class Item(object):
+    def compete(self, item):
+        # Use a tuple for table lookup:
+        return outcome[self.__class__, item.__class__]
+    def __str__(self):
+        return self.__class__.__name__
+
+class Paper(Item): pass
+class Scissors(Item): pass
+class Rock(Item): pass
+
+outcome = {
+  (Paper, Rock): Outcome.WIN,
+  (Paper, Scissors): Outcome.LOSE,
+  (Paper, Paper): Outcome.DRAW,
+  (Scissors, Paper): Outcome.WIN,
+  (Scissors, Rock): Outcome.LOSE,
+  (Scissors, Scissors): Outcome.DRAW,
+  (Rock, Scissors): Outcome.WIN,
+  (Rock, Paper): Outcome.LOSE,
+  (Rock, Rock): Outcome.DRAW,
+}
+
+def match(item1, item2):
+    print("%s <--> %s : %s" % (
+      item1, item2, item1.compete(item2)))
+
+# Generate the items:
+def itemPairGen(n):
+    # Create a list of instances of all Items:
+    Items = Item.__subclasses__()
+    for i in range(n):
+        yield (random.choice(Items)(),
+               random.choice(Items)())
+
+for item1, item2 in itemPairGen(20):
+    match(item1, item2)

File code/Observer/BoxObserver.py

+# Observer/BoxObserver.py
+# Demonstration of Observer pattern using
+# Java's built-in observer classes.
+
+# You must inherit a type of Observable:
+class BoxObservable(Observable):
+    def notifyObservers(self, Object b):
+        # Otherwise it won't propagate changes:
+        setChanged()
+        super.notifyObservers(b)
+
+class BoxObserver(JFrame):
+    Observable notifier = BoxObservable()
+    def __init__(self, grid):
+        setTitle("Demonstrates Observer pattern")
+        Container cp = getContentPane()
+        cp.setLayout(GridLayout(grid, grid))
+        for(int x = 0 x < grid x++)
+            for(int y = 0 y < grid y++)
+                cp.add(OCBox(x, y, notifier))
+
+    def main(self, String[] args):
+        grid = 8
+            if(args.length > 0)
+                grid = Integer.parseInt(args[0])
+            JFrame f = BoxObserver(grid)
+            f.setSize(500, 400)
+            f.setVisible(1)
+            # JDK 1.3:
+            f.setDefaultCloseOperation(EXIT_ON_CLOSE)
+            # Add a WindowAdapter if you have JDK 1.2
+
+class OCBox(JPanel) implements Observer:
+    Color cColor = newColor()
+    colors = [
+      Color.black, Color.blue, Color.cyan,
+      Color.darkGray, Color.gray, Color.green,
+      Color.lightGray, Color.magenta,
+      Color.orange, Color.pink, Color.red,
+      Color.white, Color.yellow
+    ]
+    def newColor():
+        return colors[
+          (int)(Math.random() * colors.length)
+        ]
+
+    def __init__(self, x, y, Observable notifier):
+        self.x = x
+        self.y = y
+        notifier.addObserver(self)
+        self.notifier = notifier
+        addMouseListener(ML())
+
+    def paintComponent(self, Graphics g):
+        super.paintComponent(g)
+        g.setColor(cColor)
+        Dimension s = getSize()
+        g.fillRect(0, 0, s.width, s.height)
+
+    class ML(MouseAdapter):
+        def mousePressed(self, MouseEvent e):
+            notifier.notifyObservers(OCBox.self)
+
+    def update(self, Observable o, Object arg):
+        OCBox clicked = (OCBox)arg
+        if(nextTo(clicked)):
+            cColor = clicked.cColor
+            repaint()
+
+    def nextTo(OCBox b):
+        return Math.abs(x - b.x) <= 1 &&
+            Math.abs(y - b.y) <= 1

File code/Observer/BoxObserver.rsrc.py

+# Observer/BoxObserver.rsrc.py
+{'stack':{'type':'Stack',
+          'name':'BoxObserver',
+    'backgrounds': [
+      { 'type':'Background',
+        'name':'bgBoxObserver',
+        'title':'Demonstrates Observer pattern',
+        'position':(5, 5),
+        'size':(500, 400),
+        'components': [
+
+] # end components
+} # end background
+] # end backgrounds
+} }

File code/Observer/BoxObserverPythonCard.py

+# Observer/BoxObserverPythonCard.py
+""" Written by Kevin Altis as a first-cut for
+converting BoxObserver to Python. The Observer
+hasn't been integrated yet.
+To run this program, you must:
+Install WxPython from
+http://www.wxpython.org/download.php
+Install PythonCard. See:
+http://pythoncard.sourceforge.net
+"""
+from PythonCardPrototype import log, model
+import random
+
+GRID = 8
+
+class ColorBoxesTest(model.Background):
+    def on_openBackground(self, event):
+        self.document = []
+        for row in range(GRID):
+            line = []
+            for column in range(GRID):
+                line.append(self.createBox(row, column))
+            self.document.append(line[:])
+    def createBox(self, row, column):
+        colors = ['black', 'blue', 'cyan',
+        'darkGray', 'gray', 'green',
+        'lightGray', 'magenta',
+        'orange', 'pink', 'red',
+        'white', 'yellow']
+        width, height = self.panel.GetSizeTuple()
+        boxWidth = width / GRID
+        boxHeight = height / GRID
+        log.info("width:" + str(width) +
+          " height:" + str(height))
+        log.info("boxWidth:" + str(boxWidth) +
+          " boxHeight:" + str(boxHeight))
+        # use an empty image, though some other
+        # widgets would work just as well
+        boxDesc = {'type':'Image',
+          'size':(boxWidth, boxHeight), 'file':''}
+        name = 'box-%d-%d' % (row, column)
+        # There is probably a 1 off error in the
+        # calculation below since the boxes should
+        # probably have a slightly different offset
+        # to prevent overlaps
+        boxDesc['position'] = \
+          (column * boxWidth, row * boxHeight)
+        boxDesc['name'] = name
+        boxDesc['backgroundColor'] = \
+          random.choice(colors)
+        self.components[name] =  boxDesc
+        return self.components[name]
+
+    def changeNeighbors(self, row, column, color):
+
+        # This algorithm will result in changing the
+        # color of some boxes more than once, so an
+        # OOP solution where only neighbors are asked
+        # to change or boxes check to see if they are
+        # neighbors before changing would be better
+        # per the original example does the whole grid
+        # need to change its state at once like in a
+        # Life program? should the color change
+        # in the propogation of another notification
+        # event?
+
+        for r in range(max(0, row - 1),
+                       min(GRID, row + 2)):
+            for c in range(max(0, column - 1),
+                           min(GRID, column + 2)):
+                self.document[r][c].backgroundColor=color
+
+    # this is a background handler, so it isn't
+    # specific to a single widget. Image widgets
+    # don't have a mouseClick event (wxCommandEvent
+    # in wxPython)
+    def on_mouseUp(self, event):
+        target = event.target
+        prefix, row, column = target.name.split('-')
+        self.changeNeighbors(int(row), int(column),
+                             target.backgroundColor)
+
+if __name__ == '__main__':
+    app = model.PythonCardApp(ColorBoxesTest)
+    app.MainLoop()

File code/Observer/ObservedFlower.py

+# Observer/ObservedFlower.py
+# Demonstration of "observer" pattern.
+import sys
+sys.path += ['../util']
+from Observer import Observer, Observable
+
+class Flower:
+    def __init__(self):
+        self.isOpen = 0
+        self.openNotifier = Flower.OpenNotifier(self)
+        self.closeNotifier= Flower.CloseNotifier(self)
+    def open(self): # Opens its petals
+        self.isOpen = 1
+        self.openNotifier.notifyObservers()
+        self.closeNotifier.open()
+    def close(self): # Closes its petals
+        self.isOpen = 0
+        self.closeNotifier.notifyObservers()
+        self.openNotifier.close()
+    def closing(self): return self.closeNotifier
+
+    class OpenNotifier(Observable):
+        def __init__(self, outer):
+            Observable.__init__(self)
+            self.outer = outer
+            self.alreadyOpen = 0
+        def notifyObservers(self):
+            if self.outer.isOpen and \
+            not self.alreadyOpen:
+                self.setChanged()
+                Observable.notifyObservers(self)
+                self.alreadyOpen = 1
+        def close(self):
+            self.alreadyOpen = 0
+
+    class CloseNotifier(Observable):
+        def __init__(self, outer):
+            Observable.__init__(self)
+            self.outer = outer
+            self.alreadyClosed = 0
+        def notifyObservers(self):
+            if not self.outer.isOpen and \
+            not self.alreadyClosed:
+                self.setChanged()
+                Observable.notifyObservers(self)
+                self.alreadyClosed = 1
+        def open(self):
+            alreadyClosed = 0
+
+class Bee:
+    def __init__(self, name):
+        self.name = name
+        self.openObserver = Bee.OpenObserver(self)
+        self.closeObserver = Bee.CloseObserver(self)
+    # An inner class for observing openings:
+    class OpenObserver(Observer):
+        def __init__(self, outer):
+            self.outer = outer
+        def update(self, observable, arg):
+            print("Bee " + self.outer.name + \)
+              "'s breakfast time!"
+    # Another inner class for closings:
+    class CloseObserver(Observer):
+        def __init__(self, outer):
+            self.outer = outer
+        def update(self, observable, arg):
+            print("Bee " + self.outer.name + \)
+              "'s bed time!"
+
+class Hummingbird:
+    def __init__(self, name):
+        self.name = name
+        self.openObserver = \
+          Hummingbird.OpenObserver(self)
+        self.closeObserver = \
+          Hummingbird.CloseObserver(self)
+    class OpenObserver(Observer):
+        def __init__(self, outer):
+            self.outer = outer
+        def update(self, observable, arg):
+            print("Hummingbird " + self.outer.name + \
+              "'s breakfast time!")
+    class CloseObserver(Observer):
+        def __init__(self, outer):
+            self.outer = outer
+        def update(self, observable, arg):
+            print("Hummingbird " + self.outer.name + \
+              "'s bed time!")
+
+f = Flower()
+ba = Bee("Eric")
+bb = Bee("Eric 0.5")
+ha = Hummingbird("A")
+hb = Hummingbird("B")
+f.openNotifier.addObserver(ha.openObserver)
+f.openNotifier.addObserver(hb.openObserver)
+f.openNotifier.addObserver(ba.openObserver)
+f.openNotifier.addObserver(bb.openObserver)
+f.closeNotifier.addObserver(ha.closeObserver)
+f.closeNotifier.addObserver(hb.closeObserver)
+f.closeNotifier.addObserver(ba.closeObserver)
+f.closeNotifier.addObserver(bb.closeObserver)
+# Hummingbird 2 decides to sleep in:
+f.openNotifier.deleteObserver(hb.openObserver)
+# A change that interests observers:
+f.open()
+f.open() # It's already open, no change.
+# Bee 1 doesn't want to go to bed:
+f.closeNotifier.deleteObserver(ba.closeObserver)
+f.close()
+f.close() # It's already closed; no change
+f.openNotifier.deleteObservers()
+f.open()
+f.close()

File code/PatternRefactoring/clip1.py

+# PatternRefactoring/clip1.py
+    for(int i = 0 i < 30 i++)
+        switch((int)(Math.random() * 3)):
+            case 0 :
+                bin.add(new
+                  Aluminum(Math.random() * 100))
+                break
+            case 1 :
+                bin.add(new
+                  Paper(Math.random() * 100))
+                break
+            case 2 :
+                bin.add(new
+                  Glass(Math.random() * 100))

File code/PatternRefactoring/clip2.py

+# PatternRefactoring/clip2.py
+class Messenger:
+    # Must change this to add another type:
+    MAX_NUM = 4
+    def __init__(self, typeNum, val):
+        self.type = typeNum % MAX_NUM
+        self.data = val

File code/PatternRefactoring/clip3.py

+# PatternRefactoring/clip3.py
+    def factory(messenger):
+        switch(messenger.type):
+            default: # To quiet the compiler
+            case 0:
+                return Aluminum(messenger.data)
+            case 1:
+                return Paper(messenger.data)
+            case 2:
+                return Glass(messenger.data)
+            # Two lines here:
+            case 3:
+                return Cardboard(messenger.data)

File code/PatternRefactoring/clip4.py

+# PatternRefactoring/clip4.py
+    for(int i = 0 i < 30 i++)
+        bin.add(
+          Trash.factory(
+            Messenger(
+              (int)(Math.random() * Messenger.MAX_NUM),
+              Math.random() * 100)))

File code/PatternRefactoring/doubledispatch/DDAluminum.py

+# PatternRefactoring/doubledispatch/DDAluminum.py
+# Aluminum for double dispatching.
+
+class DDAluminum(Aluminum, TypedBinMember):
+    def __init__(self, wt): Aluminum.__init__(wt)
+    def addToBin(self, TypedBin[] tb):
+        for(int i = 0 i < tb.length i++)
+            if(tb[i].add(self)):
+                return True
+        return False::
+
+
+# PatternRefactoring/doubledispatch/DDPaper.py
+# Paper for double dispatching.
+
+class DDPaper(Paper, TypedBinMember):
+    def __init__(self, wt): Paper.__init__(wt)
+    def addToBin(self, TypedBin[] tb):
+        for(int i = 0 i < tb.length i++)
+            if(tb[i].add(self))
+                return True
+        return False::
+
+
+# PatternRefactoring/doubledispatch/DDGlass.py
+# Glass for double dispatching.
+
+class DDGlass(Glass, TypedBinMember):
+    def __init__(self, wt): Glass.__init__(wt)
+    def addToBin(self, TypedBin[] tb):
+        for(int i = 0 i < tb.length i++)
+            if(tb[i].add(self))
+                return True
+        return False::
+
+
+# PatternRefactoring/doubledispatch/DDCardboard.py
+# Cardboard for double dispatching.
+
+class DDCardboard(Cardboard, TypedBinMember):
+    def __init__(self, wt):
+        Cardboard.__init__(wt)
+    def addToBin(self, TypedBin[] tb):
+        for(int i = 0 i < tb.length i++)
+            if(tb[i].add(self))
+                return True
+        return False

File code/PatternRefactoring/doubledispatch/DDTrash.dat

+# PatternRefactoring/doubledispatch/DDTrash.dat
+DDGlass:54
+DDPaper:22
+DDPaper:11
+DDGlass:17
+DDAluminum:89
+DDPaper:88
+DDAluminum:76
+DDCardboard:96
+DDAluminum:25
+DDAluminum:34
+DDGlass:11
+DDGlass:68
+DDGlass:43
+DDAluminum:27
+DDCardboard:44
+DDAluminum:18
+DDPaper:91
+DDGlass:63
+DDGlass:50
+DDGlass:80
+DDAluminum:81
+DDCardboard:12
+DDGlass:12
+DDGlass:54
+DDAluminum:36
+DDAluminum:93
+DDGlass:93
+DDPaper:80
+DDGlass:36
+DDGlass:12
+DDGlass:60
+DDPaper:66
+DDAluminum:36