First we'll perform a small refactoring and extract the seat designator parsing and validation logic into it's own method, _parse_seat(). We use a leading underscore here because this method is an implementation detail:
class Flight:
# ...
def _parse_seat(self, seat):
"""Parse a seat designator into a valid row and letter.
Args:
seat: A seat designator such as 12F
Returns:
A tuple containing an integer,string for row and seat.
"""
row_numbers, seat_letters = self._aircraft.seating_plan()
letter = seat[-1]
if letter not in seat_letters:
raise ValueError("Invalid seat letter {}".format(letter))
row_text = seat[:-1]
try:
row = int(row_text)
except ValueError:
raise...