Skip to content

Instantly share code, notes, and snippets.

@270ajay
Created December 3, 2023 09:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 270ajay/e6f6081cf79f7785e9555abe97ab225c to your computer and use it in GitHub Desktop.
Save 270ajay/e6f6081cf79f7785e9555abe97ab225c to your computer and use it in GitHub Desktop.
Design Patterns: Taken from Derek Banas's Design Patterns Playlist on YouTube
from abc import ABC, abstractmethod
class EnemyShipBuilding(ABC):
@abstractmethod
def make_enemy_ship(self, type_of_ship: str) -> "EnemyShip":
pass
def order_the_ship(self, type_of_ship: str) -> "EnemyShip":
the_enemy_ship = self.make_enemy_ship(type_of_ship)
the_enemy_ship.make_ship()
the_enemy_ship.display_enemy_ship()
the_enemy_ship.follow_hero_ship()
the_enemy_ship.enemy_ship_shoots()
return the_enemy_ship
class UFOEnemyShipBuilding(EnemyShipBuilding):
def make_enemy_ship(self, type_of_ship: str) -> "EnemyShip":
if type_of_ship == "UFO":
ship_parts_factory = UFOEnemyShipFactory()
the_enemy_ship = UFOEnemyShip(ship_parts_factory)
the_enemy_ship.name = "UFO Grunt Ship"
elif type_of_ship == "UFO BOSS":
ship_parts_factory = UFOBossEnemyShipFactory()
the_enemy_ship = UFOBossEnemyShip(ship_parts_factory)
the_enemy_ship.name = "UFO Boss Ship"
else:
raise ValueError("type of ship must be UFO or UFO BOSS")
return the_enemy_ship
class ESWeapon(ABC):
@abstractmethod
def __str__(self) -> str:
pass
class ESEngine(ABC):
@abstractmethod
def __str__(self) -> str:
pass
class ESUFOGun(ESWeapon):
def __str__(self) -> str:
return "20 damage"
class ESUFOEngine(ESEngine):
def __str__(self) -> str:
return "1000 mph"
class ESUFOBossGun(ESWeapon):
def __str__(self) -> str:
return "40 damage"
class ESUFOBossEngine(ESEngine):
def __str__(self) -> str:
return "2000 mph"
class EnemyShipFactory(ABC):
@abstractmethod
def add_es_gun(self) -> "ESWeapon":
pass
@abstractmethod
def add_es_engine(self) -> "ESEngine":
pass
class UFOEnemyShipFactory(EnemyShipFactory):
def add_es_gun(self) -> "ESWeapon":
return ESUFOGun()
def add_es_engine(self) -> "ESEngine":
return ESUFOEngine()
class UFOBossEnemyShipFactory(EnemyShipFactory):
def add_es_gun(self) -> "ESWeapon":
return ESUFOBossGun()
def add_es_engine(self) -> "ESEngine":
return ESUFOBossEngine()
class EnemyShip(ABC):
def __init__(self):
self.name: str = ""
self.weapon: ESWeapon = None
self.engine: ESEngine = None
@abstractmethod
def make_ship(self) -> None:
pass
def __str__(self) -> str:
info_on_ship = f"The {self.name} has a top speed of {self.engine} and an attack power of {self.weapon}"
return info_on_ship
def follow_hero_ship(self) -> None:
print(f"{self.name} is following the hero at {self.engine}")
def display_enemy_ship(self) -> None:
print(f"{self.name} is on the screen")
def enemy_ship_shoots(self) -> None:
print(f"{self.name} attacks and does {self.weapon}")
class UFOEnemyShip(EnemyShip):
def __init__(self, ship_factory: EnemyShipFactory):
super().__init__()
self.ship_factory = ship_factory
def make_ship(self) -> None:
print(f"Making enemy ship {self.name}")
self.weapon = self.ship_factory.add_es_gun()
self.engine = self.ship_factory.add_es_engine()
class UFOBossEnemyShip(EnemyShip):
def __init__(self, ship_factory: EnemyShipFactory):
super().__init__()
self.ship_factory = ship_factory
def make_ship(self) -> None:
print(f"Making enemy ship {self.name}")
self.weapon = self.ship_factory.add_es_gun()
self.engine = self.ship_factory.add_es_engine()
class RocketEnemyShip(EnemyShip):
def __init__(self):
super().__init__()
self.name = "Rocket Enemy Ship"
self.amt_damage = 10.0
class BigUFOEnemyShip(UFOEnemyShip):
def __init__(self):
super().__init__()
self.name = "Big UFO Enemy Ship"
self.amt_damage = 40.0
def do_stuff_enemy(an_enemy_ship: EnemyShip) -> None:
an_enemy_ship.display_enemy_ship()
an_enemy_ship.follow_hero_ship()
an_enemy_ship.enemy_ship_shoots()
# Enemy ship factory
def make_enemy_ship(new_ship_type: str) -> EnemyShip:
if new_ship_type == "U":
return UFOEnemyShip()
elif new_ship_type == "R":
return RocketEnemyShip()
elif new_ship_type == "B":
return BigUFOEnemyShip()
else:
raise ValueError("Ship type can be U or R or B only")
if __name__ == "__main__":
make_ufos = UFOEnemyShipBuilding()
the_grunt = make_ufos.order_the_ship("UFO")
print(the_grunt, "\n")
the_boss = make_ufos.order_the_ship("UFO BOSS")
print(the_boss, "\n")
import random
from abc import ABC, abstractmethod
class EnemyAttacker(ABC):
@abstractmethod
def fire_weapon(self) -> None:
pass
@abstractmethod
def drive_forward(self) -> None:
pass
@abstractmethod
def assign_driver(self, driver_name: str) -> None:
pass
class EnemyTank(EnemyAttacker):
def fire_weapon(self) -> None:
attack_damage = random.randint(1, 11)
print(f"Enemy tank does {attack_damage} damage")
def drive_forward(self) -> None:
movement = random.randint(1, 6)
print(f"Enemy tank moves {movement} spaces")
def assign_driver(self, driver_name: str) -> None:
print(f"{driver_name} is driving the tank")
class EnemyRobot:
def smash_with_hands(self) -> None:
attack_damage = random.randint(1, 11)
print(f"Enemy robot cause {attack_damage} damage with its hands")
def walk_forward(self) -> None:
movement = random.randint(1, 6)
print(f"Enemy robot walks forward {movement} spaces")
def react_to_human(self, driver_name: str) -> None:
print(f"Enemy robot tramps on {driver_name}")
class EnemyRobotAdapter(EnemyAttacker):
def __init__(self, new_robot: EnemyRobot):
self.the_robot: EnemyRobot = new_robot
def fire_weapon(self) -> None:
self.the_robot.smash_with_hands()
def drive_forward(self) -> None:
self.the_robot.walk_forward()
def assign_driver(self, driver_name: str) -> None:
self.the_robot.react_to_human(driver_name)
if __name__ == "__main__":
random.seed(10)
rx7_tank = EnemyTank()
fred_the_robot = EnemyRobot()
robot_adapter = EnemyRobotAdapter(fred_the_robot)
print("The Robot")
fred_the_robot.react_to_human("Paul")
fred_the_robot.walk_forward()
fred_the_robot.smash_with_hands()
print()
print("The Enemy Tank")
rx7_tank.assign_driver("Frank")
rx7_tank.drive_forward()
rx7_tank.fire_weapon()
print()
print("The Robot With Adapter")
robot_adapter.assign_driver("Mark")
robot_adapter.drive_forward()
robot_adapter.fire_weapon()
from abc import ABC, abstractmethod
class EntertainmentDevice(ABC):
def __init__(self):
self.device_state: int = 0
self.max_setting: int = 0
self.volume_level: int = 0
@abstractmethod
def button_five_pressed(self) -> None:
pass
@abstractmethod
def button_six_pressed(self) -> None:
pass
def device_feedback(self) -> None:
if self.device_state > self.max_setting or self.device_state < 0:
self.device_state = 0
print("On", self.device_state)
def button_seven_pressed(self) -> None:
self.volume_level += 1
print("Volume at:", self.volume_level)
def button_eight_pressed(self) -> None:
self.volume_level -= 1
print("Volume at:", self.volume_level)
class TVDevice(EntertainmentDevice):
def __init__(self, new_device_state: int, new_max_setting: int):
super().__init__()
self.device_state = new_device_state
self.max_setting = new_max_setting
def button_five_pressed(self) -> None:
print("Channel Down")
self.device_state -= 1
def button_six_pressed(self) -> None:
print("Channel Up")
self.device_state += 1
class RemoteButton(ABC):
def __init__(self, new_entertainment_device: EntertainmentDevice):
self.the_device: EntertainmentDevice = new_entertainment_device
def button_five_pressed(self) -> None:
self.the_device.button_five_pressed()
def button_six_pressed(self) -> None:
self.the_device.button_six_pressed()
def device_feedback(self) -> None:
self.the_device.device_feedback()
@abstractmethod
def button_nine_pressed(self) -> None:
pass
class TVRemoteMute(RemoteButton):
def __init__(self, new_device: EntertainmentDevice):
super().__init__(new_device)
def button_nine_pressed(self) -> None:
print("TV was muted")
class TVRemotePause(RemoteButton):
def __init__(self, new_device: EntertainmentDevice):
super().__init__(new_device)
def button_nine_pressed(self) -> None:
print("TV was paused")
if __name__ == "__main__":
the_tv = TVRemoteMute(TVDevice(1, 200))
the_tv2 = TVRemotePause(TVDevice(1, 200))
print(f"Test TV with mute")
the_tv.button_five_pressed()
the_tv.button_six_pressed()
the_tv.button_nine_pressed()
print(f"\nTest TV with pause")
the_tv2.button_five_pressed()
the_tv2.button_six_pressed()
the_tv2.button_six_pressed()
the_tv2.button_six_pressed()
the_tv2.button_six_pressed()
the_tv2.button_nine_pressed()
the_tv2.device_feedback()
from abc import ABC, abstractmethod
class RobotPlan(ABC):
@abstractmethod
def set_robot_head(self, head: str) -> None:
pass
@abstractmethod
def set_robot_torso(self, torso: str) -> None:
pass
@abstractmethod
def set_robot_arms(self, arms: str) -> None:
pass
@abstractmethod
def set_robot_legs(self, legs: str) -> None:
pass
class Robot(RobotPlan):
def __init__(self):
self.robot_head: str = ""
self.robot_torso: str = ""
self.robot_arms: str = ""
self.robot_legs: str = ""
def set_robot_head(self, head: str) -> None:
self.robot_head = head
def set_robot_torso(self, torso: str) -> None:
self.robot_torso = torso
def set_robot_arms(self, arms: str) -> None:
self.robot_arms = arms
def set_robot_legs(self, legs: str) -> None:
self.robot_legs = legs
class RobotBuilder(ABC):
@abstractmethod
def build_robot_head(self) -> None:
pass
@abstractmethod
def build_robot_torso(self) -> None:
pass
@abstractmethod
def build_robot_arms(self) -> None:
pass
@abstractmethod
def build_robot_legs(self) -> None:
pass
@abstractmethod
def get_robot(self) -> Robot:
pass
class OldRobotBuilder(RobotBuilder):
def __init__(self):
self.robot: Robot = Robot()
def build_robot_head(self) -> None:
self.robot.set_robot_head("Tin Head")
def build_robot_torso(self) -> None:
self.robot.set_robot_torso("Tin Torso")
def build_robot_arms(self) -> None:
self.robot.set_robot_arms("Blowtorch Arms")
def build_robot_legs(self) -> None:
self.robot.set_robot_legs("Roller Skates")
def get_robot(self) -> Robot:
return self.robot
class RobotEngineer:
def __init__(self, robot_builder: RobotBuilder):
self.robot_builder: RobotBuilder = robot_builder
def get_robot(self) -> Robot:
return self.robot_builder.get_robot()
def make_robot(self) -> None:
self.robot_builder.build_robot_head()
self.robot_builder.build_robot_torso()
self.robot_builder.build_robot_arms()
self.robot_builder.build_robot_legs()
if __name__ == "__main__":
old_style_robot = OldRobotBuilder()
robot_engineer = RobotEngineer(old_style_robot)
robot_engineer.make_robot()
first_robot = robot_engineer.get_robot()
print(f"Robot Built")
print(f"Robot Head Type: {first_robot.robot_head}")
print(f"Robot Torso Type: {first_robot.robot_torso}")
print(f"Robot Arm Type: {first_robot.robot_arms}")
print(f"Robot Leg Type: {first_robot.robot_legs}")
from abc import ABC, abstractmethod
class Chain(ABC):
@abstractmethod
def set_next_chain(self, next_chain: "Chain") -> None:
pass
@abstractmethod
def calculate(self, request: "Numbers") -> None:
pass
class Numbers:
def __init__(self, number1: int, number2: int, calc_wanted: str):
self.number1: int = number1
self.number2: int = number2
self.calculation_wanted: str = calc_wanted
class AddNumbers(Chain):
def __init__(self):
self.next_in_chain: Chain = None
def set_next_chain(self, next_chain: "Chain") -> None:
self.next_in_chain = next_chain
def calculate(self, request: "Numbers") -> None:
if request.calculation_wanted == "add":
print(
f"{request.number1} + {request.number2} = {request.number1 + request.number2}"
)
else:
self.next_in_chain.calculate(request)
class SubtractNumbers(Chain):
def __init__(self):
self.next_in_chain: Chain = None
def set_next_chain(self, next_chain: "Chain") -> None:
self.next_in_chain = next_chain
def calculate(self, request: "Numbers") -> None:
if request.calculation_wanted == "sub":
print(
f"{request.number1} - {request.number2} = {request.number1 - request.number2}"
)
else:
self.next_in_chain.calculate(request)
class MultiplyNumbers(Chain):
def __init__(self):
self.next_in_chain: Chain = None
def set_next_chain(self, next_chain: "Chain") -> None:
self.next_in_chain = next_chain
def calculate(self, request: "Numbers") -> None:
if request.calculation_wanted == "mult":
print(
f"{request.number1} * {request.number2} = {request.number1 * request.number2}"
)
else:
self.next_in_chain.calculate(request)
class DivideNumbers(Chain):
def __init__(self):
self.next_in_chain: Chain = None
def set_next_chain(self, next_chain: "Chain") -> None:
self.next_in_chain = next_chain
def calculate(self, request: "Numbers") -> None:
if request.calculation_wanted == "div":
print(
f"{request.number1} / {request.number2} = {request.number1 / request.number2}"
)
else:
print("Only works for add, sub, mult, and div")
if __name__ == "__main__":
chain_calc1 = AddNumbers()
chain_calc2 = SubtractNumbers()
chain_calc3 = MultiplyNumbers()
chain_calc4 = DivideNumbers()
chain_calc1.set_next_chain(chain_calc2)
chain_calc2.set_next_chain(chain_calc3)
chain_calc3.set_next_chain(chain_calc4)
request = Numbers(4, 2, "mult")
chain_calc1.calculate(request)
from abc import ABC, abstractmethod
class ElectronicDevice(ABC):
@abstractmethod
def on(self) -> None:
pass
@abstractmethod
def off(self) -> None:
pass
@abstractmethod
def volume_up(self) -> None:
pass
@abstractmethod
def volume_down(self) -> None:
pass
class Television(ElectronicDevice):
def __init__(self):
self.volume = 0
def on(self) -> None:
print("TV is on")
def off(self) -> None:
print("TV is off")
def volume_up(self) -> None:
self.volume += 1
print("TV Volume is at", self.volume)
def volume_down(self) -> None:
self.volume -= 1
print("TV Volume is at", self.volume)
class Radio(ElectronicDevice):
def __init__(self):
self.volume = 0
def on(self) -> None:
print("Radio is on")
def off(self) -> None:
print("Radio is off")
def volume_up(self) -> None:
self.volume += 1
print("Radio Volume is at", self.volume)
def volume_down(self) -> None:
self.volume -= 1
print("Radio Volume is at", self.volume)
class Command(ABC):
@abstractmethod
def execute(self) -> None:
pass
@abstractmethod
def undo(self) -> None:
pass
class TurnTVOn(Command):
def __init__(self, new_device: ElectronicDevice):
self.the_device: ElectronicDevice = new_device
def execute(self) -> None:
self.the_device.on()
def undo(self) -> None:
self.the_device.off()
class TurnTVOff(Command):
def __init__(self, new_device: ElectronicDevice):
self.the_device: ElectronicDevice = new_device
def execute(self) -> None:
self.the_device.off()
def undo(self) -> None:
self.the_device.on()
class TurnTVUp(Command):
def __init__(self, new_device: ElectronicDevice):
self.the_device: ElectronicDevice = new_device
def execute(self) -> None:
self.the_device.volume_up()
def undo(self) -> None:
self.the_device.volume_down()
class DeviceButton:
def __init__(self, new_command: Command):
self.the_command: Command = new_command
def press(self) -> None:
self.the_command.execute()
def press_undo(self) -> None:
self.the_command.undo()
class TurnItAllOff(Command):
def __init__(self, new_devices: list[ElectronicDevice]):
self.the_devices: list[ElectronicDevice] = new_devices
def execute(self) -> None:
for device in self.the_devices:
device.off()
def undo(self) -> None:
for device in self.the_devices:
device.on()
if __name__ == "__main__":
new_device = Television()
on_command = TurnTVOn(new_device)
on_pressed = DeviceButton(on_command)
on_pressed.press()
off_command = TurnTVOff(new_device)
on_pressed = DeviceButton(off_command)
on_pressed.press()
vol_up_command = TurnTVUp(new_device)
on_pressed = DeviceButton(vol_up_command)
on_pressed.press()
on_pressed.press()
on_pressed.press()
turn_off_devices = TurnItAllOff([Television(), Radio()])
turn_them_off = DeviceButton(turn_off_devices)
turn_them_off.press()
turn_them_off.press_undo()
from abc import ABC
class SongComponent(ABC):
def add(self, new_song_component: "SongComponent") -> None:
raise NotImplementedError
def remove(self, new_song_component: "SongComponent") -> None:
raise NotImplementedError
def get(self, component_index: int) -> "SongComponent":
raise NotImplementedError
def get_song_name(self) -> str:
raise NotImplementedError
def get_band_name(self) -> str:
raise NotImplementedError
def get_release_year(self) -> int:
raise NotImplementedError
def display_song_info(self) -> None:
raise NotImplementedError
class SongGroup(SongComponent):
def __init__(self, new_group_name: str, new_group_description: str):
self.song_components: list[SongComponent] = []
self.group_name: str = new_group_name
self.group_description: str = new_group_description
def add(self, new_song_component: "SongComponent") -> None:
self.song_components.append(new_song_component)
def remove(self, new_song_component: "SongComponent") -> None:
self.song_components.remove(new_song_component)
def get(self, component_index: int) -> "SongComponent":
return self.song_components[component_index]
def display_song_info(self) -> None:
print(f"{self.group_name} {self.group_description}\n")
for song_component in self.song_components:
song_component.display_song_info()
class Song(SongComponent):
def __init__(self, song_name: str, band_name: str, release_year: int):
self.song_name: str = song_name
self.band_name: str = band_name
self.release_year: int = release_year
def get_song_name(self) -> str:
return self.song_name
def get_band_name(self) -> str:
return self.band_name
def get_release_year(self) -> int:
return self.release_year
def display_song_info(self) -> None:
print(
f"{self.song_name} was recorded by {self.band_name} in {self.release_year}"
)
class DiskJockey:
def __init__(self, new_songs: SongComponent):
self.songs: SongComponent = new_songs
def get_song_list(self) -> None:
self.songs.display_song_info()
if __name__ == "__main__":
industrial_music = SongGroup("Industrial", "Transgressive and provocative themes")
heavy_metal_music = SongGroup("\nHeavy Metal", "Rock developed in late 1960s")
dub_step_music = SongGroup("\nDubstep", "Electronic dance music")
every_song = SongGroup("Song List", "Every song available")
every_song.add(industrial_music)
industrial_music.add(Song("Head like a hole", "NIN", 1990))
industrial_music.add(Song("Headhunter", "Front 242", 1988))
industrial_music.add(dub_step_music)
dub_step_music.add(Song("Centipede", "Knife Party", 2012))
dub_step_music.add(Song("Tetris", "Doctor P", 2011))
every_song.add(heavy_metal_music)
heavy_metal_music.add(Song("War Pigs", "Black Sabath", 1970))
heavy_metal_music.add(Song("Ace of Spades", "Motorhead", 1980))
crazy_larry = DiskJockey(every_song)
crazy_larry.get_song_list()
from abc import ABC, abstractmethod
class Pizza(ABC):
@abstractmethod
def set_description(self, new_description: str) -> None:
pass
@abstractmethod
def get_description(self) -> str:
pass
@abstractmethod
def get_cost(self) -> float:
pass
class ThreeCheesePizza(Pizza):
def set_description(self, new_description: str) -> None:
pass
def get_description(self) -> str:
return "Mozzarella, Fontina, Parmesan, Cheese Pizza"
def get_cost(self) -> float:
return 10.00
# ------------------- New code
class PizzaNew(ABC):
@abstractmethod
def get_description(self) -> str:
pass
@abstractmethod
def get_cost(self) -> float:
pass
class PlainPizza(PizzaNew):
def __init__(self):
print("Adding Dough")
def get_description(self) -> str:
return "Thin Dough"
def get_cost(self) -> float:
return 4.00
class ToppingDecorator(PizzaNew):
def __init__(self, new_pizza: PizzaNew):
self.temp_pizza: PizzaNew = new_pizza
def get_description(self) -> str:
return self.temp_pizza.get_description()
def get_cost(self) -> float:
return self.temp_pizza.get_cost()
class Mozzarella(ToppingDecorator):
def __init__(self, new_pizza: PizzaNew):
super().__init__(new_pizza)
print("Adding Moz")
def get_description(self) -> str:
return self.temp_pizza.get_description() + ", Mozzarella"
def get_cost(self) -> float:
return self.temp_pizza.get_cost() + 0.50
class TomatoSauce(ToppingDecorator):
def __init__(self, new_pizza: PizzaNew):
super().__init__(new_pizza)
print("Adding Sauce")
def get_description(self) -> str:
return self.temp_pizza.get_description() + ", Tomato Sauce"
def get_cost(self) -> float:
return self.temp_pizza.get_cost() + 0.35
if __name__ == "__main__":
# old code
three_cheese_pizza = ThreeCheesePizza()
print("Ingredients:", three_cheese_pizza.get_description())
print("Price:", three_cheese_pizza.get_cost())
print()
# new code
basic_pizza = TomatoSauce(Mozzarella(PlainPizza()))
print("Ingredients:", basic_pizza.get_description())
print("Price:", basic_pizza.get_cost())
class WelcomeToBank:
def __init__(self):
print("Welcome to ABC Bank")
print("We are happy to give you your money if we can find it\n")
class AccountNumberCheck:
def __init__(self):
self._account_number = 12345678
def account_active(self, account_number_to_check: int) -> bool:
return account_number_to_check == self._account_number
class SecurityCodeCheck:
def __init__(self):
self._security_code = 1234
def is_code_correct(self, security_code_to_check: int) -> bool:
return security_code_to_check == self._security_code
class FundsCheck:
def __init__(self):
self._cash_in_account = 1000.00
def decrease_cash_in_account(self, cash_withdrawn: float) -> None:
self._cash_in_account -= cash_withdrawn
def increase_cash_in_account(self, cash_deposited: float) -> None:
self._cash_in_account += cash_deposited
def have_enough_money(self, cash_to_withdraw: float) -> bool:
if cash_to_withdraw > self._cash_in_account:
print("Error: You don't have enough money")
print("Current Balance:", self._cash_in_account)
return False
self.decrease_cash_in_account(cash_to_withdraw)
print("Withdrawal Complete: Current balance is", self._cash_in_account)
return True
def make_deposit(self, cash_to_deposit: float) -> None:
self.increase_cash_in_account(cash_to_deposit)
print("Deposit Complete: Current balance is", self._cash_in_account)
class BankAccountFacade:
def __init__(self, account_number: int, security_code: int):
self.account_number: int = account_number
self.security_code: int = security_code
self.account_checker: AccountNumberCheck = AccountNumberCheck()
self.code_checker: SecurityCodeCheck = SecurityCodeCheck()
self.fund_checker: FundsCheck = FundsCheck()
self.bank_welcome: WelcomeToBank = WelcomeToBank()
def withdraw_cash(self, cash_to_get: float) -> None:
if (
self.account_checker.account_active(self.account_number)
and self.code_checker.is_code_correct(self.security_code)
and self.fund_checker.have_enough_money(cash_to_get)
):
print("Transaction Complete\n")
else:
print("Transaction Failed\n")
def deposit_cash(self, cash_to_deposit: float) -> None:
if self.account_checker.account_active(
self.account_number
) and self.code_checker.is_code_correct(self.security_code):
self.fund_checker.make_deposit(cash_to_deposit)
print("Transaction Complete\n")
else:
print("Transaction Failed\n")
if __name__ == "__main__":
accessing_bank = BankAccountFacade(12345678, 1234)
accessing_bank.withdraw_cash(50.00)
accessing_bank.withdraw_cash(900.00)
accessing_bank.deposit_cash(200.00)
from abc import ABC
class EnemyShip(ABC):
def __init__(self):
self.name: str = ""
self.amt_damage: float = 0.0
def follow_hero_ship(self) -> None:
print(f"{self.name} is following the hero")
def display_enemy_ship(self) -> None:
print(f"{self.name} is on the screen")
def enemy_ship_shoots(self) -> None:
print(f"{self.name} attacks and does {self.amt_damage}")
class UFOEnemyShip(EnemyShip):
def __init__(self):
super().__init__()
self.name = "UFO Enemy Ship"
self.amt_damage = 20.0
class RocketEnemyShip(EnemyShip):
def __init__(self):
super().__init__()
self.name = "Rocket Enemy Ship"
self.amt_damage = 10.0
class BigUFOEnemyShip(UFOEnemyShip):
def __init__(self):
super().__init__()
self.name = "Big UFO Enemy Ship"
self.amt_damage = 40.0
def do_stuff_enemy(an_enemy_ship: EnemyShip) -> None:
an_enemy_ship.display_enemy_ship()
an_enemy_ship.follow_hero_ship()
an_enemy_ship.enemy_ship_shoots()
# Enemy ship factory
def make_enemy_ship(new_ship_type: str) -> EnemyShip:
if new_ship_type == "U":
return UFOEnemyShip()
elif new_ship_type == "R":
return RocketEnemyShip()
elif new_ship_type == "B":
return BigUFOEnemyShip()
else:
raise ValueError("Ship type can be U or R or B only")
if __name__ == "__main__":
# old code
enemy_ship_option = input("What type of ship? (U / R) ")
if enemy_ship_option == "U":
the_enemy = UFOEnemyShip()
elif enemy_ship_option == "R":
the_enemy = RocketEnemyShip()
else:
raise ValueError("Only U or R is accepted")
do_stuff_enemy(the_enemy)
print()
# new code
enemy_ship_option = input("What type of ship? (U / R / B) ")
the_enemy = make_enemy_ship(enemy_ship_option)
do_stuff_enemy(the_enemy)
from abc import ABC, abstractmethod
class SongInfo:
def __init__(self, new_song_name: str, new_band_name: str, new_year_released: int):
self.song_name: str = new_song_name
self.band_name: str = new_band_name
self.year_released: int = new_year_released
class SongIterator(ABC):
@abstractmethod
def __iter__(self):
pass
class SongsOfThe70s(SongIterator):
def __init__(self):
self.best_songs: list[SongInfo] = []
self.add_song("Imagine", "John Lennon", 1971)
self.add_song("American Pie", "Don McLean", 1971)
self.add_song("I Will Survice", "Gloria Gaynor", 1979)
def add_song(self, song_name: str, band_name: str, year_released: int) -> None:
self.best_songs.append(SongInfo(song_name, band_name, year_released))
# od code
def get_best_songs(self) -> list[SongInfo]:
return self.best_songs
def __iter__(self):
return iter(self.best_songs)
class SongsOfThe80s(SongIterator):
def __init__(self):
self.best_songs: list[SongInfo] = []
self.add_song("Roam", "B52s", 1989)
self.add_song("Cruel Summer", "Bananarama", 1984)
self.add_song("Head Over Heels", "Tears For Fears", 1985)
def add_song(self, song_name: str, band_name: str, year_released: int) -> None:
self.best_songs.append(SongInfo(song_name, band_name, year_released))
# old code
def get_best_songs(self) -> list[SongInfo]:
return self.best_songs
def __iter__(self):
return iter(self.best_songs)
class SongsOfThe90s(SongIterator):
def __init__(self):
self.best_songs: dict[int, SongInfo] = {}
self.hash_key = 0
self.add_song("Losing My Religion", "REM", 1991)
self.add_song("Creep", "Radiohead", 1993)
self.add_song("Walk on the Ocean", "Toad the Wet Sprocket", 1991)
def add_song(self, song_name: str, band_name: str, year_released: int) -> None:
self.best_songs[self.hash_key] = SongInfo(song_name, band_name, year_released)
self.hash_key += 1
# old code
def get_best_songs(self) -> dict[int, SongInfo]:
return self.best_songs
def __iter__(self):
return iter(self.best_songs.values())
class DiscJockey:
def __init__(
self,
songs_70s: SongsOfThe70s,
songs_80s: SongsOfThe80s,
songs_90s: SongsOfThe90s,
):
self.songs_70s: SongsOfThe70s = songs_70s
self.songs_80s: SongsOfThe80s = songs_80s
self.songs_90s: SongsOfThe90s = songs_90s
def show_the_songs(self) -> None:
songs_70s_list = self.songs_70s.get_best_songs()
print("\nSongs of the 70s")
for song in songs_70s_list:
print(song.song_name)
print(song.band_name)
print(song.year_released)
songs_80s_list = self.songs_80s.get_best_songs()
print("\nSongs of the 80s")
for song in songs_80s_list:
print(song.song_name)
print(song.band_name)
print(song.year_released)
songs_90s_dict = self.songs_90s.get_best_songs()
print("\nSongs of the 90s")
for song in songs_90s_dict.values():
print(song.song_name)
print(song.band_name)
print(song.year_released)
class DiscJockeyNew:
def __init__(
self, songs_70s: SongIterator, songs_80s: SongIterator, songs_90s: SongIterator
):
self.iter_songs_70s: SongIterator = songs_70s
self.iter_songs_80s: SongIterator = songs_80s
self.iter_songs_90s: SongIterator = songs_90s
def show_the_songs2(self) -> None:
print("\nSongs of the 70s")
self._print_the_songs(self.iter_songs_70s)
print("\nSongs of the 80s")
self._print_the_songs(self.iter_songs_80s)
print("\nSongs of the 90s")
self._print_the_songs(self.iter_songs_90s)
def _print_the_songs(self, song_iterator: SongIterator) -> None:
for song in song_iterator:
print(song.song_name)
print(song.band_name)
print(song.year_released)
if __name__ == "__main__":
songs_70s = SongsOfThe70s()
songs_80s = SongsOfThe80s()
songs_90s = SongsOfThe90s()
# old code
mad_mike = DiscJockey(songs_70s, songs_80s, songs_90s)
mad_mike.show_the_songs()
# new code
mad_mike2 = DiscJockeyNew(songs_70s, songs_80s, songs_90s)
mad_mike2.show_the_songs2()
from abc import ABC, abstractmethod
class StockOffer:
def __init__(self, num_shares: int, stock: str, coll_code: int):
self.stock_shares: int = num_shares
self.stock_symbol: str = stock
self.colleague_code: int = coll_code
class Colleague(ABC):
def __init__(self, mediator: "Mediator"):
self.mediator: "Mediator" = mediator
self.colleague_code: int = 0
self.mediator.add_colleague(self)
def sale_offer(self, stock: str, shares: int) -> None:
self.mediator.sale_offer(stock, shares, self.colleague_code)
def buy_offer(self, stock: str, shares: int) -> None:
self.mediator.buy_offer(stock, shares, self.colleague_code)
def set_colleague_code(self, coll_code: int) -> None:
self.colleague_code = coll_code
class GormanSlacks(Colleague):
def __init__(self, mediator: "Mediator"):
super().__init__(mediator)
print("Gorman Slacks signed up for the exchange\n")
class JTPoorman(Colleague):
def __init__(self, mediator: "Mediator"):
super().__init__(mediator)
print("JT Poorman signed up for the exchange\n")
class Mediator(ABC):
@abstractmethod
def sale_offer(self, stock: str, shares: int, coll_code: int) -> None:
pass
@abstractmethod
def buy_offer(self, stock: str, shares: int, coll_code: int) -> None:
pass
@abstractmethod
def add_colleague(self, colleague: "Colleague") -> None:
pass
class StockMediator(Mediator):
def __init__(self):
self.colleagues: list[Colleague] = []
self.stock_buy_offers: list[StockOffer] = []
self.stock_sell_offers: list[StockOffer] = []
self.colleague_codes: int = 0
def add_colleague(self, colleague: "Colleague") -> None:
self.colleagues.append(colleague)
self.colleague_codes += 1
colleague.set_colleague_code(self.colleague_codes)
def sale_offer(self, stock: str, shares: int, coll_code: int) -> None:
stock_sold = False
for offer in self.stock_buy_offers:
if offer.stock_symbol == stock and offer.stock_shares == shares:
print(
f"{shares} shares of {stock} sold to colleague code {offer.colleague_code}"
)
self.stock_buy_offers.remove(offer)
stock_sold = True
break
if not stock_sold:
print(f"{shares} shares of {stock} added to inventory")
new_offering = StockOffer(shares, stock, coll_code)
self.stock_sell_offers.append(new_offering)
def buy_offer(self, stock: str, shares: int, coll_code: int) -> None:
stock_bought = False
for offer in self.stock_sell_offers:
if offer.stock_symbol == stock and offer.stock_shares == shares:
print(
f"{shares} shares of {stock} bought by colleague code {offer.colleague_code}"
)
self.stock_sell_offers.remove(offer)
stock_bought = True
break
if not stock_bought:
print(f"{shares} shares of {stock} added to inventory")
new_offering = StockOffer(shares, stock, coll_code)
self.stock_buy_offers.append(new_offering)
def get_stock_offerings(self) -> None:
print("\nStocks for sale")
for offer in self.stock_sell_offers:
print(f"{offer.stock_shares} of {offer.stock_symbol}")
print("\nStocks Buy offers")
for offer in self.stock_buy_offers:
print(f"{offer.stock_shares} of {offer.stock_symbol}")
if __name__ == "__main__":
nyse = StockMediator()
broker = GormanSlacks(nyse)
broker2 = JTPoorman(nyse)
broker.sale_offer("MSFT", 100)
broker2.sale_offer("GOOG", 50)
broker.buy_offer("MSFT", 100)
broker2.sale_offer("NRG", 10)
broker.buy_offer("NRG", 10)
nyse.get_stock_offerings()
class Memento:
def __init__(self, article_save: str):
self.article: str = article_save
class Originator:
def __init__(self):
self.article: str = ""
def store_in_memento(self, article: str) -> "Memento":
print("Saving to Memento")
return Memento(article)
def restore_from_memento(self, memento: Memento) -> str:
print("Restoring memento")
article = memento.article
return article
class Caretaker:
def __init__(self):
self.saved_articles: list[Memento] = []
def add_memento(self, m: Memento) -> None:
self.saved_articles.append(m)
def get_memento(self, index: int) -> Memento:
return self.saved_articles[index]
if __name__ == "__main__":
care_taker = Caretaker()
originator = Originator()
saved_files = 0
current_article = 0
care_taker.add_memento(originator.store_in_memento(""))
while True:
save_or_undo_or_redo = input("-Save or undo or redo? S/U/R ")
if save_or_undo_or_redo == "S":
text = input("--Please enter the text to be saved: ")
care_taker.add_memento(originator.store_in_memento(text))
current_article += 1
saved_files += 1
elif save_or_undo_or_redo == "U":
if current_article > 0:
current_article -= 1
text = originator.restore_from_memento(
care_taker.get_memento(current_article)
)
print("---TEXT:", text)
else:
print("Nothing to undo")
elif save_or_undo_or_redo == "R":
if current_article < saved_files:
current_article += 1
text = originator.restore_from_memento(
care_taker.get_memento(current_article)
)
print("---TEXT:", text)
else:
print("Nothing to redo")
else:
print("-Only S or U or R are accepted")
from abc import ABC, abstractmethod
class Subject(ABC):
@abstractmethod
def register(self, observer: "Observer") -> None:
pass
@abstractmethod
def unregister(self, observer: "Observer") -> None:
pass
@abstractmethod
def notify_observer(self) -> None:
pass
class Observer(ABC):
@abstractmethod
def update(self, ibm_price: float, aapl_price: float, goog_price: float) -> None:
pass
class StockGrabber(Subject):
def __init__(self):
self.observers: list[Observer] = []
self.ibm_price = 0.0
self.aapl_price: float = 0.0
self.goog_price: float = 0.0
def register(self, observer: "Observer") -> None:
self.observers.append(observer)
def unregister(self, delete_observer: "Observer") -> None:
self.observers.remove(delete_observer)
print("Observer deleted")
def notify_observer(self) -> None:
for observer in self.observers:
observer.update(self.ibm_price, self.aapl_price, self.goog_price)
def set_ibm_price(self, new_ibm_price: float) -> None:
self.ibm_price = new_ibm_price
self.notify_observer()
def set_aapl_price(self, new_aapl_price: float) -> None:
self.aapl_price = new_aapl_price
self.notify_observer()
def set_goog_price(self, new_goog_price: float) -> None:
self.goog_price = new_goog_price
self.notify_observer()
class StockObserver(Observer):
observed_id_tracker = 0
def __init__(self, stock_grabber: Subject):
self.ibm_price = 0.0
self.aapl_price: float = 0.0
self.goog_price: float = 0.0
StockObserver.observed_id_tracker += 1
self.observer_id = StockObserver.observed_id_tracker
self.stock_grabber: Subject = stock_grabber
print("New Observer ", self.observer_id)
self.stock_grabber.register(self)
def update(self, ibm_price: float, aapl_price: float, goog_price: float) -> None:
self.ibm_price = ibm_price
self.aapl_price = aapl_price
self.goog_price = goog_price
self.print_the_prices()
def print_the_prices(self) -> None:
print(
f"{self.observer_id} \nIBM: {self.ibm_price} \nAAPL: {self.aapl_price} \nGOOG: {self.goog_price}\n"
)
if __name__ == "__main__":
stock_grabber = StockGrabber()
observer1 = StockObserver(stock_grabber)
stock_grabber.set_ibm_price(197.00)
stock_grabber.set_aapl_price(677.60)
stock_grabber.set_goog_price(676.40)
observer2 = StockObserver(stock_grabber)
stock_grabber.set_ibm_price(197.00)
stock_grabber.set_aapl_price(677.60)
stock_grabber.set_goog_price(676.40)
stock_grabber.unregister(observer1)
stock_grabber.set_ibm_price(197.00)
stock_grabber.set_aapl_price(677.60)
stock_grabber.set_goog_price(676.40)
import copy
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def __copy__(self) -> "Animal":
pass
class Sheep(Animal):
def __init__(self):
print("Sheep is made")
def __copy__(self) -> "Animal":
print("Sheep is being made")
return Sheep()
def __str__(self) -> str:
return "Dolly is my hero, baaaa"
def get_clone(animal_sample: "Animal") -> "Animal":
return copy.copy(animal_sample)
if __name__ == "__main__":
sally = Sheep()
cloned_sheep = get_clone(sally)
print(sally)
print(cloned_sheep)
print(f"Sally hashcode: {id(sally)}")
print(f"Clone hashcode: {id(cloned_sheep)}")
from abc import ABC, abstractmethod
class GetATMData(ABC):
@abstractmethod
def get_atm_data(self) -> "ATMState":
pass
@abstractmethod
def get_cash_in_machine(self) -> int:
pass
class ATMProxy(GetATMData):
def get_atm_data(self) -> "ATMState":
real_atm_machine = ATMMachine()
return real_atm_machine.get_atm_data()
def get_cash_in_machine(self) -> int:
real_atm_machine = ATMMachine()
return real_atm_machine.get_cash_in_machine()
class ATMState(ABC):
@abstractmethod
def insert_card(self) -> None:
pass
@abstractmethod
def eject_card(self) -> None:
pass
@abstractmethod
def insert_pin(self, pin_entered: int) -> None:
pass
@abstractmethod
def request_cash(self, cash_to_withdraw: int) -> None:
pass
# Code below copied from State Pattern
# ATMMachine below extends GetATMData interface
class ATMMachine(GetATMData):
def __init__(self):
self.has_card: ATMState = HasCard(self)
self.no_card: ATMState = NoCard(self)
self.has_correct_pin: ATMState = HasPin(self)
self.atm_out_of_money: ATMState = NoCash(self)
self.atm_state: ATMState = self.no_card
self.cash_in_machine: int = 2000
self.correct_pin_entered: bool = False
if self.cash_in_machine < 0:
self.atm_state = self.atm_out_of_money
def set_atm_state(self, new_atm_state: ATMState) -> None:
self.atm_state = new_atm_state
def set_cash_in_machine(self, new_cash_in_machine: int) -> None:
self.cash_in_machine = new_cash_in_machine
def insert_card(self) -> None:
self.atm_state.insert_card()
def eject_card(self) -> None:
self.atm_state.eject_card()
def request_cash(self, cash_to_withdraw: int) -> None:
self.atm_state.request_cash(cash_to_withdraw)
def insert_pin(self, pin_entered: int) -> None:
self.atm_state.insert_pin(pin_entered)
def get_yes_card_state(self) -> ATMState:
return self.has_card
def get_no_card_state(self) -> ATMState:
return self.no_card
def get_has_pin(self) -> ATMState:
return self.has_correct_pin
def get_no_cash_state(self) -> ATMState:
return self.atm_out_of_money
def get_atm_data(self) -> "ATMState":
return self.atm_state
def get_cash_in_machine(self) -> int:
return self.cash_in_machine
class HasCard(ATMState):
def __init__(self, new_atm_machine: ATMMachine):
self.atm_machine: ATMMachine = new_atm_machine
def insert_card(self) -> None:
print("You can't enter more than one card")
def eject_card(self) -> None:
print("Card ejected")
self.atm_machine.set_atm_state(self.atm_machine.get_no_card_state())
def insert_pin(self, pin_entered: int) -> None:
if pin_entered == 1234:
print("Correct PIN")
self.atm_machine.correct_pin_entered = True
self.atm_machine.set_atm_state(self.atm_machine.get_has_pin())
else:
print("Wrong PIN")
self.atm_machine.correct_pin_entered = False
print("Card ejected")
self.atm_machine.set_atm_state(self.atm_machine.get_no_card_state())
def request_cash(self, cash_to_withdraw: int) -> None:
print("Enter PIN first")
class NoCard(ATMState):
def __init__(self, new_atm_machine: ATMMachine):
self.atm_machine: ATMMachine = new_atm_machine
def insert_card(self) -> None:
print("Please enter a PIN")
self.atm_machine.set_atm_state(self.atm_machine.get_yes_card_state())
def eject_card(self) -> None:
print("Enter a card first")
def insert_pin(self, pin_entered: int) -> None:
print("Enter a card first")
def request_cash(self, cash_to_withdraw: int) -> None:
print("Enter a card first")
class HasPin(ATMState):
def __init__(self, new_atm_machine: ATMMachine):
self.atm_machine: ATMMachine = new_atm_machine
def insert_card(self) -> None:
print("You can't enter more than one card")
def eject_card(self) -> None:
print("Card ejected")
self.atm_machine.set_atm_state(self.atm_machine.get_no_card_state())
def insert_pin(self, pin_entered: int) -> None:
print("Already entered PIN")
def request_cash(self, cash_to_withdraw: int) -> None:
if cash_to_withdraw > self.atm_machine.cash_in_machine:
print("Don't have that cash")
print("Card Ejected")
self.atm_machine.set_atm_state(self.atm_machine.get_no_card_state())
else:
print(f"{cash_to_withdraw} is provided by the machine")
self.atm_machine.set_cash_in_machine(
self.atm_machine.cash_in_machine - cash_to_withdraw
)
print("Card Ejected")
self.atm_machine.set_atm_state(self.atm_machine.get_no_card_state())
if self.atm_machine.cash_in_machine <= 0:
self.atm_machine.set_atm_state(self.atm_machine.get_no_cash_state())
class NoCash(ATMState):
def __init__(self, new_atm_machine: ATMMachine):
self.atm_machine: ATMMachine = new_atm_machine
def insert_card(self) -> None:
print("We don't have money")
def eject_card(self) -> None:
print("We don't have money. You didn't enter a card")
def insert_pin(self, pin_entered: int) -> None:
print("We don't have money")
def request_cash(self, cash_to_withdraw: int) -> None:
print("We don't have money")
if __name__ == "__main__":
atm_proxy = ATMProxy()
print("\nCurrent ATM State", atm_proxy.get_atm_data())
print("\nCash in ATM Machine $", atm_proxy.get_cash_in_machine())
class _Singleton:
instance: "_Singleton" = None
def Singleton() -> _Singleton:
if _Singleton.instance is None:
_Singleton.instance = _Singleton()
return _Singleton.instance
if __name__ == "__main__":
singleton1 = Singleton()
singleton2 = Singleton()
assert singleton1 is singleton2, "Both are not same"
from abc import ABC, abstractmethod
class ATMState(ABC):
@abstractmethod
def insert_card(self) -> None:
pass
@abstractmethod
def eject_card(self) -> None:
pass
@abstractmethod
def insert_pin(self, pin_entered: int) -> None:
pass
@abstractmethod
def request_cash(self, cash_to_withdraw: int) -> None:
pass
class ATMMachine:
def __init__(self):
self.has_card: ATMState = HasCard(self)
self.no_card: ATMState = NoCard(self)
self.has_correct_pin: ATMState = HasPin(self)
self.atm_out_of_money: ATMState = NoCash(self)
self.atm_state: ATMState = self.no_card
self.cash_in_machine: int = 2000
self.correct_pin_entered: bool = False
if self.cash_in_machine < 0:
self.atm_state = self.atm_out_of_money
def set_atm_state(self, new_atm_state: ATMState) -> None:
self.atm_state = new_atm_state
def set_cash_in_machine(self, new_cash_in_machine: int) -> None:
self.cash_in_machine = new_cash_in_machine
def insert_card(self) -> None:
self.atm_state.insert_card()
def eject_card(self) -> None:
self.atm_state.eject_card()
def request_cash(self, cash_to_withdraw: int) -> None:
self.atm_state.request_cash(cash_to_withdraw)
def insert_pin(self, pin_entered: int) -> None:
self.atm_state.insert_pin(pin_entered)
def get_yes_card_state(self) -> ATMState:
return self.has_card
def get_no_card_state(self) -> ATMState:
return self.no_card
def get_has_pin(self) -> ATMState:
return self.has_correct_pin
def get_no_cash_state(self) -> ATMState:
return self.atm_out_of_money
class HasCard(ATMState):
def __init__(self, new_atm_machine: ATMMachine):
self.atm_machine: ATMMachine = new_atm_machine
def insert_card(self) -> None:
print("You can't enter more than one card")
def eject_card(self) -> None:
print("Card ejected")
self.atm_machine.set_atm_state(self.atm_machine.get_no_card_state())
def insert_pin(self, pin_entered: int) -> None:
if pin_entered == 1234:
print("Correct PIN")
self.atm_machine.correct_pin_entered = True
self.atm_machine.set_atm_state(self.atm_machine.get_has_pin())
else:
print("Wrong PIN")
self.atm_machine.correct_pin_entered = False
print("Card ejected")
self.atm_machine.set_atm_state(self.atm_machine.get_no_card_state())
def request_cash(self, cash_to_withdraw: int) -> None:
print("Enter PIN first")
class NoCard(ATMState):
def __init__(self, new_atm_machine: ATMMachine):
self.atm_machine: ATMMachine = new_atm_machine
def insert_card(self) -> None:
print("Please enter a PIN")
self.atm_machine.set_atm_state(self.atm_machine.get_yes_card_state())
def eject_card(self) -> None:
print("Enter a card first")
def insert_pin(self, pin_entered: int) -> None:
print("Enter a card first")
def request_cash(self, cash_to_withdraw: int) -> None:
print("Enter a card first")
class HasPin(ATMState):
def __init__(self, new_atm_machine: ATMMachine):
self.atm_machine: ATMMachine = new_atm_machine
def insert_card(self) -> None:
print("You can't enter more than one card")
def eject_card(self) -> None:
print("Card ejected")
self.atm_machine.set_atm_state(self.atm_machine.get_no_card_state())
def insert_pin(self, pin_entered: int) -> None:
print("Already entered PIN")
def request_cash(self, cash_to_withdraw: int) -> None:
if cash_to_withdraw > self.atm_machine.cash_in_machine:
print("Don't have that cash")
print("Card Ejected")
self.atm_machine.set_atm_state(self.atm_machine.get_no_card_state())
else:
print(f"{cash_to_withdraw} is provided by the machine")
self.atm_machine.set_cash_in_machine(
self.atm_machine.cash_in_machine - cash_to_withdraw
)
print("Card Ejected")
self.atm_machine.set_atm_state(self.atm_machine.get_no_card_state())
if self.atm_machine.cash_in_machine <= 0:
self.atm_machine.set_atm_state(self.atm_machine.get_no_cash_state())
class NoCash(ATMState):
def __init__(self, new_atm_machine: ATMMachine):
self.atm_machine: ATMMachine = new_atm_machine
def insert_card(self) -> None:
print("We don't have money")
def eject_card(self) -> None:
print("We don't have money. You didn't enter a card")
def insert_pin(self, pin_entered: int) -> None:
print("We don't have money")
def request_cash(self, cash_to_withdraw: int) -> None:
print("We don't have money")
if __name__ == "__main__":
atm_machine = ATMMachine()
atm_machine.insert_card()
atm_machine.eject_card()
atm_machine.insert_card()
atm_machine.insert_pin(1234)
atm_machine.request_cash(2000)
atm_machine.insert_card()
atm_machine.insert_pin(1234)
from abc import ABC, abstractmethod
class Animal:
def __init__(self):
self.name: str = ""
self.height: float = 0.0
self.weight: int = 0
self.fav_food: str = ""
self.speed: float = 0.0
self.sound: str = ""
def fly(self) -> str:
return "I can't fly"
class Dog(Animal):
def __init__(self):
super().__init__()
self.sound = "Bark"
def dig_hole(self) -> None:
print("Dug a hole")
def fly(self) -> str:
return "I can't fly"
class Bird(Animal):
def __init__(self):
super().__init__()
self.sound = "Tweet"
def fly(self) -> str:
return "Flying High"
# ----------------- New code
class Flies(ABC):
@abstractmethod
def fly(self) -> str:
pass
class ItFlies(Flies):
def fly(self) -> str:
return "Flying High"
class CantFly(Flies):
def fly(self) -> str:
return "I can't fly"
class AnimalNew:
def __init__(self):
self.name: str = ""
self.height: float = 0.0
self.weight: int = 0
self.fav_food: str = ""
self.speed: float = 0.0
self.sound: str = ""
self.flying_type: Flies = CantFly()
def fly(self) -> str:
return self.flying_type.fly()
def set_flying_ability(self, new_fly_type: Flies) -> None:
self.flying_type = new_fly_type
class DogNew(AnimalNew):
def __init__(self):
super().__init__()
self.sound = "Bark"
self.flying_type = CantFly()
def dig_hole(self) -> None:
print("Dug a hole")
class BirdNew(AnimalNew):
def __init__(self):
super().__init__()
self.sound = "Tweet"
self.flying_type = ItFlies()
if __name__ == "__main__":
sparky = Dog()
tweety = Bird()
print("Dog:", sparky.fly())
print("Bird:", tweety.fly())
sparky_new = DogNew()
tweety_new = BirdNew()
print("Dog:", sparky_new.fly())
print("Bird:", tweety_new.fly())
sparky_new.set_flying_ability(ItFlies())
print("Dog:", sparky_new.fly())
from abc import ABC, abstractmethod
class Hoagie(ABC):
def make_sandwich(self) -> None:
self.cut_bun()
if self.customer_wants_meat():
self.add_meat()
if self.customer_wants_cheese():
self.add_cheese()
if self.customer_wants_vegetables():
self.add_vegetables()
if self.customer_wants_condiments():
self.add_condiments()
self.wrap_the_hoagie()
def cut_bun(self) -> None:
print("The hoagie is cut")
@abstractmethod
def add_meat(self) -> None:
pass
@abstractmethod
def add_cheese(self) -> None:
pass
@abstractmethod
def add_vegetables(self) -> None:
pass
@abstractmethod
def add_condiments(self) -> None:
pass
def customer_wants_meat(self) -> bool:
return True
def customer_wants_cheese(self) -> bool:
return True
def customer_wants_vegetables(self) -> bool:
return True
def customer_wants_condiments(self) -> bool:
return True
def wrap_the_hoagie(self) -> None:
print("Wrap the hoagie")
class ItalianHoagie(Hoagie):
def __init__(self):
self.meat_used: list[str] = ["Salami", "Pepperoni", "Capicola Ham"]
self.cheese_used: list[str] = ["Provolone"]
self.veggies_used: list[str] = [
"Lettuce",
"Tomatoes",
"Onions",
"Sweet Peppers",
]
self.condiments_used: list[str] = ["Oil", "Vinegar"]
def add_meat(self) -> None:
print("Adding the meat:", end=" ")
for meat in self.meat_used:
print(meat, end=" ")
print()
def add_cheese(self) -> None:
print("Adding the cheese:", end=" ")
for cheese in self.cheese_used:
print(cheese, end=" ")
print()
def add_vegetables(self) -> None:
print("Adding the veggies:", end=" ")
for veggie in self.veggies_used:
print(veggie, end=" ")
print()
def add_condiments(self) -> None:
print("Adding the condiments:", end=" ")
for condiment in self.condiments_used:
print(condiment, end=" ")
print()
class VeggieHoagie(Hoagie):
def __init__(self):
self.veggies_used: list[str] = [
"Lettuce",
"Tomatoes",
"Onions",
"Sweet Peppers",
]
self.condiments_used: list[str] = ["Oil", "Vinegar"]
def customer_wants_meat(self) -> bool:
return False
def customer_wants_cheese(self) -> bool:
return False
def add_meat(self) -> None:
pass
def add_cheese(self) -> None:
pass
def add_vegetables(self) -> None:
print("Adding the veggies:", end=" ")
for veggie in self.veggies_used:
print(veggie, end=" ")
print()
def add_condiments(self) -> None:
print("Adding the condiments:", end=" ")
for condiment in self.condiments_used:
print(condiment, end=" ")
print()
if __name__ == "__main__":
cust12_hoagie = ItalianHoagie()
cust12_hoagie.make_sandwich()
print()
cust13_hoagie = VeggieHoagie()
cust13_hoagie.make_sandwich()
from abc import ABC, abstractmethod
class Visitor(ABC):
@abstractmethod
def visit_liquor(self, liquor_item: "Liquor") -> float:
pass
@abstractmethod
def visit_tobacco(self, tobacco_item: "Tobacco") -> float:
pass
@abstractmethod
def visit_necessity(self, necessity_item: "Necessity") -> float:
pass
class TaxVisitor(Visitor):
def visit_liquor(self, liquor_item: "Liquor") -> float:
print("Liquor item: Price with Tax")
return liquor_item.price * 0.18 + liquor_item.price
def visit_tobacco(self, tobacco_item: "Tobacco") -> float:
print("Tobacco item: Price with Tax")
return tobacco_item.price * 0.32 + tobacco_item.price
def visit_necessity(self, necessity_item: "Necessity") -> float:
print("Necessity item: Price with Tax")
return necessity_item.price
class TaxHolidayVisitor(Visitor):
def visit_liquor(self, liquor_item: "Liquor") -> float:
print("Liquor item: Price with Tax")
return liquor_item.price * 0.10 + liquor_item.price
def visit_tobacco(self, tobacco_item: "Tobacco") -> float:
print("Tobacco item: Price with Tax")
return tobacco_item.price * 0.30 + tobacco_item.price
def visit_necessity(self, necessity_item: "Necessity") -> float:
print("Necessity item: Price with Tax")
return necessity_item.price
class Visitable(ABC):
@abstractmethod
def accept(self, visitor: Visitor) -> float:
pass
class Liquor(Visitable):
def __init__(self, item_price):
self.price = item_price
def accept(self, visitor: Visitor) -> float:
return visitor.visit_liquor(self)
class Tobacco(Visitable):
def __init__(self, item_price):
self.price = item_price
def accept(self, visitor: Visitor) -> float:
return visitor.visit_tobacco(self)
class Necessity(Visitable):
def __init__(self, item_price):
self.price = item_price
def accept(self, visitor: Visitor) -> float:
return visitor.visit_necessity(self)
if __name__ == "__main__":
tax_calc = TaxVisitor()
tax_holiday_calc = TaxHolidayVisitor()
milk = Necessity(3.47)
vodka = Liquor(11.99)
cigars = Tobacco(19.99)
print(f"{milk.accept(tax_calc)}\n")
print(f"{vodka.accept(tax_calc)}\n")
print(f"{cigars.accept(tax_calc)}\n")
print("TAX HOLIDAY PRICES\n")
print(f"{milk.accept(tax_holiday_calc)}\n")
print(f"{vodka.accept(tax_holiday_calc)}\n")
print(f"{cigars.accept(tax_holiday_calc)}\n")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment