Skip to content

Commit 800c5e8

Browse files
Added Go-Jek Parking Lot Assignment Python
1 parent 7930f42 commit 800c5e8

File tree

10 files changed

+662
-0
lines changed

10 files changed

+662
-0
lines changed
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
# C extensions
7+
*.so
8+
9+
# Distribution / packaging
10+
.Python
11+
build/
12+
develop-eggs/
13+
dist/
14+
downloads/
15+
eggs/
16+
.eggs/
17+
lib/
18+
lib64/
19+
parts/
20+
sdist/
21+
var/
22+
wheels/
23+
*.egg-info/
24+
.installed.cfg
25+
*.egg
26+
MANIFEST
27+
28+
# PyInstaller
29+
# Usually these files are written by a python script from a template
30+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
31+
*.manifest
32+
*.spec
33+
34+
# Installer logs
35+
pip-log.txt
36+
pip-delete-this-directory.txt
37+
38+
# Unit test / coverage reports
39+
htmlcov/
40+
.tox/
41+
.coverage
42+
.coverage.*
43+
.cache
44+
nosetests.xml
45+
coverage.xml
46+
*.cover
47+
.hypothesis/
48+
.pytest_cache/
49+
50+
# Translations
51+
*.mo
52+
*.pot
53+
54+
# Django stuff:
55+
*.log
56+
local_settings.py
57+
db.sqlite3
58+
59+
# Flask stuff:
60+
instance/
61+
.webassets-cache
62+
63+
# Scrapy stuff:
64+
.scrapy
65+
66+
# Sphinx documentation
67+
docs/_build/
68+
69+
# PyBuilder
70+
target/
71+
72+
# Jupyter Notebook
73+
.ipynb_checkpoints
74+
75+
# pyenv
76+
.python-version
77+
78+
# celery beat schedule file
79+
celerybeat-schedule
80+
81+
# SageMath parsed files
82+
*.sage.py
83+
84+
# Environments
85+
.env
86+
.venv
87+
env/
88+
venv/
89+
ENV/
90+
env.bak/
91+
venv.bak/
92+
environment/
93+
94+
# vscode
95+
.vscode/
96+
97+
# Spyder project settings
98+
.spyderproject
99+
.spyproject
100+
101+
# Rope project settings
102+
.ropeproject
103+
104+
# mkdocs documentation
105+
/site
106+
107+
# mypy
108+
.mypy_cache/
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/usr/bin/env python3
2+
3+
CREATE_PARKING_LOT = 'create_parking_lot'
4+
PARK_CAR = 'park'
5+
CAR_DEPARTURE = 'leave'
6+
LOT_STATUS = 'status'
7+
SEARCH_SLOT_BY_COLOUR = 'slot_numbers_for_cars_with_colour'
8+
SEARCH_CAR_BY_COLOUR = 'registration_numbers_for_cars_with_colour'
9+
SEARCH_SLOT_BY_CAR_NUMBER = 'slot_number_for_registration_number'
10+
EXIT = 'exit'
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
FROM python:alpine
2+
ADD . /app
3+
WORKDIR /app
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#!/usr/bin/env python3
2+
3+
import sys
4+
from Constants import *
5+
from Utilities import (ParkingLot, create_parking_lot, park_car, car_departure,
6+
lot_status, car_by_colour, slot_by_car_number, slot_by_colour)
7+
8+
9+
def executeCommand(parkingLot, command):
10+
if command[0] == CREATE_PARKING_LOT:
11+
parkingLot = create_parking_lot(command[1])
12+
elif command[0] == PARK_CAR:
13+
print(park_car(parkingLot, command[1], command[2]))
14+
elif command[0] == CAR_DEPARTURE:
15+
print(car_departure(parkingLot, command[1]))
16+
elif command[0] == LOT_STATUS:
17+
print(lot_status(parkingLot).rstrip('\n'))
18+
elif command[0] == SEARCH_SLOT_BY_CAR_NUMBER:
19+
print(slot_by_car_number(parkingLot, command[1]).rstrip(', '))
20+
elif command[0] == SEARCH_CAR_BY_COLOUR:
21+
print(car_by_colour(parkingLot, command[1]).rstrip(', '))
22+
elif command[0] == SEARCH_SLOT_BY_COLOUR:
23+
print(slot_by_colour(parkingLot, command[1]).rstrip(', '))
24+
else:
25+
print('Command is not applicable')
26+
return parkingLot
27+
28+
29+
def commandMode(parkingLot):
30+
try:
31+
command = input().split()
32+
while command[0] != EXIT:
33+
parkingLot = executeCommand(parkingLot, command)
34+
command = input().split()
35+
except Exception as e:
36+
print(e)
37+
38+
39+
def fileReaderMode(parkingLot, fileName):
40+
try:
41+
with open(fileName) as file:
42+
commands = file.readlines()
43+
for command in commands:
44+
parkingLot = executeCommand(
45+
parkingLot, command.replace('\n', '').split())
46+
except Exception as e:
47+
print(e)
48+
49+
50+
def main():
51+
parkingLot = None
52+
if len(sys.argv) > 1:
53+
fileReaderMode(parkingLot, sys.argv[1])
54+
else:
55+
commandMode(parkingLot)
56+
57+
58+
if __name__ == '__main__':
59+
main()
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# Go-Jek Parking Lot Assignment (Python)
2+
3+
## 1. Problem Statment
4+
Design a Parking lot which can hold `n` Cars. Every car been issued a ticket for a slot and the slot been assigned based on the nearest to the entry. The system should also return some queries such as:
5+
6+
- Registration numbers of all cars of a particular colour.
7+
- Slot number in which a car with a given registration number is parked.
8+
- Slot numbers of all slots where a car of a particular colour is parked.
9+
10+
## 2. Solution Approach
11+
A car consist of Registration number, slot number and it's colour. Likewise our Parking Lot consist slots. For not making it too complicated, I choose a python dictionary for storing cars on slots and implemented the functionalities as accordingly.
12+
13+
## 3. Supported Commands
14+
15+
- `create_parking_lot` <`n`>
16+
To create a Parking lot. Where `n` is the size of the parking lot
17+
18+
- `park` <`registration_number`> <`colour`>
19+
To park the car in the parking lot and prints the allocated slot in the parking lot. Where `registration_number` is given registration number for the car and `colour` is given colour for the car
20+
21+
- `leave` <`slot`>
22+
To leave the parking lot from desired slot and prints the leaving slot. given slot number. Where `slot` is given sloat number
23+
24+
- `status`
25+
To check the status of Parking Lot
26+
27+
- `slot_numbers_for_cars_with_colour` <`colour`>
28+
To prints the registration number of the cars for the given colour. Where `color` is given colour
29+
30+
- `slot_number_for_registration_number` <`registration_number`>
31+
prints the slot number of the cars for the given number. Where `registration_number` is given registration number.
32+
33+
- `registration_numbers_for_cars_with_colour` <`colour`>
34+
To prints the slot number of the cars for the given colour. Where `colour` is given colour.
35+
36+
## 4. Running Application
37+
#### 4.1 Running the application in File mode:
38+
39+
```python
40+
./ParkingLot.py input.txt
41+
```
42+
43+
#### 4.2 Running the application in Interactive mode:
44+
45+
```python
46+
./ParkingLot.py
47+
```
48+
49+
## 5. Test Cases
50+
- Total number of test cases - 14
51+
- Code coverage - 86%
52+
53+
#### 5.1 For running the tests
54+
55+
```python
56+
python Tests.py
57+
```
58+
59+
#### 5.2 For calculating code coverage
60+
```python
61+
coverage run Tests.py
62+
coverage report
63+
```
64+
65+
## 6. Running the application in a Docker Container
66+
67+
#### Build the image:
68+
69+
```python
70+
docker build -t parkinglot:1.0 .
71+
```
72+
73+
#### 6.1 Running the application in Interactive mode:
74+
75+
```python
76+
docker run -it parkinglot:1.0 ./ParkingLot.py
77+
```
78+
79+
#### 6.2 Running the application in File mode:
80+
81+
```python
82+
docker run -it parkinglot:1.0 ./ParkingLot.py input.txt
83+
```
84+
85+
## 7. Possible errors
86+
87+
When using running application in Docker, if it gives this error:
88+
89+
```bash
90+
docker: Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "exec: \"./ParkingLot.py\": permission denied": unknown.
91+
```
92+
93+
just change the permissions by running
94+
95+
```bash
96+
sudo chmod +x ./ParkingLot.py
97+
```
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import unittest
2+
from Utilities import create_parking_lot, park_car, parking_lot_is_full, car_departure, \
3+
car_by_colour, slot_by_car_number, slot_by_colour
4+
5+
6+
class TestParkingLotUtilities(unittest.TestCase):
7+
"""
8+
will test the endpoints
9+
"""
10+
11+
def test_create_parking_lot(self):
12+
testParkingLot = create_parking_lot(str(6))
13+
self.assertEqual(len(testParkingLot.get_slots()), 6)
14+
15+
def test_parking_lot_is_full(self):
16+
testParkingLot = create_parking_lot(str(6))
17+
self.assertEqual(parking_lot_is_full(testParkingLot), False)
18+
19+
def test_park_car_lot_not_defined(self):
20+
testString = park_car(None, 'KA-01-AA-1111', 'White')
21+
self.assertEqual('Parking lot is not defined', testString)
22+
23+
def test_park_car_lot_allocated(self):
24+
testParkingLot = create_parking_lot(str(6))
25+
testString = park_car(testParkingLot, 'KA-01-AA-1112', 'White')
26+
self.assertEqual('Allocated slot number: 1', testString)
27+
28+
def test_park_car_lot_full(self):
29+
testParkingLot = create_parking_lot(str(1))
30+
testParkString = park_car(testParkingLot, 'KA-01-AA-1112', 'White')
31+
testString = park_car(testParkingLot, 'KA-01-AA-1113', 'White')
32+
self.assertEqual('Sorry, parking lot is full', testString)
33+
34+
def test_car_departure_empty(self):
35+
testParkingLot = create_parking_lot(str(6))
36+
testString = car_departure(testParkingLot, '1')
37+
self.assertEqual('Sorry, parking lot is empty', testString)
38+
39+
def test_car_departure_free(self):
40+
testParkingLot = create_parking_lot(str(6))
41+
testParkString = park_car(testParkingLot, 'KA-01-AA-1114', 'White')
42+
testString = car_departure(testParkingLot, '1')
43+
self.assertEqual('Slot number 1 is free', testString)
44+
45+
def test_car_departure_cannot_exit(self):
46+
testParkingLot = create_parking_lot(str(6))
47+
testParkString = park_car(testParkingLot, 'KA-01-AA-1115', 'White')
48+
testString = car_departure(testParkingLot, '7')
49+
self.assertEqual('Cannot exit slot: 7 as no such exist!', testString)
50+
51+
def test_car_departure_slot_free(self):
52+
testParkingLot = create_parking_lot(str(6))
53+
testParkString = park_car(testParkingLot, 'KA-01-AA-1116', 'White')
54+
testString = car_departure(testParkingLot, '2')
55+
self.assertEqual('No car at Slot number 2', testString)
56+
57+
def test_car_departure_not_defined(self):
58+
testString = car_departure(None, '1')
59+
self.assertEqual('Parking lot is not defined', testString)
60+
61+
def test_car_by_colour(self):
62+
testParkingLot = create_parking_lot(str(6))
63+
testParkString = park_car(testParkingLot, 'KA-01-AA-1117', 'White')
64+
testString = car_by_colour(testParkingLot, 'White')
65+
self.assertEqual(testString, 'KA-01-AA-1117, ')
66+
67+
def test_slot_by_car_number_not_found(self):
68+
testParkingLot = create_parking_lot(str(6))
69+
testParkString = park_car(testParkingLot, 'KA-01-AA-1118', 'White')
70+
testString = slot_by_car_number(testParkingLot, 'KA-01-AA-1113')
71+
self.assertEqual(testString, 'Not found')
72+
73+
def test_slot_by_car_number(self):
74+
testParkingLot = create_parking_lot(str(6))
75+
testParkString = park_car(testParkingLot, 'KA-01-AA-1103', 'White')
76+
testString = slot_by_car_number(testParkingLot, 'KA-01-AA-1103')
77+
self.assertEqual(testString, '1, ')
78+
79+
def test_slot_by_colour(self):
80+
testParkingLot = create_parking_lot(str(6))
81+
testParkString = park_car(testParkingLot, 'KA-01-AA-1119', 'White')
82+
testString = slot_by_colour(testParkingLot, 'White')
83+
self.assertEqual(testString, '1, ')
84+
85+
86+
if __name__ == '__main__':
87+
unittest.main()

0 commit comments

Comments
 (0)