Skip to content

Commit 507767f

Browse files
author
Tusamma Sal Sabil
committed
Add Parking Lot Codes
1 parent 43fccb3 commit 507767f

File tree

7 files changed

+404
-0
lines changed

7 files changed

+404
-0
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from .constants import *
2+
3+
4+
class Account:
5+
def __init__(self, user_name, password, person, status=AccountStatus.Active):
6+
self.__user_name = user_name
7+
self.__password = password
8+
self.__person = person
9+
self.__status = status
10+
11+
def reset_password(self):
12+
None
13+
14+
15+
class Admin(Account):
16+
def __init__(self, user_name, password, person, status=AccountStatus.Active):
17+
super().__init__(user_name, password, person, status)
18+
19+
def add_parking_floor(self, floor):
20+
None
21+
22+
def add_parking_spot(self, floor_name, spot):
23+
None
24+
25+
def add_parking_display_board(self, floor_name, display_board):
26+
None
27+
28+
def add_customer_info_panel(self, floor_name, info_panel):
29+
None
30+
31+
def add_entrance_panel(self, entrance_panel):
32+
None
33+
34+
def add_exit_panel(self, exit_panel):
35+
None
36+
37+
38+
class ParkingAttendant(Account):
39+
def __init__(self, user_name, password, person, status=AccountStatus.Active):
40+
super().__init__(user_name, password, person, status)
41+
42+
def process_ticket(self, ticket_number):
43+
None
44+
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from enum import Enum
2+
3+
4+
class VehicleType(Enum):
5+
CAR, TRUCK, ELECTRIC, VAN, MOTORBIKE = 1, 2, 3, 4, 5
6+
7+
8+
class ParkingSpotType(Enum):
9+
HANDICAPPED, COMPACT, LARGE, MOTORBIKE, ELECTRIC = 1, 2, 3, 4, 5
10+
11+
12+
class AccountStatus(Enum):
13+
ACTIVE, BLOCKED, BANNED, COMPROMISED, ARCHIVED, UNKNOWN = 1, 2, 3, 4, 5, 6
14+
15+
16+
class ParkingTicketStatus(Enum):
17+
ACTIVE, PAID, LOST = 1, 2, 3
18+
19+
20+
class Address:
21+
def __init__(self, street, city, state, zip_code, country):
22+
self.__street_address = street
23+
self.__city = city
24+
self.__state = state
25+
self.__zip_code = zip_code
26+
self.__country = country
27+
28+
29+
class Person():
30+
def __init__(self, name, address, email, phone):
31+
self.__name = name
32+
self.__address = address
33+
self.__email = email
34+
self.__phone = phone
35+
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
class ParkingDisplayBoard:
2+
def __init__(self, id):
3+
self.__id = id
4+
self.__handicapped_free_spot = None
5+
self.__compact_free_spot = None
6+
self.__large_free_spot = None
7+
self.__motorbike_free_spot = None
8+
self.__electric_free_spot = None
9+
10+
def show_empty_spot_number(self):
11+
message = ""
12+
if self.__handicapped_free_spot.is_free():
13+
message += "Free Handicapped: " + self.__handicapped_free_spot.get_number()
14+
else:
15+
message += "Handicapped is full"
16+
message += "\n"
17+
18+
if self.__compact_free_spot.is_free():
19+
message += "Free Compact: " + self.__compact_free_spot.get_number()
20+
else:
21+
message += "Compact is full"
22+
message += "\n"
23+
24+
if self.__large_free_spot.is_free():
25+
message += "Free Large: " + self.__large_free_spot.get_number()
26+
else:
27+
message += "Large is full"
28+
message += "\n"
29+
30+
if self.__motorbike_free_spot.is_free():
31+
message += "Free Motorbike: " + self.__motorbike_free_spot.get_number()
32+
else:
33+
message += "Motorbike is full"
34+
message += "\n"
35+
36+
if self.__electric_free_spot.is_free():
37+
message += "Free Electric: " + self.__electric_free_spot.get_number()
38+
else:
39+
message += "Electric is full"
40+
41+
print(message)
42+
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
from .constants import *
2+
from .parking_display_board import *
3+
4+
5+
class ParkingFloor:
6+
def __init__(self, name):
7+
self.__name = name
8+
self.__handicapped_spots = {}
9+
self.__compact_spots = {}
10+
self.__large_spots = {}
11+
self.__motorbike_spots = {}
12+
self.__electric_spots = {}
13+
self.__info_portals = {}
14+
self.__free_handicapped_spot_count = {'free_spot': 0}
15+
self.__free_compact_spot_count = {'free_spot': 0}
16+
self.__free_large_spot_count = {'free_spot': 0}
17+
self.__free_motorbike_spot_count = {'free_spot': 0}
18+
self.__free_electric_spot_count = {'free_spot': 0}
19+
self.__display_board = ParkingDisplayBoard()
20+
21+
def add_parking_spot(self, spot):
22+
switcher = {
23+
ParkingSpotType.HANDICAPPED: self.__handicapped_spots.put(spot.get_number(), spot),
24+
ParkingSpotType.COMPACT: self.__compact_spots.put(spot.get_number(), spot),
25+
ParkingSpotType.LARGE: self.__large_spots.put(spot.get_number(), spot),
26+
ParkingSpotType.MOTORBIKE: self.__motorbike_spots.put(spot.get_number(), spot),
27+
ParkingSpotType.ELECTRIC: self.__electric_spots.put(spot.get_number(), spot),
28+
}
29+
switcher.get(spot.get_type(), 'Wrong parking spot type')
30+
31+
def assign_vehicleToSpot(self, vehicle, spot):
32+
spot.assign_vehicle(vehicle)
33+
switcher = {
34+
ParkingSpotType.HANDICAPPED: self.update_display_board_for_handicapped(spot),
35+
ParkingSpotType.COMPACT: self.update_display_board_for_compact(spot),
36+
ParkingSpotType.LARGE: self.update_display_board_for_large(spot),
37+
ParkingSpotType.MOTORBIKE: self.update_display_board_for_motorbike(spot),
38+
ParkingSpotType.ELECTRIC: self.update_display_board_for_electric(spot),
39+
}
40+
switcher(spot.get_type(), 'Wrong parking spot type!')
41+
42+
def update_display_board_for_handicapped(self, spot):
43+
if self.__display_board.get_handicapped_free_spot().get_number() == spot.get_number():
44+
# find another free handicapped parking and assign to display_board
45+
for key in self.__handicapped_spots:
46+
if self.__handicapped_spots.get(key).is_free():
47+
self.__display_board.set_handicapped_free_spot(self.__handicapped_spots.get(key))
48+
49+
self.__display_board.show_empty_spot_number()
50+
51+
def update_display_board_for_compact(self, spot):
52+
if self.__display_board.get_compact_free_spot().get_number() == spot.get_number():
53+
# find another free compact parking and assign to display_board
54+
for key in self.__compact_spots.key_set():
55+
if self.__compact_spots.get(key).is_free():
56+
self.__display_board.set_compact_free_spot(self.__compact_spots.get(key))
57+
58+
self.__display_board.show_empty_spot_number()
59+
60+
def free_spot(self, spot):
61+
spot.remove_vehicle()
62+
switcher = {
63+
ParkingSpotType.HANDICAPPED: self.__free_handicapped_spot_count.update(
64+
free_spot = self.__free_handicapped_spot_count["free_spot"] + 1
65+
),
66+
ParkingSpotType.COMPACT: self.__free_compact_spot_count.update(
67+
free_spot=self.__free_compact_spot_count["free_spot"] + 1
68+
),
69+
ParkingSpotType.LARGE: self.__free_large_spot_count.update(
70+
free_spot=self.__free_large_spot_count["free_spot"] + 1
71+
),
72+
ParkingSpotType.MOTORBIKE: self.__free_motorbike_spot_count.update(
73+
free_spot=self.__free_motorbike_spot_count["free_spot"] + 1
74+
),
75+
ParkingSpotType.ELECTRIC: self.__free_electric_spot_count.update(
76+
free_spot=self.__free_electric_spot_count["free_spot"] + 1
77+
),
78+
}
79+
80+
switcher(spot.get_type(), 'Wrong parking spot type!')
81+
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import threading
2+
from .constants import *
3+
4+
5+
class ParkingLot:
6+
# singleton ParkingLot to ensure only one object of ParkingLot in the system,
7+
# all entrance panels will use this object to create new parking ticket: get_new_parking_ticket(),
8+
# similarly exit panels will also use this object to close parking tickets
9+
instance = None
10+
11+
class __OnlyOne:
12+
def __init__(self, name, address):
13+
# 1. initialize variables: read name, address and parking_rate from database
14+
# 2. initialize parking floors: read the parking floor map from database,
15+
# this map should tell how many parking spots are there on each floor. This
16+
# should also initialize max spot counts too.
17+
# 3. initialize parking spot counts by reading all active tickets from database
18+
# 4. initialize entrance and exit panels: read from database
19+
20+
self.__name = name
21+
self.__address = address
22+
self.__parking_rate = ParkingRate()
23+
24+
self.__compact_spot_count = 0
25+
self.__large_spot_count = 0
26+
self.__motorbike_spot_count = 0
27+
self.__electric_spot_count = 0
28+
self.__max_compact_count = 0
29+
self.__max_large_count = 0
30+
self.__max_motorbike_count = 0
31+
self.__max_electric_count = 0
32+
33+
self.__entrance_panels = {}
34+
self.__exit_panels = {}
35+
self.__parking_floors = {}
36+
37+
# all active parking tickets, identified by their ticket_number
38+
self.__active_tickets = {}
39+
40+
self.__lock = threading.Lock()
41+
42+
def __init__(self, name, address):
43+
if not ParkingLot.instance:
44+
ParkingLot.instance = ParkingLot.__OnlyOne(name, address)
45+
else:
46+
ParkingLot.instance.__name = name
47+
ParkingLot.instance.__address = address
48+
49+
def __getattr__(self, name):
50+
return getattr(self.instance, name)
51+
52+
def get_new_parking_ticket(self, vehicle):
53+
if self.is_full(vehicle.get_type()):
54+
raise Exception('Parking full!')
55+
# synchronizing to allow multiple entrances panels to issue a new
56+
# parking ticket without interfering with each other
57+
self.__lock.acquire()
58+
ticket = ParkingTicket()
59+
vehicle.assign_ticket(ticket)
60+
ticket.save_in_DB()
61+
# if the ticket is successfully saved in the database, we can increment the parking spot count
62+
self.__increment_spot_count(vehicle.get_type())
63+
self.__active_tickets.put(ticket.get_ticket_number(), ticket)
64+
self.__lock.release()
65+
return ticket
66+
67+
def is_full(self, type):
68+
# trucks and vans can only be parked in LargeSpot
69+
if type == VehicleType.Truck or type == VehicleType.Van:
70+
return self.__large_spot_count >= self.__max_large_count
71+
72+
# motorbikes can only be parked at motorbike spots
73+
if type == VehicleType.Motorbike:
74+
return self.__motorbike_spot_count >= self.__max_motorbike_count
75+
76+
# cars can be parked at compact or large spots
77+
if type == VehicleType.Car:
78+
return (self.__compact_spot_count + self.__large_spot_count) >= (self.__max_compact_count + self.__max_large_count)
79+
80+
# electric car can be parked at compact, large or electric spots
81+
return (self.__compact_spot_count + self.__large_spot_count + self.__electric_spot_count) >= (self.__max_compact_count + self.__max_large_count
82+
+ self.__max_electric_count)
83+
84+
# increment the parking spot count based on the vehicle type
85+
def increment_spot_count(self, type):
86+
large_spot_count = 0
87+
motorbike_spot_count = 0
88+
compact_spot_count = 0
89+
electric_spot_count = 0
90+
if type == VehicleType.Truck or type == VehicleType.Van:
91+
large_spot_count += 1
92+
elif type == VehicleType.Motorbike:
93+
motorbike_spot_count += 1
94+
elif type == VehicleType.Car:
95+
if self.__compact_spot_count < self.__max_compact_count:
96+
compact_spot_count += 1
97+
else:
98+
large_spot_count += 1
99+
else: # electric car
100+
if self.__electric_spot_count < self.__max_electric_count:
101+
electric_spot_count += 1
102+
elif self.__compact_spot_count < self.__max_compact_count:
103+
compact_spot_count += 1
104+
else:
105+
large_spot_count += 1
106+
107+
def is_full(self):
108+
for key in self.__parking_floors:
109+
if not self.__parking_floors.get(key).is_full():
110+
return False
111+
return True
112+
113+
def add_parking_floor(self, floor):
114+
# store in database
115+
None
116+
117+
def add_entrance_panel(self, entrance_panel):
118+
# store in database
119+
None
120+
121+
def add_exit_panel(self, exit_panel):
122+
# store in database
123+
None
124+
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
from abc import ABC
2+
from .constants import *
3+
4+
5+
class ParkingSpot(ABC):
6+
def __init__(self, number, parking_spot_type):
7+
self.__number = number
8+
self.__free = True
9+
self.__vehicle = None
10+
self.__parking_spot_type = parking_spot_type
11+
12+
def is_free(self):
13+
return self.__free
14+
15+
def assign_vehicle(self, vehicle):
16+
self.__vehicle = vehicle
17+
free = False
18+
19+
def remove_vehicle(self):
20+
self.__vehicle = None
21+
free = True
22+
23+
24+
class HandicappedSpot(ParkingSpot):
25+
def __init__(self, number):
26+
super().__init__(number, ParkingSpotType.HANDICAPPED)
27+
28+
29+
class CompactSpot(ParkingSpot):
30+
def __init__(self, number):
31+
super().__init__(number, ParkingSpotType.COMPACT)
32+
33+
34+
class LargeSpot(ParkingSpot):
35+
def __init__(self, number):
36+
super().__init__(number, ParkingSpotType.LARGE)
37+
38+
39+
class MotorbikeSpot(ParkingSpot):
40+
def __init__(self, number):
41+
super().__init__(number, ParkingSpotType.MOTORBIKE)
42+
43+
44+
class ElectricSpot(ParkingSpot):
45+
def __init__(self, number):
46+
super().__init__(number, ParkingSpotType.ELECTRIC)
47+

0 commit comments

Comments
 (0)