Observer Pattern

import abc
class Observer(abc.ABC):
@abc.abstractmethod
def update(self, lon, lat):
pass

class MobileApp(Observer):
def update(self, lon=0.0, lat=0.0):
print(f"{lon} : {lat}")

class MobilePhone:
lon, lat = 0.0, 0.0
observers = []

def move(cls, lon, lat):
if cls.lon == lon and cls.lat == lat:
return
cls.lon, cls.lat = lon, lat
cls.notify()

def register(cls, o):
cls.observers.append(o)

def notify(cls):
for observer in cls.observers:
observer.update(cls.lon, cls.lat)

phone = MobilePhone()

phone.register(MobileApp())
phone.move(1.0, 1.2)
phone.move(1.1, 21.2)
phone.move(1.2, 93)
phone.move(333.0, 144.2)
class Sub:
def __init__(self, name):
self.name = name
def update(self, message):
print(f"Notification for {self.name} : {message}")

class Pub:
def __init__(self):
self.subs = set()

def register(self,sub):
self.subs.add(sub)

def unregister(self, sub):
self.subs.discard(sub)

def notify(self, message):
for sub in self.subs:
sub.update(message)

sub_list = [Sub("changpil@gmail.com"), Sub("clee@suse.com"),Sub("chalee@microsoft.com")]
pub = Pub()
for sub in sub_list:
pub.register(sub)

pub.notify("greeting")
import abc
class Observer(abc.ABC):
@abc.abstractmethod
def update(self, floor):
pass


class Button:
def __init__(self, name):
self.name = name
self.on = None
self.observers = []

def request(self):
if not self.on:
self.notify()
self.on = True
print("Button activated")

def off(self):
self.on = False
print("Button deactivated")

def register(self, observer):
self.observers.append(observer)

def notify(self):
for observer in self.observers:
observer.update(self.name)


class Door():
def open(self):
self.status = "door opened"

def close(self):
self.status = "door close"




class Floor(Observer):
def __init__(self, floor):
self.floor = floor
self.door = Door()
self.upButton = Button("up")
self.downButton = Button("down")
self.upButton.register(self)
self.downButton.register(self)
self.uprequest = False
self.downrequest = False

def update(self, name):
if name == "up":
self.uprequest = True
elif name == "down":
self.downrequest = True

def requestUp(self):
self.upButton.request()

def requestDown(self):
self.downButton.request()

def opendoor(self):
self.door.open()

def closedoor(self):
self.door.close()

groundfloor = Floor(0)
groundfloor.requestUp()
print(groundfloor.uprequest)

Command Pattern

# Command Pattern is good for batch processes with behavioral class

class Document:
text = ""
def __str__(self):
return self.text

import abc
class DocumentCommand(abc.ABC):
doc = None
@abc.abstractmethod
def execute(self):
pass
@abc.abstractmethod
def undo(self):
pass

class AddStrCommand(DocumentCommand):
def __init__(self, doc, txt):
self.text = txt
self.doc = doc
def execute(self):
self.doc.text += self.text
return self.doc
def undo(self):
return DeleteStrCommand(self.doc, self.text).execute()


class DeleteStrCommand(DocumentCommand):
def __init__(self, doc, txt):
self.text = txt
self.doc = doc
def execute(self):
idx = self.doc.text.find(self.text)
if idx == -1:
return self.doc
self.doc.text = self.doc.text[:idx]
return self.doc
def undo(self):
return AddStrCommand(self.doc, self.text).execute()

doc = Document()
editingTexts = [AddStrCommand(doc,"hello\n"), AddStrCommand(doc,"My name is Chang\n"), AddStrCommand(doc,"I hope you have a good day")]
for c in editingTexts:
c.execute()

print(doc)
print(editingTexts[-1].undo())
print(editingTexts[-1].undo())
d = DeleteStrCommand(doc,"My name is Chang\n")
print(d.execute())
print(d.undo())
print(doc)
import abc
class Order(abc.ABC):
@abc.abstractmethod
def execute(self):
pass

class Stock:
def __init__(self, name):
self.name = name

def buy(self):
print(f"Stock {self.name} bought", end=" ")

