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.
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)