Fixing class method loop - python

I've encountered a problem with my class file and I can't seem to find a fix around it. I was hoping someone could point me to the right direction.
Here's my code:
class Car:
def __init__(self, year_model, make, speed):
self.__year_model = year_model
self.__make = make
self.__speed = 0
def set_year_model(self, year_model):
self.__year_model = year_model
def set_make(self, make):
self.__make = make
def get_year_model(self):
return self.__year_model
def get_make(self):
return self.__make
def accelerate(self):
self.__speed + 5
return self.__speed
def decelerate(self):
self.__speed - 5
return self.__speed
def get_speed(self):
return self.__speed
Essentially, I want the speed attribute set to 0, and have 3 methods (accelerate, decelerate, and get_speed) which add and subtract 5 to the speed attribute and eventually return the speed attribute so it can be printed.
I would guess there's a problem with my formatting but I can't seem to find the correct arrangement that would fix the class.
The real program is suppose to loop the accelerate method 5 times, but the class method is supposed to handle the sequential addition and return the final speed.
import car
user_year = 1995
user_make = "toyota"
user_speed = 0
user_car = car.Car(user_year, user_make, user_speed)
for count in range(1,6):
user_car.accelerate()
print user_car.get_speed()
I know this code is very weak, but it's all makeshift to help make my problem clearer.
So hopefully it's not too confusing and I can get an answer.

self._speed + 5 computes the current speed plus 5. But you're not actually storing the computed value anywhere. You want to use self._speed = self._speed + 5, or the more commonly used form, self._speed += 5.

The problem is, of course, the "+=" and "-=" portions that are missing, but I'd go a step further and suggest that if you're writing new python code, you become familiar with new style classes. In a new style class, your code could be written as follows:
class Car(object):
def __init__(self, year_model, make, speed):
self.year_model = year_model
self.make = make
self.speed = 0
def __set_year_model(self, year_model):
self.__year_model = year_model
def __set_make(self, make):
self.__make = make
def __set_speed(self, speed):
self.__speed = speed
def __get_year_model(self):
return self.__year_model
def __get_make(self):
return self.__make
def accelerate(self):
self.speed += 5
def decelerate(self):
self.speed -= 5
def __get_speed(self):
return self.__speed
speed = property(fget=__get_speed,fset=__set_speed,fdoc="Set or Retrieve the current speed of this instance of the Car object")
make = property(fget=__get_make,fset=__set_make,fdoc="Set or Retrieve the make of this instance of the Car object")
year_model = property(fget=__get_year_model,fset=__set_year_model,fdoc="Set or Retrieve the Year and Model of this instance of the Car object")
In addition, the code changes in the main file:
import car
user_year = 1995
user_make = "toyota"
user_speed = 0
user_car = car.Car(user_year, user_make, user_speed)
for count in range(1,6):
user_car.accelerate()
print user_car.speed

Related

Modify object attribute in Class declaration due to attributes relationship

I have a class with 3 attributes:
class Player():
def __init__(self,pos,stack):
self.pos = pos
self.stack = stack
self.debt = 0
All instances will begin with debt = 0. In my main program I will be modifying these attributes for many instances, but a player's debt can't be greater than a player's stack. Is it a way to prevent (especify) this from the class declaration? . I don't want to write
if player.debt > player.stack:
player.debt = player.stack
everytime a player's debt is modified. Is it a way to do this automatically from the class Player?
For example, in the following code I want to make the automatic modifications :
jug = Player("BTN",1000) # jug.debt then must be 0
jug.debt = 500 # jug.debt then must be 500
jug.debt = 2000 # jug.debt then must be 1000
Write a property and in the setter check if it exceeds the limit.
class Player():
def __init__(self,pos,stack):
self.pos = pos
self.stack = stack
self._debt = 0
#property
def debt(self):
return self._debt
#debt.setter
def debt(self, val):
if val > self.stack:
val = self.stack
self._debt = val

Writing a test in python