def sell(self):
print(f"Stock {self.name} sold", end=" ")

class BuyStock(Order):
def __init__(self, stock, quantity):
self.stock = stock
self.quantity = quantity

def execute(self):
self.stock.buy()
print(f"{self.quantity}")

class SellStock(Order):
def __init__(self, stock, quantity):
self.stock = stock
self.quantity = quantity

def execute(self):
self.stock.sell()
print(f"{self.quantity}")

class Broker:
def __init__(self, name):
self.name = name
self.orderList = []

def addOrder(self, order):
self.orderList.append(order)

def placeOrders(self):
for o in self.orderList:
o.execute()

broker = Broker("Fidelity")
amazonStock = Stock("Amazon")
buy1 = BuyStock(amazonStock, 10)
sell1 =SellStock(amazonStock, 5)
broker.addOrder(buy1)
broker.addOrder(sell1)

pltrStock = Stock("PLTR")
buy2 = BuyStock(pltrStock, 100)
sell2 =SellStock(pltrStock, 9)

broker.addOrder(buy2)
broker.addOrder(sell2)
broker.placeOrders()
class Pet:
def __init__(self, kind, name):
self.kind = kind
self.name = name

class FeedPet:
def __init__(self, pet, food):
self.pet = pet
self.food = food

def execute(self):
print(f"{self.pet.kind}, {self.pet.name} eats {self.food}")

class WalkPet:
def __init__(self, pet, place):
self.pet = pet
self.place = place

def execute(self):
print(f"{self.pet.name} eats {self.place}")

class PlayPet:
def __init__(self, pet, min):
self.pet = pet
self.min = min

def execute(self):
print(f"{self.pet.name} plays for {self.min}")

class AnimalFarm:
def __init__(self, name):
self.name = name
self.todoList = []

def addTodo(self, deed):
self.todoList.append(deed)

def doTodoList(self):
for do in self.todoList:
do.execute()

farm = AnimalFarm("Seattle Animal Farm")
horse = Pet("Horse", "Thunder")
cow = Pet("Cow", "Moo")
cat = Pet("cat", "Muze")
dog = Pet("dog", "Win")

farm.addTodo(FeedPet(horse, "carrot"))
farm.addTodo(PlayPet(horse, "30"))
farm.addTodo(WalkPet(dog, "dog park"))
farm.addTodo(FeedPet(cat, "salmon"))
farm.addTodo(FeedPet(cow, "hay"))

farm.doTodoList()

Composite Pattern

import abc
class IMenu(abc.ABC):
def __init__(self, title):
self.text = title

def traverse(self, prefix):
print(f"{prefix} {self.text}")
if hasattr(self, "components"):
for menu in self.components:
menu.traverse(prefix + prefix)

class Menu(IMenu):
def __init__(self, title):
super().__init__(title)
self.components = list()

def add(self, menu):
self.components.append(menu)

class MenuItem(IMenu):
def __init__(self, title):
super().__init__(title)

class FileMenuItem(MenuItem):
def __init__(self, title, file):
super().__init__(title)
self.file = file
getattr(file, title)()



class File:
def __init__(self, fn):
self.filename = fn
def open(self):
print(f"open {self.filename}")
def save(self):
print(f"save {self.filename}")
def close(self):
print(f"close {self.filename}")




mainMenu = Menu("file")
pyMenu = Menu('python file')
pf = File("python.py")
pyMenu.add(FileMenuItem("open", pf))
pyMenu.add(FileMenuItem("save", pf))
pyMenu.add(FileMenuItem("close", pf))

pdfMenu = Menu('pdf file')
pdf = File("README.pdf")
pdfMenu.add(FileMenuItem("open", pdf))
pdfMenu.add(FileMenuItem("save", pdf))
pdfMenu.add(FileMenuItem("close", pdf))

mainMenu.add(pyMenu)
mainMenu.add(pdfMenu)
mainMenu.add(MenuItem("exit"))
mainMenu.traverse("-")


open python.py
save python.py
close python.py
open README.pdf
save README.pdf
close README.pdf
- file
-- python file
---- open
---- save
---- close
-- pdf file
---- open
---- save
---- close
-- exit