class MyClassName:
Normally follow the Pascal naming convention, where the 1st letter of each word is capitalized.
From Pluralsite course: https://app.pluralsight.com/course-player?clipId=9739a4ad-e29a-4716-a1fb-f153ddb3ddcd
airtravel.py
class Flight:
def __init__(self, number):
if not number[:2].isalpha(): #make sure the 1st 2 digits of the number variable are alpha characters
raise ValueError(f"No airline code in '{number[:2]}'")
if not number[:2].isupper(): # make sure the 1st 2 digits of the number var are Upper case
raise ValueError(f"Invalid airline code. Needs to be upper case. '{number[:2]}'")
if not (number[2:].isdigit() and int(number[2:]) <= 9999): # should have 1 or more digits after the 1st 2 chars.
raise ValueError(f"Invalid route number '{number[2:]}'. Should be between 0 and 9999.")
self._number = number
def number(self):
return self._number
def airline(self):
return self._number[:2]
def route(self):
return self._number[2:]
>>> from airtravel import Flight
>>> f = Flight("SN060") #Associate "f" with the Flight class
>>> f.number() #Call the number function in the Flight Class.
'SN060'
>>> f.airline()
'SN'
>>> f.route()
'060'
def __init__(self, anything else):
The above will set anything in the init initializer once the class is called. It should not return anything.
Why number? The Implementation details of an object that are not intended for manipulation or consumption by clients, should start with an "". This is sort of like tagging something as being private (although this concept doesn't exist in Python).
>>> from airtravel import Flight, Aircraft
>>> #create a variable a with Aircraft attributes
>>> a = Aircraft("G-EUPT", "Airbus A319", num_rows=22, num_seats_per_row=6)
>>> a.model()
'Airbus A319'
>>> a.registration()
'G-EUPT'
>>> a.seating_plan()
(range(1, 23), 'ABCDEF')
airtravel.py
class Flight:
def __init__(self, number):
"""check that the first to characters of the number variable
are alpha characters"""
if not number[:2].isalpha():
raise ValueError(f"No airline code in '{number}'")
"""Check that the 1st two characters are upper case for the
number variable """
if not number[:2].isupper():
raise ValueError(f"Invalid airline code '{number}'")
"""Make sure that the last 4 digits are digits and less than 9999"""
if not (number[2:].isdigit() and int(number[2:]) < 9999):
raise ValueError(f"Invalid Route Number '{number}'")
"""If all the checks pass for the number passed, set the _number variable
to the number value passed to the class"""
self._number = number
def number(self):
return self._number
def airline(self):
"""Return the 1st 2 characters of the _number variable to show the
airline"""
return self._number[:2]
class Aircraft:
def __init__(self, registration, model, num_rows, num_seats_per_row):
self._registration = registration
self._model = model
self._num_rows = num_rows
self._num_seats_per_row = num_seats_per_row
def registration(self):
"""return the registration"""
return self._registration
def model(self):
"""return the model"""
return self._model
def seating_plan(self):
""" create a tuple of allowed seats based on num of rows
and a list of available seat letters (there is no I).
range will return a number starting with 1, up to the number of rows
specified in the num_rows parameter.
"""
return (range(1,self._num_rows + 1),
"ABCDEFGHJK"[:self._num_seats_per_row])
>>> from airtravel import *
>>> #Create f variable for the Flight class, and pass the Aircraft Class as the aircraft parameter.
>>> f = Flight("BA758", Aircraft("G-EUPT","Airbus 319",22, 6))
>>> f.aircraft_model()
'Airbus 319'
You can also create an Aircraft object and pass that to the Flight Class.
>>> a = Aircraft("G-EUPT","Airbus 319",22, 6)
>>> flight = Flight("BB123", a)
>>> flight.aircraft_model()
'Airbus 319'
airtravel.py
class Flight:
"""A Flight with a particular Passenger aircraft."""
def __init__(self, number, aircraft):
"""check that the first to characters of the number variable
are alpha characters"""
if not number[:2].isalpha():
raise ValueError(f"No airline code in '{number}'")
"""Check that the 1st two characters are upper case for the
number variable """
if not number[:2].isupper():
raise ValueError(f"Invalid airline code '{number}'")
"""Make sure that the last 4 digits are digits and less than 9999"""
if not (number[2:].isdigit() and int(number[2:]) < 9999):
raise ValueError(f"Invalid Route Number '{number}'")
"""If all the checks pass for the number passed, set the _number variable
to the number value passed to the class"""
self._number = number
self._aircraft = aircraft
def aircraft_model(self):
return self._aircraft.model()
def number(self):
return self._number
def airline(self):
"""Return the 1st 2 characters of the _number variable to show the
airline"""
return self._number[:2]
class Aircraft:
"""Parameters for passenger aircraft"""
def __init__(self, registration, model, num_rows, num_seats_per_row):
self._registration = registration
self._model = model
self._num_rows = num_rows
self._num_seats_per_row = num_seats_per_row
def registration(self):
"""return the registration"""
return self._registration
def model(self):
"""return the model"""
return self._model
def seating_plan(self):
""" create a tuple of allowed seats based on num of rows
and a list of available seat letters (there is no I).
range will return a number starting with 1, up to the number of rows
specified in the num_rows parameter.
"""
return (range(1,self._num_rows + 1),
"ABCDEFGHJK"[:self._num_seats_per_row])
>>> from airtravel import *
>>> f = Flight("BA758", Aircraft("G-EUPT","Airbus 319",22, 6))
>>> f.allocate_seat("12A", "Aaron Hatcher")
>>> f.allocate_seat("12A", "Aaron Hatcher")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "H:\Development\python\Training\airtravel.py", line 76, in allocate_seat
raise ValueError(f"seat {seat} already occupied")
ValueError: seat 12A already occupied
>>> f.allocate_seat("33A", "Aaron Hatcher")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "H:\Development\python\Training\airtravel.py", line 73, in allocate_seat
raise ValueError(f"Invalid rows number {row}")
ValueError: Invalid rows number 33
>>> f.allocate_seat("33B", "Aaron Hatcher")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "H:\Development\python\Training\airtravel.py", line 73, in allocate_seat
raise ValueError(f"Invalid rows number {row}")
ValueError: Invalid rows number 33
>>> f.allocate_seat("13Z", "Aaron Hatcher")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "H:\Development\python\Training\airtravel.py", line 62, in allocate_seat
raise ValueError(f"Invalid Seat letter {letter}")
ValueError: Invalid Seat letter Z
>>> f.allocate_seat("13A", "Ben Hatcher")
>>> f.allocate_seat("11A", "Shana Hatcher")
>>> f.allocate_seat("11A", "Jenifer Hatcher")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "H:\Development\python\Training\airtravel.py", line 76, in allocate_seat
raise ValueError(f"seat {seat} already occupied")
ValueError: seat 11A already occupied
>>> f.allocate_seat("11B", "Jenifer Hatcher")
>>> f.allocate_seat("11C", "Adam Hatcher")
>>> f.allocate_seat("11D", "Alex Hatcher")
>>> f.allocate_seat("10B", "Mary Hatcher")
>>> f.allocate_seat("10A", "Steve Hatcher")
airtravel.py
"""Model for aircraft flights."""
class Flight:
"""A flight with a particular passenger aircraft."""
def __init__(self, number, aircraft):
if not number[:2].isalpha():
raise ValueError(f"No airline code in '{number}'")
if not number[:2].isupper():
raise ValueError(f"Invalid airline code '{number}'")
if not (number[2:].isdigit() and int(number[2:]) <= 9999):
raise ValueError(f"Invalid route number '{number}'")
self._number = number
self._aircraft = aircraft
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 allocate_seat(self, seat, passenger):
"""Allocate a seat to a passenger.
Args:
seat: A seat designator such as "12C" or "21F".
passenger: The passenger name.
Raises:
ValueError: If the seat is unavailable.
"""
row, letter = self._parse_seat(seat)
if self._seating[row][letter] is not None:
raise ValueError(f"Seat {seat} 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_text = seat[:-1]
try:
row = int(row_text)
except ValueError:
raise ValueError(f"Invalid seat row {row_text}")
if row not in rows:
raise ValueError(f"Invalid row number {row}")
return row, letter
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(f"No passenger to relocate in seat {from_seat}")
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} already occupied")
self._seating[to_row][to_letter] = self._seating[from_row][from_letter]
self._seating[from_row][from_letter] = None
def num_available_seats(self):
return sum(
sum(1 for s in row.values() if s is None)
for row in self._seating
if row is not None
)
def make_boarding_cards(self, card_printer):
for passenger, seat in sorted(self._passenger_seats()):
card_printer(passenger, seat, self.number(), self.aircraft_model())
def _passenger_seats(self):
"""An iterable series of passenger seating allocations."""
row_numbers, seat_letters = self._aircraft.seating_plan()
for row in row_numbers:
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 AirbusA319(Aircraft):
def model(self):
return "Airbus A319"
def seating_plan(self):
return range(1, 23), "ABCDEF"
class Boeing777(Aircraft):
def model(self):
return "Boeing 777"
def seating_plan(self):
# For simplicity's sake, we ignore complex
# seating arrangement for first-class
return range(1, 56), "ABCDEGHJK"
def card_printer(passenger, seat, flight_number, aircraft):
output = (
f"| Name: {passenger}"
f" Flight: {flight_number}"
f" Seat: {seat}"
f" Aircraft: {aircraft}"
f" |"
)
banner = '+' + '-' * (len(output) - 2) + '+'
border = '|' + ' ' * (len(output) - 2) + '|'
lines = [banner, border, output, border, banner]
card = '\n'.join(lines)
print(card)
print()
def make_flights():
f = Flight("BA758", AirbusA319("G-EUPT"))
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")
g = Flight("AF72", Boeing777("F-GSPS"))
g.allocate_seat('55K', 'Larry Wall')
g.allocate_seat('33G', 'Yukihiro Matsumoto')
g.allocate_seat('4B', 'Brian Kernighan')
g.allocate_seat('4A', 'Dennis Ritchie')
return f, g