Skip to content

parking_spot_strategy

Strategy: To find parking spot.

FindNearestSpotStrategy

Bases: FindParkingSpotStrategy

Derived Class: Implements finding nearest free parking spot.

Source code in parking_lot/src/parking_spot_strategy.py
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
class FindNearestSpotStrategy(FindParkingSpotStrategy):
    """Derived Class: Implements finding nearest free parking spot."""

    def __init__(
        self, entrance_panels: dict[int, EntrancePanel], free_spots, parking_spot_counts
    ):
        """Initalize instance of nearest parking spot strategy."""
        # Create min heaps of free parking spots for each of the entrance panels
        self.pq = {}
        self._lock = threading.Lock()
        for entrance_id, _ in entrance_panels.items():
            self.pq[entrance_id] = {}
            for spot_type in parking_spot_counts:
                self.pq[entrance_id][spot_type] = []
                for spot_id in free_spots[spot_type].keys():
                    # Simulate different orders of allotment at different entrances
                    # For odd numbered entrances, allot in decreasing order
                    if entrance_id % 2:
                        heapq.heappush(
                            self.pq[entrance_id][spot_type],
                            -spot_id,
                        )
                    # For even numbered entrances, allot in increasing order
                    else:
                        heapq.heappush(
                            self.pq[entrance_id][spot_type],
                            spot_id,
                        )

    def find_parking_spot(
        self,
        entrance_panel_id: int,
        spot_type: ParkingSpotType,
        free_spots: dict[ParkingSpot],
    ) -> int:
        """Find spot nearest to entrance.
        Running Time: O(|Num_Entrances|)
        """
        with self._lock:
            # Top of min heap is the nearest spot to entrance
            nearest_spot_id = self.pq[entrance_panel_id][spot_type][0]
            nearest_spot_id = abs(nearest_spot_id)

            # Remove this occupied spot from priority queue of all entrances
            for entrance_id in self.pq:
                if entrance_id % 2:
                    self.pq[entrance_id][spot_type].remove(-nearest_spot_id)
                else:
                    self.pq[entrance_id][spot_type].remove(nearest_spot_id)

        return nearest_spot_id

    def update_parking_spot(self, spot_id: int, spot_type: ParkingSpotType):
        """Update list of free spots on each vehicle's exit."""
        # Add this free spot to priority queue of all entrances
        with self._lock:
            for entrance_id in self.pq:
                if entrance_id % 2:
                    self.pq[entrance_id][spot_type].append(-spot_id)
                else:
                    self.pq[entrance_id][spot_type].append(spot_id)

    def __str__(self):
        return f"Find Nearest Spot Strategy"

__init__(entrance_panels, free_spots, parking_spot_counts)

Initalize instance of nearest parking spot strategy.

Source code in parking_lot/src/parking_spot_strategy.py
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
def __init__(
    self, entrance_panels: dict[int, EntrancePanel], free_spots, parking_spot_counts
):
    """Initalize instance of nearest parking spot strategy."""
    # Create min heaps of free parking spots for each of the entrance panels
    self.pq = {}
    self._lock = threading.Lock()
    for entrance_id, _ in entrance_panels.items():
        self.pq[entrance_id] = {}
        for spot_type in parking_spot_counts:
            self.pq[entrance_id][spot_type] = []
            for spot_id in free_spots[spot_type].keys():
                # Simulate different orders of allotment at different entrances
                # For odd numbered entrances, allot in decreasing order
                if entrance_id % 2:
                    heapq.heappush(
                        self.pq[entrance_id][spot_type],
                        -spot_id,
                    )
                # For even numbered entrances, allot in increasing order
                else:
                    heapq.heappush(
                        self.pq[entrance_id][spot_type],
                        spot_id,
                    )

find_parking_spot(entrance_panel_id, spot_type, free_spots)

Find spot nearest to entrance. Running Time: O(|Num_Entrances|)

