AttributeError: 'ElectricCar' object has no attribute 'battery_size' - python-3.x

i am learning from the book' "Python crash course a handbook". i have written the code exactly as it is in book but still i m getting error. can you please tell me what is the problem with below code:
i m getting 'AttributeError: 'ElectricCar' object has no attribute 'battery_size''.
class Car:
def __init__(self, make, model, year):
self.make=make
self.model=model
self.year=year
self.odometer_reading = 0
def get_discriptive_name(self):
long_name= f"{self.year} {self.make} {self.model}"
return long_name.title()
def read_odometer(self):
"""Print a statement showing the car's mileage."""
print(f"This car has {self.odometer_reading} miles on it.")
def update_odometer(self, mileage):
"""
Set the Odometer reading to the given value.
Reject the change if it attempts to roll the odometer back.
"""
if mileage >= self.odometer_reading:
self.odometer_reading = mileage
else:
print("You can't roll back an odometer!")
def increment_odometer(self,miles):
"""Add the given amount to the odometer reading."""
self.odometer_reading += miles
"""Inheritance from parent/superclass to child/subclass."""
class ElectricCar(Car):
"""Represent aspects of a car, specific to electric vehicles."""
def __intit__(self,make,model,year):
super().__init__(make,model,year)
self.battery_size = 75
def describe_battery(self):
"""Print a statement describing the battery size."""
print(f"This car has a {self.battery_size}-kWh battery.")
my_tesla = ElectricCar('tesla','model s', 2009)
print(my_tesla.get_discriptive_name())
my_tesla.describe_battery()

class ElectricCar(Car):
def __intit__(self,make,model,year):
super().__init__(make,model,year)
self.battery_size = 75
def describe_battery(self):
"""Print a statement describing the battery size."""
print(f"This car has a {self.battery_size}-kWh battery.")
if you take a look you misspelled the init function

Related

Getting a value from a Class Object in Python based on User Input

so I'm in the process of learning Python, so forgive any naivety.
I'm doing some practice on Classes - and I'm making it so that when a user input their car - it looks for instantiated objects and then returns the price.
I get it to work okay for "BMW" - but when I try Ferrari - it only return the price for the BMW (20k). I'm thinking it is something not right with the price_check function part of the code.
Please could you provide some guidance here? Code below:
class Car:
car_list = []
def __init__(self, make, model, price):
self.make = make
self.model = model
self.price = price
self.car_list.append(self)
#this is the part of the code that i'm stuck with
def price_check(self):
for i in Car.car_list:
if New_Car.make == self.make:
return i.price
else:
print("Not available")
BMW = Car('BMW', '1 Series', "£20,000")
Ferrari = Car('Ferrari', 'Italia', "£90,000")
New_Car = Car(
input("What is make of your car? "), input("What is the model? "), "")
print("The cost of this car is: ", New_Car.price_check())
So essentially, I want it to return the price of the Ferrari if that's what the user typed.
Thanks in advance. And, sorry for any incorrect formatting, etc...
Okay, I agree with the comments made by #Jarvis regarding errors in your code, I would also add that in Cars init the price is a required variable and should cause an error on instantiation. In addition, in price_check, since the new_car instance has already been added to the list, price_check will also examine that entry and either find None or 0 price, so will never get to the "No Price Available" return. Here's how I would implement the Class
class Car:
car_list = []
def __init__(self, make, model, price=None): #makes providing price optional
self._make = make
self._model = model
self._price = price
Car.car_list.append(self)
#property
def make(self):
return self._make
#property
def model(self):
return self._model
#property
def price(self):
return self._price
#price.setter
def price(self, val):
self._price = val
def price_check(self):
for i in Car.car_list:
if i != self and self.make == i.make and self.model == i.model:
return i.price
return "Not available"
Two issues, first you need to append to the list not bound to your instance but the one bound to your class as a class-attribute:
def __init__(self, make, model, price):
self.make = make
self.model = model
self.price = price
# use the 'class' rather than the 'instance', you need to modify a class-attribute
Car.car_list.append(self)
Second, your issue in price check
def price_check(self):
for i in Car.car_list:
# you need to compare self's make with 'i.make' (elements in list)
if self.make == i.make:
return i.price
else:
print("Not available")

Function not Defined in Class

