Filling an excel file without creeating a Rasa Form

Hello everyone,

I have a spreadsheet. Each sheet corresponds to a specific user and consists of two columns. The first one has 5 questions and the other has answers. All the questions can be answered by a button or open answer. I don’t have any entity or slot for this.

Below is my custom action that I have implemented:

class ACTIVLIMquestionnaire(Action):

    def name(self):
        return "action_activlim_questionnaire"

    def run(self,
            dispatcher: CollectingDispatcher,
            tracker: Tracker,
            domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
        
        user_id = next(tracker.get_latest_entity_values("number"), None)
        current_day = datetime.datetime.today()

        try:
            workbook = load_workbook(filename=".\\activlim_q.xlsx")
        except:
            workbook = Workbook()
            workbook.save(filename=".\\activlim_q.xlsx")
        
        try:
            worksheet = workbook[f"{user_id}"]
        except:
            worksheet = workbook.create_sheet(f"{user_id}")
            worksheet["A1"] = "Questions"
            worksheet["A2"] = "Could you, please, indicate how difficult you perceive walking more than one kilometer"
            worksheet["A3"] = "Could you, please, indicate how difficult you perceive ringing a doorbell"
            worksheet["A4"] = "Could you, please, indicate how difficult you perceive carrying a heavy load"
            worksheet["A5"] = "Could you, please, indicate how difficult you perceive picking up something from the floor"
            worksheet["B1"] = current_day
            worksheet = workbook[f"{user_id}"]
        
        position = 2
        for value in worksheet.iter_rows(min_row=2, max_row=5, min_col=1, max_col=2, values_only=True):
            dispatcher.utter_message(value[0], buttons= [
                {"payload": "/inform", "title": "Impossible"},
                {"payload": "/inform", "title": "Difficult"},
                {"payload": "/inform", "title": "Easy"}
            ])
            position += 1
            if tracker.get_intent_of_latest_message == "inform":
                worksheet[f"B{position}"] = tracker.latest_message["text"]
            elif tracker.get_intent_of_latest_message == "deny":
                workbook.save(filename=".\\activlim_q.xlsx")
                dispatcher.utter_message(response="I will stop the process now.")
                break
        
        return []

My goal was to create something similar to a form loop but within the custom action (this is why I used the for loop) but I didn’t work because what it does is to answer questions in a row and takes responses only for the last one.

I would like how could I approach this problem in a better way? I am thinking that it is not an issue that I should use rasa forms to solve.

Regards

The bot needs to stop, ask, and listen after each iteration. A for loop is continuous and will not listen.

If you really don’t want to do it in forms, you can create a counter slot and increment it every time, to output the corresponding question.

So, remove the for loop, and get the row number counter from the Excel file each time.

Hey @ChrisRahme , thank you for your reply. I am not sure I really understand what will the counter slot do. Is it something specific from rasa or it is a slot that I need to create? And how I will increment its value?

It’s a slot that you create to keep track of which row/question you’re at.

You increment it with a SlotSet.

counter = int(tracket.get_slot('counter'))

# import worksheet, etc.
# get row #counter and ask the question

return [SlotSet('counter', counter+1)]

I wasn’t able to do it as you said, do for now I did by using rasa forms. Thank you anyway!

1 Like

Yes, forms are the best way to handle that, glad you decided to go for it :slight_smile:

But if you still need help doing it without forms, I’ll be here!

1 Like

Here’s how I’d handle this. Instead of looping through all the questions at once, I’d keep track of where you’re at using a custom slot, like a little “bookmark” for the current question. After the bot asks a question and gets an answer, it updates the slot to point to the next question. Then it grabs that specific question from the Excel file and saves the response right away. I’ve done something like this before, and honestly, it worked way smoother than trying to handle everything in one go. If you’re into Excel tricks and stuff like that, there are a bunch of cool resources out there to dig deeper. One of them I’ve discovered recently is https://excel.tv/ .