Why is my tripssincemaintenence output 1 instead of 99 in Python classes? - python

I am using Python 3. Here is what my class and inheritance class looks like:
class Vehicle:
def __init__(self,Make,Model,Year,Weight,TripsSinceMaintenance = 0,NeedsMaintenance = False):
self.make = Make
self.model = Model
self.year = Year
self.weight = Weight
self.needsmaintenance = NeedsMaintenance
self.tripssincemaintenance = TripsSinceMaintenance
def repair(self):
self.needsmaintenance = True
self.tripssincemaintenance = 0
class Cars(Vehicle):
def __init__(self,Make,Model,Year,Weight,TripsSinceMaintenance = 0,NeedsMaintenance = False,isdriving = False):
Vehicle.__init__(self,Make,Model,Year,Weight,TripsSinceMaintenance = 0,NeedsMaintenance = False)
self.isDriving = isdriving
def Drive(self):
self.isDriving = True
def Stop(self):
self.isDriving = False
self.tripssincemaintenance += 1
if self.tripssincemaintenance == 100:
self.needsmaintenance = True
This is where I make use of the class:
Car2 = Cars("Mercedes","G-Wagon","2016","2000", 98,False)
Car2.Drive()
Car2.Stop()
print(Car2.year)
print(Car2.model)
print(Car2.make)
print(Car2.isDriving)
print(Car2.needsmaintenance)
print(Car2.tripssincemaintenance)
print(Car2.weight)
The problem is that when self.tripssincemaintenance is printed, it shows 1 instead of 99. Why is that? TIA

Related

How to change instance variable when another related instance variable is changed in a class?

I recently try to code a text based game. I want to change player proficiency when player level up. How should I change my code for this?
class Player:
def __init__(self,name,_class,_race):
self.name = name
self.level = 1
self.proficiency = (int(self.level/3)+1)*2
self.inventory = 0
self.skills = returnSkills()
self.stats = returnStats()
self._class = _class
self._race = _race
self.exp = 0
def levelUp(self):
self.level+=1
newPlayer = Player("Player","Barbarian","Human")
print(newPlayer.level)
for i in range(10):
print(newPlayer.level)
print(newPlayer.proficiency)
newPlayer.levelUp()
You can recalculate the proficiency attribute directly in the levelUp() function. Once you have updated the level attribute, that new value of level will be used to calculate the new proficiency.
def levelUp(self):
self.level+=1
self.proficiency = (int(self.level/3)+1)*2
You could make proficiency a property, so it is calculated from the current level each time it is referenced.
class Player:
def __init__(self,name,_class,_race):
self.name = name
self.level = 1
self.inventory = 0
self.skills = returnSkills()
self.stats = returnStats()
self._class = _class
self._race = _race
self.exp = 0
#property
def proficiency(self):
return (int(self.level/3)+1)*2
...
or you could leave it as a plain attribute, and recalculate it inside your levelUp method.

Trie implementation in Python

I tried to make this implementation clear. So I created hasChild function of Node. But why am I getting this this error?
'NoneType' object has no attribute 'hasChild'
class Node():
def __init__(self,word):
self.value = str(word)
self.children = {}
self.isEndOfWord = False
def hasChild(self,ch):
return ch in self.children.keys()
def addChild(self,ch):
nodenew = Node(str(ch))
self.children[ch] = nodenew
def getChild(self,ch):
return self.children.get(ch)
class Trie():
def __init__(self):
self.root = Node('')
def insert(self,children):
current = self.root
for ch in children:
if (current.hasChild(ch) is False):
current.addChild(ch)
current = self.root.getChild(ch)
current.isEndOfWord = True
I changed current.hasChild(ch) is False into not current.hasChild(ch) and current = self.root.getChild(ch) into current = current.getChild(ch) of the insert function. It works. Thanks a lot!
class Node():
def __init__(self,word):
self.value = str(word)
self.children = {}
self.isEndOfWord = False
def hasChild(self,ch):
return ch in self.children.keys()
def addChild(self,ch):
nodenew = Node(ch)
self.children[ch] = nodenew
def getChild(self,ch):
return self.children.get(ch)
class Trie():
def __init__(self):
self.root = Node('')
def insert(self,children):
current = self.root
for ch in children:
if (not current.hasChild(ch)):
current.addChild(ch)
current = current.getChild(ch)
current.isEndOfWord = True
trie = Trie()
trie.insert('cat')
trie.insert('can')

Python Classes ('' object has no attribute '')

I defined a class, but when I want to use the function in the class, it gives me an error as follows. Can anybody help me? thank you so much.
points = 5
class State:
def __init__(self, a, b, E_min, E_max, P_s_a, P_s_b, points)):
self.state = state
self.isEnd = False
self.a = a
self.b = b
self.E_min = E_min
self.E_max = E_max
self.P_s_a = P_s_a
self.P_s_b = P_s_b
self.points = points
y_model = np.zeros(self.points)
def model(self):
for j in range(0, points):
y_model[j] = a * j + b
print(State.model(2,3))
AttributeError: class State has no attribute 'model'
When you define model, it is defined inside __init__. To fix this you must change the indentation.
points = 5
class State:
def __init__(self, a, b, E_min, E_max, P_s_a, P_s_b, points)):
self.state = state
self.isEnd = False
self.a = a
self.b = b
self.E_min = E_min
self.E_max = E_max
self.P_s_a = P_s_a
self.P_s_b = P_s_b
self.points = points
y_model = np.zeros(self.points)
def model(self):
for j in range(0, points):
y_model[j] = a * j + b
print(State.model(2,3))

How to alter a variable defined in a parent class in the child class without altering the parent class variable itself?

I'm trying to create two subclasses based on the same parent class, so that they each have their own versions of the same variables defined in the parent object. However I realized that changing these variables in one of these subclasses will cause the versions in the other subclass to change as well. I know I am probably not fully understanding the idea of Inheritance. Please help!
import random
class PlayerParent():
id = 1
# Cooperate: True; Betrayal: False
opponent_moves_history = {}
self_moves_history = {}
def append_opponent_history(self, round_num, c_true, misunderstand=0.0):
# randomly change the result based on probability given in misunderstand
random_num = random.uniform(0, 1)
if random_num <= misunderstand:
c_true = not c_true
self.opponent_moves_history[round_num] = c_true
def append_self_history(self, round_num, c_true, misunderstand=0.0):
# randomly change the result based on probability given in misunderstand
random_num = random.uniform(0, 1)
if random_num <= misunderstand:
c_true = not c_true
self.self_moves_history[round_num] = c_true
score = int(0)
def score_keeper(self, round_num):
if (self.opponent_moves_history[round_num] == True) and (self.self_moves_history[round_num] == False):
self.score += 7
if (self.opponent_moves_history[round_num] == True) and (self.self_moves_history[round_num] == True):
self.score += 5
if (self.opponent_moves_history[round_num] == False) and (self.self_moves_history[round_num] == True):
self.score += 1
if (self.opponent_moves_history[round_num] == False) and (self.self_moves_history[round_num] == False):
self.score += 2
def get_score(self):
return self.score
class TitForTat(PlayerParent):
def rule(self, round_num):
if len(self.opponent_moves_history) == 0:
return True
else:
return self.opponent_moves_history[round_num - 1]
class Random(PlayerParent):
def rule(self, round_num):
random_num = random.uniform(0, 1)
if random_num >= 0.5:
return True
else:
return False
Random = Random()
Random.id = 1
TitForTat = TitForTat()
TitForTat.id = 2
def match(a, b):
game_counter = 1
# while game_counter <= 10:
#a_result = a.rule(game_counter)
# b_result = b.rule(game_counter)
# print(a_result, b_result)
# a.append_self_history(game_counter, a_result)
# b.append_opponent_history(game_counter, a_result)
# b.append_self_history(game_counter, b_result)
# a.append_opponent_history(game_counter, b_result)
# a.score_keeper(game_counter)
# b.score_keeper(game_counter)
# game_counter += 1
# print(a.get_score(), b.get_score())
a.self_moves_history[1] = True
print(a.self_moves_history, '\n', b.self_moves_history)
match(Random, TitForTat)
Resulting a.self_moves_history and b.self_moves_history is identical even though no alteration has been done to the b class variable.
I commented out chunks of the codes just to test where went wrong.
You are making opponent_moves_history a class variable, so naturally any change to it is class-wide.
In your case you should make opponent_moves_history, along with self_moves_history and id instance variables instead, so that changes made to them are specific to the instances.
class PlayerParent():
def __init__(self):
self.id = 1
self.opponent_moves_history = {}
self.self_moves_history = {}

