Search code examples
pythonjsonpython-2.7chatterbot

How to separate JSON output for Chatterbot


I'm creating a simple chatbot with Python and the chatterbot library. I've been able to get something able to work, where the user inputs something and the bot responds based on a .json of patterns and responses.
Every time I execute the bot is able to tell what "tag" the user input and responds accordingly only in this format: "patterns": ["cya", "See you later", "Goodbye", "I am Leaving", "Have a Good day"], But I would like it to remove the quotations, commas, etc and just pick one response at random. I've tried this tokenizing thing? Seems not to be working
Code

## MODULES
from chatterbot import ChatBot #This imports the chatbot
from chatterbot.trainers import ListTrainer #Method used for training the chatbot
import chatterbot #Just in case
import os

## BOT VARIABLES
bot = ChatBot("Test") #This creates the chatbot and names it 'Test'
trainer = ListTrainer(bot) #Creates the trainer
data = "C:/Users/PAVILION/Desktop/ChatBotTest2/INTS/"

for files in os.listdir(data):
    conv = open(data + files, 'r').readlines() #This opens the direrctory full of data
    trainer.train(conv) #This trains the chatbot trainer with data from the directory

## CHATTERBOT OUTPUT
while True:
    message = input("You: ")

    if message.strip() != "Bye":
        response = bot.get_response(message)
        print("ChatBot: ", response)

    if message.strip() == "Bye":
        print("ChatBot: Farewell")
        break

Intentions.json

{"intents": [
    {"tag": "greeting",
     "patterns": ["Hi", "How are you", "Is anyone there?", "Hello", "Good day", "Whats up"],
     "responses": ["Hello!", "Good to see you again!", "Hi there, how can I help?"],
     "context_set": ""
    },
    {"tag": "goodbye",
     "patterns": ["cya", "See you later", "Goodbye", "I am Leaving", "Have a Good day"],
     "responses": ["Sad to see you go :(", "Talk to you later", "Goodbye!"],
     "context_set": ""
    },
    {"tag": "age",
     "patterns": ["how old", "how old is tim", "what is your age", "how old are you", "age?"],
     "responses": ["I am 18 years old!", "18 years young!"],
     "context_set": ""
    },
    {"tag": "name",
     "patterns": ["what is your name", "what should I call you", "whats your name?"],
     "responses": ["You can call me Tim.", "I'm Tim!", "I'm Tim aka Tech With Tim."],
     "context_set": ""
    },
    {"tag": "shop",
     "patterns": ["Id like to buy something", "whats on the menu", "what do you reccommend?", "could i get something to eat"],
     "responses": ["We sell chocolate chip cookies for $2!", "Cookies are on the menu!"],
     "context_set": ""
    },
    {"tag": "hours",
     "patterns": ["when are you guys open", "what are your hours", "hours of operation"],
     "responses": ["We are open 7am-4pm Monday-Friday!"],
     "context_set": ""
    }
]
}

json was gotten from Tech with Tim tutorial btw.


Solution

  • You can load that json into a python object by removing the top level 'intents' (it's not needed) and loading the list into a variable;

    intents = [
    
        {"tag": "greeting",
        "patterns": ["Hi", "How are you", "Is anyone there?", "Hello", "Good day", "Whats up"],
        "responses": ["Hello!", "Good to see you again!", "Hi there, how can I help?"],
        "context_set": ""
        },
    
        # rest of json pasted here
    ]
    

    You can then access the dicts in the list by using next and a generator

    selected_intent = next((i for i in intents if i['tag'] == 'greeting'), None) 
    

    Now selected_intent will be the intent dict from the list if the tag is greeting (in this example), but if no intents have that tag it will return None - so be sure to handle this.

    You can now access any parts of the intent dict by their keys e.g. selected_intent['patterns'] - this would return the list of patterns for this tag. So you can do;

    import random
    
    patterns = selected_intent['patterns']
    return_pattern = patterns[ random.randint(0, len(patterns)-1) ]
    
    print(return_pattern) # output: whats up
    

    This will generate a random int between 0 and the length of the list -1, which is used as an index to extract a random string from the list.

    p.s. your if statements can be condensed with an else block because the second if is just the inverse of the first.

    if message.strip() != "Bye":
        response = bot.get_response(message)
        print("ChatBot: ", response) 
    else:
        print("ChatBot: Farewell")
        break