HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Simple chatbot written in Python

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
chatbotsimplewrittenpython

Problem

I wrote a simple chatbot in Python a while ago, and I'd like to know how it could be improved. Here's the code:

import random
import pickle

class Bot:
    current = ""
    botText = "BOT> "

    def __init__(self, data, saveFile):
        self.data = data
        self.saveFile = saveFile

    def say(self, text):
        print(self.botText + text)
        self.current = text

    def addResponse(self, userInput, response):
        if userInput in self.data:
            self.data[userInput].extend(response)

        else:
            self.data[userInput] = []
            self.data[userInput].extend(response)

    def evaluate(self, text):
        if text in self.data:
            self.say(random.choice(self.data[text]))

        elif text == "/SAVE":
            f = open(self.saveFile, 'wb')
            pickle.dump(self.data, f)
            f.close()

        elif text == "/LOAD":
            f = open(self.saveFile, 'rb')
            self.data = pickle.load(f)
            f.close()

        elif text == "/DATA":
            print(self.data)

        else:
            if not self.current in self.data:
                self.data[self.current] = []

            self.data[self.current].append(text)
            self.say(text)


Here's how the bot works. I'm sorry if you don't understand, I'm not the best at explaining things.

  • User enters input.



  • If the input is in the database, choose a random response associated with the input and output it.



  • If it isn't, add the input to the database and echo the input.



  • User enters input again.



  • The input is associated with the bot's output.



Inputs and outputs can be added manually using the addResponse() function.

There are also a few commands, which are quite self-explanatory, but I'll list them here anyways.

  • /SAVE pickles the file and saves it in the saveFile.



  • /LOAD unpickles the saveFile and loads it.



  • /DATA displays the database.

Solution

Clean and straightforward, very nice.

Minor suggestions:

-
If you do

from collections import defaultdict

...

self.data = defaultdict(list)

then you can make addResponse be just:

self.data[userInput].extend(response)

and likewise you can leave out the if block under the else clause in evaluate

-
The code:

f = open(self.saveFile, 'rb')
self.data = pickle.load(f)
f.close()


is slightly-better written as:

with open(self.saveFile, 'rb') as f:
    self.data = pickle.load(f)


so that if pickle.load() throws an exception, the file will still get closed. Similar for the /SAVE code.

Code Snippets

f = open(self.saveFile, 'rb')
self.data = pickle.load(f)
f.close()
with open(self.saveFile, 'rb') as f:
    self.data = pickle.load(f)

Context

StackExchange Code Review Q#136760, answer score: 5

Revisions (0)

No revisions yet.