Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

My inventory will print strings but not objects

I was provided with a solution to my problem yesterday which looked a bit like this:

from collections import Counter
from items import *

class Player:
    def __init__(self):
        self.inventory = ["Log","Log","Flint","SteelScrap"]

    def print_inv(self):
        print(" -- Inventory -- ")
        for item, quantity in Counter(self.inventory).items():
            print(f" > {item}({quantity})")

Player().print_inv()

This solution works fine with strings but if I try to print objects like below it doesn’t work as intended.

from collections import Counter
from items import *

class Player:
    def __init__(self):
        self.inventory = [Log(),Log(),Flint(),SteelScrap()]

    def print_inv(self):
        print(" -- Inventory -- ")
        for item, quantity in Counter(self.inventory).items():
            print(f" > {item}({quantity})")

Player().print_inv()

The items classes are shown below.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

class Item:
    def __init__(self, name, description):
        self.name = name
        self.description = description

    def __str__(self):
        return self.name.title()

class Log(Item):
    def __init__(self):
        super().__init__(name="Log",
                         description="A Large wooden log.")

class Flint(Item):
    def __init__(self):
        super().__init__(name="Flint",
                         description="A fragment of flint.")

class SteelScrap(Item):
    def __init__(self):
        super().__init__(name="Steel Scrap",
                         description="A piece of steel scrap.")

>Solution :

The problem is you’re creating different instances of the same class, and expecting your code to think they’re the same. They’re not. When you define Log() twice, it creates two unique objects. If you don’t add the brackets and just refer to the classes, then it will work as intended.

class Player:
    def __init__(self):
        # The brackets are removed, no objects are created
        self.inventory = [Log,Log,Flint,SteelScrap]

    def print_inv(self):
        print(" -- Inventory -- ")
        for item, quantity in Counter(self.inventory).items():
            print(f" > {item}({quantity})")

Player().print_inv()

The result:

-- Inventory -- 
 > <class '__main__.Log'>(2)
 > <class '__main__.Flint'>(1)
 > <class '__main__.SteelScrap'>(1)

If you want to take inventory while still defining new objects, you can use the type function.

class Player:
    def __init__(self):
        self.inventory = [Log(),Log(),Flint(),SteelScrap()]

    def print_inv(self):
        print(" -- Inventory -- ")
        # creates a new list with the types of every object in self.inventory
        types = [type(obj) for obj in self.inventory]
        for item, quantity in Counter(types).items():
            print(f" > {item}({quantity})")

Player().print_inv()

This produces the same result as before.

-- Inventory -- 
 > <class '__main__.Log'>(2)
 > <class '__main__.Flint'>(1)
 > <class '__main__.SteelScrap'>(1)
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading