Commits

Anonymous committed 1dddb7e

Fixed Jython in code directory. More improvements to CodeManager.py.

  • Participants
  • Parent commits 94d3219

Comments (0)

Files changed (121)

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: 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])
+
+       

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/Jython/GreenHouseController.java

+// Jython/GreenHouseController.java
+package jython;
+import org.python.util.PythonInterpreter;
+import org.python.core.*;
+import junit.framework.*;
+
+public class
+GreenHouseController extends TestCase  {
+  PythonInterpreter interp =
+    new PythonInterpreter();
+  public void test() throws PyException  {
+    System.out.println(
+      "Loading GreenHouse Language");
+    interp.execfile("GreenHouseLanguage.py");
+    System.out.println(
+      "Loading GreenHouse Script");
+    interp.execfile("Schedule.ghs");
+    System.out.println(
+      "Executing GreenHouse Script");
+    interp.exec("run()");
+  }
+  public static void
+  main(String[] args) throws PyException  {
+    junit.textui.TestRunner.run(GreenHouseController.class);
+  }
+}

File code/Jython/GreenHouseLanguage.py

+# Jython/GreenHouseLanguage.py
+
+class Event:
+    events = [] # static
+    def __init__(self, action, time):
+        self.action = action
+        self.time = time
+        Event.events.append(self)
+    # Used by sort(). This will cause
+    # comparisons to be based only on time:
+    def __cmp__ (self, other):
+        if self.time < other.time: return -1
+        if self.time > other.time: return 1
+        return 0
+    def run(self):
+        print("%.2f: %s" % (self.time, self.action))
+
+class LightOn(Event):
+    def __init__(self, time):
+        Event.__init__(self, "Light on", time)
+
+class LightOff(Event):
+    def __init__(self, time):
+        Event.__init__(self, "Light off", time)
+
+class WaterOn(Event):
+    def __init__(self, time):
+        Event.__init__(self, "Water on", time)
+
+class WaterOff(Event):
+    def __init__(self, time):
+        Event.__init__(self, "Water off", time)
+
+class ThermostatNight(Event):
+    def __init__(self, time):
+        Event.__init__(self,"Thermostat night", time)
+
+class ThermostatDay(Event):
+    def __init__(self, time):
+        Event.__init__(self, "Thermostat day", time)
+
+class Bell(Event):
+    def __init__(self, time):
+        Event.__init__(self, "Ring bell", time)
+
+def run():
+    Event.events.sort();
+    for e in Event.events:
+        e.run()
+
+# To test, this will be run when you say:
+# python GreenHouseLanguage.py
+if __name__ == "__main__":
+    ThermostatNight(5.00)
+    LightOff(2.00)
+    WaterOn(3.30)
+    WaterOff(4.45)
+    LightOn(1.00)
+    ThermostatDay(6.00)
+    Bell(7.00)
+    run()

File code/Jython/JavaClassInPython.py

+# Jython/JavaClassInPython.py
+# run with: jython.bat JavaClassInPython.py
+# Using Java classes within Jython
+from java.util import Date, HashSet, HashMap
+from jython.javaclass import JavaClass
+from math import sin
+
+d = Date() # Creating a Java Date object
+print(d) # Calls toString()
+
+# A "generator" to easily create data:
+class ValGen:
+    def __init__(self, maxVal):
+        self.val = range(maxVal)
+    # Called during 'for' iteration:
+    def __getitem__(self, i):
+        # Returns a tuple of two elements:
+        return self.val[i], sin(self.val[i])
+
+# Java standard containers:
+map = HashMap()
+set = HashSet()
+
+for x, y in ValGen(10):
+    map.put(x, y)
+    set.add(y)
+    set.add(y)
+
+print(map)
+print(set)
+
+# Iterating through a set:
+for z in set:
+    print(z, z.__class__)
+
+print(map[3]) # Uses Python dictionary indexing
+for x in map.keySet(): # keySet() is a Map method
+    print(x, map[x])
+
+# Using a Java class that you create yourself is
+# just as easy:
+jc = JavaClass()
+jc2 = JavaClass("Created within Jython")
+print(jc2.getVal())
+jc.setVal("Using a Java class is trivial")
+print(jc.getVal())
+print(jc.getChars())
+jc.val = "Using bean properties"
+print(jc.val)

File code/Jython/MultipleJythons.java