Im currently taking a python class and im new in programming. I have written the code below and want to write a code that tests if the ResilientPlayer actually does what it is supposed to. The code is from a chutes and ladders board game where the ResilientPlayer is a "special" type of player that gets a "superpower" in its next move afther falling down a chute. The next round afther he has fallen down a chute, he will add a given or a default number to the die_roll, and I want to test if my code actually does this! Hope someone can help me with this problem :)
class Player:
def __init__(self, board):
self.board = board
self.position = 0
self.n_steps = 0
def move(self):
die_roll = random.randint(1, 6)
self.position = self.get_position() + die_roll
self.board.position_adjustment(self.position)
self.n_steps += 1
def get_position(self):
return self.position
def get_steps(self):
return self.n_steps
class ResilientPlayer(Player):
default_extra_steps = 1
def __init__(self, board, extra_steps=None):
super().__init__(board)
self.extra_steps = extra_steps
if self.extra_steps is None:
self.extra_steps = self.default_extra_steps
def move(self):
if self.get_position() in self.board.chutes.values():
die_roll = random.randint(1, 6)
self.position = self.get_position() + die_roll + self.extra_steps
self.board.position_adjustment(self.position)
self.n_steps += 1
else:
super().move()
def get_position(self):
return self.position
def get_steps(self):
return self.n_steps
The best way to do this is using the unittest class, I do this as following:
import unittest
from .... import ResilientPlayer
class TestResilientPlayer(unittest.TestCase):
def setUp(self):
self.resilient_player = ResilientPlayer(....)
def test_move(self):
# Do stuff
self.assertEqual(1, 1)
if __name__ == '__main__':
unittest.main()
Here, unittest.main() will run all the tests in the file. setUp is run before each test (so you can have multiple tests with the same starting conditions).
This is an incredible useful module and I strongly suggest reading more on it, check the documentation

Having difficulty understanding Python OOP

I'm fairly green to OOP and I was just playing around with it in Python and came across something I can't explain so hopefully you guys will be able to help.
I was playing with the code below:
class Car():
def __init__(self, brand, model, speed):
self.brand = brand
self.model = model
self.speed = speed
def increase_speed(self):
return self.speed + 1
def decrease_speed(self, decrease_by):
return self.speed - decrease_by
car1 = Car("tesla","x",30)
print(car1.brand)
print(car1.speed)
print(car1.increase_speed())
print(car1.speed)
print(car1.decrease_speed(10))
My question is, I am expecting after increasing the speed, car1's speed will be 31 but instead it prints out 30. Why is it that way and how should the code be written for the speed to be 31 instead?
def increase_speed(self):
self.speed += 1
return self.speed
Previously you did not increase your speed, rather you just return a value that is equal to the speed plus 1. Similarly, change your decrease_speed function.
Instead of returning the values, set them on the attributes:
class Car():
def __init__(self, brand, model, speed):
self.brand = brand
self.model = model
self.speed = speed
def increase_speed(self):
self.speed = self.speed + 1
def decrease_speed(self, decrease_by):
self.speed = self.speed - decrease_by
I deliberately don't return the changed speed anymore, as it's good style (at least with methods mainly setting attributes) to either return something or change state:
car1 = Car("tesla","x",30)
print(car1.brand)
print(car1.speed)
car1.increase_speed()
print(car1.speed)
car1.decrease_speed(10)
print(car1.speed)
The method increase_speed is just returning self.speed + 1, if you wish to update the speed you need to self.speed = self.speed + 1 into the method increase speed.

Create a Car class in python

