Using multilevel dictionary in custom action and to give response

I am having a multilevel dictionary

{X1:{Y1:{Z1:a,Z2:b,Z3:c},
        Y2:{Z4:d,Z5:e,Z6:f}}
 X2:{Y3:{Z7:g,Z8:h,Z9:i},
        Y4:{Z10:j,Z11:k,Z12:l}}}

I can store X in one slot and Y in other slot and want to print the response in the form of

Z1:a
Z2:b
Z3:c 

depending on X & Y values in slot

Please help in writing custom action for this.

Your question is purely about Python and not Rasa.

It’s not clear what the scenario is, what you want to extract, and what you want to display.

Is your dictionary always the same format? Are there particular keys you are looking for? Do you want to only print keys from the last level? How does the response depend on X and Y? Are X and Y slot names or do you want to save them in slots?

@ChrisRahme Thanks for the answer Here X and Y are the slot names and X1, X2 are the slot values in X and Y1, Y2 are the slot value for Y. As you told this is python problem and I have solved it with below code

my_dict = {X1:{Y1:{Z1:a,Z2:b,Z3:c},
               Y2:{Z4:d,Z5:e,Z6:f}}
           X2:{Y3:{Z7:g,Z8:h,Z9:i},
               Y4:{Z10:j,Z11:k,Z12:l}}}

class ActionTables(Action):
    def name(self) -> Text:
        """Unique identifier of the form"""

        return "action_tables"

    def run(self,
            dispatcher: CollectingDispatcher,
            tracker: Tracker,
            domain: DomainDict,
        ) -> Dict[Text, Any]:
        slot_value1 = tracker.get_slot('X')
        slot_value2 = tracker.get_slot('Y')
        dispatcher.utter_message(print('\n'.join("{}: {}".format(k, v) for k, v in my_dict[slot_value2][slot_value1].items())))
        return []

Now I need your help in return[]. How can I return ('\n'.join("{}: {}".format(k, v) for k, v in my_dict[slot_value2][slot_value1].items())) to RASA server instead of printing this on action server. Putting this line of code in return giving me error.

1 Like

You’re doing dispatcher.utter_message(print(x)).

print(x) will print x and return None.

So your code will be dispatcher.utter_message(None) at runtime, which does not print anything on the bot’s side.

Just do dispatcher.utter_message(x) :slight_smile:

1 Like

I think this part is wrong

        dispatcher.utter_message(print('\n'.join("{}: {}".format(k, v) for k, v in my_dict[slot_value2][slot_value1].items())))

the correct usage dispatcher.utter_message is like that

dispatcher.utter_message(text=f"text to send user")

Edit ----- Chris return more faster :stuck_out_tongue:

1 Like

@ChrisRahme Thanks. It’s working.