The error says:
AttributeError: 'list' object has no attribute 'cost' I am trying to get a simple profit calculation to work using the following class to handle a dictionary of bicycles:
class Bike(object): def __init__(self, name, weight, cost): self.name = name self.weight = weight self.cost = cost bikes = { # Bike designed for children" "Trike": ["Trike", 20, 100], # Bike designed for everyone" "Kruzer": ["Kruzer", 50, 165] } When I try to calculate profit with my for statement, I get the attribute error.
# Markup of 20% on all sales margin = .2 # Revenue minus cost after sale for bike in bikes.values(): profit = bike.cost * margin First, I don't know why it is referring to a list, and everything seems to be defined, no?
13 Answers
Consider:
class Bike(object): def __init__(self, name, weight, cost): self.name = name self.weight = weight self.cost = cost bikes = { # Bike designed for children" "Trike": Bike("Trike", 20, 100), # <-- # Bike designed for everyone" "Kruzer": Bike("Kruzer", 50, 165), # <-- } # Markup of 20% on all sales margin = .2 # Revenue minus cost after sale for bike in bikes.values(): profit = bike.cost * margin print(profit) Output:
33.0 20.0
The difference is that in your bikes dictionary, you're initializing the values as lists [...]. Instead, it looks like the rest of your code wants Bike instances. So create Bike instances: Bike(...).
As for your error
AttributeError: 'list' object has no attribute 'cost' this will occur when you try to call .cost on a list object. Pretty straightforward, but we can figure out what happened by looking at where you call .cost -- in this line:
profit = bike.cost * margin This indicates that at least one bike (that is, a member of bikes.values() is a list). If you look at where you defined bikes you can see that the values were, in fact, lists. So this error makes sense.
But since your class has a cost attribute, it looked like you were trying to use Bike instances as values, so I made that little change:
[...] -> Bike(...) and you're all set.
2They are lists because you type them as lists in the dictionary:
bikes = { # Bike designed for children" "Trike": ["Trike", 20, 100], # Bike designed for everyone" "Kruzer": ["Kruzer", 50, 165] } You should use the bike-class instead:
bikes = { # Bike designed for children" "Trike": Bike("Trike", 20, 100), # Bike designed for everyone" "Kruzer": Bike("Kruzer", 50, 165) } This will allow you to get the cost of the bikes with bike.cost as you were trying to.
for bike in bikes.values(): profit = bike.cost * margin print(bike.name + " : " + str(profit)) This will now print:
Kruzer : 33.0 Trike : 20.0 You need to pass the values of the dict into the Bike constructor before using like that. Or, see the namedtuple -- seems more in line with what you're trying to do.