+// Jython/MultipleJythons.java
+// You can run multiple interpreters, each
+// with its own name space.
+package jython;
+import org.python.util.PythonInterpreter;
+import org.python.core.*;
+import junit.framework.*;
+
+public class MultipleJythons extends TestCase  {
+  PythonInterpreter
+    interp1 =  new PythonInterpreter(),
+    interp2 =  new PythonInterpreter();
+  public void test() throws PyException {
+    interp1.set("a", new PyInteger(42));
+    interp2.set("a", new PyInteger(47));
+    interp1.exec("print(a)");
+    interp2.exec("print(a)");
+    PyObject x1 = interp1.get("a");
+    PyObject x2 = interp2.get("a");
+    System.out.println("a from interp1: " + x1);
+    System.out.println("a from interp2: " + x2);
+  }
+  public static void
+  main(String[] args) throws PyException  {
+    junit.textui.TestRunner.run(MultipleJythons.class);
+  }
+}

File code/Jython/PyUtil.java

+// Jython/PyUtil.java
+// PythonInterpreter utilities
+package net.mindview.python;
+import org.python.util.PythonInterpreter;
+import org.python.core.*;
+import java.util.*;
+
+public class PyUtil {
+  /** Extract a Python tuple or array into a Java
+  List (which can be converted into other kinds
+  of lists and sets inside Java).
+  @param interp The Python interpreter object
+  @param pyName The id of the python list object
+  */
+  public static List
+  toList(PythonInterpreter interp, String pyName){
+    return new ArrayList(Arrays.asList(
+      (Object[])interp.get(
+        pyName, Object[].class)));
+  }
+  /** Extract a Python dictionary into a Java Map
+  @param interp The Python interpreter object
+  @param pyName The id of the python dictionary
+  */
+  public static Map
+  toMap(PythonInterpreter interp, String pyName){
+    PyList pa = ((PyDictionary)interp.get(
+      pyName)).items();
+    Map map = new HashMap();
+    while(pa.__len__() != 0) {
+      PyTuple po = (PyTuple)pa.pop();
+      Object first = po.__finditem__(0)
+        .__tojava__(Object.class);
+      Object second = po.__finditem__(1)
+        .__tojava__(Object.class);
+      map.put(first, second);
+    }
+    return map;
+  }
+  /** Turn a Java Map into a PyDictionary,
+  suitable for placing into a PythonInterpreter
+  @param map The Java Map object
+  */
+  public static PyDictionary
+  toPyDictionary(Map map) {
+    Map m = new HashMap();
+    Iterator it = map.entrySet().iterator();
+    while(it.hasNext()) {
+      Map.Entry e = (Map.Entry)it.next();
+      m.put(Py.java2py(e.getKey()),
+        Py.java2py(e.getValue()));
+    }
+    // PyDictionary constructor wants a Hashtable:
+    return new PyDictionary(new Hashtable(m));
+  }
+}

File code/Jython/PythonDialogs.py

+# Jython/PythonDialogs.py
+# Dialogs.java from "Thinking in Java, 2nd
+# edition," Chapter 13, converted into Jython.
+# Don't run this as part of the automatic make:
+#=M @echo skipping PythonDialogs.py
+from java.awt import FlowLayout
+from javax.swing import JFrame, JDialog, JLabel
+from javax.swing import JButton
+
+class MyDialog(JDialog):
+    def __init__(self, parent=None):
+        JDialog.__init__(self,
+          title="My dialog", modal=1)
+        self.contentPane.layout = FlowLayout()
+        self.contentPane.add(JLabel("A dialog!"))
+        self.contentPane.add(JButton("OK",
+          actionPerformed =
+            lambda e, t=self: t.dispose()))
+        self.pack()
+
+frame = JFrame("Dialogs", visible=1,
+  defaultCloseOperation=JFrame.EXIT_ON_CLOSE)
+dlg = MyDialog()
+frame.contentPane.add(
+  JButton("Press here to get a Dialog Box",
+    actionPerformed = lambda e: dlg.show()))
+frame.pack()

File code/Jython/PythonInterpreterGetting.java

