├── README.md
├── Section 2
├── singleton_modules
│ ├── a_single_var.py
│ ├── mod2.py
│ └── mod1.py
├── borg.py
├── singleton.py
├── prototype.py
├── factory.py
├── abstract_factory.py
└── builder.py
├── Section 1
├── 01_03
│ ├── iterators.py
│ ├── generator.py
│ ├── list_comp.py
│ └── timer_wrapper.py
└── 01_04
│ ├── multiple_inheritance.py
│ └── inheritance.py
├── Section 3
├── 03_03
│ ├── __pycache__
│ │ ├── proxy_1.cpython-36.pyc
│ │ └── proxy_2.cpython-36.pyc
│ ├── proxy_2.py
│ └── proxy_1.py
├── 03_01
│ ├── example_page.html
│ └── mvc.py
├── decorator.py
├── facade.py
└── adapter.py
├── Section 5
├── reactive.py
├── memento.py
├── template.py
├── observer.py
└── strategy.py
├── Section 4
├── state.py
├── interpreter.py
├── chain.py
└── command.py
├── LICENSE
└── Section 6
└── spaghetti.py
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | # Python-Design-Patterns
--------------------------------------------------------------------------------
/Section 2/singleton_modules/a_single_var.py:
--------------------------------------------------------------------------------
1 | only_one = "I'm the only one"
2 |
--------------------------------------------------------------------------------
/Section 2/singleton_modules/mod2.py:
--------------------------------------------------------------------------------
1 | from singleton_modules import a_single_var
2 |
3 | print(a_single_var.only_one)
4 |
--------------------------------------------------------------------------------
/Section 1/01_03/iterators.py:
--------------------------------------------------------------------------------
1 | list = [1,2,3]
2 | for i in list:
3 | print(i)
4 | iter = list.__iter
5 | iter.__next__()
6 |
--------------------------------------------------------------------------------
/Section 2/borg.py:
--------------------------------------------------------------------------------
1 | class Borg:
2 | __shared_state = {}
3 | def __init__(self):
4 | self.__dict__ = self.__shared_state
5 |
--------------------------------------------------------------------------------
/Section 2/singleton_modules/mod1.py:
--------------------------------------------------------------------------------
1 | from singleton_modules import a_single_var
2 |
3 | print(a_single_var.only_one)
4 | a_single_var.only_one += ' modified'
5 |
--------------------------------------------------------------------------------
/Section 3/03_03/__pycache__/proxy_1.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Python-Design-Patterns/HEAD/Section 3/03_03/__pycache__/proxy_1.cpython-36.pyc
--------------------------------------------------------------------------------
/Section 3/03_03/__pycache__/proxy_2.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Python-Design-Patterns/HEAD/Section 3/03_03/__pycache__/proxy_2.cpython-36.pyc
--------------------------------------------------------------------------------
/Section 1/01_03/generator.py:
--------------------------------------------------------------------------------
1 | def fib_list(max):
2 | numbers = []
3 | a, b = 0, 1
4 | while a < max:
5 | numbers.append(a)
6 | a, b = b, a + b
7 | return numbers
8 |
--------------------------------------------------------------------------------
/Section 3/03_01/example_page.html:
--------------------------------------------------------------------------------
1 | {% for entry in entries %}
2 |
3 | {{ entry.title }}
4 | {{ entry.text|safe }}
5 |
6 | {% else %}
7 | No entries yet.
8 | {% endfor %}
9 |
--------------------------------------------------------------------------------
/Section 1/01_03/list_comp.py:
--------------------------------------------------------------------------------
1 | numbers = [1,2,3,4,5]
2 | numbers_again = [n for n in numbers]
3 | even_numbers = [n for n in numbers if n%2 == 0]
4 | odd_squares = [n**2 for n in numbers if n%2 == 1]
5 | matrix = [[1,2,3], [4,5,6], [7,8,9]]
6 | flattened_matrix = [n for row in x for n in row]
7 |
--------------------------------------------------------------------------------
/Section 2/singleton.py:
--------------------------------------------------------------------------------
1 | class Singleton:
2 | __instance = None
3 | def __new__(cls, val=None):
4 | if Singleton.__instance is None:
5 | Singleton.__instance = object.__new__(cls)
6 | Singleton.__instance.val = val
7 | return Singleton.__instance
8 |
--------------------------------------------------------------------------------
/Section 5/reactive.py:
--------------------------------------------------------------------------------
1 | from rx import Observer
2 |
3 | class MyObserver(Observer):
4 | def on_next(self, x):
5 | print("Got: %s" % x)
6 |
7 | def on_error(self, e):
8 | print("Got error: %s" % e)
9 |
10 | def on_completed(self):
11 | print("Sequence completed")
12 |
--------------------------------------------------------------------------------
/Section 3/03_01/mvc.py:
--------------------------------------------------------------------------------
1 | @app.route('/')
2 | def example_page():
3 | """Searches the database for entries, then displays them."""
4 | db = get_db()
5 | query = db.execute('select * from entries order by id desc')
6 | entries = query.fetchall()
7 | return render_template('example_page.html', entries=entries)
8 |
--------------------------------------------------------------------------------
/Section 1/01_04/multiple_inheritance.py:
--------------------------------------------------------------------------------
1 | class A(object):
2 | def __init__(self):
3 | print('A')
4 |
5 | @staticmethod
6 | def foo():
7 | print('foo')
8 |
9 | class B(object):
10 | def __init__(self):
11 | print('B')
12 |
13 | @staticmethod
14 | def bar():
15 | print('bar')
16 |
17 | class C(A,B):
18 | def foobar(self):
19 | self.foo()
20 | self.bar()
21 |
--------------------------------------------------------------------------------
/Section 2/prototype.py:
--------------------------------------------------------------------------------
1 | from copy import deepcopy
2 |
3 | class Point:
4 | def __init__(self, x, y):
5 | self.x = x
6 | self.y = y
7 |
8 | def __str__(self):
9 | print("({}, {})".format(self.x, self.y))
10 |
11 | def move(self, x, y):
12 | self.x += x
13 | self.y += y
14 |
15 | def clone(self, move_x, move_y):
16 | obj = deepcopy(self)
17 | obj.move(move_x, move_y)
18 |
19 | return obj
20 |
--------------------------------------------------------------------------------
/Section 1/01_03/timer_wrapper.py:
--------------------------------------------------------------------------------
1 | import time
2 |
3 | def timing_function(some_function):
4 | def wrapper():
5 | t1 = time.time()
6 | some_function()
7 | t2 = time.time()
8 | print("Time it took to run the function: " + str((t2 - t1)) + "\n")
9 | return wrapper
10 |
11 | @timing_function
12 | def my_function():
13 | num_list = []
14 | for num in (range(0, 10000)):
15 | num_list.append(num)
16 | print("\nSum of all the numbers: " + str((sum(num_list))))
17 |
--------------------------------------------------------------------------------
/Section 2/factory.py:
--------------------------------------------------------------------------------
1 | class ShapeInterface:
2 | def draw(self): pass
3 |
4 |
5 | class Circle(ShapeInterface):
6 | def draw(self):
7 | print("Circle.draw")
8 |
9 |
10 | class Square(ShapeInterface):
11 | def draw(self):
12 | print("Square.draw")
13 |
14 |
15 | class ShapeFactory:
16 | @staticmethod
17 | def getShape(type):
18 | if type == 'Cirle':
19 | return Circle()
20 | if type == 'Square':
21 | return Square()
22 | assert 0, "Could not find shape " + type
23 |
--------------------------------------------------------------------------------
/Section 3/03_03/proxy_2.py:
--------------------------------------------------------------------------------
1 | class Blog:
2 | def read(self):
3 | print('Read the blog')
4 |
5 | def write(self):
6 | print('Write the blog')
7 |
8 | class Proxy:
9 | def __init__(self, target):
10 | self.target = target
11 |
12 | def __getattr__(self, attr):
13 | return getattr(self.target, attr)
14 |
15 | class AnonUserBlogProxy(Proxy):
16 | def __init__(self, blog):
17 | super().__init__(blog)
18 | def write(self):
19 | print('Only authorized users can write blog posts.')
20 |
--------------------------------------------------------------------------------
/Section 1/01_04/inheritance.py:
--------------------------------------------------------------------------------
1 | class Pet(object):
2 | """Base class for all pets"""
3 | def __init__(self, name, species):
4 | self.name = name
5 | self.species = species
6 |
7 | def getName(self):
8 | return self.name
9 |
10 | def getSpecies(self):
11 | return self.species
12 |
13 | def __str__(self):
14 | return "%s is a %s" % (self.name, self.species)
15 |
16 | class Dog(Pet):
17 |
18 | def __init__(self, name, chases_cats):
19 | super().__init__(name, "Dog")
20 | self.chases_cats = chases_cats
21 |
22 | def chasesCats(self):
23 | return self.chases_cats
24 |
25 | def __str__(self):
26 | additional_info = ""
27 | if self.chases_cats:
28 | additional_info = " who chases cats"
29 | return super().__str__() + additional_info
30 |
--------------------------------------------------------------------------------
/Section 5/memento.py:
--------------------------------------------------------------------------------
1 | import copy
2 |
3 | class Memento:
4 |
5 | def __init__(self, data):
6 | # make a deep copy of every variable in the given class
7 | for attribute in vars(data):
8 | setattr(self, attribute, copy.deepcopy(getattr(data, attribute)))
9 |
10 |
11 | class Undoable:
12 |
13 | def __init__(self):
14 | # each instance keeps the latest saved copy so that there is only one
15 | # copy of each in memory
16 | self.__last = None
17 |
18 | def save(self):
19 | self.__last = Memento(self)
20 |
21 | def undo(self):
22 | for attribute in vars(self):
23 | setattr(self, attribute, getattr(self.__last, attribute))
24 |
25 |
26 | class Data(Undoable):
27 |
28 | def __init__(self):
29 | super(Data, self).__init__()
30 | self.numbers = []
31 |
--------------------------------------------------------------------------------
/Section 3/03_03/proxy_1.py:
--------------------------------------------------------------------------------
1 | class SubjectInterface:
2 | """
3 | Define the common interface for RealSubject and Proxy so that a
4 | Proxy can be used anywhere a RealSubject is expected.
5 | """
6 | def request(self): pass
7 |
8 |
9 | class Proxy(SubjectInterface):
10 | """
11 | Maintain a reference that lets the proxy access the real subject.
12 | Provide an interface identical to Subject's.
13 | """
14 |
15 | def __init__(self, real_subject):
16 | self._real_subject = real_subject
17 |
18 | def request(self):
19 | print("Proxy may be doing something, like controlling request access")
20 | self._real_subject.request()
21 |
22 |
23 | class RealSubject(SubjectInterface):
24 | """
25 | Define the real object that the proxy represents.
26 | """
27 |
28 | def request(self):
29 | print("The real thing is dealing with the request")
30 |
--------------------------------------------------------------------------------
/Section 5/template.py:
--------------------------------------------------------------------------------
1 | class MakeMeal:
2 |
3 | def buy_ingredients(self, money):
4 | if money < self.cost:
5 | assert 0, 'Not enough money to buy ingredients!'
6 |
7 | def prepare(self):
8 | pass
9 |
10 | def cook(self):
11 | pass
12 |
13 | def go(self, money):
14 | self.buy_ingredients(money)
15 | self.prepare()
16 | self.cook()
17 |
18 | class MakePizza(MakeMeal):
19 | def __init__(self):
20 | self.cost = 3
21 |
22 | def prepare(self):
23 | print("Prepare Pizza - make the dough and add toppings")
24 |
25 | def cook(self):
26 | print("Cook Pizza - cook in the oven on gas mark 8 for 10 minutes")
27 |
28 | class MakeCake(MakeMeal):
29 | def __init__(self):
30 | self.cost = 2
31 |
32 | def prepare(self):
33 | print("Prepare Cake - mix ingredients together and pour into a cake tin")
34 |
35 | def cook(self):
36 | print("Cook Cake - bake in the oven on gas mark 6 for 20 minutes")
37 |
--------------------------------------------------------------------------------
/Section 4/state.py:
--------------------------------------------------------------------------------
1 | # Base state class
2 | class ComputerState:
3 | name = "state"
4 | allowed = []
5 |
6 | def switch(self, state):
7 | """ Switch to new state """
8 | if state.name in self.allowed:
9 | print ('Current:', self ,' => switched to new state', state.name)
10 | self.__class__ = state
11 | else:
12 | print('Current:', self ,' => switching to', state.name, 'not possible.')
13 |
14 | def __str__(self):
15 | return self.name
16 |
17 | class Off(ComputerState):
18 | name = "off"
19 | allowed = ['on']
20 |
21 | class On(ComputerState):
22 | name = "on"
23 | allowed = ['off','suspend','hibernate']
24 |
25 | class Suspend(ComputerState):
26 | name = "suspend"
27 | allowed = ['on']
28 |
29 | class Hibernate(ComputerState):
30 | name = "hibernate"
31 | allowed = ['on']
32 |
33 | class Computer:
34 | def __init__(self):
35 | self.state = Off()
36 |
37 | def change(self, state):
38 | self.state.switch(state)
39 |
--------------------------------------------------------------------------------
/Section 5/observer.py:
--------------------------------------------------------------------------------
1 | class Observable:
2 |
3 | def __init__(self):
4 | self.observers = []
5 |
6 | def register(self, observer):
7 | if not observer in self.observers:
8 | self.observers.append(observer)
9 |
10 | def unregister(self, observer):
11 | if observer in self.observers:
12 | self.observers.remove(observer)
13 |
14 | def unregister_all(self):
15 | if self.observers:
16 | del self.observers[:]
17 |
18 | def update_observers(self, *args, **kwargs):
19 | for observer in self.observers:
20 | observer.update(*args, **kwargs)
21 |
22 |
23 | class Observer:
24 | def update(self, *args, **kwargs):
25 | pass
26 |
27 |
28 | class AmericanStockMarket(Observer):
29 | def update(self, *args, **kwargs):
30 | print("American stock market received: {0}\n{1}".format(args, kwargs))
31 |
32 |
33 | class EuropeanStockMarket(Observer):
34 | def update(self, *args, **kwargs):
35 | print("European stock market received: {0}\n{1}".format(args, kwargs))
36 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Packt
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Section 4/interpreter.py:
--------------------------------------------------------------------------------
1 | class Expression:
2 | def interpret(self, text): pass
3 |
4 |
5 | class TerminalExpression(Expression):
6 | def __init__(self, word):
7 | self.word = word
8 |
9 | def interpret(self, text):
10 | words = text.split()
11 | if self.word in text:
12 | return True
13 | else:
14 | return False
15 |
16 |
17 | class OrExpression(Expression):
18 | def __init__(self, exp1, exp2):
19 | self.exp1 = exp1
20 | self.exp2 = exp2
21 |
22 | def interpret(self, text):
23 | return self.exp1.interpret(text) or self.exp2.interpret(text)
24 |
25 |
26 | class AndExpression(Expression):
27 | def __init__(self, exp1, exp2):
28 | self.exp1 = exp1
29 | self.exp2 = exp2
30 |
31 | def interpret(self, text):
32 | return self.exp1.interpret(text) and self.exp2.interpret(text)
33 |
34 |
35 | john = TerminalExpression('John')
36 | henry = TerminalExpression('Henry')
37 | mary = TerminalExpression('Mary')
38 | sarah = TerminalExpression('Sarah')
39 |
40 | # construct the rule sarah and (mary or (john and henry))
41 |
--------------------------------------------------------------------------------
/Section 3/decorator.py:
--------------------------------------------------------------------------------
1 | class WindowInterface:
2 | def build(self): pass
3 |
4 |
5 | class AbstractWindowDecorator(WindowInterface):
6 | """
7 | Maintain a reference to a Window object and define an interface
8 | that conforms to Window's interface.
9 | """
10 |
11 | def __init__(self, window):
12 | self._window = window
13 |
14 | def build(self): pass
15 |
16 |
17 | class Window(WindowInterface):
18 | def build(self):
19 | print("Building window")
20 |
21 |
22 | class BorderDecorator(AbstractWindowDecorator):
23 | def add_border(self):
24 | print("Adding border")
25 |
26 | def build(self):
27 | self.add_border()
28 | self._window.build()
29 |
30 |
31 | class VerticalSBDecorator(AbstractWindowDecorator):
32 | def add_vertical_scroll_bar(self):
33 | print("Adding vertical scroll bar")
34 |
35 | def build(self):
36 | self.add_vertical_scroll_bar()
37 | self._window.build()
38 |
39 |
40 | class HorizontalSBDecorator(AbstractWindowDecorator):
41 | def add_horizontal_scroll_bar(self):
42 | print("Adding horizontal scroll bar")
43 |
44 | def build(self):
45 | self.add_horizontal_scroll_bar()
46 | self._window.build()
47 |
--------------------------------------------------------------------------------
/Section 3/facade.py:
--------------------------------------------------------------------------------
1 | class Engine:
2 |
3 | def __init__(self):
4 | # how much the motor is spinning in revs per minute
5 | self.spin = 0
6 |
7 | def start(self, spin):
8 | self.spin = min(spin, 3000)
9 |
10 | class StarterMotor:
11 |
12 | def __init__(self):
13 | # how much the starter motor is spinning in revs per minute
14 | self.spin = 0
15 |
16 | def start(self, charge):
17 | # if there is enough power then spin fast
18 | if (charge > 50):
19 | self.spin = 2500
20 |
21 | class Battery:
22 |
23 | def __init__(self):
24 | # % charged, starts flat
25 | self.charge = 0
26 |
27 | class Car:
28 | # the facade object that deals with the battery, engine and starter motor.
29 |
30 | def __init__(self):
31 | self.battery = Battery()
32 | self.starter = StarterMotor()
33 | self.engine = Engine()
34 |
35 | def turn_key(self):
36 | self.starter.start(self.battery.charge)
37 | self.engine.start(self.starter.spin)
38 | if (self.engine.spin > 0):
39 | print('Engine started')
40 | else:
41 | print('Engine not started')
42 |
43 | def jump(self):
44 | self.battery.charge = 100
45 | print('Jumped')
46 |
--------------------------------------------------------------------------------
/Section 4/chain.py:
--------------------------------------------------------------------------------
1 | class Car:
2 | def __init__(self, name, water, fuel, oil):
3 | self.name = name
4 | self.water = water
5 | self.fuel = fuel
6 | self.oil = oil
7 |
8 | def is_fine(self):
9 | if self.water >= 20 and self.fuel >= 5 and self.oil >= 10:
10 | print('Car is good to go')
11 | return True
12 | else:
13 | return False
14 |
15 |
16 | class Handler:
17 | def __init__(self, successor=None):
18 | self._successor = successor
19 |
20 | def handle_request(self, car):
21 | if not car.is_fine() and self._successor is not None:
22 | self._successor.handle_request(car)
23 |
24 |
25 | class WaterHandler(Handler):
26 |
27 | def handle_request(self, car):
28 | if car.water < 20:
29 | car.water = 100
30 | print('Added water')
31 | super().handle_request(car)
32 |
33 |
34 | class FuelHandler(Handler):
35 |
36 | def handle_request(self, car):
37 | if car.fuel < 5:
38 | car.fuel = 100
39 | print('Added fuel')
40 | super().handle_request(car)
41 |
42 |
43 | class OilHandler(Handler):
44 |
45 | def handle_request(self, car):
46 | if car.oil < 10:
47 | car.oil = 100
48 | print('Added oil')
49 | super().handle_request(car)
50 |
--------------------------------------------------------------------------------
/Section 2/abstract_factory.py:
--------------------------------------------------------------------------------
1 | # === abstract shape classes ===
2 | class Shape2DInterface:
3 | def draw(self): pass
4 |
5 | class Shape3DInterface:
6 | def build(self): pass
7 |
8 | # === concrete shape classes ===
9 | class Circle(Shape2DInterface):
10 | def draw(self):
11 | print("Circle.draw")
12 |
13 | class Square(Shape2DInterface):
14 | def draw(self):
15 | print("Square.draw")
16 |
17 | class Sphere(Shape3DInterface):
18 | def build(self):
19 | print("Sphere.build")
20 |
21 | class Cube(Shape3DInterface):
22 | def build(self):
23 | print("Cube.build")
24 |
25 |
26 | # === Abstract shape factory ===
27 | class ShapeFactoryInterface:
28 | def getShape(sides): pass
29 |
30 | # === Concrete shape factories ===
31 | class Shape2DFactory(ShapeFactoryInterface):
32 | @staticmethod
33 | def getShape(sides):
34 | if sides == 1:
35 | return Circle()
36 | if sides == 4:
37 | return Square()
38 | assert 0, "Bad 2D shape creation: shape not defined for " + sides + "sides"
39 |
40 | class Shape3DFactory(ShapeFactoryInterface):
41 | @staticmethod
42 | def getShape(sides):
43 | """here, sides refers to the number of faces"""
44 | if sides == 1:
45 | return Sphere()
46 | if sides == 6:
47 | return Cube()
48 | assert 0, "Bad 3D shape creation: shape not defined for " + sides + "faces"
49 |
--------------------------------------------------------------------------------
/Section 3/adapter.py:
--------------------------------------------------------------------------------
1 | # Adaptee (source) interface
2 | class EuropeanSocketInterface:
3 | def voltage(self): pass
4 | def live(self): pass
5 | def neutral(self): pass
6 | def earth(self): pass
7 |
8 | # Target interface
9 | class USASocketInterface:
10 | def voltage(self): pass
11 | def live(self): pass
12 | def neutral(self): pass
13 |
14 | # Adaptee
15 | class EuropeanSocket(EuropeanSocketInterface):
16 | def voltage(self):
17 | return 230
18 |
19 | def live(self):
20 | return 1
21 |
22 | def neutral(self):
23 | return -1
24 |
25 | def earth(self):
26 | return 0
27 |
28 | # Client
29 | class AmericanKettle:
30 | __power = None
31 |
32 | def __init__(self, power):
33 | self.__power = power
34 |
35 | def boil(self):
36 | if self.__power.voltage() > 110:
37 | print("Kettle on fire!")
38 | else:
39 | if self.__power.live() == 1 and self.__power.neutral() == -1:
40 | print("Coffee time!")
41 | else:
42 | print("No power.")
43 |
44 | class Adapter(USASocketInterface):
45 | __socket = None
46 |
47 | def __init__(self, socket):
48 | self.__socket = socket
49 |
50 | def voltage(self):
51 | return 110
52 |
53 | def live(self):
54 | return self.__socket.live()
55 |
56 | def neutral(self):
57 | return self.__socket.neutral()
58 |
--------------------------------------------------------------------------------
/Section 6/spaghetti.py:
--------------------------------------------------------------------------------
1 | import random
2 |
3 | def play_blackjack(draw_if_less_than):
4 |
5 | deck = []
6 | hand = []
7 | dealer = []
8 | handTotal = 0
9 | handDealer = 0
10 |
11 | # Create single-digit cards
12 | for i in range(2, 10):
13 | a = i
14 | deck.append(a)
15 |
16 | # Create 10 cards
17 | count_1 = 16
18 | while count_1 > 0:
19 | deck.append(10)
20 | count_1 -= 1
21 |
22 | # Create aces
23 | count_2 = 4
24 | while count_2 > 0:
25 | deck.append(11)
26 | count_2 -= 1
27 |
28 | # Set up 2 hand for yourself
29 | while len(hand) < 2:
30 | drawCard = random.choice(deck)
31 | hand.append(drawCard)
32 | deck.remove(drawCard)
33 | handTotal += drawCard
34 |
35 | # Set up 2 hand for the dealer
36 | while len(dealer) < 2:
37 | drawCard = random.choice(deck)
38 | dealer.append(drawCard)
39 | deck.remove(drawCard)
40 | handDealer += drawCard
41 |
42 | # Hit or stand descision
43 | while handTotal < draw_if_less_than:
44 | drawCard = random.choice(deck)
45 | hand.append(drawCard)
46 | deck.remove(drawCard)
47 | handTotal += drawCard
48 | print(hand)
49 |
50 | # Dealer moves
51 | while handDealer <= 17:
52 | drawCard = random.choice(deck)
53 | dealer.append(drawCard)
54 | deck.remove(drawCard)
55 | handDealer += drawCard
56 | print(dealer)
57 |
58 | print(handTotal)
59 | print(handDealer)
60 |
--------------------------------------------------------------------------------
/Section 5/strategy.py:
--------------------------------------------------------------------------------
1 | class PrimeFinder:
2 |
3 | def __init__(self):
4 | self.primes = []
5 |
6 | def calculate(self, limit):
7 | """ Will calculate all the primes below limit. """
8 | pass
9 |
10 | def out(self):
11 | """ Prints the list of primes prefixed with which algorithm made it """
12 | print(self.__class__.__name__)
13 | for prime in self.primes:
14 | print(prime)
15 |
16 |
17 | class HardCodedPrimeFinder(PrimeFinder):
18 | def calculate(self, limit):
19 | hardcoded_primes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47]
20 | primes = []
21 | for prime in hardcoded_primes:
22 | if (prime < limit):
23 | self.primes.append(prime)
24 |
25 |
26 | class StandardPrimeFinder(PrimeFinder):
27 | def calculate(self, limit):
28 | self.primes = [2]
29 | # check only odd numbers.
30 | for number in range(3, limit, 2):
31 | is_prime = True
32 | for prime in self.primes:
33 | if (number % prime == 0):
34 | is_prime = False
35 | break
36 | if (is_prime):
37 | self.primes.append(number)
38 |
39 |
40 | class PrimeFinderClient:
41 |
42 | def __init__(self, limit):
43 | self.limit = limit
44 | if limit <= 50:
45 | self.finder = HardCodedPrimeFinder()
46 | else:
47 | self.finder = StandardPrimeFinder()
48 |
49 | def get_primes(self):
50 | self.finder.calculate(self.limit)
51 | self.finder.out()
52 |
--------------------------------------------------------------------------------
/Section 4/command.py:
--------------------------------------------------------------------------------
1 | class Screen(object):
2 | def __init__(self, text=''):
3 | self.text = text
4 | self.clip_board = ''
5 |
6 | def cut(self, start=0, end=0):
7 | self.clip_board = self.text[start:end]
8 | self.text = self.text[:start] + self.text[end:]
9 |
10 | def paste(self, offset=0):
11 | self.text = self.text[:offset] + self.clip_board + self.text[offset:]
12 |
13 | def clear_clipboard(self):
14 | self.clip_board = ''
15 |
16 | def length(self):
17 | return len(self.text)
18 |
19 | def __str__(self):
20 | return self.text
21 |
22 |
23 | # Screen command interface
24 | class ScreenCommand:
25 | def __init__(self, screen):
26 | self.screen = screen
27 | self.previous_state = screen.text
28 |
29 | def execute(self):
30 | pass
31 |
32 | def undo(self):
33 | pass
34 |
35 |
36 | class CutCommand(ScreenCommand):
37 | def __init__(self, screen, start=0, end=0):
38 | super().__init__(screen)
39 | self.start = start
40 | self.end = end
41 |
42 | def execute(self):
43 | self.screen.cut(start=self.start, end=self.end)
44 |
45 | def undo(self):
46 | self.screen.clear_clipboard()
47 | self.screen.text = self.previous_state
48 |
49 |
50 | class PasteCommand(ScreenCommand):
51 | def __init__(self, screen, offset=0):
52 | super().__init__(screen)
53 | self.offset = offset
54 |
55 | def execute(self):
56 | self.screen.paste(offset=self.offset)
57 |
58 | def undo(self):
59 | self.screen.clear_clipboard()
60 | self.screen.text = self.previous_state
61 |
62 |
63 | class ScreenInvoker:
64 | def __init__(self):
65 | self.history = []
66 |
67 | def store_and_execute(self, command):
68 | command.execute()
69 | self.history.append(command)
70 |
71 | def undo_last(self):
72 | if self.history:
73 | self.history.pop().undo()
74 |
--------------------------------------------------------------------------------
/Section 2/builder.py:
--------------------------------------------------------------------------------
1 | from copy import deepcopy
2 |
3 | class Car:
4 | def __init__(self):
5 | self.__wheels = list()
6 | self.__engine = None
7 | self.__body = None
8 |
9 | def setBody(self, body):
10 | self.__body = body
11 |
12 | def attachWheel(self, wheel):
13 | self.__wheels.append(wheel)
14 |
15 | def setEngine(self, engine):
16 | self.__engine = engine
17 |
18 | def specification(self):
19 | print("body: %s" % self.__body.shape)
20 | print("engine horsepower: %d" % self.__engine.horsepower)
21 | print("tire size: %d\'" % self.__wheels[0].size)
22 |
23 | def clone(self):
24 | return deepcopy(self)
25 |
26 | # === Car parts ===
27 | class Wheel:
28 | size = None
29 |
30 | class Engine:
31 | horsepower = None
32 |
33 | class Body:
34 | shape = None
35 |
36 |
37 | class Director:
38 | __builder = None
39 |
40 | def setBuilder(self, builder):
41 | self.__builder = builder
42 |
43 | # The algorithm for assembling a car
44 | def getCar(self):
45 | car = Car()
46 |
47 | # First goes the body
48 | body = self.__builder.getBody()
49 | car.setBody(body)
50 |
51 | # Then engine
52 | engine = self.__builder.getEngine()
53 | car.setEngine(engine)
54 |
55 | # And four wheels
56 | i = 0
57 | while i < 4:
58 | wheel = self.__builder.getWheel()
59 | car.attachWheel(wheel)
60 | i += 1
61 |
62 | return car
63 |
64 |
65 | class BuilderInterface:
66 | def getWheel(self): pass
67 | def getEngine(self): pass
68 | def getBody(self): pass
69 |
70 |
71 | class JeepBuilder(BuilderInterface):
72 | def getWheel(self):
73 | wheel = Wheel()
74 | wheel.size = 22
75 | return wheel
76 |
77 | def getEngine(self):
78 | engine = Engine()
79 | engine.horsepower = 400
80 | return engine
81 |
82 | def getBody(self):
83 | body = Body()
84 | body.shape = "SUV"
85 | return body
86 |
87 |
88 | class NissanBuilder(BuilderInterface):
89 | def getWheel(self):
90 | wheel = Wheel()
91 | wheel.size = 16
92 | return wheel
93 |
94 | def getEngine(self):
95 | engine = Engine()
96 | engine.horsepower = 100
97 | return engine
98 |
99 | def getBody(self):
100 | body = Body()
101 | body.shape = "hatchback"
102 | return body
103 |
--------------------------------------------------------------------------------