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
Related
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
Why "can't assign to operator" error for this line point * hours = QP?
class Student(object):
def __init__(self, name, surname, grade, hours, QP):
self.name = name
self.surname = surname
self.grade = grade
self.hours = hours
self.QP = QP
def getName(self):
return '{}'.format(self.name)
def getSurname(self):
return '{}'.format(self.surname)
def getGrade(self):
return list(zip(self.grade, self.hours))
def getHours(self):
return '{}'.format(self.hours)
def point(self):
if grade == A:
point = 4.0
elif grade == B:
point = 3.0
elif grade == C:
point = 2.0
elif grade == D:
point = 1.0
else:
point = 0.0
def getQPoints(self):
point * hours = QP
return QP
stud1 = Student("John","Brown",["A","B","A"],["15.0","25.0","20.0"],"")
stud2 = Student("Mary","Watson",["C","A","B"],["15.0","25.0","20.0"],"")
print (stud1.getQPoints())
I don't believe that you can reverse that. Instead, do
QP = point * hours
That way, you instantiate the new variable, and set it to the product of the points and the hours.
Some other issues: your point variable isn't defined either. You need
self.point = point
in order to have the variable as an actual variable. Also, it might cause some confusion between the point function and the point variable, because of the two being the same name. One or the other, I'd name one as points.
If I understood what are you trying to do:
You are trying to assign points * hours to QP which is not possible in python that way, so you have to do it normally like this:
`QP = points * hours`
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
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
NB Noob alert ... !
I am trying to use recursion in a Python class method, but with limited results.
I'm trying to build a car class, with very basic attributes: id, position in a one lane road (represented by an integer), and velocity. One of the functions I have is used to return which car id is in front on this one -- i.e. if we have class:
class Car:
def __init__(self, position, id, velocity):
self.position = position
self.id = id
self.velocity = velocity
Now, I've come up with the following class method (additional details below the code):
def findSuccessorCar(self, cars):
successorCar = ""
smallestGapFound = 20000000
for car in cars:
if car.id == self.id: continue
currentGap = self.calculateGap(car)
if (currentGap > -1) and (currentGap < smallestGapFound):
smallestGapFound = currentGap
successorCar = car
if successorCar == "":
return 1 # calling code checks for 1 as an error code
else:
return successorCar
The plan is to create car objects, then store them in a list. Each time the findSuccessorMethod is called, this global list of cars is passed to it, e.g.
c1 = testCar.Car(4, 5, 1) # position, pos_y, Vel, ID
c2 = testCar.Car(7, 9, 2)
c3 = testCar.Car(9, 1, 2)
cars = [c1, c2, c3]
c1_succ = c1.findSuccessorCar(cars)
This works fine: the find successor car function will say that car c2 is in front of car c1 (position 7 ahead of position 4).
However, I want car c1 to work out what car is in front of its immediate successor -- that is, which car is in front of the car in front, which in this case is car c3. My thinking was that if I did c1_succ.findSuccessorCars(cars) then this should work fine: doing type(c1_succ) shows it is an instance and hasattr shows that it has the anticipated object attributes.
However, when I do try to execute c1_succ.findSuccessorCars(cars), an integer is returned. Hence, I am confused -- why doesn't this work? Why can you not recursively execute a class method in this fashion? Where does this integer come from?
NB Gut feel says that this has something to do with the self declaration, and that I'll need to modify my code so that as well as a global list of cars, there'll need to be a global list of their current positions, or another class method, e.g.
findSuccessorsSuccessor (yes, fully aware of crummy naming!). However, I am interested to understand why this recursive approach does not work.
UPDATE
Here is the requested code for calculating a gap between 2 cars -- I appreciate it is very basic, so not too much laughter at the back please.
def calculateGap(self, car):
''' Calculate the gap between two cars
'''
thisCar = self
otherCar = car
gap = otherCar.position_x - thisCar.position_x
return gap
What you're calling a class method is actually an instance method. Class methods operate on the class, and instance methods operate on the instance. Here, we're dealing with Car instances, not the Car class itself.
class Car(object):
def __init__(self, position, id, velocity):
self.position = position
self.id = id
self.velocity = velocity
def __eq__(self, other):
return self.id == other.id
def __str__(self):
return 'Car(%d, %d, %d)' % (self.position, self.id, self.velocity)
def calculateGap(self, other):
return other.position - self.position
def findSuccessor(self, cars):
ret = smallestGap = None
for car in cars:
if car == self:
continue
gap = self.calculateGap(car)
if gap < 0:
continue
if smallestGap is None or gap < smallestGap:
ret, smallestGap = car, gap
return ret
def findNthSuccessor(self, n, cars):
cur = self
for x in xrange(n):
cur = cur.findSuccessor(cars)
if cur is None:
return None
return cur
c1 = Car(4, 5, 1)
c2 = Car(7, 9, 2)
c3 = Car(9, 1, 2)
cars = [c1, c2, c3]
print c1.findSuccessor(cars)
print c1.findSuccessor(cars).findSuccessor(cars)
print c1.findNthSuccessor(2, cars)
Output:
Car(7, 9, 2)
Car(9, 1, 2)
Car(9, 1, 2)
Your method does work in theory; this is an implementation bug. That said, it is not the right way to do things; specifically, findSuccessorCar should not be a class method of Car. This is because the list of Car instances is a separate construct; the class Car doesn't and shouldn't know anything about it. If you wanted to make a class for it you should make a Road which is a list of Cars, and put findSuccessorCar on that.
That said, I don't see why you can't do
import operator
cars.sort( key = operator.attrgetter( "position" ) )
to sort the list of cars in position order. I think you're implementing your own sorting algorithm to find the successor car?
Other points of note: you should use exceptions (raise BadCarMojoError) to indicate failure, not magic return codes; classmethods traditionally use cls instead of self as the first argument; and Car should inherit from object.
import bisect
class Car( object) :
def __init__( self, position, id, velocity ):
self.position = position
self.id = id
self.velocity = velocity
def __lt__( self, other ):
return self.position < other.position
class Road( object ):
def __init__( self ):
self.cars = [ ]
def driveOn( self, car ):
bisect.insort( self.cars, car )
def successor( self, car ):
i = bisect.bisect_left( self.cars, car )
if i == len( self.cars ):
raise ValueError( 'No item found with key at or above: %r' % ( car, ) )
return self.cars[ i + 1 ]
c1 = Car( 4, 5, 1 )
c2 = Car( 7, 9, 2 )
c3 = Car( 9, 1, 2 )
c1 < c2
road = Road( )
for car in ( c1, c2, c3 ):
road.driveOn( car )
c1_succ = road.successor( c1 )