Design a Math Expression Library

import abc
class Expression(abc.ABC):
@abc.abstractmethod
def evaluate(self):
pass
@abc.abstractmethod
def simplify(self):
pass

class Number(Expression):
def __init__(self, num):
self.num = num
def evaluate(self):
return self.num
def simplify(self):
return ascii(self.num)

class Variable(Expression):
def __init__(self, var, num):
self.var = var
self.num = num
def evaluate(self):
return self.num
def simplify(self):
return self.var

class Parenthersis(Expression):
def __init__(self, express):
self.express = express
def evaluate(self):
return self.express.evaluate()
def simplify(self):
return "(" + self.express.simplify() + ")"

class Operator(Expression):
pass
class Addition(Operator):
def __init__(self, right, left):
self.left, self.right = left, right

def evaluate(self):
return self.left.evaluate() + self.right.evaluate()

def simplify(self):
if self.left.simplify == "0":
return self.right.simplify()
elif self.right.simplify() == "0":
return self.left.simplify()

elif self.left.simplify == "0" and self.right.simplify() == "0":
return "0"

return self.left.simplify() + "+" + self.right.simplify()

class Multiplication(Operator):
def __init__(self, right, left):
self.left, self.right = left, right
def evaluate(self):
return self.left.evaluate() * self.right.evaluate()

def simplify(self):
if self.left.simplify == "1":
return self.right.simplify()
elif self.right.simplify() == "1":
return self.left.simplify()
elif self.left.simplify == "1" and self.right.simplify() == "1":
return "1"
return self.left.simplify() + "*" + self.right.simplify()
# Test 
# 5*(a+2)*b+a
a = Variable("a", 1)
b = Variable("b", 2)
num2 = Number(2)
num5 = Number(5)
sub = Multiplication(b, Parenthersis(Addition(num2,a)))
exp = Addition(a, Multiplication(sub,num5))
print(exp.simplify())
print(exp.evaluate())

# Test
# a*b*(0+a)*1
a = Variable("a", 1)
b = Variable("b", 0)
num1 = Number(1)
num0 = Number(0)
sub = Multiplication(b, Parenthersis(Addition(num0,a)))
exp = Addition(a, Multiplication(sub,num1))
print(exp.simplify())
print(exp.evaluate())

Design Elevator

class Door:
def __init__(self, floor):
self.floor = floor
def open(self):
print(f"{self.floor} door opened")
self.status = "door opened"
def close(self):
print(f"{self.floor} door closed")
self.status = "door close"
class Button:
def __init__(self, floor, name):
self.floor = floor
self.name = name
self.on = None
self.systemObservers = []
def request(self):
if not self.on:
self.systemNotify()
self.on = True
print(f"{self.floor} Button activated")
def turnon(self):
self.on = True
print(f"{self.floor} Button turned on")
def turnoff(self):
self.on = False
print(f"{self.floor} Button turned off")
def systemRegister(self, observer):
self.systemObservers.append(observer)
def systemNotify(self):
for observer in self.systemObservers:
if self.name == "elevator":
observer.elevatorButtonNotify(self.floor)
elif self.name == "up":
observer.floorButtonNotify(self.floor, True)
elif self.name == "down":
observer.floorButtonNotify(self.floor, False)
class Floor:
def __init__(self, floor):
self.floor = floor
self.door = Door(floor)
self.upButton = Button(floor, "up")
self.downButton = Button(floor, "down")
self.systemObserver = []

def opendoor(self, isUp):
self.door.open()
self.updateButton(isUp)
def closedoor(self):
self.door.close()
def systemRegister(self, observer):
self.systemObserver.append(observer)
self.upButton.systemRegister(observer)
self.downButton.systemRegister(observer)
def updateButton(self, isUp):
if isUp:
self.upButton.turnoff()
else:
self.downButton.turnoff()
class Elevator:
def __init__(self, story):
self.story = story
self.buttons = [Button(i, "elevator") for i in range(story)]
self.door = Door(-1)
self.currentfloor = 0
self.systemObserver = None
def opendoor(self, floor):
self.door.open()
self.systemObserver.floors[floor].opendoor(self.systemObserver.directionUp)
def closedoor(self, floor):
self.door.close()
self.systemObserver.floors[floor].closedoor()
def moveup(self):
if self.currentfloor < self.story:
self.currentfloor += 1
self.systemObserver.elevatorNotify(self.currentfloor)
def movedown(self):
if self.currentfloor > 1:
self.currentfloor -= 1
self.systemObserver.elevatorNotify(self.currentfloor)
def SystemRegister(self, observer):
self.systemObserver = observer
for button in self.buttons:
button.systemRegister(observer)
import heapq, time
class ElevatorSystem:
def __init__(self, story):
self.story = story
self.floors = [Floor(i) for i in range(story)]
for floor in self.floors:
floor.systemRegister(self)
self.elevator = Elevator(story)
self.elevator.SystemRegister(self)

self.maxHeap = []
self.minHeap = []
self.directionUp = True
self.currentHeap = self.minHeap
self.moveElevator = self.elevator.moveup
self.currentFloor = 0
self.operation = True

def operate(self):
while self.operation:
while self.currentHeap:
floor = self.currentHeap.pop()
while self.currentFloor != floor:
self.moveElevator()
s.elevator.opendoor(floor)
s.elevator.closedoor(floor)
self.directionChange()
def directionChange(self):
time.sleep(1)
self.directionUp = not self.directionUp
if self.directionUp:
self.currentHeap = self.minHeap
self.moveElevator = self.elevator.moveup
else:
self.currentHeap = self.maxHeap
self.moveElevator = self.elevator.movedown
def stop(self):
self.minHeap.clear()
self.maxHeap.clear()
self.operation = False
def elevatorButtonNotify(self, floor):
if self.currentFloor < floor:
heapq.heappush(self.minHeap, floor)
else:
heapq.heappush(self.maxHeap, floor)
def floorButtonNotify(self, floor, isUp):
if self.currentFloor < floor:
heapq.heappush(self.minHeap, floor)
else:
heapq.heappush(self.maxHeap, floor)
def elevatorNotify(self, floor):
self.currentFloor = floor
def __str__(self):
s = f"{self.currentFloor}, is Elevator Going up?: {self.directionUp}, current Heap: {self.currentHeap} "
return s
import threading
def simpleTest():
s = ElevatorSystem(5)
threading.Thread(target=s.operate).start()


time.sleep(1)
s.floors[2].upButton.request()
time.sleep(1)
print(s)
s.elevator.buttons[4].request()
print(s)
s.elevator.buttons[0].request()
print(s)
s.floors[4].upButton.request()
s.floors[3].upButton.request()
print(s)
s.stop()

Singleton Pattern

class Logger(object):
_instance = None
def __init__(self):
raise RuntimeError('Error: Call instance() instead')
@classmethod
def instance(cls):
if cls._instance is None:
print('Creating new instance')
cls._instance = cls.__new__(cls)
return cls._instance
def __str__(self):
return "singleton pattern"

try:
l = Logger()
except RuntimeError as err:
print(err)
l = Logger.instance()
print(type(l))
print(l)