PYTHON: AttributeError: 'int' object has no attribute 'hand' - python

So I have an exercise on python - building a BlackJack game.
I have started with defining how every phrase of the game would go.
Now when I run this code below, In case the input is '0' - which means you don't want cards anymore, it runs perfectly. But when the input is '1' - which means you want to pick card, I get an error:
Traceback (most recent call last):
File "C:/Users/Maymon/PycharmProjects/untitled4/BlackJack.py", line 1, in <module>
class blackjack(object):
File "C:/Users/Maymon/PycharmProjects/untitled4/BlackJack.py", line 34, in blackjack
player(1)
File "C:/Users/Maymon/PycharmProjects/untitled4/BlackJack.py", line 25, in player
PickCard(1)
File "C:/Users/Maymon/PycharmProjects/untitled4/BlackJack.py", line 18, in PickCard
self.hand+= random.randrange(1, 13)
AttributeError: 'int' object has no attribute 'hand'
The code:
class blackjack(object):
#this func defines how player should react
def player(self):
#this func defines what case of technical loosing
def loser():
print("You have reached", hand , ". Which is beyond 21. Therefor, you have lost the game. Better luck next time!")
#this func is responsible for picking card issue.
def PickCard(self):
import random
x=1
while x == 1:
pick = int(raw_input("Enter 1 if you want another card, else Enter 0"))
if pick == 1:
self.hand = self.hand + random.randrange(1, 13)
else:
x=0
import random
print "Now your first card will automatically be given to you:"
hand=random.randrange(1,13)
print "hand: ", hand
PickCard(1)
print hand
if hand>21:
loser()
elif hand==21:
pass
else:
pass
player(1)
Thanks in advance.

You are making the function call as player(1) where the player function expects the argument as of self type .i.e. instance of the class blackjack. Hence, while doing self.hand = self.hand + random.randrange(1, 13) it is throwing the above mentioned error.
I think you do not want to make a call to player() function from within the class, Is it? Move that part to outside the class. Firstly create the object of class blackjack (Note: In Python, class names should be defined as CamelCase variables like: BlackJack). For example:
blackjack_obj = blackjack()
Then call the player() function as:
blackjack_obj.player()

Related

Call to a variable that is inside another function

def HOME():
""" The first screen
"""
print ('Welcome to my program!')
input_grocery_list = input('Hello, please enter here a list of groceries: ')
def input_to_list():
""" This f takes the input
and put it inside a list
without the: ','
and print the list
"""
new_grocery_list = []
separator = ", "
while ',' in input_grocery_list:
d = input_grocery_list.index(',')
y = input_grocery_list[:d]
new_grocery_list.append(y)
input_grocery_list = input_grocery_list[(d+1):]
if ',' not in input_grocery_list:
new_grocery_list.append(input_grocery_list)
print(separator.join(new_grocery_list))
def the_groceries_list():
""" Do somthing to the first input
accord to the next choice
"""
print("You can chose a number betwen 1 - 9 n/ and we do the rest..")
grocery_list = input('please enter here your choice : ')
if grocery_list == '1':
input_to_list(input_grocery_list)
if len(input_grocery_list) != 0:
the_groceries_list()
HOME()
The error
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 37, in HOME
File "<stdin>", line 34, in the_groceries_list
TypeError: input_to_list() takes 0 positional arguments but 1 was given
My problem is probably in the second function called "input_to_list ()"
  While I am trying to read / change the "input_grocery_list" variable that is inside the first function (HOME)
