Accessing values in a nested dictionary

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
errantknight
Newbie
Posts: 3
Joined: Fri Jul 01, 2022 2:38 pm
Contact:

Accessing values in a nested dictionary

#1 Post by errantknight »

Hello, I am new to both renpy and python. I could get the info in just python but I'm having trouble doing the same in renpy. I can't get any info other than [key]. When trying to get info via v[key] it gives an error so my question is how do I access the nested keys and values? Or should I be setting up this information differently.

Code: Select all

 
init python:


    F01 = {
        'name': 'Food01',
        'recipe': ['orange','red','blue'],
        'text': 'Item 01'
    }
    F02 = {
        'name': 'Food02',
        'recipe': ['blue', 'green', 'orange'],
        'text': 'Item 02'
    }

    fooddic = {
        'F01' : F01,
        'F02' : F02
    }



define n = Character("")
define x = 'recipe'

# The game starts here.

label start:
    python:
        for k, v in fooddic.items():
            for key in v:
                if key == x:
                    say(n,"Result: [key] [v[key]]", interact=True)


    return
errorcode:

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "game/script.rpy", line 33, in script
    python:
  File "game/script.rpy", line 37, in <module>
    say(n,"Result: [key] [v[key]]", interact=True)
  File "renpy/common/00library.rpy", line 284, in say
    who(what, interact=interact, *args, **kwargs)
KeyError: 'key'

-- Full Traceback ------------------------------------------------------------

Full traceback:
  File "game/script.rpy", line 33, in script
    python:
  File "S:\Program Files\Renpy\renpy-8.0.0-sdk\renpy\ast.py", line 1111, in execute
    renpy.python.py_exec_bytecode(self.code.bytecode, self.hide, store=self.store)
  File "S:\Program Files\Renpy\renpy-8.0.0-sdk\renpy\python.py", line 1049, in py_exec_bytecode
    exec(bytecode, globals, locals)
  File "game/script.rpy", line 37, in <module>
    say(n,"Result: [key] [v[key]]", interact=True)
  File "renpy/common/00library.rpy", line 284, in say
    who(what, interact=interact, *args, **kwargs)
  File "S:\Program Files\Renpy\renpy-8.0.0-sdk\renpy\character.py", line 1240, in __call__
    what = self.prefix_suffix("what", self.what_prefix, what, self.what_suffix)
  File "S:\Program Files\Renpy\renpy-8.0.0-sdk\renpy\character.py", line 1159, in prefix_suffix
    return (sub(prefix) + sub(body) + sub(suffix))
  File "S:\Program Files\Renpy\renpy-8.0.0-sdk\renpy\character.py", line 1139, in sub
    return renpy.substitutions.substitute(s, scope=scope, force=force, translate=translate)[0]
  File "S:\Program Files\Renpy\renpy-8.0.0-sdk\renpy\substitutions.py", line 278, in substitute
    s = formatter.vformat(s, (), kwargs) # type: ignore
  File "/home/tom/ab/renpy-build/tmp/install.linux-x86_64/lib/python3.9/string.py", line 165, in vformat
  File "/home/tom/ab/renpy-build/tmp/install.linux-x86_64/lib/python3.9/string.py", line 205, in _vformat
  File "S:\Program Files\Renpy\renpy-8.0.0-sdk\renpy\substitutions.py", line 168, in get_field
    obj, arg_used = super(Formatter, self).get_field(field_name, args, kwargs)
  File "/home/tom/ab/renpy-build/tmp/install.linux-x86_64/lib/python3.9/string.py", line 278, in get_field
KeyError: 'key'

Windows-10-10.0.19043 AMD64
Ren'Py 8.0.0.22062402
DictionaryTesting 1.0
Fri Jul  1 13:46:56 2022

User avatar
Alex
Lemma-Class Veteran
Posts: 3094
Joined: Fri Dec 11, 2009 5:25 pm
Contact:

Re: Accessing values in a nested dictionary

#2 Post by Alex »

errantknight wrote: Fri Jul 01, 2022 2:49 pm ...
You have two options

Code: Select all

    python:
        for k, v in fooddic.items():
            for key in v:
                if key == x:
                    say(n,"Result: {} {}".format(key, v[key]), interact=True)
                    #say(n,"Result: %s %s" %(key, v[key]), interact=True)

User avatar
zmook
Veteran
Posts: 421
Joined: Wed Aug 26, 2020 6:44 pm
Contact:

Re: Accessing values in a nested dictionary

#3 Post by zmook »

Square-bracket substitution like "[key]" is a renpy thing, not a python thing, so it only happens within renpy statements. The 'python:' block is a pure python context, where you have to use standard python string substitution.

https://realpython.com/python-string-formatting/

Personally I prefer the "old style" python %-substitution in renpy projects because renpy strings frequently include curly braces and it's annoying to have to keep track of what's supposed to be quoted and what isn't.
colin r
➔ if you're an artist and need a bit of help coding your game, feel free to send me a PM

User avatar
m_from_space
Miko-Class Veteran
Posts: 975
Joined: Sun Feb 21, 2021 3:36 am
Contact:

Re: Accessing values in a nested dictionary

#4 Post by m_from_space »