Python variable is not getting initialized with desired object, why?

So I am designing a battleship backend system that will be running on google apps engine... I just started yesterday and designed a framework for the game.
Unfortunately for me, I have not coded too much in python so I am not too familiar with the specifics of the language. I keep getting the following error when I try to run the program:
File "C:\Users\Shlomo\Desktop\eclipse\plugins\org.python.pydev_2.7.5.2013052819\pysrc\pydev_runfiles.py", line 432, in __get_module_from_str
mod = __import__(modname)
File "C:\Users\Shlomo\workspace\battleship\Battleship.py", line 222, in <module>
battleship = BattleshipGame("Shlomo",1,1,4,1,1,2,5,2,1,3,3,3,1,4,2,4,1,5,5,5,"John",1,1,4,1,1,2,5,2,1,3,3,3,1,4,2,4,1,5,5,5)
File "C:\Users\Shlomo\workspace\battleship\Battleship.py", line 210, in __init__
field = self.player1_field.getField()
AttributeError: 'NoneType' object has no attribute 'getField'
ERROR: Module: Battleship could not be imported (file: C:\Users\Shlomo\workspace\battleship\Battleship.py).
So I translated this error as the variable field is not getting initialized with the PlayerField object...
Here is my code:
import random
class Player:
player_name = None
player_id = None
game_id = None
your_turn = False
player_field = None
hit_field = None
opponent = None
def __init__(self,name,player_field,hit_field,opponent):
self.player_name = name
self.player_field = player_field
self.hit_field = hit_field
self.opponent = opponent
def getPlayerField(self):
return self.player_field
def performHit(self,x,y):
mark = None
hit = self.opponent.getPlayerField.hitAt(x,y)
if hit:
mark = 'X'
else:
mark = 'O'
self.hit_field.markHitField(x,y,mark)
class HitField:
hit_field = None
def __init__(self):
hit_field = [[0 for i in xrange(10)] for i in xrange(10)]
def markHitField(self,x,y,mark):
self.hitfield[x][y] = mark
class PlayerField:
player_field = [[0 for i in xrange(10)] for i in xrange(10)]
shipsOnField = []
goodToGo = False
def __init__(self,battleship,aircraft,destroyer,submarine,patrol):
if self.validPlacement(battleship)and self.validPlacement(aircraft)and self.validPlacement(destroyer) and self.validPlacement(submarine) and self.validPlacement(patrol):
self.placeShip(battleship)
self.placeShip(aircraft)
self.placeShip(destroyer)
self.placeShip(submarine)
self.placeShip(patrol)
self.shipsOnField.append(battleship)
self.shipsOnField.append(aircraft)
self.shipsOnField.append(destroyer)
self.shipsOnField.append(submarine)
self.shipsOnField.append(patrol)
self.goodToGo = True
else:
print "some pieces have been placed incorrectly"
def validPlacement(self,ship):
hx = ship.getHeadX;
hy = ship.getHeadY;
tx = ship.getTailX;
ty = ship.getTailY;
if not hx > 0 and not hx < 11:
return False
return True
def placeShip(self,ship):
hx = ship.getHeadX();
hy = ship.getHeadY();
tx = ship.getTailX();
ty = ship.getTailY();
for y in range(ty,hy):
for x in range(tx,hx):
self.player_field[x][y] = ship.getShipID
def hitAt(self,x,y):
hitPos = self.player_field[x][y]
if not hitPos == 0 and not hitPos == 'X':
self.getShipByID(hitPos).removeHealth
self.player_field[x][y] = 'X'
return True
def getShipByID(self,ID):
for ship in self.shipsOnField:
if ship.getShipID == ID:
return ship
def getField(self):
return self.player_field
class Ship(object):
ship_id = None
ship_name = None
max_health = None
remaining_health = None
head_pos_x = None
head_pos_y = None
tail_pos_x = None
tail_pos_y = None
def __init__(self,id,name,max,hx,hy,tx,ty):
self.ship_id = id
self.max_health = max
self.remaining_health = max
self.ship_name = name
self.head_pos_x = hx
self.head_pos_y = hy
self.tail_pos_x = tx
self.tail_pos_y = ty
self.remaining_health = max
def removeHealth(self):
self.remaining_health -= 1
def getHeadX(self):
return self.head_pos_x
def getHeadY(self):
return self.head_pos_y
def getTailX(self):
return self.tail_pos_x
def getTailY(self):
return self.tail_pos_y
def getRemainingHealth(self):
return self.remaining_health
def getShipID(self):
return self.ship_id
class Battleship(Ship):
def __init__(self,hx,hy,tx,ty):
Ship.__init__(self,1,"Battle Ship",4,hx,hy,tx,ty)
class AircraftCarrier(Ship):
def __init__(self,hx,hy,tx,ty):
Ship.__init__(self,2,"Aircraft Carrier",5,hx,hy,tx,ty)
class Destroyer(Ship):
def __init__(self,hx,hy,tx,ty):
Ship.__init__(self,3,"Destroyer",3,hx,hy,tx,ty)
class Submarine(Ship):
def __init__(self,hx,hy,tx,ty):
Ship.__init__(self,4,"Submarine",3,hx,hy,tx,ty)
class PatrolBoat(Ship):
def __init__(self,hx,hy,tx,ty):
Ship.__init__(self,5,"Patrol Boat",2,hx,hy,tx,ty)
class BattleshipGame:
current_turn = None
player1 = None
player2 = None
player1_field = None
player1_opponent = player2
player2_field = None
player2_opponent = player1
def firstTurn(self):
rand = random.randint(1,2)
if rand==1:
return self.player1
else:
return self.player2
def printGameBoard(self):
field = self.player1_field.getField()
for y in range(1,10):
for x in range(1,10):
print field[x][y]
print '\n'
def __init__(self,p1name,p1bshx,p1bshy,p1bstx,p1bsty
,p1dhx,p1dhy,p1dtx,p1dty
,p1shx,p1shy,p1stx,p1sty
,p1pbhx,p1pbhy,p1pbtx,p1pbty
,p1achx,p1achy,p1actx,p1acty
,p2name,p2bshx,p2bshy,p2bstx,p2bsty
,p2dhx,p2dhy,p2dtx,p2dty
,p2shx,p2shy,p2stx,p2sty
,p2pbhx,p2pbhy,p2pbtx,p2pbty
,p2achx,p2achy,p2actx,p2acty):
player1_field = PlayerField(Battleship(p1bshx,p1bshy,p1bstx,p1bsty),
AircraftCarrier(p1achx,p1achy,p1actx,p1acty),
Destroyer(p1dhx,p1dhy,p1dtx,p1dty),
Submarine(p1shx,p1shy,p1stx,p1sty),
PatrolBoat(p1pbhx,p1pbhy,p1pbtx,p1pbty))
player2_field = PlayerField(Battleship(p2bshx,p2bshy,p2bstx,p2bsty),
AircraftCarrier(p2achx,p2achy,p2actx,p2acty),
Destroyer(p2dhx,p2dhy,p2dtx,p2dty),
Submarine(p2shx,p2shy,p2stx,p2sty),
PatrolBoat(p2pbhx,p2pbhy,p2pbtx,p2pbty))
player1 = Player(p1name,self.player1_field,HitField(),self.player2)
player2 = Player(p2name,self.player2_field,HitField(),self.player1)
self.current_turn = self.firstTurn()
battleship = BattleshipGame("Player1",1,1,4,1,1,2,5,2,1,3,3,3,1,4,2,4,1,5,5,5,"Player2",1,1,4,1,1,2,5,2,1,3,3,3,1,4,2,4,1,5,5,5)
battleship.printGameBoard()
Sorry about the sytax, I had trouble pasting it in the code format. This code probably has a few problems but I have not been able to get passed this problem yet...
What am I doing wrong?
In your __init__, you're assigning to a local variable player1_field rather than to instance data. Instead of:
player1_field = PlayerField(...
You want:
self.player1_field = PlayerField(...
Without that, you're trying to deference your class's value for player1_field, which is None.
Python isn't Java or whatever language you are trying to write. These mutable class attributes are unlikely to do what you think they do.
class PlayerField:
player_field = [[0 for i in xrange(10)] for i in xrange(10)]
shipsOnField = []
goodToGo = False

Categories

Resources