It does not recognize him.
I tried to fix it using global or self but I probably don't really know where exactly to put them because in the meantime it didn't work for me.
Anyone know how I can fix this?
As I can see, you try to have a main function, but you should use a class instead of a function, so more like this.
class Home():
def __init__(self):
"""
define your class wide variables here as following
"""
# example
# self.your_name = 'hello'
# to access it in an function IN this class, type: self.your_name
pass
def get_items(self):
print('Welcome to my program!')
input_grocery_list = input('Hello, please enter here a list of groceries (sep with comma): ')
self.input_to_list(input_grocery_list)
# you forgot this
# ||
# \/
def input_to_list(self, grocery_list: str):
""" This f takes the input
and put it inside a list
without the: ','
and print the list
"""
new_grocery_list = grocery_list.split(',')
# to print as list
print(new_grocery_list)
# to print every item in list
for item in new_grocery_list:
print(item)
# print('List End') # if you want to
# I don't really know what that is supposed to do, but whatever it is it wont
"""
def the_groceries_list(self):
# Do somthing to the first input
# accord to the next choice
print("You can chose a number betwen 1 - 9 n/ and we do the rest..")
grocery_list = input('please enter here your choice : ')
if grocery_list == '1':
input_to_list(input_grocery_list)
if len(input_grocery_list) != 0:
the_groceries_list()
"""
# to use this class and it's functions first create an object
home = Home()
# than call a function
home.get_items()
I wont go into details of Classes and Object but here is a link for you.
Read this, it should explain the basics pretty good.
You need to change definition of your nested function so it can take args:
def input_to_list(input_grocery_list):

AttributeError: 'NoneType' object has no attribute 'foo'

I'm getting this error:
[...], line 28, in <module>
PlayerDamage = Dice * int(set_p_w.player_damage)
AttributeError: 'NoneType' object has no attribute 'player_damage'
When I run this code:
import player
Dice = random.randrange(1, 7)
set_p_w = player.set_player_weapon()
PlayerDamage = Dice * set_p_w.player_damage
This is how player.set_player_weapon() looks like:
def set_player_weapon():
import items
player_weapon = items.WBrokenSword
player_damage = player_weapon.damage
I searched everywhere and tried a bunch of different solutions, but nothing helped me. What is wrong with my code?
From the code you posted, player.set_player_weapon() doesn’t return anything. So set_p_w is nothing. You are interacting with set_p_w as if it is an object, but set_player_weapon() doesn’t create an object, it just sets two local variables (player_weapon and player_damage) and then discards them when the function ends.
The simplest way to get this to work is to have your player.set_player_weapon() method return a tuple with that information so it can be stored in the a variable outside the function: (player_weapon, player_damage).
Tuple Method
def set_player_weapon():
import items
player_weapon = items.WBrokenSword
player_damage = player_weapon.damage
return (player_weapon, player_damage)
player_weapon_damage = player.set_player_weapon()
PlayerDamage = Dice * player_weapon_damage[0]
A better way would be to make an class for Player which has the attributes player_weapon and player_damage as well as methods like def set_player_weapon() that set and change its attributes.

How to call a stat from a class into a function - Python

I am struggling to create a health/anger (variables) drop when making the user fight a knight. I have defined a class called kingsmen, that is very simple and used for each knight, but I keep getting told that I am not calling the class properly. I'm not sure how to explain it. Below is the code for the class and for the knight, and the error message will be at the bottom. Some of the print spacing is weird (the ones with ''' ''') because the site is being difficult.
Thank you!
Class:
class kingsmen:
def __init__(self):
self.stats = {}
def attributes(self):
health=15
anger=7
self.stats["health"] = 15 #storing default health count
self.stats["anger"] = 7
return self.stats
def warning(self): #players will see this message when meeting a knight
print ('A kingsmen! Prepare for battle!')
def noise(self):
print ("H e y , i t ' s a v i l l a g e r !") #have these attributes later.
def death(self):
if healh == 0:
print ('''DEFEATED''')
Knight:
def rknightOne(kingsmen): #r stands for random, he will be one of 5 random villains you can face
rknightOne=kingsmen()
#while health in kingsmen.stats()!= 0 and anger != 0:
if action == 'attack':
for health in rknightOne.attributes:
health=health-1
print health
print_slowly ('I did not feel a thing. Ha ha ha!')
healthDrop(user)
elif action == 'mercy':
for anger in rknightOne.attributes:
anger=anger-1
print_slowly ('Huh. I feel something warm inside.')
elif action=='run':
print_slowly ('Not so fast!')
else:
print_slowly ("Jeez this guy is looney. I CAN'T UNDERSTAND YOU!")
Error:
Traceback (most recent call last):
File "C:/Python27/REDEMPTION/Redemption Game V1.py", line 678, in <module>
print randomKnight()
File "C:/Python27/REDEMPTION/Redemption Game V1.py", line 440, in randomKnight
print random.choice([rknightOne(kingsmen), rknightTwo(kingsmen), rknightThree(kingsmen), rknightFour(kingsmen), rknightFive(kingsmen)])
File "C:/Python27/REDEMPTION/Redemption Game V1.py", line 178, in rknightOne
for health in rknightOne.attributes:
TypeError: 'instancemethod' object is not iterable
The random function it's talking about is just cycling through 5 knights that could pop up. This is the code in case it's helpful:
def randomKnight():
print random.choice([rknightOne(kingsmen), rknightTwo(kingsmen), rknightThree(kingsmen), rknightFour(kingsmen), rknightFive(kingsmen)])
Change this
for health in kingsmen.stats():
with one of the following statements
for health in kingsmen.stats: # if you don't want to call the method
for health in kingsmen.stats(some_argument): # or if you want to call the method provide arguments
Reason you are getting this error is that you have defined both
self.stats = {}
and
def stats(self)
in kingsmen class, so it's confusing you.
With the latest revision of your code, it is clear what you are trying to do now. The error message you are seeing is telling you that you cannot iterate over an instance method. That is exactly what you are trying to do. You are trying to loop over kingsmen.attributes which is a method in your class. You cannot do that. Your method is actually returning a dictionary, and the result of executing that method is something you can iterate over. So you actually want to iterate over the result of calling attributes(). However, there is one more problem to clear up before that as I'll explain below.
In order to be able to properly call attributes, you have to instantiate your class (documentation on classes and objects in Python) first.
What you are doing is not executing the method, furthermore, not instantiating the class to be able to access and execute the method.
To resolve this, your line here:
for health in kingsmen.attributes:
You need to first instantiate your class, and then use the object from your class to call the attributes method. The return of that attributes method as you implemented will return the dictionary that you are trying to iterate over. So, your code should look like this:
my_kingsmen = kinsgmen()
for health in my_kinsgmen.attributes():

Python: Why is it saying my method isn't defined when it clearly is?

class GameMech:
def __init__(self ,aCharacter):
print("A battle is starting")
def getMP(self, aCharacter):
return aCharacter.mp
def getHP(aCharacter):
return aCharacter.hp
def getAtk(aCharacter):
return aCharacter.atk
def getDef(aCharacter):
return aCharacter.defense
def usePotion(aCharacter):
aCharacter.hp += 100
return aCharacter.hp
def useSpecial(self, aCharacter, target):
if aCharacter.mp >= 100:
target.hp -= 45
def dead(self, aCharacter):
return aCharacter.name +" is now dead"
def attack(self, aCharacter, target):
if target.hp - (aCharacter.atk/aCharacter.defense) <= 0:
dead(target)
else:
target.hp - aCharacter.atk/aCharacter.defense
print(getHP(target))
def guard(self, aCharacter):
print(aCharacter + "was unharmed")
if aCharacter.hp <= 50:
retaliation(aCharacter, target)
def retaliation(self ,aCharacter, target):
target.hp - (aCharacter.atk/10)
print(getHP(target))
def battleMenu(aNumber, self):
if aNumber == 1:
attack(aCharacter, target)
if aNumber == 2:
guard(aCharacter)
print(aCharacter + " was unharmed!")
if aNumber == 3:
useSpecial(aCharacter, target)
print(getHP(target))
if aNumber == 4:
heal = useItem(aCharacter)
print(heal)
def myTurn(self):
print("ATTACK")
print("GUARD")
print("SPECIAL")
print("ITEM")
aNumber = int(input("What would you like to do? "))
battleMenu(aNumber)
def oppTurn(self):
print("It is the opponent's turn")
randomNum = random.randint(1,4)
battleMenu(randomNum)
a few notes, obviously due to this formatting you can't tell that all my methods are actually under the class, but they are.
you can ignore the first few parts, the part im focusing on is battle menu.
So i'm creating a little text game as a project for myself, pure leisure nothing academic or for a job. Just a little game for myself to help me jog my memory in regards to python. So that's where the gut of my game is, the character class is an another file and there's nothing important in there just the attributes of character (hp, mp, atk, def)
here's the main
import random
import character
import battle
#create a battle menu
#and a character value check menu
#add buttons
def main():
char1 = character.Character("Charlie", 5000, 2000, 1500, 750)
char2 = character.Character("Mark", 2000, 4000, 2000, 900)
newGame = battle.GameMech(char1)
while char1.hp != 0 or char2.hp != 0:
newGame.myTurn()
newGame.oppTurn()
main()
(not sure why it's not including the definition of my main in the code snippet)
Any how I'm getting this error saying "name 'battleMenu' is not defined".
Name usually applies to variables correct? But battleMenu is a method is there a reason i'm getting this error?
Traceback (most recent call last):
File "E:\PythonGame\mainGame.py", line 22, in <module>
main()
File "E:\PythonGame\mainGame.py", line 20, in main
newGame.myTurn()
File "E:\PythonGame\battle.py", line 55, in myTurn
battleMenu(self,aNumber)
NameError: name 'battleMenu' is not defined
To call a method, you need to mention the instance you're calling it on, so you need to do self.battleMenu(). You need to make similar changes for all of the method calls in your code. You also need to add a self argument to all your methods so that these changes will work. You also need to read the Python tutorial to get an understanding of Python basics.
self.battleMenu(...) # note the "self" here
You are calling it wrongly, def battleMenu(aNumber): , your function is not defined as an instance function, neither as a static method, If you want a static function you should first annotate the method as a static one , by using #staticmethod annotation.
Then call your function as - GameMech.battleMenu(random) .
If you want it to be an instance function, change the definition to def battleMenu(self, aNumber): and then check.

Python: TypeError: __init__() takes exactly 2 arguments (1 given)

I know this question has been asked several times, but none have managed to provide me with a solution to my issue. I read these:
__init__() takes exactly 2 arguments (1 given)?
class __init__() takes exactly 2 arguments (1 given)
All I am trying to do is create two classes for a "survival game" much like a very crappy version of minecraft. Bellow is the full code for the two classes:
class Player:
'''
Actions directly relating to the player/character.
'''
def __init__(self, name):
self.name = name
self.health = 10
self.shelter = False
def eat(self, food):
self.food = Food
if (food == 'apple'):
Food().apple()
elif (food == 'pork'):
Food().pork()
elif (food == 'beef'):
Food().beef()
elif (food == 'stew'):
Food().stew()
class Food:
'''
Available foods and their properties.
'''
player = Player()
def __init__(self):
useless = 1
Amount.apple = 0
Amount.pork = 0
Amount.beef = 0
Amount.stew = 0
class Amount:
def apple(self):
player.health += 10
def pork(self):
player.health += 20
def beef(self):
player.health += 30
def stew(self):
player.health += 25
And now for the full error:
Traceback (most recent call last):
File "/home/promitheas/Desktop/programming/python/pygame/Survive/survive_classe s.py", line 26, in <module>
class Food:
File "/home/promitheas/Desktop/programming/python/pygame/Survive/survive_classe s.py", line 30, in Food
player = Player()
TypeError: __init__() takes exactly 2 arguments (1 given)
I just want to make the classes work.
The code you used is as follows:
player = Player()
This is an issue since the __init__ must be supplied by one parameter called name according to your code. Therefore, to solve your issue, just supply a name to the Player constructor and you are all set:
player = Player('sdfasf')
The problem is that the Class Player's __init__ function accepts a name argument while you are initializing the Class instance. The first argument, self is automatically handled when you create a class instance. So you have to change
player = Player()
to
player = Player('somename')
to get the program up and running.
__init__() is the function called when the class is instantiated. So, any arguments required by __init__ need to be passed when creating an instance. So, instead of
player = Player()
use
player = Player("George")
The first argument is the implicit self, which doesn't need to be included when instantiating. name, however, is required. You were getting the error because you weren't including it.
Your code know expects that you input something in __init__ which you don't.
I have made a simple example below that does give you an idea where the error __init__() takes exactly 2 arguments (1 given) is coming from.
What I did is I made a definition where I give input to useless.
And I am calling that definition from __init__.
Example code:
class HelloWorld():
def __init__(self):
self.useThis(1)
def useThis(self, useless):
self.useless = useless
print(useless)
# Run class
HelloWorld()
If you have a definition like def exampleOne(self) it doesn't expect any input. It just looks a t itself. But def exampleTwo(self, hello, world) expects two inputs.
So to call these two you need:
self.exampleOne()
self.exampleTwo('input1', 'input2')

Categories

Resources