OODesign for Parking lot
Requirements¶
- We need a simple system which can be used by a cutomer to check if there is a parking available
- Customer should be able to park the vehicle and later retrieve it back
- Customer can pay by card or cash
Actors and usecases¶
- For now lets keep things simple and only have a customer who comes and parks the vehicle
- Customer should be able to :
- Check available parking and cost
- Park
- Unpark
- Pay
- Search by ticket
Classes and responsibilities¶
- Vehicle
- Take care of parking area / size required to park it
- Park/Unpark itself
- The identity of the vehicle
- This will be an abstract class
- User
- a super class responsible for identifying the user
- This can be extended by Customer , Agent or Parking lot manager later on
- ParkingSpot
- this will represent the actual spot used to park
- there can be different types of the spots - small medium large
- these spots can be added or remove wrt to the parking lot
- ParkingLot
- This holds all pieces together
- This should be responsible to tie all the things together
- This should take a parking request, park, generate ticket and return to the customer
- This should also take a ticket and then search the vehicle and unpark upon the request
- Payment
- this should handle the way customer wants to make payment
- it can be an interface and different types of payments can implement it
- implementations can implement their functionality
- ParkingLotCLI
- This will be a helper CLI for cutomer (should be extensible to other actors later)
- This will be primarily responsible for taking inputs from user and display of state for user
- Ticket
- this will just be a simple object to identify the reservation with customer
- it handles the way ticket should be printed and what needs to printed on it
- it will be responsible for maintainig the count of ticket id uniquely
You can run this program online here at : https://colab.research.google.com/drive/1xFTn7Z0dKD2ibAVdqnG0ELGLZNDYwVw1
In [50]:
from abc import ABC, abstractmethod
import time
import enum
class Vehicle(ABC):
def __init__(self, vehicle_id):
self.id = vehicle_id
def park(self, spot):
spot.hold_spot(self)
def unpark(self, spot):
spot.free_spot(self)
@abstractmethod
def size(self):
pass
@abstractmethod
def pricing(self):
pass
class SpotSize(enum.Enum):
SMALL = 0
MEDIUM = 1
LARGE = 2
XLARGE = 3
class PriceStrategy(object):
BIKE = 100
CAR = 300
BUS = 1000
class Bike(Vehicle):
def size(self):
return SpotSize.SMALL
def pricing(self):
return PriceStrategy.BIKE
class Car(Vehicle):
def size(self):
return SpotSize.MEDIUM
def pricing(self):
return PriceStrategy.CAR
class User(object):
def __init__(self, name):
self.name = name
class Customer(User):
def __init__(self, name):
super(Customer, self).__init__(name)
vehicle = None
class Ticket(object):
COUNTER = 0
def __init__(self, customer, vehicle):
self.id = Ticket.COUNTER
Ticket.COUNTER += 1
self.customer_name = customer.name
self.vehicle_id = vehicle.id
self.creation_time = time.time()
def get_print(self):
s = ('------------------------\n Ticket id : %s\n Customer name : %s\n'
' Vehicle Id: %s\n Creation time : %f\n------------------------\n')%(self.id, self.customer_name, self.vehicle_id, self.creation_time)
return s
class ParkingSpot(object):
def __init__(self, id, size):
self.id = id
self.size = size
self.available = True
self.parked = False
self.vehicle = None
def hold_spot(self, vehicle):
self.parked = True
self.vehicle = vehicle
def free_spot(self):
self.parked = False
self.vehicle = None
class ParkingLot(object):
def __init__(self, parking_spots):
self.parking_spots = parking_spots
self.ticket_to_spot = {}
def print_ticket(self, ticket):
print(ticket.get_print())
def book_parking(self, customer, vehicle)-> Ticket:
booked_spot = None
for spot in self.parking_spots:
if spot.available and vehicle.size() == spot.size:
spot.hold_spot(vehicle)
booked_spot = spot
break
if booked_spot:
ticket = Ticket(customer, vehicle)
self.ticket_to_spot[ticket.id] = booked_spot
return ticket
else:
return None
def free_parking(self, ticket_id):
if ticket_id in self.ticket_to_spot:
booked_spot = self.ticket_to_spot[ticket_id]
booked_spot.free_spot()
del self.ticket_to_spot[ticket_id]
In [51]:
class UserType(enum.Enum):
CUSTOMER = 0
AGENT = 1
MANAGER = 2
class UserAction(enum.Enum):
PARK = 0
UNPARK = 1
ADD_VEHICLE = 2
REMOVE_VEHICLE = 3
ADD_AGENT = 4
REMOVE_AGENT = 5
ADD_SPOT = 6
REMOVE_SPOT = 7
SEE_ALL_TICKETS = 8
class ParkingLotCLI(object):
def __init__(self, total_spots):
small_spots = total_spots//3
medium_spots = total_spots//3
large_spots = total_spots - small_spots - medium_spots
spots = []
for i in range(small_spots):
spots.append(ParkingSpot('s_%d'%i, SpotSize.SMALL))
for i in range(medium_spots):
spots.append(ParkingSpot('m_%d'%i, SpotSize.MEDIUM))
for i in range(large_spots):
spots.append(ParkingSpot('l_%d'%i, SpotSize.LARGE))
self.parking_lot = ParkingLot(spots)
def _choose_user(self):
print('Choose 1)Customer 2)Agent 3)Manager\n')
choice = input('?')
if choice == '1':
return UserType.CUSTOMER
elif choice == '2':
return UserType.AGENT
else:
print('Not supported yet')
def _choose_action(self, user_type):
if user_type == UserType.CUSTOMER:
print('Choose action 1)Park 2)Unpark\n')
choice = input('?')
if choice == '1':
return UserAction.PARK
elif choice == '2':
return UserAction.UNPARK
else:
print('Not supported yet')
elif user_type == UserType.AGENT:
print('Choose action 1)See all tickets\n')
choice = input('?')
if choice == '1':
return UserAction.SEE_ALL_TICKETS
else:
print('Not supported yet')
else:
print('Not supported yet')
def _act(self, user_action):
if user_action == UserAction.PARK:
name = input('What is your name ? ')
customer = Customer(name)
vehicle = None
vehicle_type = input('What is your Vehicle type ? 1) Car 2) Bike')
vehicle_id = input('What is your Vehicle identifier ? ')
if vehicle_type == '1':
vehicle = Car(vehicle_id)
elif vehicle_type == '2':
vehicle = Bike(vehicle_id)
else:
print('Not supported yet')
ticket = self.parking_lot.book_parking(customer, vehicle)
if ticket:
print('Congrats, here is your ticket : \n %s \n' % ticket.get_print())
else:
print('Sorry unable to book parking')
elif user_action == UserAction.UNPARK:
ticket_id = input('What is yout ticket number ? ')
self.parking_lot.free_parking(int(ticket_id))
elif user_action == UserAction.SEE_ALL_TICKETS:
print('Following are all the tickets active :\n')
if len(self.parking_lot.ticket_to_spot) == 0:
print('[[[ No active tickets ]]]\n')
for ticket_id, spot in self.parking_lot.ticket_to_spot.items():
print('----------------------------\n')
print('Ticket id : %d\n' % ticket_id)
print('Parking spot id : %s\n' % spot.id)
print('----------------------------\n')
else:
print('Not supported yet')
def start(self):
while True:
user_type = self._choose_user()
action = self._choose_action(user_type)
self._act(action)
In [ ]:
cli = ParkingLotCLI(10)
cli.start()
In [ ]:
No comments:
Post a Comment