+// Jython/PythonInterpreterGetting.java
+// Getting data from the PythonInterpreter object.
+package jython;
+import org.python.util.PythonInterpreter;
+import org.python.core.*;
+import java.util.*;
+import net.mindview.python.*;
+import junit.framework.*;
+
+public class
+PythonInterpreterGetting extends TestCase {
+  PythonInterpreter interp =
+    new PythonInterpreter();
+  public void test() throws PyException  {
+    interp.exec("a = 100");
+    // If you just use the ordinary get(),
+    // it returns a PyObject:
+    PyObject a = interp.get("a");
+    // There's not much you can do with a generic
+    // PyObject, but you can print it out:
+    System.out.println("a = " + a);
+    // If you know the type it's supposed to be,
+    // you can "cast" it using __tojava__() to
+    // that Java type and manipulate it in Java.
+    // To use 'a' as an int, you must use
+    // the Integer wrapper class:
+    int ai= ((Integer)a.__tojava__(Integer.class))
+      .intValue();
+    // There are also convenience functions:
+    ai = Py.py2int(a);
+    System.out.println("ai + 47 = " + (ai + 47));
+    // You can convert it to different types:
+    float af = Py.py2float(a);
+    System.out.println("af + 47 = " + (af + 47));
+    // If you try to cast it to an inappropriate
+    // type you'll get a runtime exception:
+    //! String as = (String)a.__tojava__(
+    //!   String.class);
+
+    // If you know the type, a more useful method
+    // is the overloaded get() that takes the
+    // desired class as the 2nd argument:
+    interp.exec("x = 1 + 2");
+    int x = ((Integer)interp
+      .get("x", Integer.class)).intValue();
+    System.out.println("x = " + x);
+
+    // Since Python is so good at manipulating
+    // strings and files, you will often need to
+    // extract an array of Strings. Here, a file
+    // is read as a Python array:
+    interp.exec("lines = " +
+      "open('PythonInterpreterGetting.java')" +
+      ".readlines()");
+    // Pull it in as a Java array of String:
+    String[] lines = (String[])
+      interp.get("lines", String[].class);
+    for(int i = 0; i < 10; i++)
+      System.out.print(lines[i]);
+
+    // As an example of useful string tools,
+    // global expansion of ambiguous file names
+    // using glob is very useful, but it's not
+    // part of the standard Jython package, so
+    // you'll have to make sure that your
+    // Python path is set to include these, or
+    // that you deliver the necessary Python
+    // files with your application.
+    interp.exec("from glob import glob");
+    interp.exec("files = glob('*.java')");
+    String[] files = (String[])
+      interp.get("files", String[].class);
+    for(int i = 0; i < files.length; i++)
+      System.out.println(files[i]);
+
+    // You can extract tuples and arrays into
+    // Java Lists with net.mindview.PyUtil:
+    interp.exec(
+      "tup = ('fee', 'fi', 'fo', 'fum', 'fi')");
+    List tup = PyUtil.toList(interp, "tup");
+    System.out.println(tup);
+    // It really is a list of String objects:
+    System.out.println(tup.get(0).getClass());
+    // You can easily convert it to a Set:
+    Set tups = new HashSet(tup);
+    System.out.println(tups);
+    interp.exec("ints=[1,3,5,7,9,11,13,17,19]");
+    List ints = PyUtil.toList(interp, "ints");
+    System.out.println(ints);
+    // It really is a List of Integer objects:
+    System.out.println((ints.get(1)).getClass());
+
+    // If you have a Python dictionary, it can
+    // be extracted into a Java Map, again with
+    // net.mindview.PyUtil:
+    interp.exec("dict = { 1 : 'a', 3 : 'b'," +
+      "5 : 'c', 9 : 'd', 11 : 'e' }");
+    Map map = PyUtil.toMap(interp, "dict");
+    System.out.println("map: " + map);
+    // It really is Java objects, not PyObjects:
+    Iterator it = map.entrySet().iterator();
+    Map.Entry e = (Map.Entry)it.next();
+    System.out.println(e.getKey().getClass());
+    System.out.println(e.getValue().getClass());
+  }
+  public static void
+  main(String[] args) throws PyException  {
+    junit.textui.TestRunner.run(
+      PythonInterpreterGetting.class);
+  }
+}

File code/Jython/PythonInterpreterSetting.java

