Hi all im making a text game but first im making a test one and i was writing it and i came across this error:
Traceback (most recent call last):
File "/home/tom/Desktop/Python/Text game/main.py", line 98, in <module>
main()
File "/home/tom/Desktop/Python/Text game/main.py", line 93, in main
print 'his attributes are:' + orc.getAttributesInfo()
TypeError: unbound method getAttributesInfo() must be called with orc instance as first argument (got nothing instead)

heres the code:

#!/usr/bin/env python

import random

choice = 0

class sword():
    def _init_(self):
        self.attack = random.randrange(1,3)
        self.defense = random.randrange(1,3)

class axe():
    def _init_(self):
        self.attack = player.base_attack + random.randrange(1,5)
        self.defense = player.defense + random.randrange(1,4)
        print 'You hit him for ' + self.damage + 'damage!'
        for self.damage in axe():
            if self.attack > troll.defense or orc.defense:
                self.damage = (player.attack +self.attack) - monster.defense
            elif self.attack < troll.defense or orc.defense:
                print 'You did\'nt do any damage...' 
        
            
         
                
class player():
    def _init_(self):
        self.health = 10
        self.defense = 4
        self.base_attack = 3
        self.attacking = 1

    def weapon(self):
        self.weapon = random.range(1,2)
        if self.weapon == 1:
            self.weapon = sword()
            print "you got a sword."
        elif self.weapon == 2:
            self.weapon = axe()
            print "you got an axe."

    def attack(monster):
        if not self.attacking == 1:
            self.attacking = 1
        if self.weapon.attack > monster.defense:
            attack = True
            monster.health = monster.health - self.weapon.damage
        

class orc():
    def _init_(self):
        self.health = 30
        self.defense = 5
        self.attack = 4
        self.name = 'Orc'
        if player.attacking == 1:
            print "You are attacking an orc."
        if self.health <= 0:
            print 'You killed the Orc'
            
    def getAttributesInfo():
        return self.name 
        return 'Attack:' + self.attack
        return 'Health:' + self.health
        return 'Defense' + self.defense
            
class troll():
    def _init_(self):
        self.health = 50
        self.defense = 7
        self.attack = 7
        self.name = 'Troll'
        if player.attacking == 1:
            print "You are attacking a Troll."
        if self.health <= 0:
            print 'You killed the Troll'
        
    def getAttributesInfo():
        return self.name
        return 'Attack:' + self.attack
        return 'Health:' + self.health
        return 'Defense' + self.defense

def main():
    monster_attacking = random.randrange(1,2)
    if monster_attacking == 1:
        new_monster = orc()
    elif monster_attacking == 2:
        new_monster = troll()
    choce = raw_input('Do you want to attack:')
    if choice ==  'yes' or 'yer' or ' yes' or ' yer':
        if monster_attacking == 1:
            print 'his attributes are:' + orc.getAttributesInfo()
        if monster_attacking == 2:
            print 'his attributes are:' + troll.getAttributesInfo()

if __name__ == '__main__':
      main()

hope someone can help, Tom

Can you please edit the post and put the code within CODE tags? Otherwise indentation gets lost, and as you know, identation is crucial in Python.
(And as a quick tip, you might want to make a base class for all weapons, and then have individual weapon classes extend that base one. Same goes for Actors (player, NPCs, enemies), and then have others extend that base class). Anyways, add the code tags above and then I'll try taking a look through your code.

It also looks like your "getAttributesInfo()" function in the troll class doesn't have "self" passed to it as an argument, and the same goes for the orc one. I think that's what your error is coming from. They should read "def getAttributesInfo( self ):"

Hi all im making a text game but first im making a test one and i was writing it and i came across this error:
Traceback (most recent call last):

File "/home/tom/Desktop/Python/Text game/main.py", line 98, in <module>
main()
File "/home/tom/Desktop/Python/Text game/main.py", line 93, in main
print 'his attributes are:' + orc.getAttributesInfo()
TypeError: unbound method getAttributesInfo() must be called with orc instance as first argument (got nothing instead)

heres the code:

#!/usr/bin/env python

import random

choice = 0

class sword():
    def _init_(self):
        self.attack = random.randrange(1,3)
        self.defense = random.randrange(1,3)

class axe():
    def _init_(self):
        self.attack = player.base_attack + random.randrange(1,5)
        self.defense = player.defense + random.randrange(1,4)
        self.damage = 0




class player():
    def _init_(self):
        self.health = 10
        self.defense = 4
        self.base_attack = 3
        self.attacking = 1

    def weapon(self):
        self.weapon = random.range(1,2)
        if self.weapon == 1:
            self.weapon = sword()
            print "you got a sword."
        elif self.weapon == 2:
            self.weapon = axe()
            print "you got an axe."

    def attack(monster_attacking):
        if not self.attacking == 1:
            self.attacking = 1
        if self.weapon.attack > monster.defense:
            attack = True
            monster.health = monster.health - self.weapon.damage
            print 'You hit him for ' + self.damage + 'damage!'
        for self.damage in axe():
            if self.attack > troll.defense or orc.defense:
                self.damage = (player.attack +self.attack) - monster.defense
            elif self.attack < troll.defense or orc.defense:
                print 'You did\'nt do any damage...' 


