That question is related to general Python more than Rasa. Maybe you can find better help on Stack Overflow, but I’ll guide you
It’s bad to stack if
s like that. What if you have 100 elements, each one with 50 properties? You code should be scalable for any number of data and any number of properties, and maybe even each data having different properties. When you see something repetitive like this, you have two choices: for
loops and/or functions.
It’s easily achievable to do this using JSON and a for
loop.
You can define that data in a JSON file in the same folder as the actions. You can also use an SQL database, Python classes, or whatever you prefer. Let’s stick to JSON for now. Create a file called sayi.json
for example with the following format:
{
"data": [
{
"isim": "At",
"renk": "Kahverengi",
"bacak": 4,
etc...
},
{
"isim": "Kus",
"renk": "Mavi",
"bacak": 2,
// etc...
},
// etc...
]
}
Then, in your action’s run()
method, read that file, transform it into a Python list, and access the sayi
th element, then set the slots!
Don’t forget to add import json
at the top of the actions.py
file.
# Initialize the variable
data = []
# Fill `data` with the file
with open('sayi.json') as file:
data = json.load(json_file)['data']
# Generate a random number between 0 and the number of objects
sayi_number = random.randint(len(data))
# Get the `sayi_number`th object
sayi = data[sayi_number]
dispatcher.utter_message(str(sayi_number))
return [
SlotSet("hayvan_adi": sayi['isim']),
SlotSet("hayvan_rengi": sayi['renk']),
SlotSet("hayvan_bacak": sayi['bacak']),
# etc...
]
Even better: I suggest that you give the attributes the same names as the slots (or at least be able to deduce one from the other as I’ll do next). If you do that, you won’t even have to write multiple SlotSet()
s:
{
"data": [
{
"adi": "At",
"rengi": "Kahverengi",
"bacak": 4,
etc...
},
{
"adi": "Kus",
"rengi": "Mavi",
"bacak": 2,
// etc...
},
// etc...
]
}
Then, you can do this:
# Initialize the variable
data = []
# Fill `data` with the file
with open('sayi.json') as file:
data = json.load(json_file)['data']
# Generate a random number between 0 and the number of objects
sayi_number = random.randint(len(data))
# Get the `sayi_number`th object
sayi = data[sayi_number]
slot_sets = []
# Make a `SlotSet()` for every key-value pair
for key, value in sayi.items():
slot_name = "hayvan_" + str(key)
slot_value = value
slot_sets.append(SlotSet(slot_name, slot_value)
dispatcher.utter_message(str(sayi_number))
return slot_sets
or even:
data = json.load('sayi.json')['data']
sayi_number = random.randint(len(data))
dispatcher.utter_message(str(sayi_number))
return [SlotSet("hayvan_" + str(key), value) for key, value in data[sayi_number].items()]
It’s also doable in one line But of course, the code will be less readable without any quality/scalability improvements. What I would do is the final code, not less than that. But if you’re still a beginner, the one before that should be good so that you can understand better.