+// Jython/PythonInterpreterSetting.java
+// Passing data from Java to python when using
+// the PythonInterpreter object.
+package jython;
+import org.python.util.PythonInterpreter;
+import org.python.core.*;
+import java.util.*;
+import net.mindview.python.*;
+import junit.framework.*;
+
+public class
+PythonInterpreterSetting extends TestCase  {
+  PythonInterpreter interp =
+    new PythonInterpreter();
+  public void test() throws PyException  {
+    // It automatically converts Strings
+    // into native Python strings:
+    interp.set("a", "This is a test");
+    interp.exec("print(a)");
+    interp.exec("print(a[5:])"); // A slice
+    // It also knows what to do with arrays:
+    String[] s = { "How", "Do", "You", "Do?" };
+    interp.set("b", s);
+    interp.exec("for x in b: print(x[0], x)");
+    // set() only takes Objects, so it can't
+    // figure out primitives. Instead,
+    // you have to use wrappers:
+    interp.set("c", new PyInteger(1));
+    interp.set("d", new PyFloat(2.2));
+    interp.exec("print(c + d)");
+    // You can also use Java's object wrappers:
+    interp.set("c", new Integer(9));
+    interp.set("d", new Float(3.14));
+    interp.exec("print(c + d)");
+    // Define a Python function to print arrays:
+    interp.exec(
+      "def prt(x): \n" +
+      "  print(x)\n" +
+      "  for i in x: \n" +
+      "    print(i,)\n" +
+      "  print(x.__class__)\n");
+    // Arrays are Objects, so it has no trouble
+    // figuring out the types contained in arrays:
+    Object[] types = {
+      new boolean[]{ true, false, false, true },
+      new char[]{ 'a', 'b', 'c', 'd' },
+      new byte[]{ 1, 2, 3, 4 },
+      new int[]{ 10, 20, 30, 40 },
+      new long[]{ 100, 200, 300, 400 },
+      new float[]{ 1.1f, 2.2f, 3.3f, 4.4f },
+      new double[]{ 1.1, 2.2, 3.3, 4.4 },
+    };
+    for(int i = 0; i < types.length; i++) {
+      interp.set("e", types[i]);
+      interp.exec("prt(e)");
+    }
+    // It uses toString() to print Java objects:
+    interp.set("f", new Date());
+    interp.exec("print(f)");
+    // You can pass it a List
+    // and index into it...
+    List x = new ArrayList();
+    for(int i = 0; i < 10; i++)
+        x.add(new Integer(i * 10));
+    interp.set("g", x);
+    interp.exec("print(g)");
+    interp.exec("print(g[1])");
+    // ... But it's not quite smart enough
+    // to treat it as a Python array:
+    interp.exec("print(g.__class__)");
+    // interp.exec("print(g[5:])"); // Fails
+    // must extract the Java array:
+    System.out.println("ArrayList to array:");
+    interp.set("h", x.toArray());
+    interp.exec("print(h.__class__)");
+    interp.exec("print(h[5:])");
+    // Passing in a Map:
+    Map m = new HashMap();
+    m.put(new Integer(1), new Character('a'));
+    m.put(new Integer(3), new Character('b'));
+    m.put(new Integer(5), new Character('c'));
+    m.put(new Integer(7), new Character('d'));
+    m.put(new Integer(11), new Character('e'));
+    System.out.println("m: " + m);
+    interp.set("m", m);
+    interp.exec("print(m, m.__class__," +
+      "m[1], m[1].__class__)");
+    // Not a Python dictionary, so this fails:
+    //! interp.exec("for x in m.keys():" +
+    //!   "print(x, m[x])");
+    // To convert a Map to a Python dictionary,
+    // use net.mindview.python.PyUtil:
+    interp.set("m", PyUtil.toPyDictionary(m));
+    interp.exec("print(m, m.__class__, " +
+      "m[1], m[1].__class__)");
+    interp.exec("for x in m.keys():print(x,m[x])");
+  }
+  public static void
+  main(String[] args) throws PyException  {
+    junit.textui.TestRunner.run(
+      PythonInterpreterSetting.class);
+  }
+}

File code/Jython/PythonSwing.py

