Now we've laid the groundwork for our relocate_passenger() method:
class Flight:
# ...
def relocate_passenger(self, from_seat, to_seat):
"""Relocate a passenger to a different seat.
Args:
from_seat: The existing seat designator for the
passenger to be moved.
to_seat: The new seat designator.
"""
from_row, from_letter = self._parse_seat(from_seat)
if self._seating[from_row][from_letter] is None:
raise ValueError(
"No passenger to relocate in seat {}".format(from_seat))
to_row, to_letter = self._parse_seat(to_seat)
if self._seating[to_row][to_letter] is not None:
raise ValueError(
"Seat {} already occupied".format(to_seat))
self._seating[to_row][to_letter] = self._seating[from_row]
[from_letter]
self._seating[from_row][from_letter] = None
This parses and validates the from_seat and to_seat arguments and then moves the passenger to the new location.
It's also getting tiresome recreating the Flight object each time, so we'll add a module level convenience function for that too:
def make_flight():
f = Flight("BA758", Aircraft("G-EUPT", "Airbus A319",
num_rows=22, num_seats_per_row=6))
f.allocate_seat('12A', 'Guido van Rossum')
f.allocate_seat('15F', 'Bjarne Stroustrup')
f.allocate_seat('15E', 'Anders Hejlsberg')
f.allocate_seat('1C', 'John McCarthy')
f.allocate_seat('1D', 'Richard Hickey')
return f
In Python it's quite normal to mix related functions and classes in the same module. Now, from the REPL:
>>> from airtravel import make_flight
>>> f = make_flight()
>>> f
<airtravel.Flight object at 0x1007a6690>
You may find it remarkable that we have access to the Flight class when we have only imported a single function, make_flight. This is quite normal and it's a powerful aspect of Python’s dynamic type system that facilitates this very loose coupling between code.
Let's get on and move Guido back to row 15 with his fellow Europeans:
>>> f.relocate_passenger('12A', '15D')
>>> from pprint import pprint as pp
>>> pp(f._seating)
[None,
{'A': None,'B': None, 'C': 'John McCarthy', 'D': 'Richard Hickey',
'E': None, 'F': None},
{'A': None, 'B': None, 'C': None, 'D': None, 'E': None, 'F': None},
{'A': None, 'B': None, 'C': None, 'D': None, 'E': None, 'F': None},
{'A': None, 'B': None, 'C': None, 'D': None, 'E': None, 'F': None},
{'A': None, 'B': None, 'C': None, 'D': None, 'E': None, 'F': None},
{'A': None, 'B': None, 'C': None, 'D': None, 'E': None, 'F': None},
{'A': None, 'B': None, 'C': None, 'D': None, 'E': None, 'F': None},
{'A': None, 'B': None, 'C': None, 'D': None, 'E': None, 'F': None},
{'A': None, 'B': None, 'C': None, 'D': None, 'E': None, 'F': None},
{'A': None, 'B': None, 'C': None, 'D': None, 'E': None, 'F': None},
{'A': None, 'B': None, 'C': None, 'D': None, 'E': None, 'F': None},
{'A': None, 'B': None, 'C': None, 'D': None, 'E': None, 'F': None},
{'A': None, 'B': None, 'C': None, 'D': None, 'E': None, 'F': None},
{'A': None, 'B': None, 'C': None, 'D': None, 'E': None, 'F': None},
{'A': None,'B': None,'C': None,'D': 'Guido van Rossum',
'E': 'Anders Hejlsberg','F': 'Bjarne Stroustrup'},
{'A': None, 'B': None, 'C': None, 'D': None, 'E': None, 'F': None},
{'A': None, 'B': None, 'C': None, 'D': None, 'E': None, 'F': None},
{'A': None, 'B': None, 'C': None, 'D': None, 'E': None, 'F': None},
{'A': None, 'B': None, 'C': None, 'D': None, 'E': None, 'F': None},
{'A': None, 'B': None, 'C': None, 'D': None, 'E': None, 'F': None},
{'A': None, 'B': None, 'C': None, 'D': None, 'E': None, 'F': None},
{'A': None, 'B': None, 'C': None, 'D': None, 'E': None, 'F': None}]