Python Count function not work on instances of a class?

Question:

So Ive been trying to make a method which checks if an entered Item is present in the players inventory. For that I used the count to check if the item exists atleast once. However it seems like that it does not instances of the class. (All the items in the inventory of the player are instance of a classs)

   inventory = []

   def equipItem(self):

       equipinput = input("Chosse Item to equip: ")
       #Get Input which item to equip
       itemcount = self.inventory.count(equipinput)
       #Count how many times the item was found

       if itemcount >= 1: 

           itemindex = self.inventory.index(equipinput)
           if self.inventory[itemindex].typeitem == "weapontype":
           #Check the item type(is an attribute of the item/Class)

               self.inventory[0], self.inventory[itemindex] =  self.inventory[itemindex], self.inventory[0] 
               #Switch position of the item to equip and that of the current item (It is always on the first position)
               print("Changed Weapon to " + str(equipinput))
               game()
               #Go back to the game

           else:

               self.inventory[1], self.inventory[itemindex] =  self.inventory[itemindex], self.inventory[1]
               print("Changed Armor to " + str(equipinput))
               game()
       else:

           print(f"{Fore.RED}You do not have this item!{Style.RESET_ALL}")
           #Output an error Message in red
           game()

Example inventory:

self.inventory = [Wooden Dagger, Steel Sword]

Example input would be then: Steel Sword

Expected Output/inventory:

self.inventory = [Steel Sword, Wooden Dagger]
Asked By: Apollox

||

Answers:

You cannot count instances of a class this way. If you look at the representation of it by printing it, you will see something like <__main__.SteelSword object at 0x7f15e6f97430>. They are obviously different, but are instances of the same class. So you can do:

[isinstance(ins, SteelSword) for ins in self.inventory].count(True)

Now, if you use input(), you will always get a string back, which is different from a class reference: 'SteelSword' != <class '__main__.SteelSword'>

So you need a way to address this issue. What you could do, for example, is to create a dict that takes your class names as a string ('SteelSword') key and the class references as the corresponding values.

Answered By: Confused Learner

You are comparing apples to oranges. The returned value of input is type string and the inventory array contains instances of some class (which you have omitted but i will call the "equipment" class).

You could create a __str__(self): method for the omitted "equipment" class like so.

class Equipment:

    def __init__(self, name: str):
        self.name = name

    def __str__(self):
        return self.name

You could then use list comprehension to create an array of string representations of the inventory and compare the input to that.

inventory = [Equipment('steel sword'), Equipment('basic axe')]
def equip_item(self):
    string_inventory = [str(item) for item in self.inventory] # creates array ['steel sword', 'basic axe']
    print(string_inventory.count('basic axe')) # now we can compare strings to strings with the count method

I would also recommend looking into the __repr__(self): magic method.

lastly, if comparing string, I also recommend using the .upper() method so capitalization does not cause problems.

Answered By: DPGraham4401
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.