Python - Using spaces only not solving class methods 'IndentationError' on compilation? - python-3.x

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?

Related

Why the type of a parameter of a function in a class would change into list?

class Employee:
num_of_emps = 0
raise_amount = 1.04
def __init__(self, first, last, pay):
self.first = first
self.last = last
self.pay = pay
self.email = first + last + '#gmail.com'
Employee.num_of_emps += 1
def fullname(self):
return f'I am {self.first} {self.last}'
def apply_raise(self):
self.pay = int(self.pay * Employee.raise_amount)
#classmethod
def set_raise_amt(cls, amount):
cls.raise_amount = amount
#classmethod
def from_string(cls, emp_str):
first, last, pay = emp_str.split('-')
return cls(first, last, pay)
#staticmethod
def is_workday(day):
if day.weekday() == 5 or day.weekday() == 6:
return False
return True
class Developer(Employee):
raise_amount = 1.50
def __init__(self, first, last, pay, prog_lang):
super().__init__(first, last, pay)
self.prog_lang = prog_lang
class Manager(Employee):
def __init__(self, first, last, pay, employees=None):
super().__init__(first, last, pay)
if employees is None:
self.employees = []
else:
self.employees = employees
def add_emp(self,emp):
if emp not in self.employees:
self.employees.append(emp)
def remove_emp(self,emp):
if emp in self.employees:
self.employees.remove(emp)
def print_emps(self):
for emp in self.employees:
print('--->', emp.full_name())
dev_1 = Developer('John','Doe',30000, 'Python')
dev_2 = Developer('Emily','Smith',23000, 'Java')
# print(help(Developer))
print(dev_1.email)
print(dev_2.email)
print(dev_1.pay)
dev_1.apply_raise()
print(dev_1.pay)
mgr_1 = Manager('Sarah','Smith',34000, [dev_1])
print(type(mgr_1.employees))
print(mgr_1.employees)
print(type(dev_1))
print(type([dev_1]))
print([dev_1])
mgr_1.print_emps()
I recently studied this code on youtube. So basically this code started with a class named 'Employee' at the beginning, and then a subclass called 'Developer' was created. I still able to catch up with the logic behind the code at the moment, but after another subclass called 'Manager' was created, I lost.
I don't know why the parameter,'employees' in the class 'Manager' would suddenly become a list in the end
And I also don't know why the for loop could be able to run
Please help, thank you so much
mgr_1 = Manager('Sarah','Smith',34000, [dev_1])
first='Sarah', last='Smith', pay=34000, employees=[dev_1]
Your parameter is an list

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")

AttributeError: 'ElectricCar' object has no attribute 'battery_size'

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

how to access to data from a class which is stored in another class in python?

This is my code. I got a problem when i want to print the information inside the class 'pokemon'
class trainer(object):
def __init__(self, name, pokemons = [], money = 0):
self.name = name
self.pokemons = pokemons
self.money = money
this is my first class which has every pokemon per trainer
class pokemon(object):
def __init__(self, name, attribute, attacks = {}, health = '==========='):
self.name = name
self.attribute = attribute
self.health = health
self.attacks = attacks
The other class where I take the pokemon to import to the other class
class fight():
def __init__(self, fighter1, fighter2):
self.fighter1 = fighter1
self.fighter2 = fighter2
def fighting(self):
if len(Trainer1.pokemons) >= 1 and len(Trainer2.pokemons) >= 1:
print('{} wanna fight against {}'.format(Trainer1.name, Trainer2.name))
keepgoing = True
print('{} got this Pokemons: '.format(Trainer1.name))
i = 0
for i in Trainer1.pokemons:
print(i)
#while (keepgoing):
else:
print('You gotta have pokemons to fight')
return False
I thought that creating a class named fight for getting in battle would be the most wise idea but I'd like to know another method to do it
Pokemon1 = pokemon('Charizard', 'Fire', attacks={'1':'ball fire', '2':'cut', '3':'fire blast', '4':'mega kick'})
Pokemon2 = pokemon('Charmander', 'fire', attacks={'1':'blast', '2':'scratch', '3':'heat', '4':'tear'})
Trainer1 = trainer('Santiago', pokemons=[Pokemon1, Pokemon2])
Pokemon3 = pokemon('Charizard', 'Fire', attacks={'1':'ball fire', '2':'cut', '3':'fire blast', '4':'mega kick'})
Pokemon4 = pokemon('Charmander', 'fire', attacks={'1':'blast', '2':'scratch', '3':'heat', '4':'tear'})
Trainer2 = trainer('Alejandra', pokemons=[Pokemon3, Pokemon4])
Okay my problem is in the class fight. when i want to print the names of the pokemons i get the following message:
Santiago got this Pokemons:
<__main__.pokemon object at 0x000002AAD9B64D00>
<__main__.pokemon object at 0x000002AAD9B92DF0>
i know that the pokemon class has various instances, but how can i access to them?
To make your life easier, I recommend that you implement the __str__ dunder method on pokemon. This will resolve the issue that you are seeing right now, and make future prints of pokemon much easier.
That would look something like this:
class pokemon(object):
def __init__(self, name, attribute, attacks = {}, health = '==========='):
self.name = name
self.attribute = attribute
self.health = health
self.attacks = attacks
def __str__(self):
return "Pokemon: %s (Health: %11s)" % (self.name, self.health)
When you print the 'Charmander' pokemon, it'll look something like this:
Pokemon: Charmander (Health: ===========)
Of course, you can change the return of the __str__ to return whatever you want out of the pokemon.

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