Issue with passing attributes between classes in python - python

Ive made these classes below and I'm trying to have a tile in the game present a text based on an attribute in another class. I keep getting this error.
File "C:\Users\xxxxxxxx\PycharmProjects\Game.idea\Girls.py", line 20, in not_interested
return (self.interest < 10)
AttributeError: 'GirlTile' object has no attribute 'interest'
class Girls():
def __init__(self):
self.girlnames = ["Lucy", "Cindy", "April", "Allison", "Heather", "Andrea", "Brittany", "Jessica", "Lane", "Lauren", "Sabrina","Chelsea","Amber"]
self.name = random.choice(self.girlnames)
self.height = random.randrange(60, 72)
self.age = random.randrange(18, 25)
self.number = self.new_number()
self.interest = 0
def not_interested(self):
return (self.interest < 10)
from Girls import Girls
class GirlTile(MapTile):
def __init__(self,x,y):
self.enemy = Girls()
super().__init__(x, y)
def intro_text(self):
self.stance = Girls.not_interested(self)
if self.stance:
print("Hey whats up")

It looks like not_interested is an instance-level method, but you are trying to call it with a class (Girls). And the call is sort of "working" because you are passing the GirlTile instance in the call -- hence the error that the GirlTile has no interest attribute (because it does not).
Maybe you intended this instead?
def intro_text(self):
# Use an actual Girl instance to call not_interested().
self.stance = self.enemy.not_interested()
...

Related

Getting NameError for class variable while accessing it in methods of another class

Actually I wanted to create one instance of Class 'car' and wanted to use that Object within methods of a different class. As 'carObj' is a Class variable of class 'fourWheeler', we can define just before all methods and we can use. This is the understanding I got after going through few tutorials. But why here I am getting this error. I just wanted to understand. Any suggestions/advice will help me a lot.
class car:
def __init__(self,name, mileage):
self.__name = name
self.__mileage = mileage
def SpeedDetails(self):
print("Top Speed : 140")
print("Avg speed : 80")
class fourWheeler:
carObj = car('Honda', 20)
def Vehicletype():
print(carObj)
def VehicleSpeed():
carObj.SpeedDetails()
if __name__ == '__main__':
vehicle = fourWheeler
vehicle.Vehicletype()
vehicle.VehicleSpeed()
The error I got after running the script:
ssh://root#kick-bgl-caas6.cisco.com:41114/kick/bin/python -u /tmp/pycharm_project_977/Test.py
Traceback (most recent call last):
File "/tmp/pycharm_project_977/Test.py", line 20, in <module>
vehicle.Vehicletype()
File "/tmp/pycharm_project_977/Test.py", line 13, in Vehicletype
print(carObj)
**NameError: name 'carObj' is not defined**
Added your mistakes as comments
class car:
def __init__(self,name, mileage):
self.__name = name
self.__mileage = mileage
def SpeedDetails(self):
print("Top Speed : 140")
print("Avg speed : 80")
class fourWheeler:
carObj = car('Honda', 20)
def Vehicletype(self): #missed self here
print(self.carObj)
def VehicleSpeed(self): #missed self here
self.carObj.SpeedDetails()
if __name__ == '__main__':
vehicle = fourWheeler() # use constructor
vehicle.Vehicletype()
vehicle.VehicleSpeed()

Referencing self variables outside of original class

class player(object):
def __init__(self):
self.health = 100
self.stats = {'STR': 0,
'DEF':0}
class create_character(object):
def choose_class(self):
inp = input("Please choose a class!: ").lower()
s = ("Knight, Archer, or Mage")
print(s)
if inp == 'knight':
self.stats['STR'] = 15
self.stats['DEF'] = 15
print(self.stats)
The problem I'm facing currently, is that when I reference self.stats under create_character, it tells me that specific class doesn't have a 'self.stats'. If I try player.self.stats or player.stats, it tells me the same thing, that the class doesn't have those attributes. How can I reference a dictionary or a variable from another class, and change its properties. Also, when I print self.health, or self.stats, or self.name or whatever properties the player class hold, it gives me a bunch of unneeded information. Is there a way to exclude the extra information?
I believe that this will do the job that you are looking for:
class player(object):
def __init__(self):
self.health = 100
self.stats = {'STR': 0,
'DEF':0}
def choose_class():
inp = input("Please choose a class (Knight, Archer, or Mage): ").lower()
if inp == 'knight':
# create the player object
p = player()
# changes the values for the attributes in the player object
p.stats['STR'] = 15
p.stats['DEF'] = 15
print(p.stats)
# calls the function to choose the class
choose_class()
This is not really a good coding style though, so I would recommend following an OOP Python tutorial.

how to reference an attribute before it exists python

I'm writing a game in pygame, and I have a class that makes a heads up display with stats for each building when you click on it. the class variable current_hud starts as None, but when a building is clicked, its value becomes the building object so that when the draw function is called it only draws the hud of the selected building.
The problem is, I'm trying to create an instance of my "Text" class in the hud, but I'm getting the AttributeError: 'NoneType' object has no attribute 'name' because self.current_hud isn't an object yet, so self.current_hud.name isn't an attribute yet. How do I reference an attribute that doesn't exist yet? is waiting to instantiate the hud class until after the building is clicked on really the only option?
class Hud:
current_hud = None
def __init__(self,x,y):
self.x = x
self.y = y
self.name_text = Text(x,y,str(self.current_hud.name), (0,0,0), 36)
def draw(self):
if Hud.current_hud == self:
self.square = pygame.Rect((self.x,self.y),(440,400))
pygame.draw.rect(screen,(255,255,255),self.square)
self.name_text.x = self.x + 10
self.name_text.y = self.y + 20
sorry if this is convoluted, but it's a little difficult to explain. The full code is here if you want to run it and see how it all works: https://github.com/hailfire006/economy_game/blob/master/economy_game.py
You can take the name as an option to the Hud class and set it prior to instantiating the Text class.
class Hud:
current_hud = None
def __init__(self,x,y,name):
self.x = x
self.y = y
self.current_hud.name = name
self.name_text = Text(x,y,str(self.current_hud.name), (0,0,0), 36)
def draw(self):
if Hud.current_hud == self:
self.square = pygame.Rect((self.x,self.y),(440,400))
pygame.draw.rect(screen,(255,255,255),self.square)
self.name_text.x = self.x + 10
self.name_text.y = self.y + 20
In your full code example it looks like when you instantiate a building you have its name and can then pass that along to the Hud on instantiation.
class Building:
def __init__(self,posX,posY,color,name):
self.hud = Hud(0,0,name)

TypeError: 'tuple' object is not callable when trying to call method

Here is what I have going on so far:
# -*- coding: cp1252 -*-
import time
class Item():
def __init__(self, name, description, base_value):
self.name = name
self.description = description
self.ingredients = ingredients
self.base_value = value
def __str__(self):
return format(self.name, self.description, self.ingredients, self.base_value)
class Metal(Item):
def __init__(self, name, description, ingredients, base_value):
self.smelt_time = smelt_time
self.smelted = smelted
def __str__(self):
return format(self.name, self.description, self.ingredients, self.base_value, self.smelt_time, self.smelted)
class Bronze_Ingot(Metal):
def __init__(self):
self.name = "Bronze Ingot",
self.description = "A refined ingot of bronze."
#self.ingredients = Tin_Ore(1)+Copper_Ore(1) <--- I will get these lines working later...
self.base_value = 33
self.smelt_time = 15
self.smelted = ()
class Fuel(Item):
def __init__(self, name, description, ingredients, base_value):
self.fuel_time = fuel_time
def __str__(self):
return format(self.name, self.description, self.ingredients, self.base_value, self.fuel_time)
class Cloth(Fuel):
def __init__(self):
self.name = "Cloth",
self.description = "A piece of cotton cloth."
#self.ingredients = 2 Cotton <--- I will get these lines working later...
self.base_value = 2
self.fuel_time = 5
But I am having great trouble with this function...
def smelted(Fuel, Metal):
if (Fuel.fuel_time - Metal.smelt_time) > 0:
time.sleep(1)
print "Smelting", Metal.name, "..."
time.sleep(Metal.smelt_time)
print "Time to forge!"
The problem is more or less making it work. My friend and I have tried EVERYTHING that we can think of when running this function, but to no avail. Here is our most recent attempt:
from Smelting_Progress import *
x = Cloth()
y = Bronze_Ingot()
y.smelted(x,y)
After trying to run this, I received this error:
Traceback (most recent call last):
File "C:\Users\WCS-HSSTUDENT\Desktop\Files\Project SAOffline\Coding\New Aincrad World\Items\NAI_Smelted.pyw", line 6, in <module>
Metal.smelted(Fuel, Metal)
TypeError: 'tuple' object is not callable
You have an instance attribute smelted; you set it in Metal.__init__():
self.smelted = smelted
Your Bronze_Ingot subclass sets it to an empty tuple:
self.smelted = ()
You cannot have both a method and and a tuple use the same name. Rename one or the other.
If you meant to use your smelted() code as a function, then define it at the top level (same indentation as your classes), and call it as a function, not a method:
smelted(x, y)
(note, no y. in front).

Error: unbound method Dragon( ) must be called with Enemy instance as first argument (got Player instance instead)

class Character:
def __init__(self):
self.name = ""
self.health = 1
self.health_max = 1
class Player(Character):
def __init__(self):
Character.__init__(self)
self.state = 'normal'
self.health = 10
self.health_max = 10
class Monster(Character):
def Dragon(self):
self.name = "Dragon"
self.health = 20
def Goblin(self):
name = "Goblin"
health = 5
p = Player()
p.name = raw_input("Please enter your name: ")
print p.name
print p.state
print p.health
print p.health_max
m = Monster()
enemy = m.Dragon
print enemy.name
print enemy.health
Sorry, I've made this a little simpler to explain what I'm having difficulty with. I'm having a little bit of trouble with the basics of OOP, and I'm running into an issue with this snippet of code. I'm trying to create a "Dragon" here but I'm running into the following error:
Traceback (most recent call last):
File "test2.py", line 32, in
print enemy.name
AttributeError: 'function' object has no attribute 'name'
Can you tell me what I'm doing wrong here? Thanks.
You have to create an instance of a class first before you call any functions from it:
myenemy = Enemy()
myenemy.Dragon()
In your code, it looks like you created self.enemy, but later you call self.enemy = Enemy.Dragon(self). Instead of this last line, put self.enemy = self.enemy.Dragon(self).
It seems to be a recurring issue in the rest of your code as well. Commands = {'explore': Player.explore} should probably be Commands = {'explore': p.explore} (after you have created the instance p).
Since your updated code, I think you're getting functions and classes mixed up. Dragon is a function, and when you do enemy = m.Dragon, you are simply copying the function onto enemy. And thus when you do enemy.name, thinking it's a class, an error is raised, because enemy is now a function, not an instance.
You will have to create separate classes for different monsters:
class Dragon:
self.name = "Dragon"
self.health = 20
class Goblin:
name = "Goblin"
health = 5

Categories

Resources