I have to create a Car class that has the following characteristics:
It has a gas_level attribute.
It has a constructor (init method) that takes a float representing the initial gas level and sets the gas level of the car to this value.
It has an add_gas method that takes a single float value and adds this amount to the current value of the gas_level attribute.
It has a fill_up method that sets the car’s gas level up to 13.0 by adding the amount of gas necessary to reach this level. It will return a float of the amount of gas that had to be added to the car to get the gas level up to 13.0. However, if the car’s gas level was greater than or equal to 13.0 to begin with, then it doesn’t need to add anything and it simply returns a 0.
Result should be:
example_car = Car(9)
print(example_car.fill_up()) # should print 4
another_car = Car(18)
print(another_car.fill_up()) # should print 0
This is what I have so far. Just got stuck in the add_gas and fill_up methods.
class Car:
def __init__(self, gas_level_x):
self.x = gas_level_x
def add_gas(self):
return ((self.x +
def fill_up(self):
return
def main():
ex_car = Car(9)
print(ex_car.fill_up())
if __name__ == "__main__":
main()
If I understand it right all you want is this?
if the tank is lower then 13 you tank it full till it's 13 and return the added value.
else return 0
class Car:
def __init__(self, gas_level_x):
self.x = gas_level_x
def add_gas(self, gas):
self.x += gas
def fill_up(self):
added = 13-self.x
self.x += added # Or call self.add_gas(added) if for some reason you want to use the method
if added > 0:
return added
return 0
Edit: And to test your requirements I've ran:
car = Car(9)
print(car.fill_up()) # Prints 4
car = Car(18)
print(car.fill_up()) # Prints 0
class Car:
def __init__(self, init_g):
self.g = init_g
def add_gas(gas):
self.g = self.g + gas
def fill_up(self):
if self.g < 13:
return 13 - self.g
else:
return 0

How to effectively update the attributes of an object

I am creating a "pet game" in order to train my computing skills in python (that is just an excuse: it is because it is fun).
I decided to do a simple RPG game. For that, I defined the class hero:
class hero:
#Common class for the main character
def __init__(self, name, lvl, str, agi, vit, int, luk, prof):
self.name = name
self.lvl = lvl
self.str = str
self.agi = agi
self.vit = vit
self.int = int
self.luk = luk
self.prof = prof
self.exp = 0
if prof==1:
self.dmg=3*(self.str)+1*(self.agi)
self.skillList=['heavySlash01']
self.strUp=3
self.agiUp=1
self.vitUp=2
self.intUp=1
self.lukUp=1
if prof==2:
self.dmg=1*(self.str)+3*(self.agi)
self.skillList=['doubleAttack02']
self.strUp=1
self.agiUp=3
self.vitUp=1
self.intUp=1
self.lukUp=2
if prof==3:
self.dmg=4*(self.int)
self.skillList=['fireBall03']
self.strUp=1
self.agiUp=1.5
self.vitUp=0.5
self.intUp=3.5
self.lukUp=1.5
self.hp=19*vit
However, I noticed that whenever the hero leveled up, I needed to update all of its status separately. For instance, I needed to manually update the hero.dmg. Changing the agi, str and int did not automatically change the dmg as I would expect.
My question is then: Is there a way to make the dmg automatically update itself, based on its formula?
Make dmg a property instead of setting in the __init__ function. The __init__ only runs when the instance is initialized, which is why things aren't updating. However, making it a property runs the method whenever the property is accessed.
#property
def dmg(self):
if prof==1:
return 3*(self.str)+1*(self.agi)
if prof==2:
...
It's better to use inheritance in your case:
class Hero(object):
def __init__(self, name, lvl, _str, agi, vit, _int, luk):
self.name = name
self.lvl = lvl
self._str = _str # Should not use "str" because of reserved keyword of the same name
self.agi = agi
self.vit = vit
self._int = _int # Should not use "int" because of reserved keyword of the same name
self.luk = luk
self.exp = 0
#property
def hp(self):
return 19 * self.vit
class HeroProf_1(Hero):
skillList = ['heavySlash01']
strUp = 3
agiUp = 1
vitUp = 2
intUp = 1
lukUp = 1
#property
def dmg(self):
return 3 * self._str + 1 * self.agi
class HeroProf_2(Hero):
skillList = ['doubleAttack02']
strUp = 1
agiUp = 3
vitUp = 1
intUp = 1
lukUp = 2
#property
def dmg(self):
return 1 * self._str + 3 * self.agi
class HeroProf_3(Hero):
skillList = ['fireBall03']
strUp = 1
agiUp = 1.5
vitUp = 0.5
intUp = 3.5
lukUp = 1.5
#property
def dmg(self):
return 4 * self._int

Categories