瀏覽代碼

Merge pull request #1 from faif/master

Update from original
Ibrahim Diop 11 年之前
父節點
當前提交
640cf76b32
共有 37 個文件被更改,包括 773 次插入327 次删除
  1. 1 0
      .gitignore
  2. 26 5
      3-tier.py
  3. 35 28
      README.md
  4. 二進制
      __pycache__/facade.cpython-33.pyc
  5. 二進制
      __pycache__/mediator.cpython-33.pyc
  6. 二進制
      __pycache__/null.cpython-33.pyc
  7. 27 10
      abstract_factory.py
  8. 13 10
      adapter.py
  9. 12 0
      append_output.sh
  10. 25 9
      borg.py
  11. 15 5
      bridge.py
  12. 10 1
      builder.py
  13. 17 6
      catalog.py
  14. 40 26
      chain.py
  15. 33 0
      chaining_method.py
  16. 11 4
      command.py
  17. 45 36
      composite.py
  18. 22 35
      decorator.py
  19. 26 1
      facade.py
  20. 15 3
      factory_method.py
  21. 9 0
      flyweight.py
  22. 0 1
      foo.txt
  23. 37 27
      graph_search.py
  24. 9 0
      iterator.py
  25. 35 10
      mediator.py
  26. 35 2
      memento.py
  27. 17 0
      mvc.py
  28. 0 81
      null.py
  29. 28 2
      observer.py
  30. 10 0
      pool.py
  31. 22 9
      prototype.py
  32. 24 13
      proxy.py
  33. 92 0
      publish_subscribe.py
  34. 17 0
      state.py
  35. 6 0
      strategy.py
  36. 50 0
      template.py
  37. 9 3
      visitor.py

+ 1 - 0
.gitignore

@@ -0,0 +1 @@
+__pycache__

+ 26 - 5
3-tier.py

@@ -3,6 +3,7 @@
 
 
 
 
 class Data(object):
 class Data(object):
+    """ Data Store Class """
 
 
     products = {
     products = {
         'milk': {'price': 1.50, 'quantity': 10},
         'milk': {'price': 1.50, 'quantity': 10},
@@ -10,20 +11,26 @@ class Data(object):
         'cheese': {'price': 2.00, 'quantity': 10}
         'cheese': {'price': 2.00, 'quantity': 10}
     }
     }
 
 
+    def __get__(self, obj, klas):
+        print ("(Fetching from Data Store)")
+        return {'products': self.products}
+
 
 
 class BusinessLogic(object):
 class BusinessLogic(object):
 
 
-    def __init__(self):
-        self.data = Data()
+    """ Business logic holding data store instances """
+
+    data = Data()
 
 
     def product_list(self):
     def product_list(self):
-        return self.data.products.keys()
+        return self.data['products'].keys()
 
 
     def product_information(self, product):
     def product_information(self, product):
-        return self.data.products.get(product, None)
+        return self.data['products'].get(product, None)
 
 
 
 
 class Ui(object):
 class Ui(object):
+    """ UI interaction class """
 
 
     def __init__(self):
     def __init__(self):
         self.business_logic = BusinessLogic()
         self.business_logic = BusinessLogic()
@@ -31,7 +38,8 @@ class Ui(object):
     def get_product_list(self):
     def get_product_list(self):
         print('PRODUCT LIST:')
         print('PRODUCT LIST:')
         for product in self.business_logic.product_list():
         for product in self.business_logic.product_list():
-            print(product)
+            #print(product)
+            yield product
         print('')
         print('')
 
 
     def get_product_information(self, product):
     def get_product_information(self, product):
@@ -56,3 +64,16 @@ def main():
 
 
 if __name__ == '__main__':
 if __name__ == '__main__':
     main()
     main()
+
+### OUTPUT ###
+# (Fetching from Data Store)
+# PRODUCT INFORMATION:
+# Name: Cheese, Price: 2.00, Quantity: 10
+# (Fetching from Data Store)
+# PRODUCT INFORMATION:
+# Name: Eggs, Price: 0.20, Quantity: 100
+# (Fetching from Data Store)
+# PRODUCT INFORMATION:
+# Name: Milk, Price: 1.50, Quantity: 10
+# (Fetching from Data Store)
+# That product "arepas" does not exist in the records

+ 35 - 28
README.md

@@ -1,34 +1,41 @@
 python-patterns
 python-patterns
 ===============
 ===============
 
 
-A collection of design patterns implemented (by other people) in python
+A collection of design patterns and idioms in Python.
+
+When an implementation is added or modified, be sure to update this file and
+rerun `append_output.sh` (eg. ./append_output.sh borg.py) to keep the output
+comments at the bottom up to date.
 
 
 Current Patterns:
 Current Patterns:
 
 
-* 3-tier		
-* composite		
-* mvc
-* decorator		
-* null
-* facade		
-* observer
-* abstract_factory	
-* factory_method	
-* pool
-* adapter		
-* flyweight		
-* prototype
-* borg					
-* proxy
-* bridge		
-* graph_search		
-* state
-* builder		
-* iterator		
-* strategy
-* chain		
-* mediator		
-* template
-* command		
-* memento		
-* visitor
+| Pattern | Description |
+|:-------:| ----------- |
+| [3-tier](3-tier.py) | data<->business logic<->presentation separation (strict relationships) |
+| [abstract_factory](abstract_factory.py) | use a generic function with specific factories |
+| [adapter](adapter.py) | adapt one interface to another using a whitelist |
+| [borg](borg.py) | a singleton with shared-state among instances |
+| [bridge](bridge.py) | a client-provider middleman to soften interface changes |
+| [builder](builder.py) | call many little discrete methods rather than having a huge number of constructor parameters |
+| [catalog](catalog.py) | general methods will call different specialized methods based on construction parameter |
+| [chain](chain.py) | apply a chain of successive handlers to try and process the data |
+| [command](command.py) | bundle a command and arguments to call later |
+| [composite](composite.py) | encapsulate and provide access to a number of different objects |
+| [decorator](decorator.py) | wrap functionality with other functionality in order to affect outputs |
+| [facade](facade.py) | use one class as an API to a number of others |
+| [factory_method](factory_method.py) | delegate a specialized function/method to create instances |
+| [flyweight](flyweight.py) | transparently reuse existing instances of objects with similar/identical state |
+| [graph_search](graph_search.py) | (graphing algorithms, not design patterns) |
+| [mediator](mediator.py) | an object that knows how to connect other objects and act as a proxy |
+| [memento](memento.py) | generate an opaque token that can be used to go back to a previous state |
+| [mvc](mvc.py) | model<->view<->controller (non-strict relationships) |
+| [observer](observer.py) | provide a callback for notification of events/changes to data |
+| [pool](pool.py) | preinstantiate and maintain a group of instances of the same type |
+| [prototype](prototype.py) | use a factory and clones of a prototype for new instances (if instantiation is expensive) |
+| [proxy](proxy.py) | an object funnels operations to something else |
+| [publish_subscribe](publish_subscribe.py) | a source syndicates events/data to 0+ registered listeners |
+| [state](state.py) | logic is org'd into a discrete number of potential states and the next state that can be transitioned to |
+| [strategy](strategy.py) | selectable operations over the same data |
+| [template](template.py) | an object imposes a structure but takes pluggable components |
+| [visitor](visitor.py) | invoke a callback for all items of a collection |
+| [chaining_method](chaining_method.py) | continue callback next object method |

二進制
__pycache__/facade.cpython-33.pyc


二進制
__pycache__/mediator.cpython-33.pyc


二進制
__pycache__/null.cpython-33.pyc


+ 27 - 10
abstract_factory.py

@@ -1,32 +1,34 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
 # http://ginstrom.com/scribbles/2007/10/08/design-patterns-python-style/
 # http://ginstrom.com/scribbles/2007/10/08/design-patterns-python-style/
 
 
 """Implementation of the abstract factory pattern"""
 """Implementation of the abstract factory pattern"""
 
 
 import random
 import random
 
 
-
 class PetShop:
 class PetShop:
+
     """A pet shop"""
     """A pet shop"""
 
 
     def __init__(self, animal_factory=None):
     def __init__(self, animal_factory=None):
-        """pet_factory is our abstract factory.
-        We can set it at will."""
+        """pet_factory is our abstract factory.  We can set it at will."""
 
 
         self.pet_factory = animal_factory
         self.pet_factory = animal_factory
 
 
     def show_pet(self):
     def show_pet(self):
-        """Creates and shows a pet using the
-        abstract factory"""
+        """Creates and shows a pet using the abstract factory"""
 
 
         pet = self.pet_factory.get_pet()
         pet = self.pet_factory.get_pet()
-        print("This is a lovely {}".format(pet))
+        print("We have a lovely {}".format(pet))
         print("It says {}".format(pet.speak()))
         print("It says {}".format(pet.speak()))
-        print("It eats {}".format(self.pet_factory.get_food()))
+        print("We also have {}".format(self.pet_factory.get_food()))
 
 
 
 
 # Stuff that our factory makes
 # Stuff that our factory makes
 
 
 class Dog:
 class Dog:
+
     def speak(self):
     def speak(self):
         return "woof"
         return "woof"
 
 
@@ -35,6 +37,7 @@ class Dog:
 
 
 
 
 class Cat:
 class Cat:
+
     def speak(self):
     def speak(self):
         return "meow"
         return "meow"
 
 
@@ -45,6 +48,7 @@ class Cat:
 # Factory classes
 # Factory classes
 
 
 class DogFactory:
 class DogFactory:
+
     def get_pet(self):
     def get_pet(self):
         return Dog()
         return Dog()
 
 
@@ -53,13 +57,13 @@ class DogFactory:
 
 
 
 
 class CatFactory:
 class CatFactory:
+
     def get_pet(self):
     def get_pet(self):
         return Cat()
         return Cat()
 
 
     def get_food(self):
     def get_food(self):
         return "cat food"
         return "cat food"
 
 
-
 # Create the proper family
 # Create the proper family
 def get_factory():
 def get_factory():
     """Let's be dynamic!"""
     """Let's be dynamic!"""
@@ -68,8 +72,21 @@ def get_factory():
 
 
 # Show pets with various factories
 # Show pets with various factories
 if __name__ == "__main__":
 if __name__ == "__main__":
-    shop = PetShop()
     for i in range(3):
     for i in range(3):
-        shop.pet_factory = get_factory()
+        shop = PetShop(get_factory())
         shop.show_pet()
         shop.show_pet()
         print("=" * 20)
         print("=" * 20)
+
+### OUTPUT ###
+# We have a lovely Dog
+# It says woof
+# We also have dog food
+# ====================
+# We have a lovely Dog
+# It says woof
+# We also have dog food
+# ====================
+# We have a lovely Cat
+# It says meow
+# We also have cat food
+# ====================

+ 13 - 10
adapter.py

@@ -1,28 +1,25 @@
-# http://ginstrom.com/scribbles/2008/11/06/generic-adapter-class-in-python/
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
 
 
-import os
+"""http://ginstrom.com/scribbles/2008/11/06/generic-adapter-class-in-python/"""
 
 
+import os
 
 
 class Dog(object):
 class Dog(object):
     def __init__(self):
     def __init__(self):
         self.name = "Dog"
         self.name = "Dog"
-
     def bark(self):
     def bark(self):
         return "woof!"
         return "woof!"
 
 
-
 class Cat(object):
 class Cat(object):
     def __init__(self):
     def __init__(self):
         self.name = "Cat"
         self.name = "Cat"
-
     def meow(self):
     def meow(self):
         return "meow!"
         return "meow!"
 
 
-
 class Human(object):
 class Human(object):
     def __init__(self):
     def __init__(self):
         self.name = "Human"
         self.name = "Human"
-
     def speak(self):
     def speak(self):
         return "'hello'"
         return "'hello'"
 
 
@@ -30,12 +27,12 @@ class Human(object):
 class Car(object):
 class Car(object):
     def __init__(self):
     def __init__(self):
         self.name = "Car"
         self.name = "Car"
-
     def make_noise(self, octane_level):
     def make_noise(self, octane_level):
         return "vroom{0}".format("!" * octane_level)
         return "vroom{0}".format("!" * octane_level)
 
 
 
 
 class Adapter(object):
 class Adapter(object):
+
     """
     """
     Adapts an object by replacing methods.
     Adapts an object by replacing methods.
     Usage:
     Usage:
@@ -60,6 +57,7 @@ class Adapter(object):
     A Human goes 'hello'
     A Human goes 'hello'
     A Car goes vroom!!!
     A Car goes vroom!!!
     """
     """
+
     def __init__(self, obj, adapted_methods):
     def __init__(self, obj, adapted_methods):
         """We set the adapted methods in the object's dict"""
         """We set the adapted methods in the object's dict"""
         self.obj = obj
         self.obj = obj
@@ -86,5 +84,10 @@ def main():
 
 
 
 
 if __name__ == "__main__":
 if __name__ == "__main__":
-    import doctest
-    doctest.testmod()
+    main()
+
+### OUTPUT ###
+# A Dog goes woof!
+# A Cat goes meow!
+# A Human goes 'hello'
+# A Car goes vroom!!!

+ 12 - 0
append_output.sh

@@ -0,0 +1,12 @@
+#!/bin/bash
+
+set -e
+
+src=$(sed -n -e '/### OUTPUT ###/,$!p' "$1")
+output=$(python "$1" | sed 's/^/# /')
+
+# These are done separately to avoid having to insert a newline, which causes
+# problems when the text itself has '\n' in strings
+echo "$src" > $1
+echo -e "\n### OUTPUT ###" >> $1
+echo "$output" >> $1

+ 25 - 9
borg.py

@@ -1,8 +1,13 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+
 class Borg:
 class Borg:
     __shared_state = {}
     __shared_state = {}
 
 
     def __init__(self):
     def __init__(self):
         self.__dict__ = self.__shared_state
         self.__dict__ = self.__shared_state
+        self.state = 'Init'
 
 
     def __str__(self):
     def __str__(self):
         return self.state
         return self.state
@@ -18,19 +23,30 @@ if __name__ == '__main__':
     rm1.state = 'Idle'
     rm1.state = 'Idle'
     rm2.state = 'Running'
     rm2.state = 'Running'
 
 
-    print('rm1:', rm1)
-    print('rm2:', rm2)
+    print('rm1: {0}'.format(rm1))
+    print('rm2: {0}'.format(rm2))
 
 
     rm2.state = 'Zombie'
     rm2.state = 'Zombie'
 
 
-    print('rm1:', rm1)
-    print('rm2:', rm2)
+    print('rm1: {0}'.format(rm1))
+    print('rm2: {0}'.format(rm2))
 
 
-    print('rm1 id:', id(rm1))
-    print('rm2 id:', id(rm2))
+    print('rm1 id: {0}'.format(id(rm1)))
+    print('rm2 id: {0}'.format(id(rm2)))
 
 
     rm3 = YourBorg()
     rm3 = YourBorg()
 
 
-    print('rm1:', rm1)
-    print('rm2:', rm2)
-    print('rm3:', rm3)
+    print('rm1: {0}'.format(rm1))
+    print('rm2: {0}'.format(rm2))
+    print('rm3: {0}'.format(rm3))
+
+### OUTPUT ###
+# rm1: Running
+# rm2: Running
+# rm1: Zombie
+# rm2: Zombie
+# rm1 id: 140732837899224
+# rm2 id: 140732837899296
+# rm1: Init
+# rm2: Init
+# rm3: Init

+ 15 - 5
bridge.py

@@ -1,30 +1,36 @@
-# http://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Bridge_Pattern#Python
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""http://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Bridge_Pattern#Python"""
 
 
 
 
 # ConcreteImplementor 1/2
 # ConcreteImplementor 1/2
 class DrawingAPI1(object):
 class DrawingAPI1(object):
+
     def draw_circle(self, x, y, radius):
     def draw_circle(self, x, y, radius):
         print('API1.circle at {}:{} radius {}'.format(x, y, radius))
         print('API1.circle at {}:{} radius {}'.format(x, y, radius))
 
 
 
 
 # ConcreteImplementor 2/2
 # ConcreteImplementor 2/2
 class DrawingAPI2(object):
 class DrawingAPI2(object):
+
     def draw_circle(self, x, y, radius):
     def draw_circle(self, x, y, radius):
         print('API2.circle at {}:{} radius {}'.format(x, y, radius))
         print('API2.circle at {}:{} radius {}'.format(x, y, radius))
 
 
 
 
 # Refined Abstraction
 # Refined Abstraction
 class CircleShape(object):
 class CircleShape(object):
+
     def __init__(self, x, y, radius, drawing_api):
     def __init__(self, x, y, radius, drawing_api):
         self._x = x
         self._x = x
         self._y = y
         self._y = y
         self._radius = radius
         self._radius = radius
         self._drawing_api = drawing_api
         self._drawing_api = drawing_api
- 
+
     # low-level i.e. Implementation specific
     # low-level i.e. Implementation specific
     def draw(self):
     def draw(self):
         self._drawing_api.draw_circle(self._x, self._y, self._radius)
         self._drawing_api.draw_circle(self._x, self._y, self._radius)
- 
+
     # high-level i.e. Abstraction specific
     # high-level i.e. Abstraction specific
     def scale(self, pct):
     def scale(self, pct):
         self._radius *= pct
         self._radius *= pct
@@ -35,11 +41,15 @@ def main():
         CircleShape(1, 2, 3, DrawingAPI1()),
         CircleShape(1, 2, 3, DrawingAPI1()),
         CircleShape(5, 7, 11, DrawingAPI2())
         CircleShape(5, 7, 11, DrawingAPI2())
     )
     )
- 
+
     for shape in shapes:
     for shape in shapes:
         shape.scale(2.5)
         shape.scale(2.5)
         shape.draw()
         shape.draw()
- 
+
 
 
 if __name__ == '__main__':
 if __name__ == '__main__':
     main()
     main()
+
+### OUTPUT ###
+# API1.circle at 1:2 radius 7.5
+# API2.circle at 5:7 radius 27.5

+ 10 - 1
builder.py

@@ -9,6 +9,7 @@ https://gist.github.com/420905#file_builder_python.py
 
 
 # Director
 # Director
 class Director(object):
 class Director(object):
+
     def __init__(self):
     def __init__(self):
         self.builder = None
         self.builder = None
 
 
@@ -23,6 +24,7 @@ class Director(object):
 
 
 # Abstract Builder
 # Abstract Builder
 class Builder(object):
 class Builder(object):
+
     def __init__(self):
     def __init__(self):
         self.building = None
         self.building = None
 
 
@@ -32,6 +34,7 @@ class Builder(object):
 
 
 # Concrete Builder
 # Concrete Builder
 class BuilderHouse(Builder):
 class BuilderHouse(Builder):
+
     def build_floor(self):
     def build_floor(self):
         self.building.floor = 'One'
         self.building.floor = 'One'
 
 
@@ -40,15 +43,17 @@ class BuilderHouse(Builder):
 
 
 
 
 class BuilderFlat(Builder):
 class BuilderFlat(Builder):
+
     def build_floor(self):
     def build_floor(self):
         self.building.floor = 'More than One'
         self.building.floor = 'More than One'
-        
+
     def build_size(self):
     def build_size(self):
         self.building.size = 'Small'
         self.building.size = 'Small'
 
 
 
 
 # Product
 # Product
 class Building(object):
 class Building(object):
+
     def __init__(self):
     def __init__(self):
         self.floor = None
         self.floor = None
         self.size = None
         self.size = None
@@ -68,3 +73,7 @@ if __name__ == "__main__":
     director.construct_building()
     director.construct_building()
     building = director.get_building()
     building = director.get_building()
     print(building)
     print(building)
+
+### OUTPUT ###
+# Floor: One | Size: Big
+# Floor: More than One | Size: Small

+ 17 - 6
catalog.py

@@ -1,20 +1,28 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
 """
 """
-A class that uses different static function depending of a parameter passed in init
-Note the use of a single dictionnary instead of multiple conditions
+A class that uses different static function depending of a parameter passed in
+init. Note the use of a single dictionnary instead of multiple conditions
 """
 """
 __author__ = "Ibrahim Diop <http://ibrahim.zinaria.com>"
 __author__ = "Ibrahim Diop <http://ibrahim.zinaria.com>"
 __gist__ = "<https://gist.github.com/diopib/7679559>"
 __gist__ = "<https://gist.github.com/diopib/7679559>"
 
 
+
 class Catalog():
 class Catalog():
+
     """
     """
-    catalog of multiple static methods that are executed depending on an init parameter
+    catalog of multiple static methods that are executed depending on an init
+    parameter
     """
     """
 
 
     def __init__(self, param):
     def __init__(self, param):
 
 
-        # dictionary that will be used to determine which static method is to be executed but
-        # that will be also used to store possible param value
-        self.static_method_choices = {'param_value_1': self.static_method_1, 'param_value_2': self.static_method_2}
+        # dictionary that will be used to determine which static method is
+        # to be executed but that will be also used to store possible param
+        # value
+        self.static_method_choices = {'param_value_1': self.static_method_1,
+                                      'param_value_2': self.static_method_2}
 
 
         # simple test to validate param value
         # simple test to validate param value
         if param in self.static_method_choices.keys():
         if param in self.static_method_choices.keys():
@@ -51,3 +59,6 @@ def main():
 
 
 if __name__ == "__main__":
 if __name__ == "__main__":
     main()
     main()
+
+### OUTPUT ###
+# executed method 2!

+ 40 - 26
chain.py

@@ -1,52 +1,66 @@
-# http://www.testingperspective.com/wiki/doku.php/collaboration/chetan/designpatternsinpython/chain-of-responsibilitypattern
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
 
 
+"""http://www.testingperspective.com/wiki/doku.php/collaboration/chetan/designpatternsinpython/chain-of-responsibilitypattern"""
 
 
 class Handler:
 class Handler:
-    def successor(self, successor):
-        self.successor = successor
+    def __init__(self,successor):
+        self._successor = successor;
+    def handle(self,request):
+        i = self._handle(request)
+        if  not i:
+            self._successor.handle(request)
+    def _handle(self, request):
+        raise NotImplementedError('Must provide implementation in subclass.')
 
 
 
 
 class ConcreteHandler1(Handler):
 class ConcreteHandler1(Handler):
-    def handle(self, request):
+
+    def _handle(self, request):
         if 0 < request <= 10:
         if 0 < request <= 10:
             print('request {} handled in handler 1'.format(request))
             print('request {} handled in handler 1'.format(request))
-        else:
-            self.successor.handle(request)
-
-
+            return True
+            
 class ConcreteHandler2(Handler):
 class ConcreteHandler2(Handler):
-    def handle(self, request):
+    
+    def _handle(self, request):
         if 10 < request <= 20:
         if 10 < request <= 20:
             print('request {} handled in handler 2'.format(request))
             print('request {} handled in handler 2'.format(request))
-        else:
-            self.successor.handle(request)
-
-
+            return True
+        
 class ConcreteHandler3(Handler):
 class ConcreteHandler3(Handler):
-    def handle(self, request):
+    
+    def _handle(self, request):
         if 20 < request <= 30:
         if 20 < request <= 30:
             print('request {} handled in handler 3'.format(request))
             print('request {} handled in handler 3'.format(request))
-        else:
-            print('end of chain, no handler for {}'.format(request))
+            return True
+class DefaultHandler(Handler):
+    
+    def _handle(self, request):
+        print('end of chain, no handler for {}'.format(request))
+        return True
 
 
 
 
 class Client:
 class Client:
     def __init__(self):
     def __init__(self):
-        h1 = ConcreteHandler1()
-        h2 = ConcreteHandler2()
-        h3 = ConcreteHandler3()
-
-        h1.successor(h2)
-        h2.successor(h3)
-
-        self.handlers = (h1, h2, h3)
-
+        self.handler = ConcreteHandler1(ConcreteHandler3(ConcreteHandler2(DefaultHandler(None))))
     def delegate(self, requests):
     def delegate(self, requests):
         for request in requests:
         for request in requests:
-            self.handlers[0].handle(request)
+            self.handler.handle(request)
 
 
 
 
 if __name__ == "__main__":
 if __name__ == "__main__":
     client = Client()
     client = Client()
     requests = [2, 5, 14, 22, 18, 3, 35, 27, 20]
     requests = [2, 5, 14, 22, 18, 3, 35, 27, 20]
     client.delegate(requests)
     client.delegate(requests)
+
+### OUTPUT ###
+# request 2 handled in handler 1
+# request 5 handled in handler 1
+# request 14 handled in handler 2
+# request 22 handled in handler 3
+# request 18 handled in handler 2
+# request 3 handled in handler 1
+# end of chain, no handler for 35
+# request 27 handled in handler 3
+# request 20 handled in handler 2

+ 33 - 0
chaining_method.py

@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+class Person(object):
+
+    def __init__(self, name, action):
+        self.name = name
+        self.action = action
+
+    def do_action(self):
+        print(self.name, self.action.name, end=' ')
+        return self.action
+
+class Action(object):
+
+    def __init__(self, name):
+        self.name = name
+
+    def amount(self, val):
+        print(val, end=' ')
+        return self
+
+    def stop(self):
+        print('then stop')
+
+if __name__ == '__main__':
+
+    move = Action('move')
+    person = Person('Jack', move)
+    person.do_action().amount('5m').stop()
+
+### OUTPUT ###
+# Jack move 5m then stop

+ 11 - 4
command.py

@@ -1,15 +1,16 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
 import os
 import os
 
 
 
 
 class MoveFileCommand(object):
 class MoveFileCommand(object):
+
     def __init__(self, src, dest):
     def __init__(self, src, dest):
         self.src = src
         self.src = src
         self.dest = dest
         self.dest = dest
 
 
     def execute(self):
     def execute(self):
-        self()
-
-    def __call__(self):
         print('renaming {} to {}'.format(self.src, self.dest))
         print('renaming {} to {}'.format(self.src, self.dest))
         os.rename(self.src, self.dest)
         os.rename(self.src, self.dest)
 
 
@@ -34,4 +35,10 @@ def main():
         cmd.undo()
         cmd.undo()
 
 
 if __name__ == "__main__":
 if __name__ == "__main__":
-    main()
+    main()
+
+### OUTPUT ###
+# renaming foo.txt to bar.txt
+# renaming bar.txt to baz.txt
+# renaming baz.txt to bar.txt
+# renaming bar.txt to foo.txt

+ 45 - 36
composite.py

@@ -1,9 +1,12 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
 """
 """
 A class which defines a composite object which can store
 A class which defines a composite object which can store
 hieararchical dictionaries with names.
 hieararchical dictionaries with names.
 
 
 This class is same as a hiearchical dictionary, but it
 This class is same as a hiearchical dictionary, but it
-provides methods to add/access/modify children by name, 
+provides methods to add/access/modify children by name,
 like a Composite.
 like a Composite.
 
 
 Created Anand B Pillai     <abpillai@gmail.com>
 Created Anand B Pillai     <abpillai@gmail.com>
@@ -17,7 +20,7 @@ __version__ = "0.2"
 def normalize(val):
 def normalize(val):
     """ Normalize a string so that it can be used as an attribute
     """ Normalize a string so that it can be used as an attribute
     to a Python object """
     to a Python object """
-    
+
     if val.find('-') != -1:
     if val.find('-') != -1:
         val = val.replace('-', '_')
         val = val.replace('-', '_')
 
 
@@ -34,6 +37,7 @@ def denormalize(val):
 
 
 
 
 class SpecialDict(dict):
 class SpecialDict(dict):
+
     """ A dictionary type which allows direct attribute
     """ A dictionary type which allows direct attribute
     access to its keys """
     access to its keys """
 
 
@@ -65,9 +69,10 @@ class SpecialDict(dict):
             else:
             else:
                 # New attribute
                 # New attribute
                 self[name] = value
                 self[name] = value
-        
+
 
 
 class CompositeDict(SpecialDict):
 class CompositeDict(SpecialDict):
+
     """ A class which works like a hierarchical dictionary.
     """ A class which works like a hierarchical dictionary.
     This class is based on the Composite design-pattern """
     This class is based on the Composite design-pattern """
 
 
@@ -106,7 +111,7 @@ class CompositeDict(SpecialDict):
                     attr = getattr(self[self._name], name)
                     attr = getattr(self[self._name], name)
                     if attr:
                     if attr:
                         return attr
                         return attr
-                    
+
                     raise AttributeError('no attribute named %s' % name)
                     raise AttributeError('no attribute named %s' % name)
 
 
     def isRoot(self):
     def isRoot(self):
@@ -114,7 +119,7 @@ class CompositeDict(SpecialDict):
 
 
         # If I don't have a parent, I am root
         # If I don't have a parent, I am root
         return not self._father
         return not self._father
-    
+
     def isLeaf(self):
     def isLeaf(self):
         """ Return whether I am a leaf component or not """
         """ Return whether I am a leaf component or not """
 
 
@@ -128,7 +133,7 @@ class CompositeDict(SpecialDict):
 
 
     def getIndex(self, child):
     def getIndex(self, child):
         """ Return the index of the child ConfigInfo object 'child' """
         """ Return the index of the child ConfigInfo object 'child' """
-        
+
         if child in self._children:
         if child in self._children:
             return self._children.index(child)
             return self._children.index(child)
         else:
         else:
@@ -136,7 +141,7 @@ class CompositeDict(SpecialDict):
 
 
     def getDict(self):
     def getDict(self):
         """ Return the contained dictionary """
         """ Return the contained dictionary """
-        
+
         return self[self._name]
         return self[self._name]
 
 
     def getProperty(self, child, key):
     def getProperty(self, child, key):
@@ -156,25 +161,25 @@ class CompositeDict(SpecialDict):
         childDict = self.getInfoDict(child)
         childDict = self.getInfoDict(child)
         if childDict:
         if childDict:
             childDict[key] = value
             childDict[key] = value
-    
+
     def getChildren(self):
     def getChildren(self):
         """ Return the list of immediate children of this object """
         """ Return the list of immediate children of this object """
-        
+
         return self._children
         return self._children
 
 
     def getAllChildren(self):
     def getAllChildren(self):
         """ Return the list of all children of this object """
         """ Return the list of all children of this object """
-        
+
         l = []
         l = []
         for child in self._children:
         for child in self._children:
             l.append(child)
             l.append(child)
             l.extend(child.getAllChildren())
             l.extend(child.getAllChildren())
-            
+
         return l
         return l
 
 
     def getChild(self, name):
     def getChild(self, name):
         """ Return the immediate child object with the given name """
         """ Return the immediate child object with the given name """
-        
+
         for child in self._children:
         for child in self._children:
             if child.getName() == name:
             if child.getName() == name:
                 return child
                 return child
@@ -185,7 +190,7 @@ class CompositeDict(SpecialDict):
         # Note - this returns the first child of the given name
         # Note - this returns the first child of the given name
         # any other children with similar names down the tree
         # any other children with similar names down the tree
         # is not considered.
         # is not considered.
-        
+
         for child in self.getAllChildren():
         for child in self.getAllChildren():
             if child.getName() == name:
             if child.getName() == name:
                 return child
                 return child
@@ -195,33 +200,33 @@ class CompositeDict(SpecialDict):
 
 
         # Note: this returns a list of all the children of a given
         # Note: this returns a list of all the children of a given
         # name, irrespective of the depth of look-up.
         # name, irrespective of the depth of look-up.
-        
+
         children = []
         children = []
-        
+
         for child in self.getAllChildren():
         for child in self.getAllChildren():
             if child.getName() == name:
             if child.getName() == name:
                 children.append(child)
                 children.append(child)
 
 
         return children
         return children
-            
+
     def getPropertyDict(self):
     def getPropertyDict(self):
         """ Return the property dictionary """
         """ Return the property dictionary """
-        
+
         d = self.getChild('__properties')
         d = self.getChild('__properties')
         if d:
         if d:
             return d.getDict()
             return d.getDict()
         else:
         else:
             return {}
             return {}
-        
+
     def getParent(self):
     def getParent(self):
         """ Return the person who created me """
         """ Return the person who created me """
 
 
         return self._father
         return self._father
-    
+
     def __setChildDict(self, child):
     def __setChildDict(self, child):
         """ Private method to set the dictionary of the child
         """ Private method to set the dictionary of the child
         object 'child' in the internal dictionary """
         object 'child' in the internal dictionary """
-        
+
         d = self[self._name]
         d = self[self._name]
         d[child.getName()] = child.getDict()
         d[child.getName()] = child.getDict()
 
 
@@ -236,25 +241,25 @@ class CompositeDict(SpecialDict):
         # child is orphaned - see addChild and addChild2
         # child is orphaned - see addChild and addChild2
         # methods !
         # methods !
         self._father = father
         self._father = father
-        
+
     def setName(self, name):
     def setName(self, name):
-        """ Set the name of this ConfigInfo object to 'name' """        
+        """ Set the name of this ConfigInfo object to 'name' """
 
 
         self._name = name
         self._name = name
 
 
     def setDict(self, d):
     def setDict(self, d):
         """ Set the contained dictionary """
         """ Set the contained dictionary """
-        
+
         self[self._name] = d.copy()
         self[self._name] = d.copy()
-        
+
     def setAttribute(self, name, value):
     def setAttribute(self, name, value):
         """ Set a name value pair in the contained dictionary """
         """ Set a name value pair in the contained dictionary """
-        
+
         self[self._name][name] = value
         self[self._name][name] = value
 
 
     def getAttribute(self, name):
     def getAttribute(self, name):
         """ Return value of an attribute from the contained dictionary """
         """ Return value of an attribute from the contained dictionary """
-        
+
         return self[self._name][name]
         return self[self._name][name]
 
 
     def addChild(self, name, force=False):
     def addChild(self, name, force=False):
@@ -264,13 +269,13 @@ class CompositeDict(SpecialDict):
 
 
         This function returns the child object, whether
         This function returns the child object, whether
         new or existing """
         new or existing """
-        
+
         if type(name) != str:
         if type(name) != str:
             raise ValueError('Argument should be a string!')
             raise ValueError('Argument should be a string!')
-        
+
         child = self.getChild(name)
         child = self.getChild(name)
         if child:
         if child:
-            # print 'Child %s present!' % name
+            # print('Child %s present!' % name)
             # Replace it if force==True
             # Replace it if force==True
             if force:
             if force:
                 index = self.getIndex(child)
                 index = self.getIndex(child)
@@ -278,22 +283,22 @@ class CompositeDict(SpecialDict):
                     child = self.__class__(name)
                     child = self.__class__(name)
                     self._children[index] = child
                     self._children[index] = child
                     child.setParent(self)
                     child.setParent(self)
-                    
+
                     self.__setChildDict(child)
                     self.__setChildDict(child)
             return child
             return child
         else:
         else:
             child = self.__class__(name)
             child = self.__class__(name)
             child.setParent(self)
             child.setParent(self)
-            
+
             self._children.append(child)
             self._children.append(child)
             self.__setChildDict(child)
             self.__setChildDict(child)
 
 
             return child
             return child
-        
+
     def addChild2(self, child):
     def addChild2(self, child):
         """ Add the child object 'child'. If it is already present,
         """ Add the child object 'child'. If it is already present,
         it is overwritten by default """
         it is overwritten by default """
-        
+
         currChild = self.getChild(child.getName())
         currChild = self.getChild(child.getName())
         if currChild:
         if currChild:
             index = self.getIndex(currChild)
             index = self.getIndex(currChild)
@@ -303,10 +308,10 @@ class CompositeDict(SpecialDict):
                 # Unset the existing child's parent
                 # Unset the existing child's parent
                 currChild.setParent(None)
                 currChild.setParent(None)
                 del currChild
                 del currChild
-                
+
                 self.__setChildDict(child)
                 self.__setChildDict(child)
         else:
         else:
-            child.setParent(self)            
+            child.setParent(self)
             self._children.append(child)
             self._children.append(child)
             self.__setChildDict(child)
             self.__setChildDict(child)
 
 
@@ -316,7 +321,7 @@ if __name__ == "__main__":
     frame = window.addChild('Frame')
     frame = window.addChild('Frame')
     tfield = frame.addChild('Text Field')
     tfield = frame.addChild('Text Field')
     tfield.setAttribute('size', '20')
     tfield.setAttribute('size', '20')
-    
+
     btn = frame.addChild('Button1')
     btn = frame.addChild('Button1')
     btn.setAttribute('label', 'Submit')
     btn.setAttribute('label', 'Submit')
 
 
@@ -329,3 +334,7 @@ if __name__ == "__main__":
     # print(window.Frame.Button2)
     # print(window.Frame.Button2)
     print(window.Frame.Button1.label)
     print(window.Frame.Button1.label)
     print(window.Frame.Button2.label)
     print(window.Frame.Button2.label)
+
+### OUTPUT ###
+# Submit
+# Browse

+ 22 - 35
decorator.py

@@ -1,44 +1,31 @@
-# http://stackoverflow.com/questions/3118929/implementing-the-decorator-pattern-in-python
+"""https://docs.python.org/2/library/functools.html#functools.wraps"""
+"""https://stackoverflow.com/questions/739654/how-can-i-make-a-chain-of-function-decorators-in-python/739665#739665"""
 
 
+from functools import wraps
 
 
-class foo_decorator(object):
-    def __init__(self, decoratee):
-        self._decoratee = decoratee
 
 
-    def f1(self):
-        print("decorated f1")
-        self._decoratee.f1()
+def makebold(fn):
+    @wraps(fn)
+    def wrapped():
+        return "<b>" + fn() + "</b>"
+    return wrapped
 
 
-    def __getattr__(self, name):
-        return getattr(self._decoratee, name)
 
 
+def makeitalic(fn):
+    @wraps(fn)
+    def wrapped():
+        return "<i>" + fn() + "</i>"
+    return wrapped
 
 
-class undecorated_foo(object):
-    def f1(self):
-        print("original f1")
 
 
-    def f2(self):
-        print("original f2")
-
-
-@foo_decorator
-class decorated_foo(object):
-    def f1(self):
-        print("original f1")
-
-    def f2(self):
-        print("original f2")
-
-
-def main():
-    u = undecorated_foo()
-    v = foo_decorator(u)
-    # The @foo_decorator syntax is just shorthand for calling
-    # foo_decorator on the decorated object right after its
-    # declaration.
-
-    v.f1()
-    v.f2()
+@makebold
+@makeitalic
+def hello():
+    """a decorated hello world"""
+    return "hello world"
 
 
 if __name__ == '__main__':
 if __name__ == '__main__':
-    main()
+    print('result:{}   name:{}   doc:{}'.format(hello(), hello.__name__, hello.__doc__))
+
+### OUTPUT ###
+# result:<b><i>hello world</i></b>   name:hello   doc:a decorated hello world

+ 26 - 1
facade.py

@@ -1,4 +1,5 @@
-"""http://dpip.testingperspective.com/?p=26"""
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
 
 
 import time
 import time
 
 
@@ -7,6 +8,7 @@ SLEEP = 0.5
 
 
 # Complex Parts
 # Complex Parts
 class TC1:
 class TC1:
+
     def run(self):
     def run(self):
         print("###### In Test 1 ######")
         print("###### In Test 1 ######")
         time.sleep(SLEEP)
         time.sleep(SLEEP)
@@ -20,6 +22,7 @@ class TC1:
 
 
 
 
 class TC2:
 class TC2:
+
     def run(self):
     def run(self):
         print("###### In Test 2 ######")
         print("###### In Test 2 ######")
         time.sleep(SLEEP)
         time.sleep(SLEEP)
@@ -33,6 +36,7 @@ class TC2:
 
 
 
 
 class TC3:
 class TC3:
+
     def run(self):
     def run(self):
         print("###### In Test 3 ######")
         print("###### In Test 3 ######")
         time.sleep(SLEEP)
         time.sleep(SLEEP)
@@ -47,6 +51,7 @@ class TC3:
 
 
 # Facade
 # Facade
 class TestRunner:
 class TestRunner:
+
     def __init__(self):
     def __init__(self):
         self.tc1 = TC1()
         self.tc1 = TC1()
         self.tc2 = TC2()
         self.tc2 = TC2()
@@ -61,3 +66,23 @@ class TestRunner:
 if __name__ == '__main__':
 if __name__ == '__main__':
     testrunner = TestRunner()
     testrunner = TestRunner()
     testrunner.runAll()
     testrunner.runAll()
+
+### OUTPUT ###
+# ###### In Test 1 ######
+# Setting up
+# Running test
+# Tearing down
+# Test Finished
+#
+# ###### In Test 2 ######
+# Setting up
+# Running test
+# Tearing down
+# Test Finished
+#
+# ###### In Test 3 ######
+# Setting up
+# Running test
+# Tearing down
+# Test Finished
+#

+ 15 - 3
factory_method.py

@@ -1,14 +1,18 @@
-#encoding=utf-8
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
 """http://ginstrom.com/scribbles/2007/10/08/design-patterns-python-style/"""
 """http://ginstrom.com/scribbles/2007/10/08/design-patterns-python-style/"""
 
 
 
 
 class GreekGetter:
 class GreekGetter:
+
     """A simple localizer a la gettext"""
     """A simple localizer a la gettext"""
+
     def __init__(self):
     def __init__(self):
         self.trans = dict(dog="σκύλος", cat="γάτα")
         self.trans = dict(dog="σκύλος", cat="γάτα")
 
 
     def get(self, msgid):
     def get(self, msgid):
-        """We'll punt if we don't have a translation"""          
+        """We'll punt if we don't have a translation"""
         try:
         try:
             return self.trans[msgid]
             return self.trans[msgid]
         except KeyError:
         except KeyError:
@@ -16,7 +20,9 @@ class GreekGetter:
 
 
 
 
 class EnglishGetter:
 class EnglishGetter:
-    """Simply echoes the msg ids"""     
+
+    """Simply echoes the msg ids"""
+
     def get(self, msgid):
     def get(self, msgid):
         return str(msgid)
         return str(msgid)
 
 
@@ -31,3 +37,9 @@ e, g = get_localizer("English"), get_localizer("Greek")
 # Localize some text
 # Localize some text
 for msgid in "dog parrot cat bear".split():
 for msgid in "dog parrot cat bear".split():
     print(e.get(msgid), g.get(msgid))
     print(e.get(msgid), g.get(msgid))
+
+### OUTPUT ###
+# dog σκύλος
+# parrot parrot
+# cat γάτα
+# bear bear

+ 9 - 0
flyweight.py

@@ -1,9 +1,13 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
 """http://codesnipers.com/?q=python-flyweights"""
 """http://codesnipers.com/?q=python-flyweights"""
 
 
 import weakref
 import weakref
 
 
 
 
 class Card(object):
 class Card(object):
+
     """The object pool. Has builtin reference counting"""
     """The object pool. Has builtin reference counting"""
     _CardPool = weakref.WeakValueDictionary()
     _CardPool = weakref.WeakValueDictionary()
 
 
@@ -31,3 +35,8 @@ if __name__ == '__main__':
     print(c1, c2)
     print(c1, c2)
     print(c1 == c2)
     print(c1 == c2)
     print(id(c1), id(c2))
     print(id(c1), id(c2))
+
+### OUTPUT ###
+# <Card: 9h> <Card: 9h>
+# True
+# 140368617673296 140368617673296

+ 0 - 1
foo.txt

@@ -1 +0,0 @@
-All krakens crush undead, evil sails.

+ 37 - 27
graph_search.py

@@ -1,19 +1,24 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+
 class GraphSearch:
 class GraphSearch:
+
     """Graph search emulation in python, from source
     """Graph search emulation in python, from source
     http://www.python.org/doc/essays/graphs/"""
     http://www.python.org/doc/essays/graphs/"""
 
 
     def __init__(self, graph):
     def __init__(self, graph):
-        self.graph = graph 
-    
-    def find_path(self, start, end, path=[]):
+        self.graph = graph
+
+    def find_path(self, start, end, path=None):
         self.start = start
         self.start = start
         self.end = end
         self.end = end
-        self.path = path
+        self.path = path if path else []
 
 
         self.path += [self.start]
         self.path += [self.start]
         if self.start == self.end:
         if self.start == self.end:
             return self.path
             return self.path
-        if not self.graph.has_key(self.start):
+        if self.start not in self.graph:
             return None
             return None
         for node in self.graph[self.start]:
         for node in self.graph[self.start]:
             if node not in self.path:
             if node not in self.path:
@@ -22,55 +27,60 @@ class GraphSearch:
                     return newpath
                     return newpath
         return None
         return None
 
 
-    def find_all_path(self, start, end, path=[]):            
+    def find_all_path(self, start, end, path=None):
         self.start = start
         self.start = start
         self.end = end
         self.end = end
-        self.path = path
-        self.path += [self.start]
+        _path = path if path else []
+        _path += [self.start]
         if self.start == self.end:
         if self.start == self.end:
