{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "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)." ] }, { "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", " self.spot_size = spot_size\n", " 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 }