Skip to content

Commit ab7923c

Browse files
committed
Added SOLID - Exercise
1 parent 12b20f9 commit ab7923c

File tree

5 files changed

+370
-0
lines changed

5 files changed

+370
-0
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
from abc import ABC, abstractmethod
2+
3+
4+
class BaseWorker(ABC):
5+
6+
@staticmethod
7+
@abstractmethod
8+
def work():
9+
pass
10+
11+
12+
class Worker(BaseWorker):
13+
14+
@staticmethod
15+
def work():
16+
print("I'm working!!")
17+
18+
19+
class Manager:
20+
21+
def __init__(self):
22+
self.worker = None
23+
24+
def set_worker(self, worker):
25+
assert isinstance(worker, BaseWorker), '`worker` must be of type {}'.format(Worker)
26+
27+
self.worker = worker
28+
29+
def manage(self):
30+
if self.worker is not None:
31+
self.worker.work()
32+
33+
class SuperWorker(BaseWorker):
34+
35+
@staticmethod
36+
def work():
37+
print("I work very hard!!!")
38+
39+
40+
class LazyWorker(BaseWorker):
41+
''' This is a bonus class. It is not in the conditions. '''
42+
43+
@staticmethod
44+
def work():
45+
print("Let me sleep!")
46+
47+
48+
worker = Worker()
49+
manager = Manager()
50+
manager.set_worker(worker)
51+
manager.manage()
52+
53+
super_worker = SuperWorker()
54+
lazy_worker = LazyWorker() # bonus instance
55+
try:
56+
manager.set_worker(super_worker)
57+
manager.manage()
58+
59+
manager.set_worker(lazy_worker)
60+
manager.manage() # bonus print
61+
except AssertionError:
62+
print("manager fails to support super_worker....")
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
from abc import ABC, abstractmethod
2+
import time
3+
4+
5+
class Workable(ABC):
6+
7+
@staticmethod
8+
@abstractmethod
9+
def work():
10+
pass
11+
12+
13+
class Eatable(ABC):
14+
15+
@staticmethod
16+
@abstractmethod
17+
def eat():
18+
pass
19+
20+
21+
class Worker(Workable, Eatable):
22+
23+
@staticmethod
24+
def work():
25+
print("I'm normal worker. I'm working.")
26+
27+
@staticmethod
28+
def eat():
29+
print("Lunch break....(5 secs)")
30+
time.sleep(5)
31+
32+
class SuperWorker(Workable, Eatable):
33+
34+
@staticmethod
35+
def work():
36+
print("I'm super worker. I work very hard!")
37+
38+
@staticmethod
39+
def eat():
40+
print("Lunch break....(3 secs)")
41+
time.sleep(3)
42+
43+
44+
class Robot(Workable):
45+
46+
@staticmethod
47+
def work():
48+
print("I'm a robot. I'm working....")
49+
50+
51+
class BaseManager(ABC):
52+
53+
def __init__(self):
54+
self.worker = None
55+
56+
@abstractmethod
57+
def set_worker(self, worker):
58+
pass
59+
60+
61+
class WorkManager(BaseManager):
62+
63+
def set_worker(self, worker):
64+
assert isinstance(worker, Workable), f"`worker` must be of type {Workable}"
65+
66+
self.worker = worker
67+
68+
def manage(self):
69+
self.worker.work()
70+
71+
72+
class BreakManager(BaseManager):
73+
74+
def set_worker(self, worker):
75+
assert isinstance(worker, Eatable), f"`worker` must be of type {Eatable}"
76+
77+
self.worker = worker
78+
79+
def lunch_break(self):
80+
self.worker.eat()
81+
82+
83+
work_manager = WorkManager()
84+
break_manager = BreakManager()
85+
86+
worker = Worker()
87+
work_manager.set_worker(worker)
88+
break_manager.set_worker(worker)
89+
work_manager.manage()
90+
break_manager.lunch_break()
91+
92+
super_worker = SuperWorker()
93+
work_manager.set_worker(super_worker)
94+
break_manager.set_worker(super_worker)
95+
work_manager.manage()
96+
break_manager.lunch_break()
97+
98+
robot = Robot()
99+
work_manager.set_worker(robot)
100+
work_manager.manage()
101+
102+
# try:
103+
# break_manager.set_worker(robot)
104+
# except AssertionError:
105+
# print("Robots don't eat")
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
class Person:
2+
3+
def __init__(self, position):
4+
self.position = position
5+
6+
7+
class FreePerson(Person):
8+
9+
def __init__(self, position):
10+
super().__init__(position)
11+
12+
def walk_north(self, dist):
13+
self.position[1] += dist
14+
15+
def walk_east(self, dist):
16+
self.position[0] += dist
17+
18+
19+
class Prisoner(Person):
20+
PRISON_LOCATION = [3, 3]
21+
22+
def __init__(self):
23+
super().__init__(self.PRISON_LOCATION[::])
24+
self.is_free = False
25+
26+
27+
prisoner = Prisoner()
28+
print("The prisoner trying to walk to north by 10 and east by -3.")
29+
30+
try:
31+
prisoner.walk_north(10)
32+
prisoner.walk_east(-3)
33+
except:
34+
pass
35+
36+
print(f"The location of the prison: {tuple(prisoner.PRISON_LOCATION)}")
37+
print(f"The current position of the prisoner: {tuple(prisoner.position)}")
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
from abc import ABC, abstractmethod
2+
from math import pi
3+
4+
5+
class Shape(ABC):
6+
7+
@abstractmethod
8+
def calculate_area(self):
9+
pass
10+
11+
12+
class Rectangle(Shape):
13+
14+
def __init__(self, width, height):
15+
self.width = width
16+
self.height = height
17+
18+
def calculate_area(self):
19+
return self.width * self.height
20+
21+
22+
class Square(Shape):
23+
24+
def __init__(self, side):
25+
self.side = side
26+
27+
def calculate_area(self):
28+
return self.side * self.side
29+
30+
31+
class Triangle(Shape):
32+
33+
def __init__(self, width, height):
34+
self.width = width
35+
self.height = height
36+
37+
def calculate_area(self):
38+
return (self.width * self.height) / 2
39+
40+
41+
class Circle(Shape):
42+
43+
def __init__(self, radius):
44+
self.radius = radius
45+
46+
def calculate_area(self):
47+
return self.radius * self.radius * pi
48+
49+
50+
class AreaCalculator:
51+
52+
def __init__(self, shapes):
53+
54+
assert isinstance(shapes, list), "`shapes` should be of type `list`."
55+
self.shapes = shapes
56+
57+
@property
58+
def total_area(self):
59+
total = 0
60+
for shape in self.shapes:
61+
total += shape.calculate_area()
62+
63+
return total
64+
65+
66+
shapes = [Rectangle(1, 6), Triangle(2, 3)]
67+
calculator = AreaCalculator(shapes)
68+
print("The total area is: ", calculator.total_area)
69+
70+
71+
72+
# ''' MY TESTS '''
73+
# shapes = [Rectangle(2, 3), Square(5), Triangle(4, 6), Circle(2)]
74+
# calculator = AreaCalculator(shapes)
75+
# print("The \"ALL\" shapes total area is: ", calculator.total_area)
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
from abc import ABC, abstractmethod
2+
3+
4+
class IContent(ABC):
5+
6+
def __init__(self, text):
7+
self.text = text
8+
9+
@abstractmethod
10+
def format(self):
11+
pass
12+
13+
14+
class MyContent(IContent):
15+
16+
def format(self):
17+
return f"<MyML>{self.text}</MyML>"
18+
19+
20+
class EncryptedContent(IContent):
21+
22+
def format(self):
23+
result = ""
24+
for letter in self.text:
25+
result += chr(ord(letter) + 5)
26+
return result
27+
28+
29+
class MaskedContent(IContent):
30+
31+
def format(self):
32+
return '*' * len(self.text)
33+
34+
35+
class IEmail(ABC):
36+
37+
@abstractmethod
38+
def set_sender(self, sender):
39+
pass
40+
41+
@abstractmethod
42+
def set_receiver(self, receiver):
43+
pass
44+
45+
@abstractmethod
46+
def set_content(self, content):
47+
pass
48+
49+
50+
class Email(IEmail):
51+
52+
def __init__(self, protocol):
53+
self.protocol = protocol
54+
self.__sender = None
55+
self.__receiver = None
56+
self.__content = None
57+
58+
def set_sender(self, sender):
59+
self.__sender = sender
60+
61+
def set_receiver(self, receiver):
62+
self.__receiver = receiver
63+
64+
def set_content(self, content):
65+
self.__content = content
66+
67+
def __repr__(self):
68+
template = "Sender: I\'m {sender}\nReceiver: I\'m {receiver}\nContent:\n{content}"
69+
70+
return template.format(sender=self.__sender, receiver=self.__receiver, content=self.__content.format())
71+
72+
73+
email = Email('IM')
74+
email.set_sender('qmal')
75+
email.set_receiver('james')
76+
content = MyContent('Hello, there!')
77+
email.set_content(content)
78+
print(email)
79+
80+
81+
# 'More tests'
82+
# print()
83+
# content = EncryptedContent('Hello, there!')
84+
# email.set_content(content)
85+
# print(email)
86+
#
87+
# print()
88+
#
89+
# content = MaskedContent('Hello, there!')
90+
# email.set_content(content)
91+
# print(email)

0 commit comments

Comments
 (0)