-            return [self.path]
-        if not self.graph.has_key(self.start):
+            return [_path]
+        if self.start not in self.graph:
             return []
             return []
         paths = []
         paths = []
         for node in self.graph[self.start]:
         for node in self.graph[self.start]:
-            if node not in self.path:
-                newpaths = self.find_all_path(node, self.end, self.path)
+            if node not in _path:
+                newpaths = self.find_all_path(node, self.end, _path[:])
                 for newpath in newpaths:
                 for newpath in newpaths:
-                    paths.append(newpath)                
+                    paths.append(newpath)
         return paths
         return paths
 
 
-    def find_shortest_path(self, start, end, path=[]):         
+    def find_shortest_path(self, start, end, path=None):
         self.start = start
         self.start = start
         self.end = end
         self.end = end
-        self.path = path
-        
-        self.path += [self.start]
+        _path = path if path else []
+
+        _path += [self.start]
         if self.start == self.end:
         if self.start == self.end:
-            return self.path
-        if not self.graph.has_key(self.start):
+            return _path
+        if self.start not in self.graph:
             return None
             return None
         shortest = None
         shortest = None
         for node in self.graph[self.start]:
         for node in self.graph[self.start]:
-            if node not in self.path:
-                newpath = self.find_shortest_path(node, self.end, self.path)
+            if node not in _path:
+                newpath = self.find_shortest_path(node, self.end, _path[:])
                 if newpath:
                 if newpath:
                     if not shortest or len(newpath) < len(shortest):
                     if not shortest or len(newpath) < len(shortest):
                         shortest = newpath
                         shortest = newpath
         return shortest
         return shortest
 
 
-#example of graph usage
+# example of graph usage
 graph = {'A': ['B', 'C'],
 graph = {'A': ['B', 'C'],
          'B': ['C', 'D'],
          'B': ['C', 'D'],
          'C': ['D'],
          'C': ['D'],
          'D': ['C'],
          'D': ['C'],
          'E': ['F'],
          'E': ['F'],
-         'F': ['C']   
+         'F': ['C']
          }
          }
 
 
-#inistialization of new graph search object
+# initialization of new graph search object
 graph1 = GraphSearch(graph)
 graph1 = GraphSearch(graph)
 
 
 
 
-print graph1.find_path('A', 'D')
-print graph1.find_all_path('A', 'D')
-print graph1.find_shortest_path('A', 'D')
+print(graph1.find_path('A', 'D'))
+print(graph1.find_all_path('A', 'D'))
+print(graph1.find_shortest_path('A', 'D'))
+
+### OUTPUT ###
+# ['A', 'B', 'C', 'D']
+# [['A', 'B', 'C', 'D'], ['A', 'B', 'D'], ['A', 'C', 'D']]
+# ['A', 'B', 'D']

+ 9 - 0
iterator.py

@@ -1,3 +1,6 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
 """http://ginstrom.com/scribbles/2007/10/08/design-patterns-python-style/
 """http://ginstrom.com/scribbles/2007/10/08/design-patterns-python-style/
 
 
 Implementation of the iterator pattern with a generator"""
 Implementation of the iterator pattern with a generator"""
@@ -26,3 +29,9 @@ for number in count_to_five():
     print(number, end=' ')
     print(number, end=' ')
 
 
 print()
 print()
+
+### OUTPUT ###
+# Counting to two...
+# one two
+# Counting to five...
+# one two three four five

+ 35 - 10
mediator.py

@@ -1,3 +1,6 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
 """http://dpip.testingperspective.com/?p=28"""
 """http://dpip.testingperspective.com/?p=28"""
 
 
 import random
 import random
@@ -5,26 +8,27 @@ import time
 
 
 
 
 class TC:
 class TC:
+
     def __init__(self):
     def __init__(self):
         self._tm = None
         self._tm = None
         self._bProblem = 0
         self._bProblem = 0
 
 
     def setup(self):
     def setup(self):
         print("Setting up the Test")
         print("Setting up the Test")
-        time.sleep(1)
+        time.sleep(0.1)
         self._tm.prepareReporting()
         self._tm.prepareReporting()
 
 
     def execute(self):
     def execute(self):
         if not self._bProblem:
         if not self._bProblem:
             print("Executing the test")
             print("Executing the test")
-            time.sleep(1)
+            time.sleep(0.1)
         else:
         else:
             print("Problem in setup. Test not executed.")
             print("Problem in setup. Test not executed.")
 
 
     def tearDown(self):
     def tearDown(self):
         if not self._bProblem:
         if not self._bProblem:
             print("Tearing down")
             print("Tearing down")
-            time.sleep(1)
+            time.sleep(0.1)
             self._tm.publishReport()
             self._tm.publishReport()
         else:
         else:
             print("Test not executed. No tear down required.")
             print("Test not executed. No tear down required.")
@@ -37,42 +41,44 @@ class TC:
 
 
 
 
 class Reporter:
 class Reporter:
+
     def __init__(self):
     def __init__(self):
         self._tm = None
         self._tm = None
 
 
     def prepare(self):
     def prepare(self):
         print("Reporter Class is preparing to report the results")
         print("Reporter Class is preparing to report the results")
-        time.sleep(1)
+        time.sleep(0.1)
 
 
     def report(self):
     def report(self):
         print("Reporting the results of Test")
         print("Reporting the results of Test")
-        time.sleep(1)
+        time.sleep(0.1)
 
 
     def setTM(self, tm):
     def setTM(self, tm):
         self._tm = tm
         self._tm = tm
 
 
 
 
 class DB:
 class DB:
+
     def __init__(self):
     def __init__(self):
         self._tm = None
         self._tm = None
 
 
     def insert(self):
     def insert(self):
         print("Inserting the execution begin status in the Database")
         print("Inserting the execution begin status in the Database")
-        time.sleep(1)
-        #Following code is to simulate a communication from DB to TC
-        import random
+        time.sleep(0.1)
+        # Following code is to simulate a communication from DB to TC
         if random.randrange(1, 4) == 3:
         if random.randrange(1, 4) == 3:
             return -1
             return -1
 
 
     def update(self):
     def update(self):
         print("Updating the test results in Database")
         print("Updating the test results in Database")
-        time.sleep(1)
+        time.sleep(0.1)
 
 
     def setTM(self, tm):
     def setTM(self, tm):
         self._tm = tm
         self._tm = tm
 
 
 
 
 class TestManager:
 class TestManager:
+
     def __init__(self):
     def __init__(self):
         self._reporter = None
         self._reporter = None
         self._db = None
         self._db = None
@@ -109,10 +115,29 @@ if __name__ == '__main__':
     # For simplification we are looping on the same test.
     # For simplification we are looping on the same test.
     # Practically, it could be about various unique test classes and their
     # Practically, it could be about various unique test classes and their
     # objects
     # objects
-    while True:
+    for i in range(3):
         tc = TC()
         tc = TC()
         tc.setTM(tm)
         tc.setTM(tm)
         tm.setTC(tc)
         tm.setTC(tc)
         tc.setup()
         tc.setup()
         tc.execute()
         tc.execute()
         tc.tearDown()
         tc.tearDown()
+
+### OUTPUT ###
+# Setting up the Test
+# Inserting the execution begin status in the Database
+# Executing the test
+# Tearing down
+# Updating the test results in Database
+# Reporting the results of Test
+# Setting up the Test
+# Inserting the execution begin status in the Database
+# Reporter Class is preparing to report the results
+# Problem in setup. Test not executed.
+# Test not executed. No tear down required.
+# Setting up the Test
+# Inserting the execution begin status in the Database
+# Executing the test
+# Tearing down
+# Updating the test results in Database
+# Reporting the results of Test

+ 35 - 2
memento.py

@@ -1,4 +1,7 @@
-"""code.activestate.com/recipes/413838-memento-closure/"""
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""http://code.activestate.com/recipes/413838-memento-closure/"""
 
 
 import copy
 import copy
 
 
@@ -13,6 +16,7 @@ def Memento(obj, deep=False):
 
 
 
 
 class Transaction:
 class Transaction:
+
     """A transaction guard. This is really just
     """A transaction guard. This is really just
       syntactic suggar arount a memento closure.
       syntactic suggar arount a memento closure.
       """
       """
@@ -31,9 +35,11 @@ class Transaction:
 
 
 
 
 class transactional(object):
 class transactional(object):
+
     """Adds transactional semantics to methods. Methods decorated  with
     """Adds transactional semantics to methods. Methods decorated  with
     @transactional will rollback to entry state upon exceptions.
     @transactional will rollback to entry state upon exceptions.
     """
     """
+
     def __init__(self, method):
     def __init__(self, method):
         self.method = method
         self.method = method
 
 
@@ -49,6 +55,7 @@ class transactional(object):
 
 
 
 
 class NumObj(object):
 class NumObj(object):
+
     def __init__(self, value):
     def __init__(self, value):
         self.value = value
         self.value = value
 
 
@@ -88,7 +95,33 @@ if __name__ == '__main__':
         n.DoStuff()
         n.DoStuff()
     except:
     except:
         print('-> doing stuff failed!')
         print('-> doing stuff failed!')
+        import sys
         import traceback
         import traceback
