Syntax Question: If item in list (contained within a dict) (solved)

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
User avatar
noeinan
Eileen-Class Veteran
Posts: 1153
Joined: Sun Apr 04, 2010 10:10 pm
Projects: Ren'Py QuickStart, Crimson Rue
Organization: Statistically Unlikely Games
Deviantart: noeinan
Github: noeinan
Location: Washington State, USA
Contact:

Syntax Question: If item in list (contained within a dict) (solved)

#1 Post by noeinan »

Hello! I am in the middle of coding some combat/interaction code and ran into a syntax issue. I'm using this code to generate a random NPC for the triggered event:

Code: Select all

    def GenerateMultipleNPCs(npc):
          ## npc is number of npcs you want to create
          npc_dict = {}

          for x in range(npc):
              ## add new dictionary entries named npc1, npc2, npc3 etc
              npc_dict['npc{}'.format(x+1)] = NPCList(racelist, typelist, procaselist, inventorylist, 1)
          return npc_dict
In my NPC code, I'm able to reference a list related to the NPC like this: (For example, if I wanted to change another feature of the NPC based on if they have a book in the inventory or not.)

Code: Select all

if "book" in list(self.inventory):
Now, in one of my screens, I would like to give the player the option to see a textbutton or not see it based on the following if statement:

Code: Select all

if "book" in list(npc_dict[npc1].inventory):
    textbutton _("Grab") action [SetVariable("rhandaction", "grabbook"), Hide("rhand_actions")] #grab book

However, I'm getting an error "name 'npc1' is not defined" when I try to use it like this. However, npc1 is already defined by the time this screen is shown, and I'm able to access the npc_dict normally in dialogue like this:

Code: Select all

label tutorial:
    $ tutorial_check = 1
    $ current_event = "tutorial"
    $ offmap = True

    $ npc_dict = GenerateMultipleNPCs(3)
    
    python:
        if npc_dict["npc1"].procase == "t":
            button1 = "{a=var_label:%s}%s{/a}" % ("start_scene", "Go With Them")
        elif npc_dict["npc1"].procase == "m":
            button1 = "{a=var_label:%s}%s{/a}" % ("start_scene", "Go With Him")
        elif npc_dict["npc1"].procase == "f":
            button1 = "{a=var_label:%s}%s{/a}" % ("start_scene", "Go With Her")
        elif npc_dict["npc1"].procase == "i":
            button1 = "{a=var_label:%s}%s{/a}" % ("start_scene", "Go With It")
        elif npc_dict["npc1"].procase == "n":
            button1 = "{a=var_label:%s}%s{/a}" % ("start_scene", "Go With Them")
        else:
            button1 = "{a=var_label:%s}%s{/a}" % ("start_scene", "Go With Error: No procase")
    $ button2 = "{a=var_label:%s}%s{/a}" % ("tutorial_run", "Run Away")

    nvl clear
    "Something tugs your arm. It's a [npc_dict[npc1].nonbinary] [npc_dict[npc1].race]. \"Come with me.\" [npc_dict[npc1].they] gulp[npc_dict[npc1].s]. [npc_dict[npc1].They] tr[npc_dict[npc1].y] to pull you toward a dark alley.\n
    \n
    [button1]\n
    \n
    [button2]" (advance=False)

    $ offmap = False
    return
While looking at my previous if/else section, the only difference is I'm not checking a list, just a single string, and the whole section is in python. My previous if statements, generating NPCs, is also in python. So, do I need to switch to python to make this if statement work? And if so, how do I reconcile that with my textbuttons? I'll need to make them in python instead of using textbutton? (Also in general curious about why I need to type the "npc" in quotes in my if statements in python while I don't need them in quotes when referencing the variable in dialogue?)

Any thoughts on this are greatly appreciated! Here is the full traceback:

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "game/script.rpy", line 97, in script call
    "" #When you just start the game no description shows, gotta fix this later
  File "game/mapdata.rpy", line 71, in script call
    $ renpy.call("evt_check")
  File "game/sex.rpy", line 9, in script call
    call sex_init
  File "game/sexscript.rpy", line 3, in script
    "\n
  File "renpy/common/00nvl_mode.rpy", line 380, in do_display
    **display_args)
  File "game/overlay.rpy", line 88, in execute
    screen rhand_actions:
  File "game/overlay.rpy", line 88, in execute
    screen rhand_actions:
  File "game/overlay.rpy", line 92, in execute
    vbox:
  File "game/overlay.rpy", line 135, in execute
    if "book" in list(npc_dict[npc1].inventory):
NameError: name 'npc1' is not defined

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

Full traceback:
  File "game/script.rpy", line 97, in script call
    "" #When you just start the game no description shows, gotta fix this later
  File "game/mapdata.rpy", line 71, in script call
    $ renpy.call("evt_check")
  File "game/sex.rpy", line 9, in script call
    call sex_init
  File "game/sexscript.rpy", line 3, in script
    "\n
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\ast.py", line 706, in execute
    renpy.exports.say(who, what, *args, **kwargs)
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\exports.py", line 1336, in say
    who(what, *args, **kwargs)
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\character.py", line 1139, in __call__
    self.do_display(who, what, cb_args=self.cb_args, **display_args)
  File "renpy/common/00nvl_mode.rpy", line 380, in do_display
    **display_args)
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\character.py", line 591, in display_say
    rv = renpy.ui.interact(mouse='say', type=type, roll_forward=roll_forward)
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\ui.py", line 295, in interact
    rv = renpy.game.interface.interact(roll_forward=roll_forward, **kwargs)
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\display\core.py", line 2699, in interact
    repeat, rv = self.interact_core(preloads=preloads, trans_pause=trans_pause, **kwargs)
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\display\core.py", line 3091, in interact_core
    root_widget.visit_all(lambda i : i.per_interact())
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\display\core.py", line 541, in visit_all
    d.visit_all(callback, seen)
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\display\core.py", line 541, in visit_all
    d.visit_all(callback, seen)
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\display\core.py", line 541, in visit_all
    d.visit_all(callback, seen)
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\display\screen.py", line 430, in visit_all
    callback(self)
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\display\core.py", line 3091, in <lambda>
    root_widget.visit_all(lambda i : i.per_interact())
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\display\screen.py", line 440, in per_interact
    self.update()
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\display\screen.py", line 625, in update
    self.screen.function(**self.scope)
  File "game/overlay.rpy", line 88, in execute
    screen rhand_actions:
  File "game/overlay.rpy", line 88, in execute
    screen rhand_actions:
  File "game/overlay.rpy", line 92, in execute
    vbox:
  File "game/overlay.rpy", line 135, in execute
    if "book" in list(npc_dict[npc1].inventory):
  File "<screen language>", line 135, in <module>
NameError: name 'npc1' is not defined

Windows-8-6.2.9200
Ren'Py 7.3.2.320
Fuck Game 1.0
Sun Apr 26 19:35:51 2020
Last edited by noeinan on Mon Apr 27, 2020 2:22 am, edited 1 time in total.
Image

Image
Image

User avatar
hell_oh_world
Miko-Class Veteran
Posts: 777
Joined: Fri Jul 12, 2019 5:21 am
Contact:

Re: Syntax Question: If item in list (contained within a dict)

#2 Post by hell_oh_world »

noeinan wrote: Sun Apr 26, 2020 10:51 pm Hello! I am in the middle of coding some combat/interaction code and ran into a syntax issue. I'm using this code to generate a random NPC for the triggered event:

Code: Select all

    def GenerateMultipleNPCs(npc):
          ## npc is number of npcs you want to create
          npc_dict = {}

          for x in range(npc):
              ## add new dictionary entries named npc1, npc2, npc3 etc
              npc_dict['npc{}'.format(x+1)] = NPCList(racelist, typelist, procaselist, inventorylist, 1)
          return npc_dict
In my NPC code, I'm able to reference a list related to the NPC like this: (For example, if I wanted to change another feature of the NPC based on if they have a book in the inventory or not.)

Code: Select all

if "book" in list(self.inventory):
Now, in one of my screens, I would like to give the player the option to see a textbutton or not see it based on the following if statement:

Code: Select all

if "book" in list(npc_dict[npc1].inventory):
    textbutton _("Grab") action [SetVariable("rhandaction", "grabbook"), Hide("rhand_actions")] #grab book

However, I'm getting an error "name 'npc1' is not defined" when I try to use it like this. However, npc1 is already defined by the time this screen is shown, and I'm able to access the npc_dict normally in dialogue like this:

Code: Select all

label tutorial:
    $ tutorial_check = 1
    $ current_event = "tutorial"
    $ offmap = True

    $ npc_dict = GenerateMultipleNPCs(3)
    
    python:
        if npc_dict["npc1"].procase == "t":
            button1 = "{a=var_label:%s}%s{/a}" % ("start_scene", "Go With Them")
        elif npc_dict["npc1"].procase == "m":
            button1 = "{a=var_label:%s}%s{/a}" % ("start_scene", "Go With Him")
        elif npc_dict["npc1"].procase == "f":
            button1 = "{a=var_label:%s}%s{/a}" % ("start_scene", "Go With Her")
        elif npc_dict["npc1"].procase == "i":
            button1 = "{a=var_label:%s}%s{/a}" % ("start_scene", "Go With It")
        elif npc_dict["npc1"].procase == "n":
            button1 = "{a=var_label:%s}%s{/a}" % ("start_scene", "Go With Them")
        else:
            button1 = "{a=var_label:%s}%s{/a}" % ("start_scene", "Go With Error: No procase")
    $ button2 = "{a=var_label:%s}%s{/a}" % ("tutorial_run", "Run Away")

    nvl clear
    "Something tugs your arm. It's a [npc_dict[npc1].nonbinary] [npc_dict[npc1].race]. \"Come with me.\" [npc_dict[npc1].they] gulp[npc_dict[npc1].s]. [npc_dict[npc1].They] tr[npc_dict[npc1].y] to pull you toward a dark alley.\n
    \n
    [button1]\n
    \n
    [button2]" (advance=False)

    $ offmap = False
    return