+# Jython/PythonSwing.py
+# The HTMLButton.java example from
+# "Thinking in Java, 2nd edition," Chapter 13,
+# converted into Jython.
+# Don't run this as part of the automatic make:
+#=M @echo skipping PythonSwing.py
+from javax.swing import JFrame, JButton, JLabel
+from java.awt import FlowLayout
+
+frame = JFrame("HTMLButton", visible=1,
+  defaultCloseOperation=JFrame.EXIT_ON_CLOSE)
+
+def kapow(e):
+    frame.contentPane.add(JLabel("<html>"+
+      "<i><font size=+4>Kapow!"))
+    # Force a re-layout to
+    # include the new label:
+    frame.validate()
+
+button = JButton("<html><b><font size=+2>" +
+  "<center>Hello!<br><i>Press me now!",
+  actionPerformed=kapow)
+frame.contentPane.layout = FlowLayout()
+frame.contentPane.add(button)
+frame.pack()
+frame.size=200, 500

File code/Jython/PythonToJavaClass.py

+# Jython/PythonToJavaClass.py
+#=T python\java\test\PythonToJavaClass.class
+#=M jythonc.bat --package python.java.test \
+#=M PythonToJavaClass.py
+# A Python class created to produce a Java class
+from jarray import array
+import java
+
+class PythonToJavaClass(java.lang.Object):
+    # The '@sig' signature string is used to create
+    # the proper signature in the resulting
+    # Java code:
+    def __init__(self):
+        "@sig public PythonToJavaClass()"
+        print("Constructor for PythonToJavaClass")
+
+    def simple(self):
+        "@sig public void simple()"
+        print("simple()")
+
+    # Returning values to Java:
+    def returnString(self):
+        "@sig public java.lang.String returnString()"
+        return "howdy"
+
+    # You must construct arrays to return along
+    # with the type of the array:
+    def returnArray(self):
+        "@sig public java.lang.String[] returnArray()"
+        test = [ "fee", "fi", "fo", "fum" ]
+        return array(test, java.lang.String)
+
+    def ints(self):
+        "@sig public java.lang.Integer[] ints()"
+        test = [ 1, 3, 5, 7, 11, 13, 17, 19, 23 ]
+        return array(test, java.lang.Integer)
+
+    def doubles(self):
+        "@sig public java.lang.Double[] doubles()"
+        test = [ 1, 3, 5, 7, 11, 13, 17, 19, 23 ]
+        return array(test, java.lang.Double)
+
+    # Passing arguments in from Java:
+    def argIn1(self, a):
+        "@sig public void argIn1(java.lang.String a)"
+        print("a: %s" % a)
+        print("a.__class__", a.__class__)
+
+    def argIn2(self, a):
+        "@sig public void argIn1(java.lang.Integer a)"
+        print("a + 100: %d" % (a + 100))
+        print("a.__class__", a.__class__)
+
+    def argIn3(self, a):
+        "@sig public void argIn3(java.util.List a)"
+        print("received List:", a, a.__class__)
+        print("element type:", a[0].__class__)
+        print("a[3] + a[5]:", a[5] + a[7])
+        #! print("a[2:5]:", a[2:5]) # Doesn't work
+
+    def argIn4(self, a):
+        "@sig public void \
+           argIn4(org.python.core.PyArray a)"
+        print("received type:", a.__class__)
+        print("a: ", a)
+        print("element type:", a[0].__class__)
+        print("a[3] + a[5]:", a[5] + a[7])
+        print("a[2:5]:", a[2:5] # A real Python array)
+
+    # A map must be passed in as a PyDictionary:
+    def argIn5(self, m):
+        "@sig public void \
+           argIn5(org.python.core.PyDictionary m)"
+        print("received Map: ", m, m.__class__)
+        print("m['3']:", m['3'])
+        for x in m.keys():
+            print(x, m[x])

File code/Jython/Schedule.ghs

+# Jython/Schedule.ghs
+Bell(7.00)
+ThermostatDay(6.00)
+WaterOn(3.30)
+LightOn(1.00)
+ThermostatNight(5.00)
+LightOff(2.00)
+WaterOff(4.45)

File code/Jython/Test.java

+// Jython/Test.java
+package net.mindview.python;
+import org.python.util.PythonInterpreter;
+import java.util.*;
+import junit.framework.*;
+
+public class Test extends TestCase  {
+  PythonInterpreter pi =
+    new PythonInterpreter();
+  public void test1() {
+    pi.exec("tup=('fee','fi','fo','fum','fi')");
+    List lst = PyUtil.toList(pi, "tup");
+    System.out.println(lst);
+    System.out.println(new HashSet(lst));
+  }
+  public void test2() {
+    pi.exec("ints=[1,3,5,7,9,11,13,17,19]");
+    List lst = PyUtil.toList(pi, "ints");
+    System.out.println(lst);
+  }
+  public void test3() {
+    pi.exec("dict = { 1 : 'a', 3 : 'b', " +
+      "5 : 'c', 9 : 'd', 11 : 'e'}");
+    Map mp = PyUtil.toMap(pi, "dict");
+    System.out.println(mp);
+  }
+  public void test4() {
+    Map m = new HashMap();
+    m.put("twas", new Integer(11));
+    m.put("brillig", new Integer(27));
+    m.put("and", new Integer(47));
+    m.put("the", new Integer(42));
+    m.put("slithy", new Integer(33));
+    m.put("toves", new Integer(55));
+    System.out.println(m);
+    pi.set("m", PyUtil.toPyDictionary(m));
+    pi.exec("print(m)");
+    pi.exec("print(m['slithy'])");
+  }
+  public static void main(String args[]) {
+    junit.textui.TestRunner.run(Test.class);
+  }
+}

File code/Jython/TestPythonToJavaClass.java

+// Jython/TestPythonToJavaClass.java
+//+D python\java\test\PythonToJavaClass.class
+package jython;
+import java.lang.reflect.*;
+import java.util.*;
+import org.python.core.*;
+import junit.framework.*;
+import java.util.*;
+import net.mindview.python.*;
+// The package with the Python-generated classes:
+import python.java.test.*;
+
+public class
+TestPythonToJavaClass extends TestCase  {
+  PythonToJavaClass p2j = new PythonToJavaClass();
+  public void testDumpClassInfo() {
+    System.out.println(
+      Arrays.toString(
+        p2j.getClass().getConstructors()));
+    Method[] methods =
+      p2j.getClass().getMethods();
+    for(int i = 0; i < methods.length; i++) {
+      String nm = methods[i].toString();
+      if(nm.indexOf("PythonToJavaClass") != -1)
+        System.out.println(nm);
+    }
+  }
+  public void test1() {
+    p2j.simple();
+    System.out.println(p2j.returnString());
+    System.out.println(
+      Arrays.toString(p2j.returnArray()));
+    System.out.println(
+      Arrays.toString(p2j.ints());
+    System.out.println(
+      Arrays.toString(p2j.doubles()));
+    p2j.argIn1("Testing argIn1()");
+    p2j.argIn2(new Integer(47));
+    ArrayList a = new ArrayList();
+    for(int i = 0; i < 10; i++)
+      a.add(new Integer(i));
+    p2j.argIn3(a);
+    p2j.argIn4(
+      new PyArray(Integer.class, a.toArray()));
+    Map m = new HashMap();
+    for(int i = 0; i < 10; i++)
+      m.put("" + i, new Float(i));
+    p2j.argIn5(PyUtil.toPyDictionary(m));
+  }
+  public static void main(String[] args) {
+    junit.textui.TestRunner.run(
+      TestPythonToJavaClass.class);
+  }
+}

File code/Jython/javaclass/JavaClass.java

+// Jython/javaclass/JavaClass.java
+package jython.javaclass;
+import junit.framework.*;
+import java.util.*;
+
+public class JavaClass {
+  private String s = "";
+  public JavaClass() {
+    System.out.println("JavaClass()");
+  }
+  public JavaClass(String a) {
+    s = a;
+    System.out.println("JavaClass(String)");
+  }
+  public String getVal() {
+    System.out.println("getVal()");
+    return s;
+  }
+  public void setVal(String a) {
+    System.out.println("setVal()");
+    s = a;
+  }
+  public Character[] getChars() {
+    System.out.println("getChars()");
+    Character[] r = new Character[s.length()];
+    for(int i = 0; i < s.length(); i++)
+      r[i] = new Character(s.charAt(i));
+    return r;
+  }
+  public static class Test extends TestCase  {
+    JavaClass
+      x1 = new JavaClass(),
+      x2 = new JavaClass("UnitTest");
+    public void test1() {
+      System.out.println(x2.getVal());
+      x1.setVal("SpamEggsSausageAndSpam");
+      System.out.println(
+        Arrays.toString(x1.getChars()));
+    }
+  }
+  public static void main(String[] args) {
+    junit.textui.TestRunner.run(Test.class);
+  }
+}

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