Added python code example for parking lot - object oriented system design
parent
478a7d76fb
commit
61d889e6f4
|
@ -0,0 +1,275 @@
|
||||||
|
{
|
||||||
|
"total_number_of_parking_lot": 1,
|
||||||
|
"total_number_of_levels": 2,
|
||||||
|
"number_of_rows_in_each_level": 2,
|
||||||
|
"number_of_spots_in_each_row": 10,
|
||||||
|
"levels": {
|
||||||
|
"level_1": [
|
||||||
|
{
|
||||||
|
"level": 1,
|
||||||
|
"row": 1,
|
||||||
|
"spot_number": 1,
|
||||||
|
"spot_size": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 1,
|
||||||
|
"row": 1,
|
||||||
|
"spot_number": 2,
|
||||||
|
"spot_size": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 1,
|
||||||
|
"row": 1,
|
||||||
|
"spot_number": 3,
|
||||||
|
"spot_size": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 1,
|
||||||
|
"row": 1,
|
||||||
|
"spot_number": 4,
|
||||||
|
"spot_size": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 1,
|
||||||
|
"row": 1,
|
||||||
|
"spot_number": 5,
|
||||||
|
"spot_size": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 1,
|
||||||
|
"row": 1,
|
||||||
|
"spot_number": 6,
|
||||||
|
"spot_size": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 1,
|
||||||
|
"row": 1,
|
||||||
|
"spot_number": 7,
|
||||||
|
"spot_size": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 1,
|
||||||
|
"row": 1,
|
||||||
|
"spot_number": 8,
|
||||||
|
"spot_size": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 1,
|
||||||
|
"row": 1,
|
||||||
|
"spot_number": 9,
|
||||||
|
"spot_size": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 1,
|
||||||
|
"row": 1,
|
||||||
|
"spot_number": 10,
|
||||||
|
"spot_size": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 1,
|
||||||
|
"row": 2,
|
||||||
|
"spot_number": 1,
|
||||||
|
"spot_size": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 1,
|
||||||
|
"row": 2,
|
||||||
|
"spot_number": 2,
|
||||||
|
"spot_size": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 1,
|
||||||
|
"row": 2,
|
||||||
|
"spot_number": 3,
|
||||||
|
"spot_size": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 1,
|
||||||
|
"row": 2,
|
||||||
|
"spot_number": 4,
|
||||||
|
"spot_size": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 1,
|
||||||
|
"row": 2,
|
||||||
|
"spot_number": 5,
|
||||||
|
"spot_size": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 1,
|
||||||
|
"row": 2,
|
||||||
|
"spot_number": 6,
|
||||||
|
"spot_size": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 1,
|
||||||
|
"row": 2,
|
||||||
|
"spot_number": 7,
|
||||||
|
"spot_size": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 1,
|
||||||
|
"row": 2,
|
||||||
|
"spot_number": 8,
|
||||||
|
"spot_size": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 1,
|
||||||
|
"row": 2,
|
||||||
|
"spot_number": 9,
|
||||||
|
"spot_size": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 1,
|
||||||
|
"row": 2,
|
||||||
|
"spot_number": 10,
|
||||||
|
"spot_size": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"level_2": [
|
||||||
|
{
|
||||||
|
"level": 2,
|
||||||
|
"row": 1,
|
||||||
|
"spot_number": 1,
|
||||||
|
"spot_size": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 2,
|
||||||
|
"row": 1,
|
||||||
|
"spot_number": 2,
|
||||||
|
"spot_size": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 2,
|
||||||
|
"row": 1,
|
||||||
|
"spot_number": 3,
|
||||||
|
"spot_size": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 2,
|
||||||
|
"row": 1,
|
||||||
|
"spot_number": 4,
|
||||||
|
"spot_size": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 2,
|
||||||
|
"row": 1,
|
||||||
|
"spot_number": 5,
|
||||||
|
"spot_size": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 2,
|
||||||
|
"row": 1,
|
||||||
|
"spot_number": 6,
|
||||||
|
"spot_size": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 2,
|
||||||
|
"row": 1,
|
||||||
|
"spot_number": 7,
|
||||||
|
"spot_size": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 2,
|
||||||
|
"row": 1,
|
||||||
|
"spot_number": 8,
|
||||||
|
"spot_size": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 2,
|
||||||
|
"row": 1,
|
||||||
|
"spot_number": 9,
|
||||||
|
"spot_size": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 2,
|
||||||
|
"row": 1,
|
||||||
|
"spot_number": 10,
|
||||||
|
"spot_size": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 2,
|
||||||
|
"row": 2,
|
||||||
|
"spot_number": 1,
|
||||||
|
"spot_size": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 2,
|
||||||
|
"row": 2,
|
||||||
|
"spot_number": 2,
|
||||||
|
"spot_size": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 2,
|
||||||
|
"row": 2,
|
||||||
|
"spot_number": 3,
|
||||||
|
"spot_size": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 2,
|
||||||
|
"row": 2,
|
||||||
|
"spot_number": 4,
|
||||||
|
"spot_size": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 2,
|
||||||
|
"row": 2,
|
||||||
|
"spot_number": 5,
|
||||||
|
"spot_size": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 2,
|
||||||
|
"row": 2,
|
||||||
|
"spot_number": 6,
|
||||||
|
"spot_size": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 2,
|
||||||
|
"row": 2,
|
||||||
|
"spot_number": 7,
|
||||||
|
"spot_size": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 2,
|
||||||
|
"row": 2,
|
||||||
|
"spot_number": 8,
|
||||||
|
"spot_size": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 2,
|
||||||
|
"row": 2,
|
||||||
|
"spot_number": 9,
|
||||||
|
"spot_size": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"level": 2,
|
||||||
|
"row": 2,
|
||||||
|
"spot_number": 10,
|
||||||
|
"spot_size": 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"users":{
|
||||||
|
"1":{
|
||||||
|
"license_plate":"123-456",
|
||||||
|
"vehicle_type":"CAR",
|
||||||
|
"vehicle_size":"MEDIUM"
|
||||||
|
},
|
||||||
|
"2":{
|
||||||
|
"license_plate": "123-457",
|
||||||
|
"vehicle_type": "CAR",
|
||||||
|
"vehicle_size": "LARGE"
|
||||||
|
},
|
||||||
|
"3":{
|
||||||
|
"license_plate": "123-111",
|
||||||
|
"vehicle_type": "MOTORCYCLE",
|
||||||
|
"vehicle_size": "SMALL"
|
||||||
|
},
|
||||||
|
"4":{
|
||||||
|
"license_plate": "123-999",
|
||||||
|
"vehicle_type": "CAR",
|
||||||
|
"vehicle_size": "LARGE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,194 @@
|
||||||
|
import json
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
# design a parking lot
|
||||||
|
# assumption is vehicle size corresponds to spot size
|
||||||
|
|
||||||
|
"""
|
||||||
|
vehicle_size_small; spot_size = 0 => can park Motorcycle
|
||||||
|
vehicle_size_medium ; spot_size = 1 => can park Motorcycle or Car
|
||||||
|
vehicle_size_large ; spot_size = 2 => can park Motorcycle or Car
|
||||||
|
|
||||||
|
Bus can park if we have 5 consecutive "large" spots
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class VehicleType(Enum):
|
||||||
|
MOTORCYCLE = 'MOTORCYCLE',
|
||||||
|
CAR = 'CAR',
|
||||||
|
BUS = 'BUS'
|
||||||
|
|
||||||
|
|
||||||
|
class VehicleSize(Enum):
|
||||||
|
SMALL = 0
|
||||||
|
MEDIUM = 1
|
||||||
|
LARGE = 2
|
||||||
|
VERY_LARGE = 10
|
||||||
|
|
||||||
|
|
||||||
|
class Vehicle(object):
|
||||||
|
|
||||||
|
def __init__(self, vehicle_size, license_plate, vehicle_type):
|
||||||
|
self.vehicle_size = vehicle_size
|
||||||
|
self.license_plate = license_plate
|
||||||
|
self.vehicle_type = vehicle_type
|
||||||
|
self.spots_taken = []
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return """
|
||||||
|
vehicle_size : {vehicle_size},
|
||||||
|
license_plate : {license_plate},
|
||||||
|
vehicle_type : {vehicle_type},
|
||||||
|
spots_taken : {spots_taken}
|
||||||
|
""".format(vehicle_size=self.vehicle_size, license_plate=self.license_plate,
|
||||||
|
vehicle_type=self.vehicle_type, spots_taken=self.spots_taken)
|
||||||
|
|
||||||
|
def clear_spots(self):
|
||||||
|
for spot in self.spots_taken:
|
||||||
|
spot.remove_vehicle(self)
|
||||||
|
self.sport_taken = []
|
||||||
|
|
||||||
|
def take_spot(self, spot):
|
||||||
|
self.spots_taken.append(spot)
|
||||||
|
|
||||||
|
|
||||||
|
class ParkingLot(object):
|
||||||
|
def __init__(self, num_levels):
|
||||||
|
self.num_levels = num_levels
|
||||||
|
self.levels = []
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return """
|
||||||
|
number_of_levels : {num_levels},
|
||||||
|
levels : {levels}
|
||||||
|
""".format(num_levels=self.num_levels, levels=self.levels)
|
||||||
|
|
||||||
|
def park_vehicle(self, vehicle):
|
||||||
|
for level in self.levels:
|
||||||
|
spot = level.reserve_spot(vehicle)
|
||||||
|
if spot:
|
||||||
|
print(" == TICKET PRINTING - PARKING SPOT RESERVED == ")
|
||||||
|
print(vehicle)
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class ParkingLevel(object):
|
||||||
|
|
||||||
|
def __init__(self, level, total_spots):
|
||||||
|
|
||||||
|
self.level = level
|
||||||
|
self.num_spots = total_spots
|
||||||
|
self.available_spots = total_spots
|
||||||
|
self.parking_spots = []
|
||||||
|
self.reserved_spots = []
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return """
|
||||||
|
level : {level},
|
||||||
|
number_of_spots : {num_spots},
|
||||||
|
avialable_spots : {available_spots},
|
||||||
|
parking_spots : {parking_spots},
|
||||||
|
reserved_spots : {reserved_spots}
|
||||||
|
""".format(level=self.level, num_spots=self.num_spots, available_spots=self.available_spots,
|
||||||
|
parking_spots=self.parking_spots, reserved_spots=self.reserved_spots)
|
||||||
|
|
||||||
|
def spot_reserved(self, index, spot):
|
||||||
|
self.reserved_spots.append(spot)
|
||||||
|
self.parking_spots.pop(index)
|
||||||
|
self.available_spots -= 1
|
||||||
|
|
||||||
|
def reserve_spot(self, vehicle):
|
||||||
|
|
||||||
|
# for motorcycle or car for exact match
|
||||||
|
for index, parking_spot in enumerate(self.parking_spots):
|
||||||
|
|
||||||
|
if parking_spot.spot_size == vehicle.vehicle_size.value:
|
||||||
|
# parking_spot.vehicle = vehicle
|
||||||
|
self.spot_reserved(index, parking_spot)
|
||||||
|
vehicle.spots_taken.append(parking_spot)
|
||||||
|
return parking_spot
|
||||||
|
# for motorcycle or car no exact match;ie vehicle less then size of spot
|
||||||
|
for index, parking_spot in enumerate(self.parking_spots):
|
||||||
|
|
||||||
|
if parking_spot.spot_size > vehicle.vehicle_size.value:
|
||||||
|
# parking_spot.vehicle = vehicle
|
||||||
|
self.spot_reserved(index, parking_spot)
|
||||||
|
vehicle.spots_taken.append(parking_spot)
|
||||||
|
return parking_spot
|
||||||
|
# for bus , find 5 consecutive free spot
|
||||||
|
for index, parking_spot in enumerate(self.parking_spots):
|
||||||
|
|
||||||
|
if parking_spot.spot_size < vehicle.vehicle_size.value:
|
||||||
|
# if ... sliding window for checking 5 consecutive free spot
|
||||||
|
# loop parking_spot.vehicle = vehicle
|
||||||
|
# loop self.spot_reserved(index, parking_spot)
|
||||||
|
# loop vehicle.spots_taken.append(parking_spot)
|
||||||
|
# return parking_spot as string using ''.join()
|
||||||
|
pass
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class ParkingSpot(object):
|
||||||
|
def __init__(self, level, row, spot_number, spot_size):
|
||||||
|
self.level = level
|
||||||
|
self.row = row
|
||||||
|
self.spot_number = spot_number
|
||||||
|
self.spot_size = spot_size
|
||||||
|
self.vehicle = None
|
||||||
|
|
||||||
|
# logic for bus pending
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return """
|
||||||
|
level : {level},
|
||||||
|
row : {row},
|
||||||
|
spot_number : {spot_number},
|
||||||
|
spot_size : {spot_size}
|
||||||
|
vehicle : {vehicle}
|
||||||
|
""".format(level=self.level, row=self.row, spot_number=self.spot_number,
|
||||||
|
vehicle=self.vehicle, spot_size=self.spot_size)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
try:
|
||||||
|
f = open('input_parking_lot_example.json')
|
||||||
|
data = json.load(f)
|
||||||
|
except Exception as E:
|
||||||
|
print("Error opening input_parking_lot_example.json file")
|
||||||
|
print(E)
|
||||||
|
|
||||||
|
number_of_rows = data['number_of_rows_in_each_level']
|
||||||
|
number_of_spots_in_each_row = data['number_of_spots_in_each_row']
|
||||||
|
total_number_of_spots_in_level = number_of_rows * number_of_spots_in_each_row
|
||||||
|
number_of_levels = data['total_number_of_levels']
|
||||||
|
|
||||||
|
parking_lot = ParkingLot(num_levels=number_of_levels)
|
||||||
|
|
||||||
|
for level_name, level in data['levels'].items():
|
||||||
|
parking_level = ParkingLevel(level=level_name, total_spots=total_number_of_spots_in_level)
|
||||||
|
for spot in level:
|
||||||
|
parking_spot = ParkingSpot(
|
||||||
|
level=spot['level'],
|
||||||
|
row=spot['row'],
|
||||||
|
spot_number=spot['spot_number'],
|
||||||
|
spot_size=spot['spot_size']
|
||||||
|
)
|
||||||
|
parking_level.parking_spots.append(parking_spot)
|
||||||
|
parking_lot.levels.append(parking_level)
|
||||||
|
|
||||||
|
input_vehicle_list = []
|
||||||
|
for user_name, user in data['users'].items():
|
||||||
|
vehicle_q_id = user_name
|
||||||
|
vehicle = Vehicle(
|
||||||
|
vehicle_size=VehicleSize["MEDIUM"],
|
||||||
|
license_plate=user['license_plate'],
|
||||||
|
vehicle_type=VehicleType["CAR"])
|
||||||
|
input_vehicle_list.append(vehicle)
|
||||||
|
|
||||||
|
# processing of inputs in input_list
|
||||||
|
|
||||||
|
for idx, input_vehicle in enumerate(input_vehicle_list):
|
||||||
|
parking_lot.park_vehicle(input_vehicle)
|
Loading…
Reference in New Issue