class orc():
    def _init_(self):
        self.health = 30
        self.defense = 5
        self.attack = 4
        self.name = 'Orc'
        if player.attacking == 1:
            print "You are attacking an orc."
        if self.health <= 0:
            print 'You killed the Orc'

    def getAttributesInfo(orc):
        return self.name 
        return 'Attack:' + self.attack
        return 'Health:' + self.health
        return 'Defense' + self.defense

class troll():
    def _init_(self):
        self.health = 50
        self.defense = 7
        self.attack = 7
        self.name = 'Troll'
        if player.attacking == 1:
            print "You are attacking a Troll."
        if self.health <= 0:
            print 'You killed the Troll'

    def getAttributesInfo(self):
        return self.name
        return 'Attack:' + self.attack
        return 'Health:' + self.health
        return 'Defense' + self.defense

def main():
    monster_attacking = random.randrange(1,2)
    if monster_attacking == 1:
        new_monster = orc()
    elif monster_attacking == 2:
        new_monster = troll()
    choce = raw_input('Do you want to attack:')
    if choice ==  'yes' or 'yer' or ' yes' or ' yer':
        if monster_attacking == 1:
            print 'his attributes are:' + orc.getAttributesInfo()
            attack()
        if monster_attacking == 2:
            print 'his attributes are:' + troll.getAttributesInfo()
            attack()
if __name__ == '__main__':
      main()

Edited 3 Years Ago by mike_2000_17: Fixed formatting

you should call the method with the instance new_monster and not with the class (orc or troll)

def main():
    monster_attacking = random.randrange(1,2)
    if monster_attacking == 1:
        new_monster = orc()
    elif monster_attacking == 2:
        new_monster = troll()
    choce = raw_input('Do you want to attack:')
    if choice ==  'yes' or 'yer' or ' yes' or ' yer':
        print 'his attributes are:' + new_monster.getAttributesInfo()
        attack()

Otherwise, when classes share a function, a good idea is to define a superclass to hold the function like this

class Monster(object):
    def __init__(self, attack, health, defense):
        self.attack = attack
        self.health = health
        self.defense = defense
    def getAttributesInfo(self):
         L = [ "Attack: " + self.attack,
                 "Health: " +self.health,
                 "Defense: " + self.defense]
         return " ".join(L)

class orc(Monster):
    def __init__(self):
        Monster.__init__(self, 4, 30, 5)
        if player .....

class troll(Monster):
    def __init__(self):
        monster.__init__(self, 7, 50, 7)
        if player ....

This code is more robust because the method is only written once: the enemy of good code is repetition !

you should call the method with the instance new_monster and not with the class (orc or troll)

def main():
    monster_attacking = random.randrange(1,2)
    if monster_attacking == 1:
        new_monster = orc()
    elif monster_attacking == 2:
        new_monster = troll()
    choce = raw_input('Do you want to attack:')
    if choice ==  'yes' or 'yer' or ' yes' or ' yer':
        print 'his attributes are:' + new_monster.getAttributesInfo()
        attack()

Otherwise, when classes share a function, a good idea is to define a superclass to hold the function like this

class Monster(object):
    def __init__(self, attack, health, defense):
        self.attack = attack
        self.health = health
        self.defense = defense
    def getAttributesInfo(self):
         L = [ "Attack: " + self.attack,
                 "Health: " +self.health,
                 "Defense: " + self.defense]
         return " ".join(L)

class orc(Monster):
    def __init__(self):
        Monster.__init__(self, 4, 30, 5)
        if player .....

class troll(Monster):
    def __init__(self):
        monster.__init__(self, 7, 50, 7)
        if player ....

This code is more robust because the method is only written once: the enemy of good code is repetition !

Thanks for that, it got rid of that error but i now get this error:

Traceback (most recent call last):
File "/home/tom/Desktop/Python/Text game/main.py", line 102, in <module>
main()
File "/home/tom/Desktop/Python/Text game/main.py", line 98, in main
print 'his attributes are:' + new_monster.getAttributesInfo()
TypeError: getAttributesInfo() takes no arguments (1 given)

Even though i never gave it any agruments, wierd huh?

Yes but when i take away the self arg it still says that there is an agument, any ideas?

If your method is written as def getAttributesInfo(self): , there is no error in the call new_monster.getAttributesInfo() . Also I remarked that you define your classes as class X(): . The correct way is class X(object): (or another parent class instead of object)

This article has been dead for over six months. Start a new discussion instead.