diff --git a/abstrfactory4.py b/abstrfactory4.py new file mode 100644 index 0000000..0f40eb1 --- /dev/null +++ b/abstrfactory4.py @@ -0,0 +1,61 @@ +"""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/closure.py b/closure.py new file mode 100644 index 0000000..bf34f48 --- /dev/null +++ b/closure.py @@ -0,0 +1,15 @@ +def Dx(f, dx): + def dfdx(x): + return (f(x + dx) - f(x))/dx + return dfdx + +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) +""" diff --git a/decorator4.py b/decorator4.py new file mode 100644 index 0000000..c692ffb --- /dev/null +++ b/decorator4.py @@ -0,0 +1,31 @@ +import time + +def time_this(func): + """The time_this decorator""" + + def decorated(*args, **kwargs): + start = time.time() + result = func(*args, **kwargs) + print "Ran in", time.time() – start, "seconds" + return result + return decorated + +# Decorator syntax +@time_this +def count(until): + """Counts to 'until', then returns the result""" + + print "Counting to", until, "…" + num = 0 + for i in xrange(to_num(until)): + num += 1 + return num + +def to_num(numstr): + """Turns a comma-separated number string to an int""" + return int(numstr.replace(",", "")) + +# Run count with various values +for number in ("10,000", "100,000", "1,000,000"): + print count(number) + print "-" * 20 diff --git a/decorators.py b/decorators.py new file mode 100644 index 0000000..e5b01b7 --- /dev/null +++ b/decorators.py @@ -0,0 +1,18 @@ +def notify(f): + def g(self, n): + print n + return f(self, n) + return g + +class Point(object): + def __init__(self, x, y): + self.x = x + self.y = y + + @notify + def scale(self, n): + self.x = n * self.x + self.y = n * self.y + +p = Point(2.0, 3.0) +p.scale(2.5) diff --git a/factory4.py b/factory4.py new file mode 100644 index 0000000..8eec1f5 --- /dev/null +++ b/factory4.py @@ -0,0 +1,35 @@ +#coding: UTF8 + +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/factorymethod.py b/factorymethod.py new file mode 100644 index 0000000..354bcde --- /dev/null +++ b/factorymethod.py @@ -0,0 +1,15 @@ +class A(object): + def __init__(self): + self.a = "Hello" + +class B(object): + def __init__(self): + self.a = " World" + myfactory = { + "greeting" : A, + "subject" : B, + } + +>>> print myfactory["greeting"]().a +Hello + diff --git a/flyweight.py b/flyweight.py new file mode 100644 index 0000000..981718d --- /dev/null +++ b/flyweight.py @@ -0,0 +1,51 @@ +""" +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). +""" + +class ComplexGenetics(object): + """ 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 """ + family = {} + def __new__(cls, name, family_id): + """ i have to capture the details before the class is created, __init__ is pseudo constructor """ + try: + id = cls.family[family_id] + except KeyError: + id = object.__new__(cls) + cls.family[family_id] = id + return id + + def set_genetic_info(self, genetic_info): + cg = ComplexGenetics() + self.genetic_info = cg.genes(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: + obj = Families(i[0], i[1]) + obj.set_genetic_info(i[2]) + family_objects.append(obj) + + for i in family_objects: + print "id = " + str(id(i)) + print i.get_genetic_info() + print "similar id's says that they are same objects " + +if __name__ == '__main__': + test() diff --git a/iterator4.py b/iterator4.py new file mode 100644 index 0000000..be69fc3 --- /dev/null +++ b/iterator4.py @@ -0,0 +1,21 @@ +"""Implementation of the iterator pattern with a generator""" + +def count_to(count): + """Counts by word numbers, up to a maximum of five""" + + numbers = ["one", "two", "three", "four", "five"] + # The zip keeps from counting over the limit + for number, pos in zip(numbers, range(count)): + yield number + +# Test the generator +count_to_two = lambda : count_to(2) +count_to_five = lambda : count_to(5) + +print "Counting to two…" +for number in count_to_two(): + print number, +print "\n" +print "Counting to five…" +for number in count_to_five(): + print number, diff --git a/observer3.py b/observer3.py new file mode 100644 index 0000000..f54e0fa --- /dev/null +++ b/observer3.py @@ -0,0 +1,18 @@ +class Point(object): + def __init__(self, x, y): + self.x = x + self.y = y + + def scale(self, n): + self.x = n * self.x + self.y = n * self.y + +def notify(f): + def g(self, n): + print n + return f(self, n) + return g + +Point.scale = notify(Point.scale) +p = Point(2.0, 3.0) +p.scale(2.5) diff --git a/state4.py b/state4.py new file mode 100644 index 0000000..7e3a9f0 --- /dev/null +++ b/state4.py @@ -0,0 +1,56 @@ +"""Implementation of the state pattern""" + +class State(object): + """Base state. This is to share functionality""" + + def scan(self): + """Scan the dial to the next station""" + self.pos += 1 + if self.pos == len(self.stations): + self.pos = 0 + print "Scanning… Station is", self.stations[self.pos], self.name + +class AmState(State): + def __init__(self, radio): + self.radio = radio + self.stations = ["1250", "1380", "1510"] + self.pos = 0 + self.name = "AM" + + def toggle_amfm(self): + print "Switching to FM" + self.radio.state = self.radio.fmstate + +class FmState(State): + def __init__(self, radio): + self.radio = radio + self.stations = ["81.3", "89.1", "103.9"] + self.pos = 0 + self.name = "FM" + + def toggle_amfm(self): + print "Switching to AM" + self.radio.state = self.radio.amstate + +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""" + + self.amstate = AmState(self) + self.fmstate = FmState(self) + self.state = self.amstate + + def toggle_amfm(self): + self.state.toggle_amfm() + def scan(self): + self.state.scan() + +# Test our radio out +radio = Radio() +actions = [radio.scan] * 2 + [radio.toggle_amfm] + [radio.scan] * 2 +actions = actions * 2 +for action in actions: + action() diff --git a/strategy3.py b/strategy3.py new file mode 100644 index 0000000..f846f20 --- /dev/null +++ b/strategy3.py @@ -0,0 +1,13 @@ +def bisection(line): + return 5.5, 6.6 + +def conjugate_gradient(line): + return 3.3, 4.4 + +def test(): + solver = conjugate_gradient + print solver((5.5,5.5)) + solver = bisection + print solver((5.5,5.5)) +test() + diff --git a/testing4.py b/testing4.py new file mode 100644 index 0000000..89ffb4a --- /dev/null +++ b/testing4.py @@ -0,0 +1,47 @@ +"""An example of the Template pattern in Python""" + +# Skeletons +def iter_elements(getter, action): + """Template skeleton that iterates items""" + + for element in getter(): + action(element) + print "-" * 10 + +def rev_elements(getter, action): + """Template skeleton that iterates items in reverse order""" + + for element in getter()[::-1]: + action(element) + print "-" * 10 + +# Getters +def get_list(): + return "spam eggs".split() + +def get_lists(): + return [list(x) for x in "spam eggs".split()] + +# Actions +def print_item(item): + print item + +def reverse_item(item): + print item[::-1] + +# Makes templates +def make_template(skeleton, getter, action): + """Instantiate a template method with getter and action""" + def template(): + skeleton(getter, action) + return template + +# Create our template functions +templates = [make_template(s, g, a) + for g in (get_list, get_lists) + for a in (print_item, reverse_item) + for s in (iter_elements, rev_elements)] + +# Execute them +for template in templates: + template()