diff --git a/abstractfactory.py b/abstractfactory.py index 934372a..43bf19a 100644 --- a/abstractfactory.py +++ b/abstractfactory.py @@ -1,61 +1,65 @@ -class Klass1: - """ a very simple obj """ - def __init__(self): - pass - def hi(self): - print 'hi' - -class Factory: - """ base factory that can construct objects in a variety of ways: - * modules ['package1.subpackage',] to be searched for klass - * search global namespace - * create takes a arguement of what type of class to return - * return a default implementation - subclass must define createDefault() - """ - def __init__(self, modules=[]): - self.modules=modules - - def createDefault(self): - print dir() - raise NotImplementedError - - def create(self, klass=None): - import string - if klass in globals().keys(): - if type(globals()[klass]).__name__=='class': - return globals()[klass]() - for module in self.modules: - try: - fromlist = [] - if string.find(module, '.'): fromlist = string.split(module, '.')[:-1] - module = __import__(module, globals(), locals(), fromlist) - if hasattr(module, klass): return getattr(module, klass)() - except AttributeError: pass - return self.createDefault() - -class MyFactory(Factory): - """ concrete factory that specifies: - * what modules to search for - * implements a createDefault() - which is used if class isnt found - """ - def __init__(self, modules=[]): - Factory.__init__(self,modules) - def createDefault(self): - return Klass1() - - -#--------much simpler one by mark lutz, http://shell.rmi.net/~lutz/talk.html -def factory(aClass, *args): # varargs tuple - return apply(aClass, args) # call aClass - -class Spam: - def doit(self, message): - print message - -class Person: - def __init__(self, name, job): - self.name = name - self.job = job - -object1 = factory(Spam) -object2 = factory(Person, "Guido", "guru") +"""Implementation of the abstract factory pattern""" +import random + + +class PetShop: + """A pet shop""" + + def __init__(self, animal_factory=None): + """pet_factory is our abstract factory. We can set it at will.""" + self.pet_factory = animal_factory + + def show_pet(self): + """Creates and shows a pet using the abstract factory""" + pet = self.pet_factory.get_pet() + print "This is a lovely", pet + print "It says", pet.speak() + print "It eats", self.pet_factory.get_food() + +# Stuff that our factory makes + + +class Dog: + def speak(self): + return "woof" + + def __str__(self): + return "Dog" + + +class Cat: + def speak(self): + return "meow" + + def __str__(self): + return "Cat" + + +# Factory classes +class DogFactory: + def get_pet(self): + return Dog() + + def get_food(self): + return "dog food" + + +class CatFactory: + def get_pet(self): + return Cat() + + def get_food(self): + return "cat food" + + +# Create the proper family +def get_factory(): + """Let's be dynamic!""" + return random.choice([DogFactory, CatFactory])() + +# Show pets with various factories +shop = PetShop() +for i in range(3): + shop.pet_factory = get_factory() + shop.show_pet() + print "=" * 10 diff --git a/adapter.py b/adapter.py index a2a5e00..36b4fe4 100644 --- a/adapter.py +++ b/adapter.py @@ -1,20 +1,25 @@ -class Barfooer: - def barfoo(self, bar, foo): - pass +class Adaptee: + def specific_request(self): + return 'Adaptee' -# Per instance, by wrapping and delegation -class FoobaringWrapper: - def __init__(self, wrappee): - self.w = wrappee - def foobar(self, foo, bar): - return self.w.barfoo(bar, foo) +class Adapter: + def __init__(self, adaptee): + self.adaptee = adaptee -foobarer = FoobaringWrapper(barfooer) + def request(self): + return self.adaptee.specific_request() -# Per-classs by subclassing and self-delegation -class Foobarer(Barfooer): - def foobar(self,foo, bar): - return self.barfoo(bar, foo) +client = Adapter(Adaptee()) +print client.request() -foobarer = Foobarer(some, init, params) +# --------- Second example (by Alex Martelli)------------ +class UppercasingFile: + def __init__(self, *a, **k): + self.f = file(*a, **k) + + def write(self, data): + self.f.write(data.upper()) + + def __getattr__(self, name): + return getattr(self.f, name) diff --git a/bridge.py b/bridge.py index c8386e2..a405aa5 100644 --- a/bridge.py +++ b/bridge.py @@ -1,9 +1,60 @@ -class AbstractParser: - def __init__(self, scanner): - self.scanner = scanner -class ExprParser(AbstractParser): - def expr(self): - t = self.scanner.next()... - self.scanner.push_back(t)... +# Implementor +class DrawingAPI: + def drawCircle(x, y, radius): + pass + + +# ConcreteImplementor 1/2 +class DrawingAPI1(DrawingAPI): + def drawCircle(self, x, y, radius): + print "API1.circle at %f:%f radius %f" % (x, y, radius) + + +# ConcreteImplementor 2/2 +class DrawingAPI2(DrawingAPI): + def drawCircle(self, x, y, radius): + print "API2.circle at %f:%f radius %f" % (x, y, radius) + + +# Abstraction +class Shape: + # Low-level + def draw(self): + pass + + # High-level + def resizeByPercentage(self, pct): + pass + + +# Refined Abstraction +class CircleShape(Shape): + def __init__(self, x, y, radius, drawingAPI): + self.__x = x + self.__y = y + self.__radius = radius + self.__drawingAPI = drawingAPI + + # low-level i.e. Implementation specific + def draw(self): + self.__drawingAPI.drawCircle(self.__x, self.__y, self.__radius) + + # high-level i.e. Abstraction specific + def resizeByPercentage(self, pct): + self.__radius *= pct + + +def main(): + shapes = [ + CircleShape(1, 2, 3, DrawingAPI1()), + CircleShape(5, 7, 11, DrawingAPI2()) + ] + + for shape in shapes: + shape.resizeByPercentage(2.5) + shape.draw() + +if __name__ == "__main__": + main() diff --git a/chainofresp.py b/chainofresp.py new file mode 100644 index 0000000..776468f --- /dev/null +++ b/chainofresp.py @@ -0,0 +1,44 @@ +class Car: + def __init__(self): + self.name = None + self.km = 11100 + self.fuel = 5 + self.oil = 5 + + +def handle_fuel(car): + if car.fuel < 10: + print "added fuel" + car.fuel = 100 + + +def handle_km(car): + if car.km > 10000: + print "made a car test." + car.km = 0 + + +def handle_oil(car): + if car.oil < 10: + print "Added oil" + car.oil = 100 + + +class Garage: + def __init__(self): + self.handlers = [] + + def add_handler(self, handler): + self.handlers.append(handler) + + def handle_car(self, car): + for handler in self.handlers: + handler(car) + +if __name__ == '__main__': + handlers = [handle_fuel, handle_km, handle_oil] + garage = Garage() + + for handle in handlers: + garage.add_handler(handle) + garage.handle_car(Car()) diff --git a/closure.py b/closure.py index bf34f48..38b6f48 100644 --- a/closure.py +++ b/closure.py @@ -6,10 +6,6 @@ def dfdx(x): def f(x): return 3*x**2+x -""" ->>> print f(1.0) -4.0 ->>> print Dx(f, 0.01)(1.0) -7.03 ->>> print Dx(Dx(f, 0.01), 0.01)(1.0) -""" +print f(1.0) # 4.0 +print Dx(f, 0.01)(1.0) # 7.03 +print Dx(Dx(f, 0.01), 0.01)(1.0) diff --git a/command.py b/command.py index 0e4c557..6abbc63 100644 --- a/command.py +++ b/command.py @@ -2,120 +2,132 @@ from sys import stdout as console -# Обработка команды exit + +# Handling 'exit' command class SessionClosed(Exception): - def __init__(self, value): - self.value = value + def __init__(self, value): + self.value = value + -# Интерфейс команды +# Interface class Command: - def execute(self): - raise NotImplementedError() + def execute(self): + raise NotImplementedError() + + def cancel(self): + raise NotImplementedError() - def cancel(self): - raise NotImplementedError() + def name(): + raise NotImplementedError() - def name(): - raise NotImplementedError() -# Команда rm +# rm command class RmCommand(Command): - def execute(self): - console.write("You are executed \"rm\" command\n") + def execute(self): + console.write("You are executed \"rm\" command\n") - def cancel(self): - console.write("You are canceled \"rm\" command\n") + def cancel(self): + console.write("You are canceled \"rm\" command\n") - def name(self): - return "rm" + def name(self): + return "rm" -# Команда uptime + +# uptime command class UptimeCommand(Command): - def execute(self): - console.write("You are executed \"uptime\" command\n") + def execute(self): + console.write("You are executed \"uptime\" command\n") + + def cancel(self): + console.write("You are canceled \"uptime\" command\n") - def cancel(self): - console.write("You are canceled \"uptime\" command\n") + def name(self): + return "uptime" - def name(self): - return "uptime" -# Команда undo +# undo command class UndoCommand(Command): - def execute(self): - try: - cmd = HISTORY.pop() - TRASH.append(cmd) - console.write("Undo command \"{0}\"\n".format(cmd.name())) - cmd.cancel() + def execute(self): + try: + cmd = HISTORY.pop() + TRASH.append(cmd) + console.write("Undo command \"{0}\"\n".format(cmd.name())) + cmd.cancel() - except IndexError: - console.write("ERROR: HISTORY is empty\n") + except IndexError: + console.write("ERROR: HISTORY is empty\n") - def name(self): - return "undo" + def name(self): + return "undo" -# Команда redo + +# redo command class RedoCommand(Command): - def execute(self): - try: - cmd = TRASH.pop() - HISTORY.append(cmd) - console.write("Redo command \"{0}\"\n".format(cmd.name())) - cmd.execute() - - except IndexError: - console.write("ERROR: TRASH is empty\n") - def name(self): - return "redo" - -# Команда history -class HistoryCommand(Command): - def execute(self): - i = 0 - for cmd in HISTORY: - console.write("{0}: {1}\n".format(i, cmd.name())) - i = i + 1 - def name(self): - print "history" - -# Команда exit -class ExitCommand(Command): - def execute(self): - raise SessionClosed("Good bay!") + def execute(self): + try: + cmd = TRASH.pop() + HISTORY.append(cmd) + console.write("Redo command \"{0}\"\n".format(cmd.name())) + cmd.execute() + except IndexError: + console.write("ERROR: TRASH is empty\n") - def name(self): - return "exit" + def name(self): + return "redo" -# Словарь доступных команд -COMMANDS = {'rm': RmCommand(), 'uptime': UptimeCommand(), 'undo': UndoCommand(), 'redo': RedoCommand(), 'history': HistoryCommand(), 'exit': ExitCommand()} -HISTORY = list() -TRASH = list() - -# Шелл -def main(): +# history command +class HistoryCommand(Command): + def execute(self): + i = 0 + for cmd in HISTORY: + console.write("{0}: {1}\n".format(i, cmd.name())) + i = i + 1 - try: - while True: - console.flush() - console.write("pysh >> ") + def name(self): + print "history" - cmd = raw_input() - try: +# exit command +class ExitCommand(Command): + def execute(self): + raise SessionClosed("Good bay!") - command = COMMANDS[cmd] - command.execute() + def name(self): + return "exit" - if not isinstance(command, UndoCommand) and not isinstance(command, RedoCommand) and not isinstance(command, HistoryCommand): - TRASH = list() - HISTORY.append(command) +# available commands +COMMANDS = {'rm': RmCommand(), 'uptime': UptimeCommand(), 'undo': + UndoCommand(), 'redo': RedoCommand(), 'history': HistoryCommand(), + 'exit': ExitCommand()} - except KeyError: - console.write("ERROR: Command \"%s\" not found\n" % cmd) +HISTORY = list() +TRASH = list() - except SessionClosed as e: - console.write(e.value) -if __name__ == "__main__": main() +# Shell +def main(): + try: + while True: + console.flush() + console.write("pysh >> ") + + cmd = raw_input() + + try: + command = COMMANDS[cmd] + command.execute() + if (not isinstance(command, UndoCommand) and not + isinstance(command, RedoCommand) and not + isinstance(command, HistoryCommand)): + TRASH = list() + HISTORY.append(command) + + except KeyError: + console.write("ERROR: Command \"%s\" not found\n" % cmd) + + except SessionClosed as e: + console.write(e.value) + +if __name__ == "__main__": + main() diff --git a/composite.py b/composite.py new file mode 100644 index 0000000..f6f2c9d --- /dev/null +++ b/composite.py @@ -0,0 +1,36 @@ +class Component(object): + def __init__(self, *args, **kw): + pass + + def component_function(self): + pass + + +class Leaf(Component): + def __init__(self, *args, **kw): + Component.__init__(self, *args, **kw) + + def component_function(self): + print "some function" + + +class Composite(Component): + def __init__(self, *args, **kw): + Component.__init__(self, *args, **kw) + self.children = [] + + def append_child(self, child): + self.children.append(child) + + def remove_child(self, child): + self.children.remove(child) + + def component_function(self): + map(lambda x: x.component_function(), self.children) + +c = Composite() +l = Leaf() +l_two = Leaf() +c.append_child(l) +c.append_child(l_two) +c.component_function() diff --git a/decorator.py b/decorator.py index a624c28..68e1f9c 100644 --- a/decorator.py +++ b/decorator.py @@ -1,49 +1,34 @@ -## {{{ http://code.activestate.com/recipes/576758/ (r3) -import abc +import time -def keycomparable(Derived): - class KeyComparableImpl(metaclass = abc.ABCMeta): - @abc.abstractmethod - def _cmpkey(self): - pass - def __lt__(self, other): - if not isinstance(other, Derived): - return NotImplemented - return self._cmpkey() < other._cmpkey() +def time_this(func): + """The time_this decorator""" - def __le__(self, other): - if not isinstance(other, Derived): - return NotImplemented - return self._cmpkey() <= other._cmpkey() + def decorated(*args, **kwargs): + start = time.time() + result = func(*args, **kwargs) + print 'Rain in', time.time() - start, 'seconds' + return result + return decorated - def __eq__(self, other): - if not isinstance(other, Derived): - return NotImplemented - return self._cmpkey() == other._cmpkey() +# Decorator syntax +@time_this +def count(until): + """Counts to 'until', then returns the result""" - class Wrapper(Derived, KeyComparableImpl): - pass + print "Counting to", until, "…" + num = 0 + for i in xrange(to_num(until)): + num += 1 + return num - Wrapper.__name__ = Derived.__name__ - Wrapper.__doc__ = Derived.__doc__ - return Wrapper +def to_num(numstr): + """Turns a comma-separated number string to an int""" + return int(numstr.replace(",", "")) -@keycomparable -class IntABS: - "sample class" - def __init__(self,val): - self.val = val - - def _cmpkey(self): - return abs(self.val) - - def __str__(self): - return str(abs(self.val)) - - def __repr__(self): - return "abs({0})".format(self.val) -## end of http://code.activestate.com/recipes/576758/ }}} - +# Run count with various values +for number in ("10,000", "100,000", "1,000,000"): + print count(number) + print "-" * 20 diff --git a/facade.py b/facade.py index f3f106a..b0183a7 100644 --- a/facade.py +++ b/facade.py @@ -1,10 +1,29 @@ -# Toy-example facade -class LifoStack: +# Complex parts +class CPU: + def freeze(self): pass + def jump(self, position): pass + def execute(self): pass + +class Memory: + def load(self, position, data): pass + +class HardDrive: + def read(self, lba, size): pass + +# Facade +class Computer: def __init__(self): - self._stack = [] + self.cpu = CPU() + self.memory = Memory() + self.hard_drive = HardDrive() - def push(self, datum): - self._stack.append(datum) + def start_computer(self): + self.cpu.freeze() + self.memory.load(0, self.hard_drive.read(0, 1024)) + self.cpu.jump(10) + self.cpu.execute() - def pop(self): - return self._stack.pop() +# Client +if __name__ == '__main__': + facade = Computer() + facade.start_computer() diff --git a/factory.py b/factory.py index 37fbf23..4226d34 100644 --- a/factory.py +++ b/factory.py @@ -1,73 +1,70 @@ -""" -A generic factory implementation. -Examples: ->>f=Factory() ->>class A:pass ->>f.register("createA",A) ->>f.createA() -<__main__.A instance at 01491E7C> - ->>> class B: -... def __init__(self, a,b=1): -... self.a=a -... self.b=b -... ->>> f.register("createB",B,1,b=2) ->>> f.createB() ->>> b=f.createB() ->>> ->>> b.a -1 ->>> b.b -2 - ->>> class C: -... def __init__(self,a,b,c=1,d=2): -... self.values = (a,b,c,d) -... ->>> f.register("createC",C,1,c=3) ->>> c=f.createC(2,d=4) ->>> c.values -(1, 2, 3, 4) - ->>> f.register("importSerialization",__import__,"cPickle") ->>> pickle=f.importSerialization() ->>> pickle - ->>> f.register("importSerialization",__import__,"marshal") ->>> pickle=f.importSerialization() ->>> pickle - - ->>> f.unregister("importSerialization") ->>> f.importSerialization() -Traceback (most recent call last): - File "", line 1, in ? -AttributeError: Factory instance has no attribute 'importSerialization' -""" - -class Factory: - def register(self, methodName, constructor, *args, **kargs): - """register a constructor""" - _args = [constructor] - _args.extend(args) - setattr(self, methodName,apply(Functor,_args, kargs)) - - def unregister(self, methodName): - """unregister a constructor""" - delattr(self, methodName) - -class Functor: - def __init__(self, function, *args, **kargs): - assert callable(function), "function should be a callable obj" - self._function = function - self._args = args - self._kargs = kargs - - def __call__(self, *args, **kargs): - """call function""" - _args = list(self._args) - _args.extend(args) - _kargs = self._kargs.copy() - _kargs.update(kargs) - return apply(self._function,_args,_kargs) +class Pizza(object): + def __init__(self): + self._price = None + + def get_price(self): + return self._price + +class HamAndMushroomPizza(Pizza): + def __init__(self): + self._price = 8.5 + +class DeluxePizza(Pizza): + def __init__(self): + self._price = 10.5 + +class HawaiianPizza(Pizza): + def __init__(self): + self._price = 11.5 + +class PizzaFactory(object): + @staticmethod + def create_pizza(pizza_type): + if pizza_type == 'HamMushroom': + return HamAndMushroomPizza() + elif pizza_type == 'Deluxe': + return DeluxePizza() + elif pizza_type == 'Hawaiian': + return HawaiianPizza() + +if __name__ == '__main__': + for pizza_type in ('HamMushroom', 'Deluxe', 'Hawaiian'): + print 'Price of {0} is {1}'.format(pizza_type, PizzaFactory.create_pizza(pizza_type).get_price()) + + +# ------------------- Second example ----------------- + + +class JapaneseGetter: + """A simple localizer a la gettext""" + + def __init__(self): + self.trans = dict(dog="犬", cat="猫") + + def get(self, msgid): + """We'll punt if we don't have a translation""" + + try: + return unicode(self.trans[msgid], "utf-8") + except KeyError: + return unicode(msgid) + +class EnglishGetter: + """Simply echoes the msg ids""" + def get(self, msgid): + return unicode(msgid) + +def get_localizer(language="English"): + """The factory method""" + + languages = dict(English=EnglishGetter, + Japanese=JapaneseGetter) + + return languages[language]() + +# Create our localizers +e, j = get_localizer("English"), get_localizer("Japanese") + +# Localize some text +for msgid in "dog parrot cat".split(): + print e.get(msgid), j.get(msgid) diff --git a/flyweight.py b/flyweight.py index 981718d..642f970 100644 --- a/flyweight.py +++ b/flyweight.py @@ -1,24 +1,32 @@ """ Flyweight Design Pattern - Desc: Sharing the shareable data between the common classes and thus reducing the memory usage - Code: Believing that every person in a family will have same genetic structure, we will create a code to learn about - genetics of each family. If a same member of a family is given, no new object is created. (You can also create new - objects unlike here but keep a reference of the heavy weighted one in the new |||r object). + Desc: Sharing the shareable data between the common classes and thus + reducing the memory usage + Code: Believing that every person in a family will have same genetic + structure, we will create a code to learn about + genetics of each family. If a same member of a family is given, no new + object is created. (You can also create new + objects unlike here but keep a reference of the heavy weighted one in + the new |||r object). """ + class ComplexGenetics(object): - """ returns a huge genetic pattern""" + """Returns a huge genetic pattern""" def __init__(self): pass def genes(self, gene_code): return "ComplexPatter[%s]TooHugeinSize" % (gene_code) + class Families(object): - """ To learn about Family Genetic Pattern """ + """To learn about Family Genetic Pattern.""" family = {} + def __new__(cls, name, family_id): - """ i have to capture the details before the class is created, __init__ is pseudo constructor """ + """I have to capture the details before the class is created, __init__ + is pseudo constructor.""" try: id = cls.family[family_id] except KeyError: @@ -33,8 +41,8 @@ def set_genetic_info(self, genetic_info): def get_genetic_info(self): return (self.genetic_info) + def test(): - # name, family_id and genetic code details (i dont care if genetic code detail varies in same family [it is research fault :-D ]) data = (('a', 1, 'ATAG'), ('a', 2, 'AAGT'), ('b', 1, 'ATAG')) family_objects = [] for i in data: diff --git a/iterator.py b/iterator.py new file mode 100644 index 0000000..3f7dcd4 --- /dev/null +++ b/iterator.py @@ -0,0 +1,23 @@ +# from a sequence +x = [42, "test", -12.34] +it = iter(x) +try: + while True: + x = next(it) # in Python 2, you would use it.next() + print x +except StopIteration: + pass + + +# a generator +def foo(n): + for i in range(n): + yield i + +it = foo(5) +try: + while True: + x = next(it) # in Python 2, you would use it.next() + print x +except StopIteration: + pass diff --git a/memento.py b/memento.py index 01d04f8..f84d6d9 100644 --- a/memento.py +++ b/memento.py @@ -1,42 +1,41 @@ -## {{{ http://code.activestate.com/recipes/413838/ (r3) +# TODO finish it import copy + def Memento(obj, deep=False): - state = (copy.copy, copy.deepcopy)[bool(deep)](obj.__dict__) - def Restore(): - obj.__dict__.clear() - obj.__dict__.update(state) - return Restore + state = (copy.copy, copy.deepcopy)[bool(deep)](obj.__dict__) + def Restore(): + obj.__dict__.clear() + obj.__dict__.update(state) + return Restore class Transaction: - """A transaction guard. This is realy just - syntactic suggar arount a memento closure. - """ - deep = False - def __init__(self, *targets): - self.targets = targets - self.Commit() - def Commit(self): - self.states = [Memento(target, self.deep) for target in self.targets] - def Rollback(self): - for state in self.states: - state() + """A transaction guard. This is realy just syntactic suggar arount a memento + closure.""" + deep = False + def __init__(self, *targets): + self.targets = targets + self.Commit() + def Commit(self): + self.states = [Memento(target, self.deep) for target in self.targets] + def Rollback(self): + for state in self.states: + state() class transactional(object): - """Adds transactional semantics to methods. Methods decorated - with @transactional will rollback to entry state upon exceptions. - """ - def __init__(self, method): - self.method = method - def __get__(self, obj, T): - def transaction(*args, **kwargs): - state = Memento(obj) - try: - return self.method(obj, *args, **kwargs) - except: - state() - raise - return transaction + """Adds transactional semantics to methods. Methods decorated with + @transactional will rollback to entry state upon exceptions.""" + def __init__(self, method): + self.method = method + def __get__(self, obj, T): + def transaction(*args, **kwargs): + state = Memento(obj) + try: + return self.method(obj, *args, **kwargs) + except: + state() + raise + return transaction if __name__ == '__main__': @@ -80,5 +79,3 @@ def DoStuff(self): traceback.print_exc(0) pass print n -## end of http://code.activestate.com/recipes/413838/ }}} - diff --git a/null.py b/null.py index 2a86d99..88b13d5 100644 --- a/null.py +++ b/null.py @@ -38,6 +38,7 @@ August 2001 """ + class Null: """A class for implementing Null objects. @@ -53,20 +54,17 @@ class Null: provided here. """ - # object constructing - + # Object constructing def __init__(self, *args, **kwargs): "Ignore parameters." return None - # object calling - + # Object calling def __call__(self, *args, **kwargs): "Ignore method calls." return self - # attribute handling - + # Attribute handling def __getattr__(self, mname): "Ignore attribute requests." return self @@ -79,8 +77,7 @@ def __delattr__(self, name): "Ignore deleting attributes." return self - # misc. - + # Misc. def __repr__(self): "Return a string representation." return "" @@ -93,8 +90,7 @@ def __str__(self): def test(): "Perform some decent tests, or rather: demos." - # constructing and calling - + # Constructing and calling n = Null() n = Null('value') n = Null('value', param='value') @@ -103,8 +99,7 @@ def test(): n('value') n('value', param='value') - # attribute handling - + # Attribute handling n.attr1 n.attr1.attr2 n.method1() @@ -121,8 +116,7 @@ def test(): del n.attr1 del n.attr1.attr2.attr3 - # representation and conversion to a string - + # Representation and conversion to a string assert repr(n) == '' assert str(n) == 'Null' diff --git a/observer.py b/observer.py index cf7a78d..54959ac 100644 --- a/observer.py +++ b/observer.py @@ -1,77 +1,62 @@ -## {{{ http://code.activestate.com/recipes/131499/ (r2) -class Subject: - def __init__(self): - self._observers = [] - - def attach(self, observer): - if not observer in self._observers: - self._observers.append(observer) +class AbstractSubject: + def register(self, listener): + raise NotImplementedError("Must subclass me") - def detach(self, observer): - try: - self._observers.remove(observer) - except ValueError: - pass + def unregister(self, listener): + raise NotImplementedError("Must subclass me") - def notify(self, modifier=None): - for observer in self._observers: - if modifier != observer: - observer.update(self) + def notify_listeners(self, event): + raise NotImplementedError("Must subclass me") -# Example usage -class Data(Subject): - def __init__(self, name=''): - Subject.__init__(self) +class Listener: + def __init__(self, name, subject): self.name = name - self.data = 0 + subject.register(self) + + def notify(self, event): + print self.name, "received event", event - def setData(self, data): - self.data = data - self.notify() - def getData(self): +class Subject(AbstractSubject): + def __init__(self): + self.listeners = [] + self.data = None + + def getUserAction(self): + self.data = raw_input('Enter something to do:') return self.data + # Implement abstract Class AbstractSubject + + def register(self, listener): + self.listeners.append(listener) + + def unregister(self, listener): + self.listeners.remove(listener) + + def notify_listeners(self, event): + for listener in self.listeners: + listener.notify(event) + + +if __name__ == "__main__": + # Make a subject object to spy on + subject = Subject() + + # Register two listeners to monitor it. + listenerA = Listener("", subject) + listenerB = Listener("", subject) -class HexViewer: - def update(self, subject): - print 'HexViewer: Subject %s has data 0x%x' % (subject.name, subject.getData()) - - -class DecimalViewer: - def update(self, subject): - print 'DecimalViewer: Subject %s has data %d' % (subject.name, subject.getData()) - - -# Example usage... -def main(): - data1 = Data('Data 1') - data2 = Data('Data 2') - view1 = DecimalViewer() - view2 = HexViewer() - data1.attach(view1) - data1.attach(view2) - data2.attach(view2) - data2.attach(view1) - - print "Setting Data 1 = 10" - data1.setData(10) - print "Setting Data 2 = 15" - data2.setData(15) - print "Setting Data 1 = 3" - data1.setData(3) - print "Setting Data 2 = 5" - data2.setData(5) - print "Detach HexViewer from data1 and data2." - data1.detach(view2) - data2.detach(view2) - print "Setting Data 1 = 10" - data1.setData(10) - print "Setting Data 2 = 15" - data2.setData(15) - -if __name__ == '__main__': - main() -## end of http://code.activestate.com/recipes/131499/ }}} + # Simulated event + subject.notify_listeners("") + # Outputs: + # received event + # received event + action = subject.getUserAction() + subject.notify_listeners(action) + # Enter something to do:hello + # outputs: + # received event hello + # received event hello diff --git a/prototype.py b/prototype.py index ab9fb67..8b27676 100644 --- a/prototype.py +++ b/prototype.py @@ -1,25 +1,50 @@ -## {{{ http://code.activestate.com/recipes/86651/ (r1) -from copy import deepcopy +from copy import deepcopy, copy -class Prototype: - def __init__(self): - self._objs = {} +copyfunc = deepcopy - def registerObject(self, name, obj): - """ - register an object. - """ - self._objs[name] = obj - def unregisterObject(self, name): - """unregister an object""" - del self._objs[name] +def Prototype(name, bases, dict): + class Cls: + pass + Cls.__name__ = name + Cls.__bases__ = bases + Cls.__dict__ = dict + inst = Cls() + inst.__call__ = copyier(inst) + return inst - def clone(self, name, **attr): - """clone a registered object and add/replace attr""" - obj = deepcopy(self._objs[name]) - obj.__dict__.update(attr) - return obj -## end of http://code.activestate.com/recipes/86651/ }}} +class copyier: + def __init__(self, inst): + self._inst = inst + def __call__(self): + newinst = copyfunc(self._inst) + if copyfunc == deepcopy: + newinst.__call__._inst = newinst + else: + newinst.__call__ = copyier(newinst) + return newinst + + +class Point: + __metaclass__ = Prototype + x = 0 + y = 0 + + def move(self, x, y): + self.x += x + self.y += y + +a = Point() +print a.x, a.y # prints 0 0 +a.move(100, 100) +print a.x, a.y # prints 100 100 + +Point.move(50, 50) +print Point.x, Point.y # prints 50 50 +p = Point() +print p.x, p.y # prints 50 50 + +q = p() +print q.x, q.y # prints 50 50 diff --git a/proxy.py b/proxy.py index f711142..de64dd5 100644 --- a/proxy.py +++ b/proxy.py @@ -1,9 +1,55 @@ -class JustInTimeCreator: - def __init__(self, cls, *a, **k): - self._m = cls, a, k - - def __getattr__(self, name): - if not hasattr(self, '_x'): - cls, a, k = self._m - self._x = cls(*a, **k) - return getattr(self._x, name) +# -*- coding: utf-8 -*- + +class IMath: + """Interface for proxy and real subject.""" + def add(self, x, y): + raise NotImplementedError() + + def sub(self, x, y): + raise NotImplementedError() + + def mul(self, x, y): + raise NotImplementedError() + + def div(self, x, y): + raise NotImplementedError() + +class Math(IMath): + """Real subject.""" + def add(self, x, y): + return x + y + + def sub(self, x, y): + return x - y + + def mul(self, x, y): + return x * y + + def div(self, x, y): + return x / y + +class Proxy(IMath): + """Proxy.""" + def __init__(self): + self.math = Math() + + def add(self, x, y): + return self.math.add(x, y) + + def sub(self, x, y): + return self.math.sub(x, y) + + def mul(self, x, y): + return self.math.mul(x, y) + + def div(self, x, y): + if y == 0: + return float('inf') # Вернуть positive infinity + return self.math.div(x, y) + +p = Proxy() +x, y = 4, 2 +print '4 + 2 = ' + str(p.add(x, y)) +print '4 - 2 = ' + str(p.sub(x, y)) +print '4 * 2 = ' + str(p.mul(x, y)) +print '4 / 2 = ' + str(p.div(x, y)) diff --git a/singleton.py b/singleton.py index 50a6997..f297999 100644 --- a/singleton.py +++ b/singleton.py @@ -1,31 +1,48 @@ -# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66531 -class Borg: - __shared_state = {} - def __init__(self): - self.__dict__ = self.__shared_state +# ---------- Singletone ---------- -a=Borg() -a.toto = 12 - -b=Borg() -print b.toto -print id(a),id(b) # different ! but states are sames - - - -real Singleton instance +# Real Singleton instance class Singleton(object): def __new__(type): if not '_the_instance' in type.__dict__: type._the_instance = object.__new__(type) return type._the_instance -a=Singleton() +a = Singleton() +a.toto = 12 + +b = Singleton() +print b.toto +print id(a), id(b) # The same !! + + +# ---------- Borg's singletone ---------- +class Borg: + __shared_state = {} + + def __init__(self): + self.__dict__ = self.__shared_state + +a = Borg() a.toto = 12 -b=Singleton() +b = Borg() print b.toto -print id(a),id(b) # the same !! +print id(a), id(b) # different ! but states are sames +# ---------- Alex's Martelli examples ---------- +class Singleton(object): + def __new__(cls, *a, **k): + if not hasattr(cls, '_inst'): + cls._inst = super(Singleton, cls +).__new__(cls, *a, **k) + return cls._inst + +class Borg(object): + """Subclassing is no problem.""" + _shared_state = {} + def __new__(cls, *a, **k): + obj = super(Borg, cls).__new__(cls, *a, **k) + obj.__dict__ = cls._shared_state + return obj diff --git a/state.py b/state.py index 6e5ad19..e32fe02 100644 --- a/state.py +++ b/state.py @@ -1,72 +1,61 @@ -## {{{ http://code.activestate.com/recipes/277752/ (r3) -#!/usr/bin/env python -# -# Author: Bschorer Elmar -# State-Pattern Demo +"""Implementation of the state pattern""" +import itertools -class NetworkCardState: - """Abstract State Object""" - def send(self): - raise "NetworkCardState.send - not overwritten" - def receive(self): - raise "NetworkCardState.receive - not overwritten" +class State(object): + """Base state. This is to share functionality""" + def scan(self): + """Scan the dial to the next station""" + print "Scanning... Station is", self.stations.next(), self.name -class Online(NetworkCardState): - """Online state for NetworkCard""" - def send(self): - print "sending Data" - def receive(self): - print "receiving Data" +class AmState(State): + def __init__(self, radio): + self.radio = radio + self.stations = itertools.cycle(["1250", "1380", "1510"]) + self.name = "AM" + def toggle_amfm(self): + print "Switching to FM" + self.radio.state = self.radio.fmstate -class Offline(NetworkCardState): - """Offline state for NetworkCard""" - def send(self): - print "cannot send...Offline" - def receive(self): - print "cannot receive...Offline" +class FmState(State): + def __init__(self, radio): + self.radio = radio + self.stations = itertools.cycle(["81.3", "89.1", "103.9"]) + self.name = "FM" + def toggle_amfm(self): + print "Switching to AM" + self.radio.state = self.radio.amstate -class NetworkCard: - def __init__(self): - self.online = Online() - self.offline = Offline() - ##default state is Offline - self.currentState = self.offline - def startConnection(self): - self.currentState = self.online +class Radio(object): + """A radio. + It has a scan button, and an AM/FM toggle switch.""" + + def __init__(self): + """We have an AM state and an FM state""" - def stopConnection(self): - self.currentState = self.offline + self.amstate = AmState(self) + self.fmstate = FmState(self) + self.state = self.amstate - def send(self): - self.currentState.send() + def toggle_amfm(self): + self.state.toggle_amfm() - def receive(self): - self.currentState.receive() + def scan(self): + self.state.scan() def main(): - myNetworkCard = NetworkCard() - print "without connection:" - myNetworkCard.send() - myNetworkCard.receive() - print "starting connection" - myNetworkCard.startConnection() - myNetworkCard.send() - myNetworkCard.receive() + ''' Test our radio out ''' + radio = Radio() + actions = ([radio.scan] * 2 + [radio.toggle_amfm] + [radio.scan] * 2) * 2 + for action in actions: + action() if __name__ == '__main__': main() - - - - - -## end of http://code.activestate.com/recipes/277752/ }}} - diff --git a/strategy.py b/strategy.py new file mode 100644 index 0000000..053e0c8 --- /dev/null +++ b/strategy.py @@ -0,0 +1,54 @@ +class StrategyExample: + + def __init__(self, func=None): + if func: + self.execute = func + + def execute(self): + print "Original execution" + + +def executeReplacement1(self): + print "Strategy 1" + + +def executeReplacement2(self): + print "Strategy 2" + +if __name__ == "__main__": + + strat0 = StrategyExample() + strat1 = StrategyExample(executeReplacement1) + strat2 = StrategyExample(executeReplacement2) + + strat0.execute() + strat1.execute() + strat2.execute() + +# -------------------- With classes -------------------- + + +class AUsefulThing(object): + def __init__(self, aStrategicAlternative): + self.howToDoX = aStrategicAlternative + + def doX(self, someArg): + self. howToDoX.theAPImethod(someArg, self) + + +class StrategicAlternative(object): + pass + + +class AlternativeOne(StrategicAlternative): + def theAPIMethod(self, someArg, theUsefulThing): + pass # an implementation + + +class AlternativeTwo(StrategicAlternative): + def theAPImethod(self, someArg, theUsefulThing): + pass # another implementation + + +t = AUsefulThing(AlternativeOne()) +t.doX('arg') diff --git a/template.py b/template.py index a3a0beb..fe82e0b 100644 --- a/template.py +++ b/template.py @@ -29,15 +29,27 @@ def printWinner(self): raise TypeError('abstract method must be overridden') -Now to create concrete (non-abstract) games, you subclass AbstractGame -and override the abstract methods. +# Now to create concrete (non-abstract) games, you subclass AbstractGame +# and override the abstract methods. class Chess(AbstractGame): def initializeGame(self): # Put the pieces on the board. - ... + pass def makePlay(player): # Process a turn for the player - ... + pass +# --------- Alex's Martelli example --------- + +class AbstractBase(object): + def orgMethod(self): + self.doThis() + self.doThat() + +class Concrete(AbstractBase): + def doThis(self): + pass + def doThat(self): + pass diff --git a/visitor.py b/visitor.py index cf715ae..c1447b2 100644 --- a/visitor.py +++ b/visitor.py @@ -21,13 +21,14 @@ def visit(self, node): def visit(self, node): print "push %d" % node.props['value'] ->>> CodeGeneratingVisitor().visit(tree) -push 1 -print -push 2 -push 4 -push 3 -multiply -plus -print - +sometree = None +CodeGeneratorVisitor().visit(sometree) +# Output: +# push 1 +# print +# push 2 +# push 4 +# push 3 +# multiply +# plus +# print diff --git a/wrapper.py b/wrapper.py index 01f825f..47a6b35 100644 --- a/wrapper.py +++ b/wrapper.py @@ -5,5 +5,4 @@ def __init__(self, w, block): def __getattr__(self, n): if n in self._block: raise AttributeError, n - return getattr(self._w, n) - + return getattr(self._w, n)