I am attempting to calculate a fare for the 'Vehicle' class, whereby the fare is equal to the seating_capacity of the vehicle, multiplied by 10. My code is as follows:
class Vehicle:
def __init__(self, max_speed, mileage):
self.max_speed = max_speed
self.mileage = mileage
def seating_capacity(self, capacity=4):
self.capacity = capacity
return capacity
def fare(capacity):
fare = capacity * 10
return fare
class Bus(Vehicle):
def __init__(self, max_speed, mileage):
Vehicle.__init__(self, max_speed, mileage)
def seating_capacity(self, capacity=50):
return super().seating_capacity(capacity)
vehicle = Vehicle(240, 18)
print(f"Vehicle total fare is {vehicle.fare()}")
However, when I run the program, I am met with this traceback error:
TypeError: unsupported operand type(s) for *: 'Vehicle' and 'int'
The output should be 40, since the capacity of the vehicle is set to 4 by default. What am I doing wrong?
class Vehicle:
def __init__(self, max_speed, mileage):
self.max_speed = max_speed
self.mileage = mileage
self.capacity = 4
def seating_capacity(self):
return self.capacity
def fare(self):
fare = self.capacity * 10
return fare
class Bus(Vehicle):
def __init__(self, max_speed, mileage):
Vehicle.__init__(self, max_speed, mileage)
def seating_capacity(self, capacity=50):
return super().seating_capacity(capacity)
vehicle = Vehicle(240, 18)
print(f"Vehicle total fare is {vehicle.fare()}")
I am new to OOP and working on an example:
class Vehicle (object):
def __init__(self, name, max_speed, mileage):
self.name = name
self.max_speed = max_speed
self.mileage = mileage
def seating_capacity(self, capacity):
return f"The seating capacity of a {self.name} is {capacity} passengers"
class Bus(Vehicle):
def __init__(self, name, max_speed, mileage):
Vehicle.__init__(self, name, max_speed, mileage)
def __str__(self):
return f"Brand: {self.name}, Maximum Speed: {self.max_speed} MPH, Mileage: {self.mileage}"
def seating_capacity(self, capacity = 50):
return super().seating_capacity(capacity = 60)
b = Bus("a", 190, 29)
print(b.seating_capacity())
Here, I don't understand which default value of capacity is preferred. For example when I just write:
def seating_capacity(self, capacity = 50):
return super().seating_capacity(capacity = 60)
I get "The seating capacity of a a is 60 passengers" so this implies super().seating_capacity(capacity = 60) Has more preference and def seating_capacity(self, capacity = 50) is just a fallback value, right?
Then when I try:
def seating_capacity(self, capacity):
return super().seating_capacity(capacity = 60)
According to my understanding, In this case there is no need of fall back value. Yet I get, *TypeError: seating_capacity() missing 1 required positional argument: 'capacity'.
So what am I trying to do
Well what I'm doing is trying to create a battling system between your character and an enemy
So wheres it going wrong
Well there are two classes:
class Ally
and
class Enemy
Each class has their own unique attributes of name, health, attack and defense
class Ally
def __init__(self, name, health, attack, defense):
self.name = 'goodguy'
self.health = 100
self.attack = 50
self.defense = 30
class Enemy
def __init__(self, name, health, attack, defense):
self.name = 'badguy'
self.health = 120
self.attack = 40
self.defense = 20
But both class Ally and class Enemy need each others health and defense attributes inorder to do damage
class Ally(object):
def __init__(self, name, health, attack, defense):
self.name = goodguy
self.health = 100
self.attack = 50
self.defense = 30
def fight(self)
(damage moves)
Enemy health = Enemy.health - ((self.attack/Enemy.defense)+2)
def battle_script(self)
while self.health > 0 and Enemy.health > 0:
self.fight()
if Enemy.health <=0:
break
Enemy.fight()
if self.health <=0:
break
if Enemy.health() <= 0:
print ('The ' + Enemy.name + ' was defeated')
if self.health <= 0:
print ("You were defeated")
class Enemy(object):
def __init__(self, name, health, attack, defense):
self.name = badguy
self.health = 120
self.attack = 40
self.defense = 20
def fight(self)
(random damage moves)
Enemy health = Ally.health - ((self.attack/Ally.defense)+2)
Ally.battle_scrip()
So the problem is that I don't know how to pull in their respective attributes, i.e. in the battle script calling in the Enemy.health, I could probably pull it all into one class, but I'd rather keep them separated for when I create more enemies.
first you create instances of your class bob = Ally();evil_frank = Enemy(); ... beyond that I have no idea what you expect to happen here based on the code you are given but im guessing you want something like what follows
def fight(ally,enemy):
while ally.is_alive() and enemy.is_alive():
ally.hp -= enemy.dmg
enemy.hp -= ally.dmg
print "OK FIGHT OVER SOMEONE DIED..."
fight(bob,evil_frank)
So you want a one:many relationship for the Ally:Enemy classes? What I would do, is create a list of enemy class objects that are a member of your Ally class. You could even pass in an argument to your Ally constructor to pick the number of enemies you want.
Should be something like this:
import itertools
class Ally(object):
def __init__(self, enemies):
self.name = goodguy
self.health = 100
self.attack = 50
self.defense = 30
self.enemies = []
for _ in itertools.repeat(None, enemies):
self.enemies.append(Enemy())
...
If you want a Many:Many relationship I would create another class that can be an object for the battle. Lets call this the "Battle" class. You can then do the same trick of having a list of class objects for both your allies and enemies and then have your logic for conducting the battle in the battle class.
class Battle(object):
def __init__(self, allies, enemies):
self.allies = []
self.enemies = []
for _ in itertools.repeat(None, allies):
self.allies.append(Ally())
for _ in itertools.repeat(None, enemies):
self.enemies.append(Enemy())
...
Basically I have a class defined and I'm trying to display its attributes in a print statement EDIT:
class Player(object):
""" Default Class for the player """
def __init__(self, name):
self.name = name
self.class_type = '[CLASS]'
self.level = 1
self.health = 10
self.maxhealth = self.level * 10
self.attack = 0
self.defence = 0
self.experience = 0
self.weapon = ''
self.shield = ''
self.player_y = 9
self.player_x = 39
print('LV: {level} EXP: {exp} HP: {health}/' +
'{maxhealth}'.format(**char))
Am I doing something wrong? I'm just trying to find a more efficient way to display attributes of a class rather than doing...
print(character.name + ': Weight: ' + character.weight + ' Age: ' +
character.age + '...')
Any ideas?
You've forgotten to use self. in your Player.__init__ function, and you've forgotten to use ** in your call to str.format.
Here is working code:
class Player(object):
def __init__(self, name):
self.name = name
self.age = 125
self.height = 72
self.weight = 154
self.sex = 'Male'
character = Player('NAME')
print('{name} {height} {weight} {sex}'.format(**character.__dict__))
I have the following two classes set up:
class Player:
POINTS_PER_PASSING_YARD = 0.04
POINTS_PER_PASSING_TOUCHDOWN = 4
POINTS_PER_INTERCEPTION = -1
POINTS_PER_RUSHING_YARD = 0.1
POINTS_PER_RUSHING_TOUCHDOWN = 6
POINTS_PER_RUSHING_FUMBLE = -2
POINTS_PER_RECEPTION_YARD = 0.1
POINTS_PER_RECEPTION_TOUCHDOWN = 6
def __init__(self, name, team, rushingYards, rushingTouchdowns, rushingFumbles):
self.name = name
self.team = team
self.rushingYards = rushingYards
self.rushingTouchdowns = rushingTouchdowns
self.rushingFumbles= rushingFumbles
def calculatePoints(self):
return self.rushingYards * POINTS_PER_RUSHING_YARD + self.rushingTouchdowns * POINTS_PER_RUSHING_TOUCHDOWN + self.rushingFumbles * POINTS_PER_RUSHING_FUMBLE
def toString(self):
return "name: " + self.name + " team: " + self.team + " passing yards: " + self.passingYards + " rushing yards: " + self.rushingYards + " touchdowns: " + self.touchdowns + " interceptions: " + self.interceptions
Then I have a QB class that inherits from Player:
from Player import *
class QB(Player):
def __init__(self, name, team, rushingYards, rushingTouchdowns, rushingFumbles, passingYards, passingTouchdowns, interceptions, position="QB"):
super().__init__(self, name, team, rushingYards, rushingTouchdowns, rushingFumbles)
self.passingYards = passingYards
self.passingTouchdowns = passingTouchdowns
self.interceptions = interceptions
def toString(self):
return "position: " + self.position + super().toString()
Then in my main class, I simply do:
myQB = QB("Brees", "Saints", 0, 0, 0, 4952, 33, 17)
print(myQB)
I'm getting the following error:
Traceback (most recent call last):
File "main.py", line 35, in <module>
main()
File "main.py", line 32, in main
myQB = QB("Brees", "Saints", 0, 0, 0, 4952, 33, 17)
File "/Users/benjaminclayman/Desktop/Aurora_Fantasy_Football/QB.py", line 5, in __init__
Player.__init__(self, name, team, rushingYards, rushingTouchdowns, rushingFumbles)
TypeError: object.__init__() takes no parameters
But I'm not sure why, since all of the init methods I've written do take parameters...
Any idea what's going wrong?
Thanks,
bclayman
If your indentation in the first script (with the Player class) is correct, then that is the issue.
According to your indentation , the __init__() method and other methods are outside the class Player , so Player uses object class' __init__() , which does not take any parameters (other than self , though we do not need to pass it explicitly ).
You may want to fix the indentation so that all the instance methods (that you intended to be inside Player class) come inside the Player class.
Example -
class Player:
POINTS_PER_PASSING_YARD = 0.04
POINTS_PER_PASSING_TOUCHDOWN = 4
POINTS_PER_INTERCEPTION = -1
POINTS_PER_RUSHING_YARD = 0.1
POINTS_PER_RUSHING_TOUCHDOWN = 6
POINTS_PER_RUSHING_FUMBLE = -2
POINTS_PER_RECEPTION_YARD = 0.1
POINTS_PER_RECEPTION_TOUCHDOWN = 6
def __init__(self, name, team, rushingYards, rushingTouchdowns, rushingFumbles):
self.name = name
self.team = team
self.rushingYards = rushingYards
self.rushingTouchdowns = rushingTouchdowns
self.rushingFumbles= rushingFumbles
You will need to do this for all methods you intended to be inside Player class.
One more issue, you should not pass self in to te __init__() method called using super() .
Example -
class QB(Player):
def __init__(self, name, team, rushingYards, rushingTouchdowns, rushingFumbles, passingYards, passingTouchdowns, interceptions, position="QB"):
super().__init__(name, team, rushingYards, rushingTouchdowns, rushingFumbles)
Few issues, first you need to fix your indentation.
second, you should change
this class Player:
TO
class Player(object):
another issue is when you call a static member this is the way to handle them:
Player.POINTS_PER_RUSHING_YARD # name of the class and then the static member.
This is how your super should look like:
super(QB, self).__init__(name, team, rushingYards, rushingTouchdowns, rushingFumbles)
This is the code:
class Player(object):
POINTS_PER_PASSING_YARD = 0.04
POINTS_PER_PASSING_TOUCHDOWN = 4
POINTS_PER_INTERCEPTION = -1
POINTS_PER_RUSHING_YARD = 0.1
POINTS_PER_RUSHING_TOUCHDOWN = 6
POINTS_PER_RUSHING_FUMBLE = -2
POINTS_PER_RECEPTION_YARD = 0.1
POINTS_PER_RECEPTION_TOUCHDOWN = 6
def __init__(self, name, team, rushingYards, rushingTouchdowns, rushingFumbles):
self.name = name
self.team = team
self.rushingYards = rushingYards
self.rushingTouchdowns = rushingTouchdowns
self.rushingFumbles= rushingFumbles
def calculatePoints(self):
return self.rushingYards * Player.POINTS_PER_RUSHING_YARD + self.rushingTouchdowns * Player.POINTS_PER_RUSHING_TOUCHDOWN + self.rushingFumbles * Player.POINTS_PER_RUSHING_FUMBLE
def toString(self):
return "name: " + self.name + " team: " + self.team + " passing yards: " + self.passingYards + " rushing yards: " + self.rushingYards + " touchdowns: " + self.touchdowns + " interceptions: " + self.interceptions
class QB(Player):
def __init__(self, name, team, rushingYards, rushingTouchdowns, rushingFumbles, passingYards, passingTouchdowns, interceptions, position="QB"):
super(QB, self).__init__(name, team, rushingYards, rushingTouchdowns, rushingFumbles)
self.passingYards = passingYards
self.passingTouchdowns = passingTouchdowns
self.interceptions = interceptions
def toString(self):
return "position: " + self.position + super(Player).toString()
myQB = QB("Brees", "Saints", 0, 0, 0, 4952, 33, 17)
print(myQB)
In Python the indentation plays the major role.
List of Issues:
1) The __init__() should be within the class Player. Otherwise your initialization will not work.
2) The Other functions def calculatePoints(self), should also be within the class Player. Currently in your code it is defined outside the class.
3) The def toString(self) should also be within the class Player.
3.1) Also the concatenation of string and int is not permitted.
3.2) The variable `self.touchdowns` is not initialized in the def toString of class Player.
3.3) The alternate way to print the class with significant information
about class can be written in this manner.
class Player:
POINTS_PER_PASSING_YARD = 0.04
POINTS_PER_PASSING_TOUCHDOWN = 4
POINTS_PER_INTERCEPTION = -1
POINTS_PER_RUSHING_YARD = 0.1
POINTS_PER_RUSHING_TOUCHDOWN = 6
POINTS_PER_RUSHING_FUMBLE = -2
POINTS_PER_RECEPTION_YARD = 0.1
POINTS_PER_RECEPTION_TOUCHDOWN = 6
def __init__(self, name, team, rushingYards, rushingTouchdowns, rushingFumbles):
self.name = name
self.team = team
self.rushingYards = rushingYards
self.rushingTouchdowns = rushingTouchdowns
self.rushingFumbles= rushingFumbles
def calculatePoints(self):
return self.rushingYards * POINTS_PER_RUSHING_YARD + self.rushingTouchdowns * POINTS_PER_RUSHING_TOUCHDOWN + self.rushingFumbles * POINTS_PER_RUSHING_FUMBLE
def __str__(self):
return "name: %s team: %s passing yards: %r rushing yards: %r rushingTouchdowns: %r interceptions: %r" % (self.name, self.team, self.passingYards, self.rushingYards, self.rushingTouchdowns ,self.interceptions)
4) self.position = position need to be initialized in the class QB, like this:
class QB(Player):
def __init__(self, name, team, rushingYards, rushingTouchdowns, rushingFumbles, passingYards, passingTouchdowns, interceptions, position="QB"):
super().__init__(name, team, rushingYards, rushingTouchdowns, rushingFumbles)
self.passingYards = passingYards
self.passingTouchdowns = passingTouchdowns
self.interceptions = interceptions
self.position = position
def __str__(self):
return "position: " + self.position + super().__str__()