Not giving another answer, but since you are new to python and renpy and I don't know how much data you handled, I would suggest using a different structure for your food dictionary. Avoiding confusion and unnecessary data handling is key. You don't have to put everything inside one big dictionary you then have problems accessing.

Code: Select all

define food_repices = {
    'Food01': ['orange','red','blue'],
    'Food02': ['blue', 'green', 'orange']
}
define food_texts = {
    'Food01': 'Item01',
    'Food02': 'Item02'
}

label start:

    # show a recipe using renpy subsitutions (note that accessing a key doesn't require using quotation marks)
    "Recipe for Food01: [food_recipes[Food01]] (Description: [food_texts[Food01]])"

    # show all recipes and descriptions
    python:
        for name, recipe in food_recipes.items():
            renpy.say(n,"Recipe for {}: {} (Description: {})".format(name, recipe, food_texts[name]), interact=True)

errantknight
Newbie
Posts: 3
Joined: Fri Jul 01, 2022 2:38 pm
Contact:

Re: Accessing values in a nested dictionary

#5 Post by errantknight »

I am still getting a key error with the: say(n,"Result: %s %s" % (key, v[key]), interact=True)

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "game/script.rpy", line 33, in script
    python:
  File "game/script.rpy", line 37, in <module>
    say(n,"Result: %s %s" % (key, v[key]), interact=True)
  File "renpy/common/00library.rpy", line 284, in say
    who(what, interact=interact, *args, **kwargs)
KeyError: "'orange', 'red', 'blue'"

-- Full Traceback ------------------------------------------------------------

Full traceback:
  File "game/script.rpy", line 33, in script
    python:
  File "S:\Program Files\Renpy\renpy-8.0.0-sdk\renpy\ast.py", line 1111, in execute
    renpy.python.py_exec_bytecode(self.code.bytecode, self.hide, store=self.store)
  File "S:\Program Files\Renpy\renpy-8.0.0-sdk\renpy\python.py", line 1049, in py_exec_bytecode
    exec(bytecode, globals, locals)
  File "game/script.rpy", line 37, in <module>
    say(n,"Result: %s %s" % (key, v[key]), interact=True)
  File "renpy/common/00library.rpy", line 284, in say
    who(what, interact=interact, *args, **kwargs)
  File "S:\Program Files\Renpy\renpy-8.0.0-sdk\renpy\character.py", line 1240, in __call__
    what = self.prefix_suffix("what", self.what_prefix, what, self.what_suffix)
  File "S:\Program Files\Renpy\renpy-8.0.0-sdk\renpy\character.py", line 1159, in prefix_suffix
    return (sub(prefix) + sub(body) + sub(suffix))
  File "S:\Program Files\Renpy\renpy-8.0.0-sdk\renpy\character.py", line 1139, in sub
    return renpy.substitutions.substitute(s, scope=scope, force=force, translate=translate)[0]
  File "S:\Program Files\Renpy\renpy-8.0.0-sdk\renpy\substitutions.py", line 278, in substitute
    s = formatter.vformat(s, (), kwargs) # type: ignore
  File "/home/tom/ab/renpy-build/tmp/install.linux-x86_64/lib/python3.9/string.py", line 165, in vformat
  File "/home/tom/ab/renpy-build/tmp/install.linux-x86_64/lib/python3.9/string.py", line 205, in _vformat
  File "S:\Program Files\Renpy\renpy-8.0.0-sdk\renpy\substitutions.py", line 168, in get_field
    obj, arg_used = super(Formatter, self).get_field(field_name, args, kwargs)
  File "/home/tom/ab/renpy-build/tmp/install.linux-x86_64/lib/python3.9/string.py", line 270, in get_field
  File "/home/tom/ab/renpy-build/tmp/install.linux-x86_64/lib/python3.9/string.py", line 227, in get_value
KeyError: "'orange', 'red', 'blue'"

Windows-10-10.0.19043 AMD64
Ren'Py 8.0.0.22062402
DictionaryTesting 1.0
Tue Jul  5 11:35:02 2022
@m_from_space, That's fair! My goal was to eliminate some of the repetitiveness but if I can't access it doesn't really matter. I want to try and get the python %-substitution working but if not I'll take your advice and de nest everything and go from there.

User avatar
zmook
Veteran
Posts: 421
Joined: Wed Aug 26, 2020 6:44 pm
Contact:

Re: Accessing values in a nested dictionary

#6 Post by zmook »

"'orange', 'red', 'blue'" is a *value* in food_recipes, not a key, so it's not surprising that python complains it can't find it as a key in that dictionary. Somehow you've got things flipped around. If you show us your actual code, we can maybe tell you what to fix.
colin r
➔ if you're an artist and need a bit of help coding your game, feel free to send me a PM

errantknight
Newbie
Posts: 3
Joined: Fri Jul 01, 2022 2:38 pm
Contact:

Re: Accessing values in a nested dictionary

#7 Post by errantknight »

Ah thank you for pointing that out. The code above is basically it with say(n,"Result: [key] [v[key]]", interact=True) flipped for say(n,"Result: %s %s" %(key, v[key]), interact=True) but I don't think I grasp it well enough so I'm going to go with m_from_space advice for now and just unnest everything. Thank you everyone for your assistance, it's given me some direction and things to further dig into.

Post Reply

Who is online

Users browsing this forum: Bing [Bot], LegsWild, Toma