2017-03-04 09:54:23 +07:00
{
" cells " : [
{
" cell_type " : " markdown " ,
" metadata " : { } ,
" source " : [
2018-08-13 07:49:30 +07:00
" This notebook was prepared by [Donne Martin](https://github.com/donnemartin). Source and license info is on [GitHub](https://github.com/donnemartin/system-design-primer). "
2017-03-04 09:54:23 +07:00
]
} ,
{
" cell_type " : " markdown " ,
" metadata " : { } ,
" source " : [
" # Design a parking lot "
]
} ,
{
" cell_type " : " markdown " ,
" metadata " : { } ,
" source " : [
" ## Constraints and assumptions \n " ,
" \n " ,
" * What types of vehicles should we support? \n " ,
" * Motorcycle, Car, Bus \n " ,
" * Does each vehicle type take up a different amount of parking spots? \n " ,
" * Yes \n " ,
" * Motorcycle spot -> Motorcycle \n " ,
" * Compact spot -> Motorcycle, Car \n " ,
" * Large spot -> Motorcycle, Car \n " ,
" * Bus can park if we have 5 consecutive \" large \" spots \n " ,
" * Does the parking lot have multiple levels? \n " ,
" * Yes "
]
} ,
{
" cell_type " : " markdown " ,
" metadata " : { } ,
" source " : [
" ## Solution "
]
} ,
{
" cell_type " : " code " ,
" execution_count " : 1 ,
" metadata " : {
" collapsed " : false
} ,
" outputs " : [
{
" name " : " stdout " ,
" output_type " : " stream " ,
" text " : [
" Overwriting parking_lot.py \n "
]
}
] ,
" source " : [
" %% writefile parking_lot.py \n " ,
" from abc import ABCMeta, abstractmethod \n " ,
" \n " ,
" \n " ,
" class VehicleSize(Enum): \n " ,
" \n " ,
" MOTORCYCLE = 0 \n " ,
" COMPACT = 1 \n " ,
" LARGE = 2 \n " ,
" \n " ,
" \n " ,
" class Vehicle(metaclass=ABCMeta): \n " ,
" \n " ,
" def __init__(self, vehicle_size, license_plate, spot_size): \n " ,
" self.vehicle_size = vehicle_size \n " ,
" self.license_plate = license_plate \n " ,
2017-05-30 07:55:32 +07:00
" self.spot_size = spot_size \n " ,
2017-03-04 09:54:23 +07:00
" self.spots_taken = [] \n " ,
" \n " ,
" def clear_spots(self): \n " ,
" for spot in self.spots_taken: \n " ,
" spot.remove_vehicle(self) \n " ,
" self.spots_taken = [] \n " ,
" \n " ,
" def take_spot(self, spot): \n " ,
" self.spots_taken.append(spot) \n " ,
" \n " ,
" @abstractmethod \n " ,
" def can_fit_in_spot(self, spot): \n " ,
" pass \n " ,
" \n " ,
" \n " ,
" class Motorcycle(Vehicle): \n " ,
" \n " ,
" def __init__(self, license_plate): \n " ,
" super(Motorcycle, self).__init__(VehicleSize.MOTORCYCLE, license_plate, spot_size=1) \n " ,
" \n " ,
" def can_fit_in_spot(self, spot): \n " ,
" return True \n " ,
" \n " ,
" \n " ,
" class Car(Vehicle): \n " ,
" \n " ,
" def __init__(self, license_plate): \n " ,
" super(Car, self).__init__(VehicleSize.COMPACT, license_plate, spot_size=1) \n " ,
" \n " ,
" def can_fit_in_spot(self, spot): \n " ,
" return True if (spot.size == LARGE or spot.size == COMPACT) else False \n " ,
" \n " ,
" \n " ,
" class Bus(Vehicle): \n " ,
" \n " ,
" def __init__(self, license_plate): \n " ,
" super(Bus, self).__init__(VehicleSize.LARGE, license_plate, spot_size=5) \n " ,
" \n " ,
" def can_fit_in_spot(self, spot): \n " ,
" return True if spot.size == LARGE else False \n " ,
" \n " ,
" \n " ,
" class ParkingLot(object): \n " ,
" \n " ,
" def __init__(self, num_levels): \n " ,
" self.num_levels = num_levels \n " ,
" self.levels = [] \n " ,
" \n " ,
" def park_vehicle(self, vehicle): \n " ,
" for level in levels: \n " ,
" if level.park_vehicle(vehicle): \n " ,
" return True \n " ,
" return False \n " ,
" \n " ,
" \n " ,
" class Level(object): \n " ,
" \n " ,
" SPOTS_PER_ROW = 10 \n " ,
" \n " ,
" def __init__(self, floor, total_spots): \n " ,
" self.floor = floor \n " ,
" self.num_spots = total_spots \n " ,
" self.available_spots = 0 \n " ,
" self.parking_spots = [] \n " ,
" \n " ,
" def spot_freed(self): \n " ,
" self.available_spots += 1 \n " ,
" \n " ,
" def park_vehicle(self, vehicle): \n " ,
" spot = self._find_available_spot(vehicle) \n " ,
" if spot is None: \n " ,
" return None \n " ,
" else: \n " ,
" spot.park_vehicle(vehicle) \n " ,
" return spot \n " ,
" \n " ,
" def _find_available_spot(self, vehicle): \n " ,
" \" \" \" Find an available spot where vehicle can fit, or return None \" \" \" \n " ,
" # ... \n " ,
" \n " ,
" def _park_starting_at_spot(self, spot, vehicle): \n " ,
" \" \" \" Occupy starting at spot.spot_number to vehicle.spot_size. \" \" \" \n " ,
" # ... \n " ,
" \n " ,
" \n " ,
" class ParkingSpot(object): \n " ,
" \n " ,
" def __init__(self, level, row, spot_number, spot_size, vehicle_size): \n " ,
" self.level = level \n " ,
" self.row = row \n " ,
" self.spot_number = spot_number \n " ,
" self.spot_size = spot_size \n " ,
" self.vehicle_size = vehicle_size \n " ,
" self.vehicle = None \n " ,
" \n " ,
" def is_available(self): \n " ,
" return True if self.vehicle is None else False \n " ,
" \n " ,
" def can_fit_vehicle(self, vehicle): \n " ,
" if self.vehicle is not None: \n " ,
" return False \n " ,
" return vehicle.can_fit_in_spot(self) \n " ,
" \n " ,
" def park_vehicle(self, vehicle): # ... \n " ,
" def remove_vehicle(self): # ... "
]
}
] ,
" metadata " : {
" kernelspec " : {
" display_name " : " Python 3 " ,
" language " : " python " ,
" name " : " python3 "
} ,
" language_info " : {
" codemirror_mode " : {
" name " : " ipython " ,
" version " : 3
} ,
" file_extension " : " .py " ,
" mimetype " : " text/x-python " ,
" name " : " python " ,
" nbconvert_exporter " : " python " ,
" pygments_lexer " : " ipython3 " ,
" version " : " 3.4.3 "
}
} ,
" nbformat " : 4 ,
" nbformat_minor " : 0
}