Requirements
The system will be used by customers looking to park, the manager who manages the parking lot and the parking lot attendant.
Define Core Objects
The main objects will be the parking lot as a whole, each floor of the parking lot, individual parking spaces, and the vehicles that occupy parking spaces.
Analyze Relationships
The parking lot will have a collection of floors and each floor will have a collection of parking spaces. The parking spaces will be either occupied by a vehicle object or vacant. We need a vehicle object to keep track of so we know what car / account to charge.
Establish Hierarchy
We could have each individual vehicle subtype (car, truck, ev, etc.) inherit from a vehicle class. Also we could have each individual parking spot type (associated with the vehicle type) inherit from a parking spot class
Design Patterns
We could use singleton for the parking system. We could use a factory pattern to populate the parking spots for each floor.
Define Class Members (write code)
Attributes: For each class, define the attributes (data) it will hold...
Methods: Define the methods (functions) that operate on the attributes. Ensure they align with the object's responsibilities and adhere to the principle of encapsulation.
from abc import ABC, @abstractmethod
class ParkingSystem:
def init(self):
self.__floors = {}
class Floor:
def init(self, evs, oversized, bike, regular, space_factory):
self.ev_spaces = []
self.reg_spaces = []
self.bike_spaces = []
self.oversized_spaces = []
self.space_factory = space_factory
self.build_floor(self, evs, oversized, bike, regular)
def build_floor(self, evs, oversized, bike, regular):
self.ev_spaces = self.SpaceFactory(1, evs)
self.reg_spaces = self.SpaceFactory(2, regular)
self.bike_spaces = self.SpaceFactory(3, bike)
self.oversized_spaces = self.SpaceFactory(4, oversized)
class SpaceFactory:
def build_spaces(self, type, count):
spaces = []
if type == 1:
for _ in range(count):
spaces.append(EVSpot())
#do this for each parking spot type
class ParkingSpot(ABC):
def init(self, availability, spotID):
self.__availability = True
self.__occupiedCar = None
self.__spotID = spotID
@abstractmethod
def assign_car(self, vehicle):
pass
#replicate this for each spot type
class EVSpot(ParkingSpot):
def init(self, availability):
super.init(availability, spotID)
def assign_car(self, vehicle):
if self.__availability:
self.__occupiedCar = vehicle
self.__availability = False
else:
return ValueError
def unassign_car(self, vehicle):
if not self.__availability:
return ValueError
else:
self.__availability = True
self.__occupiedCar = None
class Vehicle(ABC):
def init(self, account, assigned_spot):
self.__account = account
self.__assigned_spot = assigned_spot
self.__v_type = None
class EV(Vehicle):
def init(self, account, assigned_spot):
self.__v_type = 1
self.__ticket = None
self.__time = None
super.init(account, assigned_spot)
def take_ticket(self, ticket, time_stamp)
self.__time = time_stamp
self.__ticket = ticket
class TicketProcessor:
def ProcessTicket(self, ticket, vehicle, currentTime):
#get current time
elapsed_time = currentTime - ticket.get_timestamp()
#calculate fee 5 dollars per hour rounded up to the nearest hour
fee = 5 * ceil(elapsed_time)
return fee
class Ticket:
def init(self, ticketid, timestamp)
Adhere to SOLID Guidelines
Check and explain whether your design adheres to solid principles (Ask interviewer what SOLID principle is if you can not recall it.)...
Consider Scalability and Flexibility
Explain how your design can handle changes in scale and whether it would be easily to extend with new functionalities...
Create/Explain your diagram(s)
Try creating a class, flow, state and/or sequence diagram using the diagramming tool. Mermaid flow diagrams can be used to represent system use cases. You can ask the interviewer bot to create a starter diagram if unfamiliar with the tool. Briefly explain your diagrams if necessary...
Future improvements
Critically examine your design for any flaws or areas for future improvement...