While looking at my previous if/else section, the only difference is I'm not checking a list, just a single string, and the whole section is in python. My previous if statements, generating NPCs, is also in python. So, do I need to switch to python to make this if statement work? And if so, how do I reconcile that with my textbuttons? I'll need to make them in python instead of using textbutton? (Also in general curious about why I need to type the "npc" in quotes in my if statements in python while I don't need them in quotes when referencing the variable in dialogue?)

Any thoughts on this are greatly appreciated! Here is the full traceback:

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "game/script.rpy", line 97, in script call
    "" #When you just start the game no description shows, gotta fix this later
  File "game/mapdata.rpy", line 71, in script call
    $ renpy.call("evt_check")
  File "game/sex.rpy", line 9, in script call
    call sex_init
  File "game/sexscript.rpy", line 3, in script
    "\n
  File "renpy/common/00nvl_mode.rpy", line 380, in do_display
    **display_args)
  File "game/overlay.rpy", line 88, in execute
    screen rhand_actions:
  File "game/overlay.rpy", line 88, in execute
    screen rhand_actions:
  File "game/overlay.rpy", line 92, in execute
    vbox:
  File "game/overlay.rpy", line 135, in execute
    if "book" in list(npc_dict[npc1].inventory):
NameError: name 'npc1' is not defined

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

Full traceback:
  File "game/script.rpy", line 97, in script call
    "" #When you just start the game no description shows, gotta fix this later
  File "game/mapdata.rpy", line 71, in script call
    $ renpy.call("evt_check")
  File "game/sex.rpy", line 9, in script call
    call sex_init
  File "game/sexscript.rpy", line 3, in script
    "\n
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\ast.py", line 706, in execute
    renpy.exports.say(who, what, *args, **kwargs)
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\exports.py", line 1336, in say
    who(what, *args, **kwargs)
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\character.py", line 1139, in __call__
    self.do_display(who, what, cb_args=self.cb_args, **display_args)
  File "renpy/common/00nvl_mode.rpy", line 380, in do_display
    **display_args)
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\character.py", line 591, in display_say
    rv = renpy.ui.interact(mouse='say', type=type, roll_forward=roll_forward)
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\ui.py", line 295, in interact
    rv = renpy.game.interface.interact(roll_forward=roll_forward, **kwargs)
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\display\core.py", line 2699, in interact
    repeat, rv = self.interact_core(preloads=preloads, trans_pause=trans_pause, **kwargs)
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\display\core.py", line 3091, in interact_core
    root_widget.visit_all(lambda i : i.per_interact())
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\display\core.py", line 541, in visit_all
    d.visit_all(callback, seen)
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\display\core.py", line 541, in visit_all
    d.visit_all(callback, seen)
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\display\core.py", line 541, in visit_all
    d.visit_all(callback, seen)
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\display\screen.py", line 430, in visit_all
    callback(self)
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\display\core.py", line 3091, in <lambda>
    root_widget.visit_all(lambda i : i.per_interact())
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\display\screen.py", line 440, in per_interact
    self.update()
  File "E:\_RenPy\renpy-7.3.2-sdk\renpy\display\screen.py", line 625, in update
    self.screen.function(**self.scope)
  File "game/overlay.rpy", line 88, in execute
    screen rhand_actions:
  File "game/overlay.rpy", line 88, in execute
    screen rhand_actions:
  File "game/overlay.rpy", line 92, in execute
    vbox:
  File "game/overlay.rpy", line 135, in execute
    if "book" in list(npc_dict[npc1].inventory):
  File "<screen language>", line 135, in <module>
NameError: name 'npc1' is not defined

Windows-8-6.2.9200
Ren'Py 7.3.2.320
Fuck Game 1.0
Sun Apr 26 19:35:51 2020
clearly, this line of code...

Code: Select all

npc_dict['npc{}'.format(x+1)] = NPCList(racelist, typelist, procaselist, inventorylist, 1)
you're trying to create the dictionary entry with string as the key, so it could yield something like...

Code: Select all

npc_dict['npc3'] = NPCList(racelist, typelist, procaselist, inventorylist, 1)
so you have to access the entry also in a form of string, don't forget the quotes in accessing the elements of the dict, since the keys are string based.
so it should be...

Code: Select all

if "book" in list(npc_dict["npc1"].inventory):
    textbutton _("Grab") action [SetVariable("rhandaction", "grabbook"), Hide("rhand_actions")] #grab book

User avatar
noeinan
Eileen-Class Veteran
Posts: 1153
Joined: Sun Apr 04, 2010 10:10 pm
Projects: Ren'Py QuickStart, Crimson Rue
Organization: Statistically Unlikely Games
Deviantart: noeinan
Github: noeinan
Location: Washington State, USA
Contact:

Re: Syntax Question: If item in list (contained within a dict)

#3 Post by noeinan »

Oh, thanks! That worked-- I could swear I tried putting it in quotes before, but maybe I had a typo somewhere. Thank you very much!
Image

Image
Image

Post Reply

Who is online

Users browsing this forum: No registered users