-        traceback.print_exc(0)
+        traceback.print_exc(file=sys.stdout)
         pass
         pass
     print(n)
     print(n)
+
+### OUTPUT ###
+# <NumObj: -1>
+# <NumObj: 0>
+# <NumObj: 1>
+# <NumObj: 2>
+# -- commited
+# <NumObj: 3>
+# <NumObj: 4>
+# <NumObj: 5>
+# -- rolled back
+# <NumObj: 2>
+# -- now doing stuff ...
+# -> doing stuff failed!
+# Traceback (most recent call last):
+#   File "memento.py", line 91, in <module>
+#     n.DoStuff()
+#   File "memento.py", line 47, in transaction
+#     return self.method(obj, *args, **kwargs)
+#   File "memento.py", line 67, in DoStuff
+# self.Increment()     # <- will fail and rollback
+#   File "memento.py", line 62, in Increment
+#     self.value += 1
+# TypeError: Can't convert 'int' object to str implicitly
+# <NumObj: 2>

+ 17 - 0
mvc.py

@@ -55,3 +55,20 @@ if __name__ == '__main__':
     controller.get_product_information('eggs')
     controller.get_product_information('eggs')
     controller.get_product_information('milk')
     controller.get_product_information('milk')
     controller.get_product_information('arepas')
     controller.get_product_information('arepas')
+
+### OUTPUT ###
+# PRODUCT LIST:
+# cheese
+# eggs
+# milk
+#
+# PRODUCT INFORMATION:
+# Name: Cheese, Price: 2.00, Quantity: 10
+#
+# PRODUCT INFORMATION:
+# Name: Eggs, Price: 0.20, Quantity: 100
+#
+# PRODUCT INFORMATION:
+# Name: Milk, Price: 1.50, Quantity: 10
+#
+# That product "arepas" does not exist in the records

+ 0 - 81
null.py

@@ -1,81 +0,0 @@
-#!/user/bin/env python 
-
-"""http://code.activestate.com/recipes/68205-null-object-design-pattern/"""
-
-
-class Null:
-    def __init__(self, *args, **kwargs):
-        """Ignore parameters."""
-        return None
-
-    def __call__(self, *args, **kwargs):
-        """Ignore method calls."""
-        return self
-
-    def __getattr__(self, mname):
-        """Ignore attribute requests."""
-        return self
-
-    def __setattr__(self, name, value):
-        """Ignore attribute setting."""
-        return self
-
-    def __delattr__(self, name):
-        """Ignore deleting attributes."""
-        return self
-
-    def __repr__(self):
-        """Return a string representation."""
-        return "<Null>"
-
-    def __str__(self):
-        """Convert to a string and return it."""
-        return "Null"
-
-
-def test():
-    """Perform some decent tests, or rather: demos."""
-
-    # constructing and calling
-
-    n = Null()
-    print(n)
-
-    n = Null('value')
-    print(n)
-
-    n = Null('value', param='value')
-    print(n)
-
-    n()
-    n('value')
-    n('value', param='value')
-    print(n)
-
-    # attribute handling
-
-    n.attr1
-    print('attr1', n.attr1)
-    n.attr1.attr2
-    n.method1()
-    n.method1().method2()
-    n.method('value')
-    n.method(param='value')
-    n.method('value', param='value')
-    n.attr1.method1()
-    n.method1().attr1
-
-    n.attr1 = 'value'
-    n.attr1.attr2 = 'value'
-
-    del n.attr1
-    del n.attr1.attr2.attr3
-
-    # representation and conversion to a string
-    
-    assert repr(n) == '<Null>'
-    assert str(n) == 'Null'
-
-
-if __name__ == '__main__':
-    test()

+ 28 - 2
observer.py

@@ -1,12 +1,16 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
 """http://code.activestate.com/recipes/131499-observer-pattern/"""
 """http://code.activestate.com/recipes/131499-observer-pattern/"""
 
 
 
 
 class Subject(object):
 class Subject(object):
+
     def __init__(self):
     def __init__(self):
         self._observers = []
         self._observers = []
 
 
     def attach(self, observer):
     def attach(self, observer):
-        if not observer in self._observers:
+        if observer not in self._observers:
             self._observers.append(observer)
             self._observers.append(observer)
 
 
     def detach(self, observer):
     def detach(self, observer):
@@ -23,6 +27,7 @@ class Subject(object):
 
 
 # Example usage
 # Example usage
 class Data(Subject):
 class Data(Subject):
+
     def __init__(self, name=''):
     def __init__(self, name=''):
         Subject.__init__(self)
         Subject.__init__(self)
         self.name = name
         self.name = name
@@ -31,7 +36,7 @@ class Data(Subject):
     @property
     @property
     def data(self):
     def data(self):
         return self._data
         return self._data
-    
+
     @data.setter
     @data.setter
     def data(self, value):
     def data(self, value):
         self._data = value
         self._data = value
@@ -39,12 +44,14 @@ class Data(Subject):
 
 
 
 
 class HexViewer:
 class HexViewer:
+
     def update(self, subject):
     def update(self, subject):
         print('HexViewer: Subject %s has data 0x%x' %
         print('HexViewer: Subject %s has data 0x%x' %
               (subject.name, subject.data))
               (subject.name, subject.data))
 
 
 
 
 class DecimalViewer:
 class DecimalViewer:
+
     def update(self, subject):
     def update(self, subject):
         print('DecimalViewer: Subject %s has data %d' %
         print('DecimalViewer: Subject %s has data %d' %
               (subject.name, subject.data))
               (subject.name, subject.data))
@@ -80,3 +87,22 @@ def main():
 
 
 if __name__ == '__main__':
 if __name__ == '__main__':
     main()
     main()
+
+### OUTPUT ###
+# Setting Data 1 = 10
+# DecimalViewer: Subject Data 1 has data 10
+# HexViewer: Subject Data 1 has data 0xa
+# Setting Data 2 = 15
+# HexViewer: Subject Data 2 has data 0xf
+# DecimalViewer: Subject Data 2 has data 15
+# Setting Data 1 = 3
+# DecimalViewer: Subject Data 1 has data 3
+# HexViewer: Subject Data 1 has data 0x3
+# Setting Data 2 = 5
+# HexViewer: Subject Data 2 has data 0x5
+# DecimalViewer: Subject Data 2 has data 5
+# Detach HexViewer from data1 and data2.
+# Setting Data 1 = 10
+# DecimalViewer: Subject Data 1 has data 10
+# Setting Data 2 = 15
+# DecimalViewer: Subject Data 2 has data 15

+ 10 - 0
pool.py

@@ -1,7 +1,11 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
 """http://stackoverflow.com/questions/1514120/python-implementation-of-the-object-pool-design-pattern"""
 """http://stackoverflow.com/questions/1514120/python-implementation-of-the-object-pool-design-pattern"""
 
 
 
 
 class QueueObject():
 class QueueObject():
+
     def __init__(self, queue, auto_get=False):
     def __init__(self, queue, auto_get=False):
         self._queue = queue
         self._queue = queue
         self.object = self._queue.get() if auto_get else None
         self.object = self._queue.get() if auto_get else None
@@ -49,3 +53,9 @@ def main():
 
 
 if __name__ == '__main__':
 if __name__ == '__main__':
     main()
     main()
+
+### OUTPUT ###
+# Inside with: yam
+# Outside with: yam
+# Inside func: sam
+# Outside func: sam

+ 22 - 9
prototype.py

@@ -1,7 +1,11 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
 import copy
 import copy
 
 
 
 
 class Prototype:
 class Prototype:
+
     def __init__(self):
     def __init__(self):
         self._objects = {}
         self._objects = {}
 
 
@@ -20,18 +24,27 @@ class Prototype:
         return obj
         return obj
 
 
 
 
-def main():
-    class A:
-        pass
+class A:
+    def __init__(self):
+        self.x = 3
+        self.y = 8
+        self.z = 15
+        self.garbage = [38, 11, 19]
 
 
-    a = A()
-    prototype = Prototype()
-    prototype.register_object('a', a)
-    b = prototype.clone('a', a=1, b=2, c=3)
+    def __str__(self):
+        return '{} {} {} {}'.format(self.x, self.y, self.z, self.garbage)
 
 
-    print(a)
-    print(b.a, b.b, b.c)
 
 
+def main():
+    a = A()
+    prototype = Prototype()
+    prototype.register_object('objecta', a)
+    b = prototype.clone('objecta')
+    c = prototype.clone('objecta', x=1, y=2, garbage=[88, 1])
+    print([str(i) for i in (a, b, c)])
 
 
 if __name__ == '__main__':
 if __name__ == '__main__':
     main()
     main()
+
+### OUTPUT ###
+# ['3 8 15 [38, 11, 19]', '3 8 15 [38, 11, 19]', '1 2 15 [88, 1]']

+ 24 - 13
proxy.py

@@ -1,26 +1,31 @@
-import time 
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import time
 
 
 
 
 class SalesManager:
 class SalesManager:
-    def work(self):                         
-        print("Sales Manager working...")             
 
 
-    def talk(self):                         
-        print("Sales Manager ready to talk") 
+    def work(self):
+        print("Sales Manager working...")
+
+    def talk(self):
+        print("Sales Manager ready to talk")
 
 
 
 
 class Proxy:
 class Proxy:
-    def __init__(self):                         
-        self.busy = 'No'                         
-        self.sales = None             
+
+    def __init__(self):
+        self.busy = 'No'
+        self.sales = None
 
 
     def work(self):
     def work(self):
-        print("Proxy checking for Sales Manager availability")                         
-        if self.busy == 'No':                                      
-            self.sales = SalesManager()                                      
+        print("Proxy checking for Sales Manager availability")
+        if self.busy == 'No':
+            self.sales = SalesManager()
             time.sleep(2)
             time.sleep(2)
-            self.sales.talk()                         
-        else:                                      
+            self.sales.talk()
+        else:
             time.sleep(2)
             time.sleep(2)
             print("Sales Manager is busy")
             print("Sales Manager is busy")
 
 
@@ -30,3 +35,9 @@ if __name__ == '__main__':
     p.work()
     p.work()
     p.busy = 'Yes'
     p.busy = 'Yes'
     p.work()
     p.work()
+
+### OUTPUT ###
+# Proxy checking for Sales Manager availability
+# Sales Manager ready to talk
+# Proxy checking for Sales Manager availability
+# Sales Manager is busy

+ 92 - 0
publish_subscribe.py

@@ -0,0 +1,92 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Reference: http://www.slideshare.net/ishraqabd/publish-subscribe-model-overview-13368808
+Author: https://github.com/HanWenfang
+"""
+
+
+class Provider:
+
+    def __init__(self):
+        self.msg_queue = []
+        self.subscribers = {}
+
+    def notify(self, msg):
+        self.msg_queue.append(msg)
+
+    def subscribe(self, msg, subscriber):
+        if msg not in self.subscribers:
+            self.subscribers[msg] = []
+            self.subscribers[msg].append(subscriber)  # unfair
+        else:
+            self.subscribers[msg].append(subscriber)
+
+    def unsubscribe(self, msg, subscriber):
+        self.subscribers[msg].remove(subscriber)
+
+    def update(self):
+        for msg in self.msg_queue:
+            if msg in self.subscribers:
+                for sub in self.subscribers[msg]:
+                    sub.run(msg)
+        self.msg_queue = []
+
+
+class Publisher:
+
+    def __init__(self, msg_center):
+        self.provider = msg_center
+
+    def publish(self, msg):
+        self.provider.notify(msg)
+
+
+class Subscriber:
+
+    def __init__(self, name, msg_center):
+        self.name = name
+        self.provider = msg_center
+
+    def subscribe(self, msg):
+        self.provider.subscribe(msg, self)
+
+    def run(self, msg):
+        print("{} got {}".format(self.name, msg))
+
+
+def main():
+    message_center = Provider()
+
+    fftv = Publisher(message_center)
+
+    jim = Subscriber("jim", message_center)
+    jim.subscribe("cartoon")
+    jack = Subscriber("jack", message_center)
+    jack.subscribe("music")
+    gee = Subscriber("gee", message_center)
+    gee.subscribe("movie")
+
+    fftv.publish("cartoon")
+    fftv.publish("music")
+    fftv.publish("ads")
+    fftv.publish("movie")
+    fftv.publish("cartoon")
+    fftv.publish("cartoon")
+    fftv.publish("movie")
+    fftv.publish("blank")
+
+    message_center.update()
+
+
+if __name__ == "__main__":
+    main()
+
+### OUTPUT ###
+# jim got cartoon
+# jack got music
+# gee got movie
+# jim got cartoon
+# jim got cartoon
+# gee got movie

+ 17 - 0
state.py

@@ -4,6 +4,7 @@
 
 
 
 
 class State(object):
 class State(object):
+
     """Base state. This is to share functionality"""
     """Base state. This is to share functionality"""
 
 
     def scan(self):
     def scan(self):
@@ -15,6 +16,7 @@ class State(object):
 
 
 
 
 class AmState(State):
 class AmState(State):
+
     def __init__(self, radio):
     def __init__(self, radio):
         self.radio = radio
         self.radio = radio
         self.stations = ["1250", "1380", "1510"]
         self.stations = ["1250", "1380", "1510"]
@@ -27,6 +29,7 @@ class AmState(State):
 
 
 
 
 class FmState(State):
 class FmState(State):
+
     def __init__(self, radio):
     def __init__(self, radio):
         self.radio = radio
         self.radio = radio
         self.stations = ["81.3", "89.1", "103.9"]
         self.stations = ["81.3", "89.1", "103.9"]
@@ -39,7 +42,9 @@ class FmState(State):
 
 
 
 
 class Radio(object):
 class Radio(object):
+
     """A radio.     It has a scan button, and an AM/FM toggle switch."""
     """A radio.     It has a scan button, and an AM/FM toggle switch."""
+
     def __init__(self):
     def __init__(self):
         """We have an AM state and an FM state"""
         """We have an AM state and an FM state"""
         self.amstate = AmState(self)
         self.amstate = AmState(self)
@@ -61,3 +66,15 @@ if __name__ == '__main__':
 
 
     for action in actions:
     for action in actions:
         action()
         action()
+
+### OUTPUT ###
+# Scanning... Station is 1380 AM
+# Scanning... Station is 1510 AM
+# Switching to FM
+# Scanning... Station is 89.1 FM
+# Scanning... Station is 103.9 FM
+# Scanning... Station is 81.3 FM
+# Scanning... Station is 89.1 FM
+# Switching to AM
+# Scanning... Station is 1250 AM
+# Scanning... Station is 1380 AM

+ 6 - 0
strategy.py

@@ -12,6 +12,7 @@ import types
 
 
 
 
 class StrategyExample:
 class StrategyExample:
+
     def __init__(self, func=None):
     def __init__(self, func=None):
         self.name = 'Strategy Example 0'
         self.name = 'Strategy Example 0'
         if func is not None:
         if func is not None:
@@ -41,3 +42,8 @@ if __name__ == '__main__':
     strat0.execute()
     strat0.execute()
     strat1.execute()
     strat1.execute()
     strat2.execute()
     strat2.execute()
+
+### OUTPUT ###
+# Strategy Example 0
+# Strategy Example 1 from execute 1
+# Strategy Example 2 from execute 2

+ 50 - 0
template.py

@@ -55,3 +55,53 @@ templates = [make_template(s, g, a)
 # Execute them
 # Execute them
 for template in templates:
 for template in templates:
     template()
     template()
+
+### OUTPUT ###
+# spam
+# ----------
+# eggs
+# ----------
+# apple
+# ----------
+# apple
+# ----------
+# eggs
+# ----------
+# spam
+# ----------
+# maps
+# ----------
+# sgge
+# ----------
+# elppa
+# ----------
+# elppa
+# ----------
+# sgge
+# ----------
+# maps
+# ----------
+# ['s', 'p', 'a', 'm']
+# ----------
+# ['e', 'g', 'g', 's']
+# ----------
+# ['a', 'p', 'p', 'l', 'e']
+# ----------
+# ['a', 'p', 'p', 'l', 'e']
+# ----------
+# ['e', 'g', 'g', 's']
+# ----------
+# ['s', 'p', 'a', 'm']
+# ----------
+# ['m', 'a', 'p', 's']
+# ----------
+# ['s', 'g', 'g', 'e']
+# ----------
+# ['e', 'l', 'p', 'p', 'a']
+# ----------
+# ['e', 'l', 'p', 'p', 'a']
+# ----------
+# ['s', 'g', 'g', 'e']
+# ----------
+# ['m', 'a', 'p', 's']
+# ----------

+ 9 - 3
visitor.py

@@ -18,10 +18,11 @@ class C(A, B):
 
 
 
 
 class Visitor(object):
 class Visitor(object):
+
     def visit(self, node, *args, **kwargs):
     def visit(self, node, *args, **kwargs):
         meth = None
         meth = None
         for cls in node.__class__.__mro__:
         for cls in node.__class__.__mro__:
-            meth_name = 'visit_'+cls.__name__
+            meth_name = 'visit_' + cls.__name__
             meth = getattr(self, meth_name, None)
             meth = getattr(self, meth_name, None)
             if meth:
             if meth:
                 break
                 break
@@ -31,10 +32,10 @@ class Visitor(object):
         return meth(node, *args, **kwargs)
         return meth(node, *args, **kwargs)
 
 
     def generic_visit(self, node, *args, **kwargs):
     def generic_visit(self, node, *args, **kwargs):
-        print('generic_visit '+node.__class__.__name__)
+        print('generic_visit ' + node.__class__.__name__)
 
 
     def visit_B(self, node, *args, **kwargs):
     def visit_B(self, node, *args, **kwargs):
-        print('visit_B '+node.__class__.__name__)
+        print('visit_B ' + node.__class__.__name__)
 
 
 
 
 a = A()
 a = A()
@@ -44,3 +45,8 @@ visitor = Visitor()
 visitor.visit(a)
 visitor.visit(a)
 visitor.visit(b)
 visitor.visit(b)
 visitor.visit(c)
 visitor.visit(c)
+
+### OUTPUT ###
+# generic_visit A
+# visit_B B
+# visit_B C