Reputation: 137
class Airplane:
def __init__(self, plane_model, serial_num, num_seats, miles_travelled):
self.model = plane_model
self.serial = serial_num
self.seat = num_seats
self.miles = miles_travelled
class Flight:
def __init__(self, plane):
self.passangers = []
self.airplane = plane
I am trying to complete the following function:
def add(self, passenger):
"""(Flight, str) -> bool
If there are still seats avalaible on this flight, add passenger to the passenger list.
Return true iff passenger is added to this flight.
>>> a = Airplane('Cesna 150E', '9378', 1, 824.8)
>>> f = Flight(a)
>>> f.add('Myrto') # Decreases the seat by 1
True
>>> f.add('Jen') # No more seats avalaible
False
"""
So far, my attempt:
if self.seat > 0:
self.seat -= 1 #num_seats
return True
else:
return False
Of course, naturally, the instance variable num_seats
would decrease by one if a passenger is added. The number of seats available is indicated on the third parameter on the Airplane
class.
If I use the function that I have designed, attempting the exact same action like the one in the docstring returns the following error:
Traceback (most recent call last):
File "<pyshell#18>", line 1, in <module>
f.add('a')
File "/Users/N/Desktop/Untitled.py", line 39, in add
if self.seat > 0:
AttributeError: 'Flight' object has no attribute 'seat'
I think I may be missing something but I am not sure what it is.
Upvotes: 1
Views: 348
Reputation: 122032
Your specific error is that a Flight
instance doesn't have a seat
attribute, that's an attribute of an Airplane
instance and should therefore be accessed via the self.airplane
attribute (which provides the link to the Airplane
instance that will be used for the Flight
instance):
if self.airplane.seat > 0:
# ^ access via 'airplane' attribute
However, I think your modelling is slightly off generally. The addition of passengers changes the number of free seats on the Flight
instance, but does not alter the number of seats on the Airplane
instance (as far as I'm aware, they don't start stripping seats out of the plane as people book!) Also, the distance to be travelled is a property of the flight, not the aeroplane. With that in mind, I would implement as:
class Airplane(object):
def __init__(self, model, seats):
self.model = model
self.seats = seats
class Flight(object):
def __init__(self, plane, code, distance):
self.plane = plane
self.code = code
self.distance = distance
self.passengers = []
@property
def free_seats(self):
return self.plane.seats - len(self.passengers)
def add(self, passenger):
if not self.free_seats:
raise Exception("Flight full.")
self.passengers.append(passenger)
Note that Flight.add
checks to ensure that the current passengers
list will fit into the plane.seats
. There is no need to keep a separate attribute - free_seats
can be calculated from other attributes, so I've made it a read-only property
. In use:
>>> f = Flight(Airplane("747", 5), "BA0123", 123)
>>> for person in ['John Cleese', 'Terry Gilliam', 'Eric Idle', 'Terry Jones', 'Michael Palin']:
f.add(person)
>>> f.passengers
['John Cleese', 'Terry Gilliam', 'Eric Idle', 'Terry Jones', 'Michael Palin']
>>> f.add('Graham Chapman')
Traceback (most recent call last):
File "<pyshell#32>", line 1, in <module>
f.add('Graham Chapman')
File "<pyshell#25>", line 13, in add
raise Exception("Flight full.")
Exception: Flight full.
>>> f.free_seats
0
(Don't worry, Graham's past caring at this point.)
This does not quite meet your specification, as Flight.add
now raises an error if the flight is full, rather than returning False
. This is a more Pythonic way of coding; see "Easier to ask for forgiveness than permission".
Upvotes: 1