Asking variable number of questions based on user input

Hi there. I am new to Rasa. I want my chat to have this functionality :-

B- Bot , U - User

B - How many players do you want?

U - 3

B - Name of player 1

U - Sergio

B - Kit number of player 1

U - 9

B - Sponsor of player 1

U - Nike

B - Name of player 2

U - Leo

B - Kit number of player 2

U - 10

B - Sponsor of player 2

U - Adidas

B - Name of player 3

U - Gonzalo

B - Kit number of player 3

U - 19

B - Sponsor of player 3

U - Puma

I can create form for a single player to store information about him. But how do I go about making variable number of forms which is based on the number provided by the user?

Please kindly help. Thanks in advance.

Hi @qm_shail_hash,

For this to achieve you have to keep two things in mind:

  1. You won’t be able to ask for a slot that isn’t defined in the domain file
  2. You most likely need to modify your actions.py

For the first thing I’d suggest the following approach. You need to ask for:

  1. player_name
  2. player_kit
  3. player_sponsor

Since you won’t know the number of players in advance, you won’t be able to specify it in your domain file hence you need to repeatedly ask for the same slots based on the count_of_players slot and then save the information-triple e.g. in a list and afterwards resetting them by returning None to ask again for the next player.

For the second task I’d suggest to overwrite the required_slots method in actions.py like this:

@staticmethod
def required_slots(tracker: Tracker) -> List[Text]:
    """A list of required slots that the form has to fill"""
    
    count_of_players = tracker.get_slot("count_of_players")
    ...

Keep in mind, that the required_slots is called repeatedly inside the actions.py so I’d suggest to use the count_players as a “starting point” to decide which amount of player information you want to fetch.

Did you get the approach?

Kind regards
Julian

Thanks a lot for your response!! Yeah I did get the approach. That’s really a cool idea.

Hi,

Blockquote hence you need to repeatedly ask for the same slots based on the count_of_players slot and then save the information-triple e.g. in a list and afterwards resetting them by returning None to ask again for the next player.

returning None in which function? In required_slots()?

Hi @kosniaz,

I think there are several ways to achieve this but I’d simply suggest:

  1. Create the init method in your FormAction
  2. Create a dictionary in init method
  3. Everytime the required slots is triggered, store the sender_id in the dictionary such that you can assign the content of the Form iteration to it
  4. Write a validate_ method for every Slot
  5. In the validator of the last slot, save the whole slot Information in the dictionary and call
  6. return [SlotSet(slotname, None), … for every slot

That should do the job since the Form would need to continue then. After the last iteration simply submit.

Did.you get it?

Regards

2 Likes

Yes, thank you very much! Have a nice day!

Regards