1
|
|
|
#!/usr/bin/python3 |
2
|
|
|
# pylint: disable=no-value-for-parameter |
3
|
|
|
|
4
|
|
|
""" |
5
|
|
|
Mainprogram for scooter simulation |
6
|
|
|
""" |
7
|
|
|
|
8
|
|
|
|
9
|
|
|
from datetime import datetime |
10
|
|
|
import time |
11
|
|
|
from src.scooter import Scooter |
12
|
|
|
from src.api import ApiData |
13
|
|
|
from main import Handler |
14
|
|
|
|
15
|
|
|
|
16
|
|
|
|
17
|
|
|
class Simulation(): |
18
|
|
|
""" Simulation class """ |
19
|
|
|
|
20
|
|
|
# saves scooter id in an array |
21
|
|
|
_scooter_id = [] |
22
|
|
|
|
23
|
|
|
# saves station in an array |
24
|
|
|
_station = [] |
25
|
|
|
|
26
|
|
|
# saves user id in an array |
27
|
|
|
_user_id = [] |
28
|
|
|
|
29
|
|
|
# saves city info in an array |
30
|
|
|
_city_data = [] |
31
|
|
|
|
32
|
|
|
|
33
|
|
|
def __init__(self): |
34
|
|
|
""" Initialize class """ |
35
|
|
|
self.scooter = Scooter() |
36
|
|
|
self.handler = Handler() |
37
|
|
|
self.api = ApiData(1) |
38
|
|
|
|
39
|
|
|
|
40
|
|
|
def move(self) -> None: |
41
|
|
|
""" Moves scooters around the cities. Simulation time is 2 minutes. """ |
42
|
|
|
end_time = time.time() + 120 # 2 minutes |
43
|
|
|
|
44
|
|
|
print("\nStep 2 - Moving scooters . . . . . . . .") |
45
|
|
|
|
46
|
|
|
while time.time() <= end_time: |
47
|
|
|
count = 0 |
48
|
|
|
|
49
|
|
|
while count < len(self._scooter_id): |
50
|
|
|
data = self.api.get_scooter_data(self._scooter_id[count]) |
51
|
|
|
|
52
|
|
|
self.scooter.add_scooter_to_dict(data) |
53
|
|
|
self.scooter.add_city_to_dict(self._city_data[count]) |
54
|
|
|
|
55
|
|
|
count = self.run(count) |
56
|
|
|
|
57
|
|
|
count += 1 |
58
|
|
|
time.sleep(0.001) |
59
|
|
|
|
60
|
|
|
|
61
|
|
|
def delete_and_remove(self, count) -> None: |
62
|
|
|
""" Removes a specific element from the list and stop the scooter """ |
63
|
|
|
self.end(count) |
64
|
|
|
|
65
|
|
|
del self._scooter_id[count] |
66
|
|
|
del self._station[count] |
67
|
|
|
del self._user_id[count] |
68
|
|
|
del self._city_data[count] |
69
|
|
|
|
70
|
|
|
|
71
|
|
|
def run(self, count: int) -> int: |
72
|
|
|
""" |
73
|
|
|
Checks if the scooter is inside the city and check battery level, if TRUE |
74
|
|
|
the scooter will be returned otherwise the scooter will continue moving. |
75
|
|
|
""" |
76
|
|
|
scooter_id = self._scooter_id[count] |
77
|
|
|
|
78
|
|
|
if self.scooter.check_scooter_in_city() is False: |
79
|
|
|
print("\nScooter {} is outside of the city\n".format(scooter_id)) |
80
|
|
|
print("Scooter {} will be returned.".format(scooter_id)) |
81
|
|
|
|
82
|
|
|
self.delete_and_remove() |
83
|
|
|
count -= 1 |
84
|
|
|
elif self.scooter.check_battery(): |
85
|
|
|
print( |
86
|
|
|
"\n\033[1;31m*\033[1;0m Low battery!! the scooter {} needs to be charged." |
87
|
|
|
.format(id) |
88
|
|
|
) |
89
|
|
|
print("Scooter {} will be returned.".format(scooter_id)) |
90
|
|
|
|
91
|
|
|
self.delete_and_remove() |
92
|
|
|
count -= 1 |
93
|
|
|
else: |
94
|
|
|
self.scooter.change_location() |
95
|
|
|
self.scooter.move_scooter() |
96
|
|
|
self.api.update_rented_scooter() |
97
|
|
|
|
98
|
|
|
return count |
99
|
|
|
|
100
|
|
|
|
101
|
|
|
def end(self, count): |
102
|
|
|
""" |
103
|
|
|
Scooter will be checked if it's outside the city/has low battery level or need |
104
|
|
|
meantience. The scooter will be returned and the log/payment/account will be uppdated. |
105
|
|
|
""" |
106
|
|
|
self.api.station = self._station[count] |
107
|
|
|
self.handler.api = ApiData(self._user_id[count]) |
108
|
|
|
|
109
|
|
|
self.handler.end_rental() |
110
|
|
|
|
111
|
|
|
|
112
|
|
|
def return_scooters(self): |
113
|
|
|
""" All scooters will be returned when simulation time ends. """ |
114
|
|
|
count = 0 |
115
|
|
|
|
116
|
|
|
print("\nStep 3 - Returning scooters . . . . . . . .") |
117
|
|
|
print("\nThe simulation has finished, the scooters will be returned.\n") |
118
|
|
|
|
119
|
|
|
while count < len(self._scooter_id): |
120
|
|
|
data = self.api.get_scooter_data(self._scooter_id[count]) |
121
|
|
|
|
122
|
|
|
self.scooter.add_scooter_to_dict(data) |
123
|
|
|
self.scooter.add_city_to_dict(self._city_data[count]) |
124
|
|
|
self.end(count) |
125
|
|
|
|
126
|
|
|
count += 1 |
127
|
|
|
time.sleep(0.001) |
128
|
|
|
|
129
|
|
|
|
130
|
|
|
def main(self, total:int): |
131
|
|
|
""" Start simulation program. """ |
132
|
|
|
print("\n************ Welcome to Scooter simulation program **************\n") |
133
|
|
|
print("\nThe simulation takes around 3 minutes, do not try to break/stop the program.\n") |
134
|
|
|
print("\nStep 1 - Renting scooters . . . . . . . .") |
135
|
|
|
|
136
|
|
|
current = datetime.now().time().strftime("%H:%M:%S") |
137
|
|
|
self.handler.start_time = [int(current[:2]), int(current[3:5]), int(current[6:8])] |
138
|
|
|
count = 1 |
139
|
|
|
|
140
|
|
|
# user id 6 means customer id 1, start counting from 6 |
141
|
|
|
user = 6 |
142
|
|
|
|
143
|
|
|
while count <= total: |
144
|
|
|
data = self.api.get_scooter_data(scooter_id = count) |
145
|
|
|
|
146
|
|
|
if self.scooter.check_scooter_status(data): |
147
|
|
|
# get city |
148
|
|
|
city = self.api.get_city_data() |
149
|
|
|
self._city_data.append(city) |
150
|
|
|
self._scooter_id.append(count) |
151
|
|
|
|
152
|
|
|
# create log/payment and update customer's account |
153
|
|
|
self._user_id.append(user) |
154
|
|
|
self.api.user_id = str(user) |
155
|
|
|
|
156
|
|
|
self.api.rent_scooter() |
157
|
|
|
self._station.append(self.api.station) |
158
|
|
|
|
159
|
|
|
user += 1 |
160
|
|
|
else: |
161
|
|
|
print("\n\033[1;31m*\033[1;0m Scooter {} is not available.\n".format(count)) |
162
|
|
|
|
163
|
|
|
count += 1 |
164
|
|
|
|
165
|
|
|
self.move() |
166
|
|
|
self.return_scooters() |
167
|
|
|
|
168
|
|
|
|
169
|
|
|
|
170
|
|
|
if __name__ == "__main__": |
171
|
|
|
Simulation().main(1000) |
172
|
|
|
|