I am having trouble with a coding project in which I am trying to use classes in python to make a card game (cheat). However, when creating the player class, one of the functions that was previously defined within the class is shown as undefined. I cannot figure out the reason, and any suggestion is appreciated. Below is the definition of the classes
class card(object):
def __init__(self,rank,suit):
self.rank = rank
self.suit = suit
class player(object):
def __init__ (self):
self.number = number
self.hand = list()
#Here, hand is a list of the card class that was distributed with a suit and a rank
def check_card(self,player_rank,player_suit):
for card in self.hand:
if card.rank == player_rank and card.suit == player_suit:
return True
break
return False
def play_card(self):
suit = input('what is the suit?')
rank = input('what is the rank?')
if check_card(self,rank,suit):
print(True)
else:
print(False)
Here is the actual code that will run it
player = player()
player.play_card()
The following error was received:
NameError: name 'check_card' is not defined
I have been troubleshooting and looking at different solutions, including moving the functions outside the class, but it continues to display the same error. Can anyone point out the mistake? Thanks!
You have the following two issues in your code
The way you passed self to the check_card function is wrong. You must call it in this way
self.check_card(rank,suit)
The second issue is that the number is not defined. Thus I passed it as an argument while initializing the player. Feel free to make changes for that.
This is the corrected code :
class card(object):
def __init__(self,rank,suit):
self.rank = rank
self.suit = suit
class player(object):
def __init__ (self, number):
self.number = number
self.hand = list()
#Here, hand is a list of the card class that was distributed with a suit and a rank
def check_card(self,player_rank,player_suit):
for card in self.hand:
if card.rank == player_rank and card.suit == player_suit:
return True
break
return False
def play_card(self):
suit = input('what is the suit?')
rank = input('what is the rank?')
if self.check_card(rank,suit):
print(True)
else:
print(False)
player = player(3)
player.play_card()
Output :
what is the suit?spade
what is the rank?3
False
Based on this document the function call in python class is self.xxxx(args) (xxxx is denoted function name)
therefore the correct version of play_card function is shown as following.
enter code here
def play_card(self):
suit = input('what is the suit?')
rank = input('what is the rank?')
if self.check_card(rank,suit):
print(True)
else:
print(False)

Why does my code say NameError: name 'self' is not defined'

Sorry if this is a really stupid question since I am terrible at python and most of my knowledge consists of the very restricted things you are taught before post 16 education. Basically I'm trying to do a coding project in preparation for when my classes start in September, and so far I've managed to get by teaching myself classes using online websites and people's online forum questions. However, I've come into a bit of a roadblock because my code keeps throwing an error. I've looked on websites and forums but they seem to be in very different situations compared to me and some of them just seem to tell me what I've done is right. The exact error given is: line 34, in returnBarbarianStats
print(self.name,"the barbarian's stats:")
NameError: name 'self' is not defined
import random
def getName():
syllables = ['en','da','fu','ka','re','toh','ko','noh','tuk','el','kar']
firstName = (random.choice(syllables))
secondName = (random.choice(syllables))
thirdName = (random.choice(syllables))
global generatedName
generatedName = firstName+'-'+secondName+'-'+thirdName
# Classes-all creatures have names generated the same way and have the same amount of health.
# The way I have selected how each subclass will be randomly chosen is having the code select a random value
# from the list and depending on which is chosen it will give a subclass.
class preset():
def _init_(self, creature, name, health=100):
self.name = generatedName
self.health = 100
getName()
self.name=generatedName
#Gives different attributes to each sub-class
class barbarian(preset):
def _init_(self, name, power=70, specialAttackPower=20, speed=50):
preset._init_(self, creature, name, health=100)
self.power = power
self.specialAttackPower = specialAttackPower
self.speed = speed
self.name = name
def returnBarbarianStats():
print(self.name,"the barbarian's stats:")
print("Health:",self.health)
print("Power damage:",self.power)
print("Special attack power damage:",self.specialAttackPower)
print("Speed:",self.speed)
class elf(preset):
def _init_(self, name, power=30, specialAttackPower=60, speed=10):
preset._init_(self, creature, name, health=100)
self.power = power
self.specialAttackPower = specialAttackPower
self.speed = speed
class wizard(preset):
def _init_(self, name, power=50, specialAttackPower=70, speed=30):
preset._init_(self, creature, name, health=100)
self.power = power
self.specialAttackPower = specialAttackPower
self.speed = speed
class dragon(preset):
def _init_(self, name, power=90, specialAttackPower=40, speed=50):
preset._init_(self, creature, name, health=100)
self.power = power
self.specialAttackPower = specialAttackPower
self.speed = speed
class knight(preset):
def _init_(self, name, power=60, specialAttackPower=10, speed=60):
preset._init_(self, creature, name, health=100)
self.power = power
self.specialAttackPower = specialAttackPower
self.speed = speed
#10 randomly generated characters.
i = 0
army = []
while i < 10:
creatures = ['barbarian','elf','wizard','dragon','knight']
creatureType = (random.choice(creatures))
if creatureType == 'barbarian':
army.append(barbarian())
elif creatureType == 'elf':
army.append(elf())
elif creatureType == 'wizard':
army.append(wizard())
elif creatureType == 'dragon':
army.append(dragon())
elif creatureType == 'knight':
army.append(knight())
i = i + 1
barbarian.returnBarbarianStats()
I've just given the whole code as I don't want to miss any important details out.
you missed self in the parameters buddy :)
[line 32]
def returnBarbarianStats():
correct it to
def returnBarbarianStats(self):

Python - Using spaces only not solving class methods 'IndentationError' on compilation?

Learning class construction, and of course I'm stuck with the 'IdentationError: unexpected indent' on the following code:
class Account:
def __init__(self, name, balance, min_balance):
self.name = name
self.balance = balance
self.min_balance = min_balance
def deposit(self, amount):
self.balance += amount
def withdraw(self, amount):
if self.balance - amount >= self.min_balance:
self.balance -= amount
else:
print("Sorry, not enough funds!")
def statement(self):
print("Account Balance: £{}".format(self.balance)
class Current(Account):
def __init__(self, name, balance):
super().__init__(name, balance, min_balance=-1000)
I believe I have exclusively used spaces for indents but I am still unable to get ahead of this one. What am I doing wrong?

Where would the best place to create Python objects be

So I'm making an OOP based program in Python and I wanted to ask: Where would be the best place to create an object? Let's say I have this object from my program.
class Player(Item):
def __init__(self,Name,Diff,Money,Experience):
self.name = Name
self.diff = Diff
self.money = Money
self.experience = Experience
But I also have a main class game. Should I create the player object inside of class game, or maybe outside of all the classes so it is global? I don't know where I should make it so I can access it whenever I need it.
You're talking about where to define a class; this is a style question. Let's see what the Style Guide for Python Code (PEP 8) has to say about this:
Surround top-level function and class definitions with two blank lines.
Ok... That's not too helpful, because now I have to use my own knowledge to answer the question. Erm...
Well, I suppose it depends on what you're trying to say. If you've got this:
class Game:
class Player:
def __init__(self, name, difficulty, money=0, experience=0):
self.name = name
self.difficulty = difficulty
self.money = money
self.experience = experience
then that suggests that if you change the Game implementation you'll have to change the Player implementation, and you can't change the Player implementation without changing the Game implementation; i.e., they're tightly coupled. So the code might carry on like this:
def attack(self, game, other):
game.hurt(other, 1000 // self.difficulty)
if other.hp == 0:
self.money += other.money
other.money = 0
def hurt(self, enemy, damage):
enemy.hp -= damage // enemy.difficulty
if enemy.hp <= 0:
enemy.hp = 0
enemy.die(self)
self.player.experience += enemy.difficulty
This is not a great way of programming; everything's tied together too much and it's a big tangled mess. What's responsible for what? Instead, I'd have something more like this:
class Game:
def __init__(self):
self._entities = set()
def register(self, entity):
if entity not in self._entities:
self._entities.add(entity)
def unregister(self, entity):
if entity in self._entities:
self._entities.remove(entity)
def end(self):
print("Game over")
raise SystemExit(0)
class Entity:
def __init__(self, *args, game, **kwargs):
super().__init__(*args, **kwargs)
self.game = game
game.register(self)
def die(self):
self.game.unregister(self)
class Fighter(Entity):
def __init__(self, *args, difficulty, money=None, **kwargs):
super().__init__(*args, **kwargs)
if money is None:
money = (difficulty ** 2 - difficulty) // 2 + 1
self.difficulty = difficulty
self.money = money
self._hp = 1000
def attack(self, other):
money = other.hit(self, self.difficulty):
self.money += money
def hit(self, other, damage):
self._hp -= damage
if self._hp <= 0:
money = self.money
self.money = 0
self.die()
return money
# Didn't kill me, so gets no money
return 0
class Player(Fighter):
def __init__(self, *args, difficulty, money=None, experience=0, **kwargs):
if money is None:
money = 1000 // difficulty # You get less money the more skilled
# you are.
self.experience = experience
super().__init__(*args, difficulty=difficulty, money=money, **kwargs)
def die(self):
self.game.end()
def attack(self, other):
# Every time you attack an enemy, you get XP
self.experience += other.difficulty
super().attack(other)
This is crude and poorly designed, but you get the general idea. Each thing is in charge of dealing with its own stuff. Really the world should be in charge of checking whether all of the players are dead, but as it doesn't store players separately I couldn't show that in the example.

Resources