Source code in parking_lot/src/parking_spot_strategy.py
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
def find_parking_spot(
    self,
    entrance_panel_id: int,
    spot_type: ParkingSpotType,
    free_spots: dict[ParkingSpot],
) -> int:
    """Find spot nearest to entrance.
    Running Time: O(|Num_Entrances|)
    """
    with self._lock:
        # Top of min heap is the nearest spot to entrance
        nearest_spot_id = self.pq[entrance_panel_id][spot_type][0]
        nearest_spot_id = abs(nearest_spot_id)

        # Remove this occupied spot from priority queue of all entrances
        for entrance_id in self.pq:
            if entrance_id % 2:
                self.pq[entrance_id][spot_type].remove(-nearest_spot_id)
            else:
                self.pq[entrance_id][spot_type].remove(nearest_spot_id)

    return nearest_spot_id

update_parking_spot(spot_id, spot_type)

Update list of free spots on each vehicle's exit.

Source code in parking_lot/src/parking_spot_strategy.py
104
105
106
107
108
109
110
111
112
def update_parking_spot(self, spot_id: int, spot_type: ParkingSpotType):
    """Update list of free spots on each vehicle's exit."""
    # Add this free spot to priority queue of all entrances
    with self._lock:
        for entrance_id in self.pq:
            if entrance_id % 2:
                self.pq[entrance_id][spot_type].append(-spot_id)
            else:
                self.pq[entrance_id][spot_type].append(spot_id)

FindParkingSpotStrategy

Base Class: to find parking spot.

Source code in parking_lot/src/parking_spot_strategy.py
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class FindParkingSpotStrategy:
    """Base Class: to find parking spot."""

    @abstractmethod
    def find_parking_spot(
        self,
        entrance_panel_id: int,
        spot_type: ParkingSpotType,
        free_spots: dict[ParkingSpot],
    ) -> int:
        """Find parking spot."""
        pass

    @abstractmethod
    def update_parking_spot_on_exit(self):
        """Update list of free spots on each vehicle's exit."""
        pass

find_parking_spot(entrance_panel_id, spot_type, free_spots) abstractmethod

Find parking spot.

Source code in parking_lot/src/parking_spot_strategy.py
15
16
17
18
19
20
21
22
23
@abstractmethod
def find_parking_spot(
    self,
    entrance_panel_id: int,
    spot_type: ParkingSpotType,
    free_spots: dict[ParkingSpot],
) -> int:
    """Find parking spot."""
    pass

update_parking_spot_on_exit() abstractmethod

Update list of free spots on each vehicle's exit.

Source code in parking_lot/src/parking_spot_strategy.py
25
26
27
28
@abstractmethod
def update_parking_spot_on_exit(self):
    """Update list of free spots on each vehicle's exit."""
    pass

FindRandomSpotStrategy

Bases: FindParkingSpotStrategy

Derived Class: Implements finding random free parking spot.

Source code in parking_lot/src/parking_spot_strategy.py
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
class FindRandomSpotStrategy(FindParkingSpotStrategy):
    """Derived Class: Implements finding random free parking spot."""

    def find_parking_spot(
        self,
        entrance_panel_id: int,
        spot_type: ParkingSpotType,
        free_spots: dict[ParkingSpot],
    ) -> int:
        """Find the first free parking spot."""
        random_spot_id = random.choice(list(free_spots.keys()))
        return random_spot_id

    def update_parking_spot_on_exit(self):
        """Update list of free spots on each vehicle's exit."""
        return

    def __str__(self):
        return f"Find Random Spot Strategy"

find_parking_spot(entrance_panel_id, spot_type, free_spots)

Find the first free parking spot.

Source code in parking_lot/src/parking_spot_strategy.py
34
35
36
37
38
39
40
41
42
def find_parking_spot(
    self,
    entrance_panel_id: int,
    spot_type: ParkingSpotType,
    free_spots: dict[ParkingSpot],
) -> int:
    """Find the first free parking spot."""
    random_spot_id = random.choice(list(free_spots.keys()))
    return random_spot_id

update_parking_spot_on_exit()

Update list of free spots on each vehicle's exit.

Source code in parking_lot/src/parking_spot_strategy.py
44
45
46
def update_parking_spot_on_exit(self):
    """Update list of free spots on each vehicle's exit."""
    return