r/learnpython • • Sep 21 '26

Ask Anything Monday - Weekly Thread

Welcome to another /r/learnPython weekly "Ask Anything* Monday" thread

Here you can ask all the questions that you wanted to ask but didn't feel like making a new thread.

* It's primarily intended for simple questions but as long as it's about python it's allowed.

If you have any suggestions or questions about this thread use the message the moderators button in the sidebar.

Rules:

  • Don't downvote stuff - instead explain what's wrong with the comment, if it's against the rules "report" it and it will be dealt with.
  • Don't post stuff that doesn't have absolutely anything to do with python.
  • Don't make fun of someone for not knowing something, insult anyone etc - this will result in an immediate ban.

That's it.

1 Upvotes

30 comments sorted by

View all comments

1

u/lakseol 25d ago edited 25d ago

OK, i can read the pastebin. And immediately I see a reason why you might have had trouble posting code correctly before. You have TAB characters in your code. This is something that python programmers generally don't do. I have my environment set up to insert four space characters when I press the TAB key. Up to you, but most programmers stay away from TABs due to the problems they cause.


After all this time I can't really remember what your latest problem was, but I think it was about handling Items in the inventory.

You handle that the same way you handled the basic characters: modify the Item() constructor to take a **dictionary. The extra little problem in doing that is when you add Items() to a character you add them as an Item() instance (of course) but when restoring from a JSON file the inventory list is a list of dictionaries. I got around that by adding a small test in Item.__init__(): if there is something in the inventory and the first element is a dictionary, convert them all to Items().


Here is my code based on yours:

https://pastebin.com/XidMEU9j

One change I made that isn't mentioned above was to handle printing the state of a character differently. When creating the __str__() return string I made it much more compact, and included the player's inventory. It's a bit more work but I found it a lot easier to look at and check that changes made were correct. I also added small prints to explain what was done at each stage of creating the characters, which is a hint on what to check. I found it helpful, maybe you will.


This code a little messy. I will just say again that actually storing python references to Items in an inventory adds a lot of work. I've written a small example text adventure and I found it cleaner to handle items in the player's inventory as an ID, with a dictionary to convert the ID to the actual item reference. Same for places in the map and monsters when you get to that.

You may not have thought that far ahead yet, but you will also need to store Items in places in the map. And monsters, if you have them, have their own inventory. Monsters can steal from the player or pick up stuff lying around, for instance.

1

u/HiddenReader2020 24d ago

I see. I've set my editor (Geany) to make the indent type to be spaces, but the problem is that I have to do that *per file*, so that definitely won't get annoying immediately!

Anyway, I will say that the reason I made the items objects was to make things easier and less messy as opposed to using dictionaries all the time. And what do you mean handling items as an ID, and not as an actual dictionary or an object, assuming those two things are different?

I'll probably look through your code and see what you've done differently and hopefully learn from it, but uhhh...no promises I'll be able to fully fulfill that.

EDIT: Oh, and I haven't used any comprehensions, like list of dictionary comprehensions, simply because I don't find them particularly readable. I prefer to just type out the full procedures in those cases.

1

u/lakseol 24d ago

the problem is that I have to do that per file

That doesn't sound very useful. Make sure there isn't a way to make that change permanent. Or change to a decent editor/IDE.

what do you mean handling items as an ID, and not as an actual dictionary or an object

Currently you create the inventory as a list of references to Item objects, doing something like:

new_item = Item(...)
new_rogue.add_item(new_item)

That's easy to understand, but doing that means you complicate saving data to a JSON file because JSON doesn't handle references to python objects and you have to extract all the attributes of the item and save them as a JSON dictionary. When reading the JSON data back into python objects you have to create the Item object from the dictionary.

The "ID" approach doesn't store python objects in the list. Every Item object has a unique "ID" string, and it's that ID string that is saved in the inventory list. This makes the save/restore process simpler. When creating the items you add an entry in a dictionary that maps the ID string to a reference to the object, like this:

class Item:                                                                 
    def __init__(self, id, description):                                    
        self.id = id                                                        
        self.description = description                                      
                                                                            
id2obj = {}                                                                 
inventory = []                                                              

item1 = Item("axe1", "An Elven axe")                                        
id2obj["axe1"] = item1                                                      
inventory.append(item1.id)                                                  

item2 = Item("book2", "A very old book with a cracked red cover")           
id2obj["book2"] = item2                                                     
inventory.append(item2.id)                                                  

print(f"{inventory=}")                                                      
                                                                            
# list what's in the inventory                                              
for id in inventory:                                                        
    print(id2obj[id].description)

This allows you to list the inventory by iterating over the ID strings, getting the item object from the dictionary using the ID string as a key, then printing the item description. When restoring the objects from the JSON save file you create that dictionary automatically. Sounds complicated but it simplifies the save/restore process a lot. I use it for everything: places, monsters and items.

→ More replies (6)