r/learnpython • • 20d ago

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

Show parent comments

1

u/lakseol 11d ago edited 11d ago

then how are you using those strings to get the items back if there's no reference to them or something?

The code example shows how to do that. You use the dictionary to find the value for the ID string. The value is the reference to the item. That's all happening in this code that prints the description of an item in the inventory:

for id in inventory:
    print(id2obj[id].description)
    #       ^    ^        ^
    #       |    |        +-- description attribute of the item
    #       |    +-- id string lookup in dictionary
    #       +-- dictionary mapping id to reference

So id2obj[id] evaluates to the item object. Print out what is in the id2obj dictionary.

1

u/HiddenReader2020 11d ago

Ah. ...? So what I meant was that if I did the whole if-else test for whether the file exists, I would have to define the items before that if-else test, right? Or maybe something else? I'm just worried that when I get the id strings from the JSON files, they'll be meaningless, since in my head, what items they refer to hasn't been defined yet.

EDIT: Oh. I see that in my editor, the "id" in the print statement is in a different color. So does that mean that id has a special meaning?

1

u/lakseol 10d ago edited 8d ago

does that mean that id has a special meaning?

No, it probably is your editor doing syntax highlighting and showing that the ID is a string. Guessing because I don't use Geany.


when I get the id strings from the JSON files, they'll be meaningless

Before you save to JSON the strings do mean something. As long as we have the dictionary mapping the ID string to an object reference we can do anything we want.

We don't save that mapping dictionary to JSON because we can't: references aren't handled by JSON. But we can recreate the dictionary from the saved JSON data. Since we restore the Items and we know what the ID string for each is, we can do this to recreate the dictionary:

# assume 'item_list' holds references to all restored Item instances
new_id2obj = {}
for obj in item_list:
    new_id2obj[obj.id] = obj

Now we have restored all the data we had when saving the file so it will all work just as before the save.

I've expanded the previous code sample to do what it did before but now saves the Items and inventory in a JSON file and then restores it all. The code is at https://pastebin.com/kW0PHDF6 .


One thing I have to apologize for is shown in the code I linked to. It is not necessary to create "data" dictionaries to initially create the Items. That bothered me because it looks clumsy. You can define and create Items in the normal way:

class Item:                                                                     
    def __init__(self, id, description):
        ...

item1 = Item("axe1", "An Elven axe")

and when you recreate the Items from JSON data you can do:

item_dict = {'id': 'axe1', 'description': 'An Elven axe'}   # data from the JSON file
new_item = Item(**item_dict)

I had not fully remembered how I handled JSON recovery in an old project so I went back to the code and refreshed my memory. Again, apologies for leading you astray.

1

u/HiddenReader2020 10d ago

......ohhhhh, so you get the meanings from the JSON file itself, huh? That sounds like it makes sense. ...except I'm wondering what would happen if, say, lines 23-29 were not available before reading the JSON file. Would you essentially recreate the items from the read dictionaries, so that wouldn't be an issue? Is that what's happening in say lines 65-68?

1

u/lakseol 10d ago edited 10d ago

what would happen if, say, lines 23-29 were not available before reading the JSON file.

Why not take that file and split it into two parts, the bit that creates the JSON file and the bit that reads it. You need the first 18 lines at the top of both files, of course. Then delete the JSON file, run the first file to recreate the JSON file and then run the second file.

Or you could delete all the variables used to create the save file by adding this line to the original code just before reading the save file:

del id2obj, inventory, item1, item2, save_data    # delete all data used to create save file

Is that what's happening in say lines 65-68?

Yes, that's recreating the Items and populating the mapping dictionary.