Bruce Eckel avatar Bruce Eckel committed b1be62c

Partway through rewrite of Jython chapter for Jython 2.5.

Comments (0)

Files changed (121)

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

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

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 contents unchanged.

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

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

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

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

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

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

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

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

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

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

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();

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)

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

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

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

code/Jython/Fractal.py

+import turtle
+turtle.clear
+
+class fractal(object):
+
+     def __init__(self, lstring, rule, line_length, angle, shrink_factor):
+         self.lstring = lstring
+         self.rule = rule
+         self.line_length = line_length
+         self.angle = angle
+         self.shrink_factor=shrink_factor
+
+     def draw(self):
+         drawingdict = {'F': lambda: turtle.forward(self.line_length),
+                        '-':lambda: turtle.right(self.angle),
+                        '+':lambda: turtle.left(self.angle),}
+         for rule in self.lstring:
+             drawingdict[rule]()
+
+     def iterate(self):
+         self.lstring = self.lstring.replace(rule[0],rule[1])
+         self.line_length=self.line_length/self.shrink_factor
+
+def recurse(f,smallest):
+     if f.line_length>=smallest:
+         turtle.reset()
+         f.iterate()
+         f.draw()
+         recurse(f,smallest)
+
+if __name__=='__main__':
+     start = 'F+F+F+F'
+     rule = ('F','F+F-F-FF+F+F-F')
+     f = fractal(start,rule,50,90,2)
+     recurse(f,10)

code/Jython/GreenHouseController.java

+// Jython/GreenHouseController.java
+import org.python.core.*;
+import org.python.util.PythonInterpreter;
+
+public class GreenHouseController {
+  public static void main(String[] args) throws PyException  {
+    PythonInterpreter interp = new PythonInterpreter();
+    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()");
+  }
+}

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

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)

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

code/Jython/PyUtil.java

+// Jython/PyUtil.java
+// PythonInterpreter utilities
+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()));
+    }
+    return new PyDictionary(m);
+  }
+}

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

code/Jython/PythonInterpreterGetting.java

+// Jython/PythonInterpreterGetting.java
+// Getting data from the PythonInterpreter object.
+import org.python.util.PythonInterpreter;
+import org.python.core.*;
+import java.util.*;
+
+public class PythonInterpreterGetting {
+  public static void
+  main(String[] args) throws PyException  {
+    PythonInterpreter interp = new PythonInterpreter();
+    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());
+  }
+}

code/Jython/PythonInterpreterSetting.java

+// Jython/PythonInterpreterSetting.java
+// Passing data from Java to python when using
+// the PythonInterpreter object.
+import org.python.util.PythonInterpreter;
+import org.python.core.*;
+import java.util.*;
+
+public class PythonInterpreterSetting {
+  public static void main(String[] args) throws PyException  {
+    PythonInterpreter interp = new PythonInterpreter();
+    // 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 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])");
+  }
+}

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

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

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)

code/Jython/Simple.py

+# Jython/Simple.py
+import platform, glob, time
+from subprocess import Popen, PIPE
+
+print platform.uname() # What are we running on?
+print glob.glob("*.py") # Find files with .py extensions
+# Send a command to the OS and capture the results:
+print Popen(["ping", "-c", "1", "www.mindview.net"], 
+               stdout=PIPE).communicate()[0]
+
+# Time an operation:
+start = time.time()
+for n in xrange(1000000):
+    for i in xrange(10): 
+        oct(i)
+print time.time() - start

code/Jython/TestPyUtil.java

+// Jython/TestPyUtil.java
+import org.python.util.PythonInterpreter;
+import java.util.*;
+
+public class TestPyUtil {
+  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[]) {
+    TestPyUtil test = new TestPyUtil();
+    test.test1();
+    test.test2();
+    test.test3();
+    test.test4();
+  }
+}

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

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

code/Jython/test.html

+
+<html><body>
+<h1>Hello, World!</h1>
+</body></html>

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

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

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)

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)

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

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

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
+