2017-03-04 09:54:23 +07:00
|
|
|
from abc import ABCMeta, abstractmethod
|
2018-03-07 07:37:46 +07:00
|
|
|
from enum import Enum
|
2017-03-04 09:54:23 +07:00
|
|
|
|
|
|
|
|
|
|
|
class VehicleSize(Enum):
|
|
|
|
|
|
|
|
MOTORCYCLE = 0
|
|
|
|
COMPACT = 1
|
|
|
|
LARGE = 2
|
|
|
|
|
|
|
|
|
|
|
|
class Vehicle(metaclass=ABCMeta):
|
|
|
|
|
|
|
|
def __init__(self, vehicle_size, license_plate, spot_size):
|
|
|
|
self.vehicle_size = vehicle_size
|
|
|
|
self.license_plate = license_plate
|
|
|
|
self.spot_size
|
|
|
|
self.spots_taken = []
|
|
|
|
|
|
|
|
def clear_spots(self):
|
|
|
|
for spot in self.spots_taken:
|
|
|
|
spot.remove_vehicle(self)
|
|
|
|
self.spots_taken = []
|
|
|
|
|
|
|
|
def take_spot(self, spot):
|
|
|
|
self.spots_taken.append(spot)
|
|
|
|
|
|
|
|
@abstractmethod
|
|
|
|
def can_fit_in_spot(self, spot):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class Motorcycle(Vehicle):
|
|
|
|
|
|
|
|
def __init__(self, license_plate):
|
|
|
|
super(Motorcycle, self).__init__(VehicleSize.MOTORCYCLE, license_plate, spot_size=1)
|
|
|
|
|
|
|
|
def can_fit_in_spot(self, spot):
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
class Car(Vehicle):
|
|
|
|
|
|
|
|
def __init__(self, license_plate):
|
|
|
|
super(Car, self).__init__(VehicleSize.COMPACT, license_plate, spot_size=1)
|
|
|
|
|
|
|
|
def can_fit_in_spot(self, spot):
|
2018-04-09 07:25:11 +07:00
|
|
|
return spot.size in (VehicleSize.LARGE, VehicleSize.COMPACT)
|
2017-03-04 09:54:23 +07:00
|
|
|
|
|
|
|
|
|
|
|
class Bus(Vehicle):
|
|
|
|
|
|
|
|
def __init__(self, license_plate):
|
|
|
|
super(Bus, self).__init__(VehicleSize.LARGE, license_plate, spot_size=5)
|
|
|
|
|
|
|
|
def can_fit_in_spot(self, spot):
|
2018-04-09 07:25:11 +07:00
|
|
|
return spot.size == VehicleSize.LARGE
|
2017-03-04 09:54:23 +07:00
|
|
|
|
|
|
|
|
|
|
|
class ParkingLot(object):
|
|
|
|
|
|
|
|
def __init__(self, num_levels):
|
|
|
|
self.num_levels = num_levels
|
|
|
|
self.levels = [] # List of Levels
|
|
|
|
|
|
|
|
def park_vehicle(self, vehicle):
|
2018-05-07 08:25:31 +07:00
|
|
|
for level in self.levels:
|
2017-03-04 09:54:23 +07:00
|
|
|
if level.park_vehicle(vehicle):
|
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
class Level(object):
|
|
|
|
|
|
|
|
SPOTS_PER_ROW = 10
|
|
|
|
|
|
|
|
def __init__(self, floor, total_spots):
|
|
|
|
self.floor = floor
|
|
|
|
self.num_spots = total_spots
|
|
|
|
self.available_spots = 0
|
|
|
|
self.spots = [] # List of ParkingSpots
|
|
|
|
|
|
|
|
def spot_freed(self):
|
|
|
|
self.available_spots += 1
|
|
|
|
|
|
|
|
def park_vehicle(self, vehicle):
|
|
|
|
spot = self._find_available_spot(vehicle)
|
|
|
|
if spot is None:
|
|
|
|
return None
|
|
|
|
else:
|
|
|
|
spot.park_vehicle(vehicle)
|
|
|
|
return spot
|
|
|
|
|
|
|
|
def _find_available_spot(self, vehicle):
|
|
|
|
"""Find an available spot where vehicle can fit, or return None"""
|
2018-03-07 07:37:46 +07:00
|
|
|
pass
|
2017-03-04 09:54:23 +07:00
|
|
|
|
|
|
|
def _park_starting_at_spot(self, spot, vehicle):
|
|
|
|
"""Occupy starting at spot.spot_number to vehicle.spot_size."""
|
2018-03-07 07:37:46 +07:00
|
|
|
pass
|
2017-03-04 09:54:23 +07:00
|
|
|
|
|
|
|
|
|
|
|
class ParkingSpot(object):
|
|
|
|
|
|
|
|
def __init__(self, level, row, spot_number, spot_size, vehicle_size):
|
|
|
|
self.level = level
|
|
|
|
self.row = row
|
|
|
|
self.spot_number = spot_number
|
|
|
|
self.spot_size = spot_size
|
|
|
|
self.vehicle_size = vehicle_size
|
|
|
|
self.vehicle = None
|
|
|
|
|
|
|
|
def is_available(self):
|
|
|
|
return True if self.vehicle is None else False
|
|
|
|
|
|
|
|
def can_fit_vehicle(self, vehicle):
|
|
|
|
if self.vehicle is not None:
|
|
|
|
return False
|
|
|
|
return vehicle.can_fit_in_spot(self)
|
|
|
|
|
2018-03-07 07:37:46 +07:00
|
|
|
def park_vehicle(self, vehicle):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def remove_vehicle(self):
|
|
|
|
pass
|