Skip to content

Instantly share code, notes, and snippets.

@alexwaweru
Created January 5, 2020 15:14
Show Gist options
  • Save alexwaweru/903957d4713d6dd6ab4591a6bfa994b4 to your computer and use it in GitHub Desktop.
Save alexwaweru/903957d4713d6dd6ab4591a6bfa994b4 to your computer and use it in GitHub Desktop.
from __future__ import annotations
from abc import ABC, abstractmethod, abstractproperty
from typing import Any
class AbstractHouseBuilder(ABC):
"""
This Builder interface specifies methods for creating the different parts of
the house.
"""
@abstractmethod
def add_wall(self) -> None:
pass
@abstractmethod
def add_floor(self) -> None:
pass
@abstractmethod
def add_swimming_pool(self) -> None:
pass
@abstractmethod
def add_balcony(self) -> None:
pass
@abstractproperty
def house(self) -> AbstractHouse:
pass
class HouseBuilder(AbstractHouseBuilder):
def __init__(self) -> None:
self._house = House()
def add_wall(self, wall=None, component_name="wall") -> None:
if not wall:
wall = Wall()
self._house.add(wall, component_name)
def add_floor(self, floor=None, component_name="floor") -> None:
if not floor:
floor = Floor()
self._house.add(floor, component_name)
def add_swimming_pool(self, swimming_pool=None, component_name="swimming_pool") -> None:
if not swimming_pool:
swimming_pool = SwimmingPool()
self._house.add(swimming_pool, component_name)
def add_balcony(self, balcony=None, component_name="balcony") -> None:
if not balcony:
balcony = Balcony()
self._house.add(balcony, component_name)
def house(self) -> House:
return self._house
class AbstractHouse(ABC):
@abstractmethod
def add(self, component: Any, component_name: str) -> None:
pass
@abstractmethod
def list_components(self) -> None:
pass
class House:
def __init__(self) -> None:
self._components = {}
def add(self, component: Any, component_name: str) -> None:
setattr(component, "identifier", component_name)
self._components[component_name] = component
def __getattr__(self, attribute):
if attribute in self._components.keys():
return self._components[attribute]
else:
raise AttributeError(f"{attribute} is not a valid attribute of {self.__class__.__name__}.")
def list_components(self) -> None:
return f"House components: {', '.join(self._components.keys())}"
class Wall:
def __init__(self, width=0, length=0, height=0):
self.identifier = None
self.width = width
self.length = length
self.height = height
def __str__(self):
return f"{self.identifier} (width: {self.width}, height: {self.height}, length: {self.length})"
class Floor:
def __init__(self, material=None, color=None, pattern=None):
self.identifier = None
self.material = material
self.color = color
self.pattern = pattern
def __str__(self):
return f"{self.identifier} (material: {self.material}, color: {self.color}, pattern: {self.pattern})"
class SwimmingPool:
def __init__(self, width=0, length=0, height=0, slope=0):
self.identifier = None
self.width = width
self.length = length
self.height = height
self.slope = slope
def __str__(self):
return f"{self.identifier} (width: {self.width}, length: {self.length}, height: {self.height}," \
f"slope: {self.slope})"
class Balcony:
def __init__(self, width=0, length=0, height=0):
self.identifier = None
self.width = width
self.length = length
self.height = height
def __str__(self):
return f"{self.identifier} (width: {self.width}, height: {self.height}, length: {self.length})"
if __name__ == "__main__":
builder = HouseBuilder()
print("House 1: ")
builder.add_wall()
builder.add_floor()
builder.add_balcony()
house = builder.house()
print(house.wall)
print(house.floor)
print(house.balcony)
print(house.list_components())
print("\n")
builder = HouseBuilder()
print("House 2: ")
wall = Wall(10,20,2)
builder.add_wall(wall, "kitchen_wall")
floor = Floor("wood", "brown", "square")
builder.add_floor(floor, "kitchen_floor")
balcony = Balcony(1, 3, 0.5)
builder.add_balcony(balcony, "main_balcony")
swimming_pool = SwimmingPool(10, 30, 2.2, 10)
builder.add_swimming_pool(swimming_pool, "infinity_pool")
house = builder.house()
print(house.kitchen_wall)
print(house.kitchen_floor)
print(house.main_balcony)
print(house.infinity_pool)
print(house.a)
print(house.list_components())
# output
'''
House 1:
wall (width: 0, height: 0, length: 0)
floor (material: None, color: None, pattern: None)
balcony (width: 0, height: 0, length: 0)
House components: wall, floor, balcony
House 2:
kitchen_wall (width: 10, height: 2, length: 20)
kitchen_floor (material: wood, color: brown, pattern: square)
main_balcony (width: 1, height: 0.5, length: 3)
infinity_pool (width: 10, length: 30, height: 2.2,slope: 10)
House components: kitchen_wall, kitchen_floor, main_balcony, infinity_pool
'''
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment