-
Notifications
You must be signed in to change notification settings - Fork 0
/
airtravel.py
201 lines (151 loc) · 6.27 KB
/
airtravel.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
"""The module is for creating flights, adding aircraft types and inforramtion,
adding passengers or relocate them and printing boarding passes.
"""
class Flight:
"""A flight with a particular passenger aircraft."""
def __init__(self, number, aircarft):
if not number[:2].isalpha():
raise ValueError(f"No Airline code in {number}")
if not number[:2].isupper():
raise ValueError(f"Invalid Airline code in {number}")
if not (number[2:].isdigit() and int(number[2:]) <= 9999):
raise ValueError(f"Invalid route number {number}")
self._number = number
self._aircraft = aircarft
self._registration = self._aircraft.registration()
rows, seats = self._aircraft.seating_plan()
self._seating = [None] + [{letter: None
for letter in seats} for _ in rows]
def number(self):
return (self._number)
def aircraft_model(self):
return (self._aircraft.model())
def airline(self):
return (self._number[:2])
def registration(self):
return (self._registration)
def allocate_seat(self, seat, passenger):
"""Allocate a seat to a passenger.
Args:
seat: A seat designator such as '12a'.
passenger: The passenger name.
Raises:
ValueError: If the seat in unavailable.
"""
row, letter = self._parse_seat(seat)
if self._seating[row][letter] is not None:
raise ValueError(f"Seat {seat} is already occupied")
self._seating[row][letter] = passenger
def _parse_seat(self, seat):
rows, seat_letters = self._aircraft.seating_plan()
letter = seat[-1]
if letter not in seat_letters:
raise ValueError(f"Invalid seat letter {letter}")
row_txt = seat[:-1]
try:
row = int(row_txt)
except ValueError:
raise ValueError(f"Invalid seat row {row_txt}")
if row not in rows:
raise ValueError(f"Invalid row number {row}")
return (row, letter)
def relocate_passenger(self, from_seat, to_seat):
"""Realocate a passenger to a different seat.
Args:
from_seat: The current occupied seat.
to_seat: The new seat to move to.
"""
to_row, to_letter = self._parse_seat(to_seat)
if self._seating[to_row][to_letter] is not None:
raise ValueError(f"Seat {to_seat} is already occupied")
from_row, from_letter = self._parse_seat(from_seat)
if self._seating[from_row][from_letter] is None:
raise ValueError(f"No passenger to relocate in seat {from_seat}")
self._seating[to_row][to_letter] = self._seating[from_row][from_letter]
self._seating[from_row][from_letter] = None
def num_availabe_seats(self):
return (sum(
sum(1 for x in row.values() if x is None) for row in self._seating
if row is not None))
def make_boarding_card(self, card_printer):
for passenger, seat in sorted(self._passenger_seats()):
card_printer(passenger, seat, self.number(), self.aircraft_model())
def _passenger_seats(self):
number_rows, seat_letters = self._aircraft.seating_plan()
for row in number_rows:
for letter in seat_letters:
passenger = self._seating[row][letter]
if passenger is not None:
yield (passenger, f"{row}{letter}")
class Aircraft:
def __init__(self, registration):
self._registration = registration
def registration(self):
return (self._registration)
def num_seats(self):
rows, row_seats = self.seating_plan()
return (len(rows) * len(row_seats))
class Airbus319(Aircraft):
def model(self):
return ("Airbus A319")
def seating_plan(self):
return (range(1, 23), "ABCDEF")
class Boeing777(Aircraft):
# For simplicity's sake, we ignore complex
# seating arrangement for first_class
def model(self):
return ("Boeing 777")
def seating_plan(self):
return (range(1, 56), "ABCDEGHJK")
class AircraftGeneral:
def __init__(self, registration, model, num_rows, num_seats_per_row):
self._registration = registration
self._model = model
if num_rows < 0:
raise ValueError(f"Invalid row number {num_rows}")
self._num_rows = num_rows
self._num_seats_per_row = num_seats_per_row
def registration(self):
return (self._registration)
def model(self):
return (self._model)
def seating_plan(self):
return ((range(1, self._num_rows + 1),
"ABCDEFGHJK"[:self._num_seats_per_row]))
def boarding_card_printer(passenger, seat, flight_number, aircraft):
output = f"| Name: {passenger}" \
f" Flight: {flight_number}" \
f" Seat: {seat}" \
f" Aircraft: {aircraft} |"
banner = "+" + "-" * (len(output) - 2) + "+"
border = "|" + " " * (len(output) - 2) + "|"
line = [banner, border, output, border, banner]
card = "\n".join(line)
print(card)
print()
def make_flight():
f = Flight("EK973", AircraftGeneral("EK-ARE", "Airbus A380", \
num_rows=22, num_seats_per_row=6))
f.allocate_seat("1A", "Mohammed Elkholy")
f.allocate_seat("1B", "Leen Hito")
f.allocate_seat("2A", "Ahmed Maher")
f.allocate_seat("22A", "Guido Van Rossum")
f.allocate_seat("22B", "Andres Heljsberg")
f.allocate_seat("11A", "John McCarthy")
return (f)
def generate_flights():
a = Flight("EK231", Airbus319("EK-YGH"))
a.allocate_seat("1A", "Mohammed Elkholy")
a.allocate_seat("1B", "Leen Hito")
a.allocate_seat("2A", "Ahmed Maher")
a.allocate_seat("22A", "Guido Van Rossum")
a.allocate_seat("22B", "Andres Heljsberg")
a.allocate_seat("11A", "John McCarthy")
b = Flight("EK973", Boeing777("EK-EDO"))
b.allocate_seat("1A", "Mohammed Elkholy")
b.allocate_seat("1B", "Leen Hito")
b.allocate_seat("2A", "Ahmed Maher")
b.allocate_seat("22A", "Guido Van Rossum")
b.allocate_seat("22B", "Andres Heljsberg")
b.allocate_seat("11A", "John McCarthy")
return (a, b)