Assignment 3: Chatbots
Contents
Assignment 3: Chatbots¶
This is a demo assignment that is available as part of the Introductory Python open materials.
Overview¶
This assignment covers Functions & Algorithms, and builds up to the application of Chatbots.
This assignment is out of 8 points, worth 8% of your grade.
Make sure your completed assignment passes all the asserts. This assignment also has hidden tests - which means that passing all the asserts you see does not guarantee that you have the correct answer! Make sure to double check and re-run your code to make sure it does what you expect.
Quick Tips¶
Make sure you execute your code to define the functions you write, and then add a new cell to apply your function to different inputs, and check that you get the outputs you expect.
If you’re not sure where to start, look at the code in the test cases (in the asserts) for examples for what kind of inputs and outputs the function you are writing should take, and what kind of behaviour it should have.
Keep in mind that each question is mostly independent from every other - so if you get stuck on something, you can always move on to the next one, and come back to any that you have trouble with later.
Setup¶
Code Imports¶
You must run the following cell before proceeding with the assignment.
# Setup - run this cell before doing the next part of the assignment
# This imports some extra code, making it available for us to use later
import string
import random
import nltk
Zen Chatbot¶
In this assignment, we will be working our way up to building a chatbot.
To start with, we can have a quick chat with a zen chatbot, to see what these kinds of chatbots look like.
Also, if you get stuck on anything, come back here, and talk to the Zen chatbot, to relax :)
Note: in this, and other, chatbot lines, running this code will start an open-ended while loop, that will interupt your code flow, until you explicity quit out of the conversation. If you want to be able to run all your code (from kernel restart & run all
), then comment these lines back out when you are finished exploring them.
# Uncomment and run this cell to talk to a Zan Chatbot
#nltk.chat.zen.demo()
Part 1: Functions¶
This part covers the basics of writing and using functions.
Function Examples¶
The following are a couple examples of functions provided to you, so you can see their structure.
You don’t need to do anything with these functions.
def basic_function(input_number):
"""Multiplies an input number by 2."""
# Multiple the input by 2
output = input_number * 2
return output
# Test using `basic_function`
print(basic_function(2))
print(basic_function(5))
def more_complicated_function(input_string):
"""Counts how many letters are in a string."""
letter_count = 0
for item in input_string:
# Uses the `isalpha` method to check if a character is from the alphabet
if item.isalpha():
# `+= 1` is a shortcut for `val = val + 1`
letter_count += 1
return letter_count
# Test using `more_complicated_function`
print(more_complicated_function('ab45b'))
Q1 - Find Max Value (0.5 points)¶
Write a function called find_max
, that takes in a single parameter called random_list
, which should be a list.
This function will find the maximum (max) value of the input list, and return it.
This function will assume the list is composed of only positive numbers.
To find the max, within the function, use a variable called list_max
, that you initialize to value 0.
Then use a for
loop, to loop through random_list
.
Inside the list, use a conditional to check if the current value is larger than list_max
, and if so, re-assign list_max
to store this new value.
After the loop, return list_max
, which should now store the maximum value from within the input list.
# YOUR CODE HERE
raise NotImplementedError()
assert callable(find_max)
assert isinstance(find_max([1,7,5]), int)
assert find_max([1,7,5]) == 7
assert callable(find_max)
Q2 - Square Everything (0.5 points)¶
Write a function called square_all
that takes an input called collection
that you assume to be a list or tuple of numbers.
This function should return a new list
, which contains the square of each value in collection
.
To do so, inside the function, you will define a new list, use a loop to loop through the input list, use an operator to square the current value, and use the append
method to add this to your output list. After the loop, return the output list.
# YOUR CODE HERE
raise NotImplementedError()
assert callable(square_all)
assert isinstance(square_all([1, 2]), list)
assert square_all((2, 4)) == [4, 16]
assert callable(square_all)
Part 2: Refactoring Code to Use Functions¶
‘Refactoring’ is the process of updating existing computer code, to keep the same outputs, but to have better internal organization and/or properties.
We’ve written a lot of code in previous assignments. However, since we did not yet have functions at our disposal, a lot of that code is not very easy to re-use.
In this section we will refactor some code - rewriting (and extending) some code from previous assignments as functions, to make it easier to re-use.
Q3 - Calculator (0.5 points)¶
Let’s start with the calculator code that we worked on in A1.
Instead of using a conditional, like we did before, we will make a series of functions to do all the mathematical operations that we want to do.
Define four functions, called summation
, subtraction
, multiplication
, and division
.
Each of them will take two inputs num1
and num2
(that could be int
or float
), and use them as follows:
summation
will addnum1
tonum2
and return the resultsubtraction
will subtractnum2
fromnum1
and return the resultmultiplication
will multiplynum1
bynum2
and return the resultdivision
will dividenum1
bynum2
and return the result
# YOUR CODE HERE
raise NotImplementedError()
assert callable(summation)
assert isinstance(summation(2, 2), int)
assert isinstance(summation(2.5, 1), float)
assert summation(1, 1) == 2
assert callable(subtraction)
assert isinstance(subtraction(2, 2), int)
assert isinstance(summation(2.5, 0.5), float)
assert subtraction(1, 1) == 0
assert callable(multiplication)
assert isinstance(multiplication(2, 2), int)
assert isinstance(multiplication(2.5, 2), float)
assert multiplication(1, 1) == 1
assert callable(division)
assert isinstance(division(2, 2), float)
assert isinstance(division(2.5, 0.5), float)
assert division(1, 1) == 1
Q4 - Extending our Calculator (0.5 points)¶
Let’s now add some more functions to our calculator:
Write a function called
squared
that takes one parameter, callednum
, and returns the square of it.Write a function called
square_root
that takes one parameter, callednum
, and returns the square root of it.
# YOUR CODE HERE
raise NotImplementedError()
assert callable(square)
assert isinstance(square(2), int)
assert square(5) == 25
assert callable(square_root)
assert isinstance(square_root(4), float)
assert square_root(144) == 12
Example: Chaining Functions Together¶
The goal of using functions is partly to be able to re-use code segments.
It’s also a way to able to flexibly apply and combine different functions together, to build up to more complex and interesting programs.
The cell below shows a couple examples of using our calculator functions that we have now defined, in combination with each other.
# Add the multiplication of 2 and 3 to the multiplication of 3 and 4
number1 = multiplication(2, 3)
number2 = multiplication(3, 4)
output1 = summation(number1, number2)
print('Output1: \t', output1)
print('')
# Note that we can use the outputs of functions directly as inputs to other functions
# Therefore, the above construction is equivalent to the following:
output2 = summation(multiplication(2, 3), multiplication(3, 4))
print('Output2: \t', output2)
# When we have something like above the functions that are inputs get evaluated first:
# So, first, `multiplication(2, 3)` evaluates as 6, and `multiplication(3, 4)` evaluales as 12
# This then reduces to calling `summation(6, 12)`, which returns our answer of 18
Q5 - Using Our Calculator (0.5 points)¶
Let’s now use our new calculator functions to do some calculations!
Add the square of 3 to the square root of 9
Save the result to a variable called
calc_a
Subtract the division of 12 by 3 from the the multiplication of 2 and 4
Save the result to a variable called
calc_b
Multiply the square root of 16 to the sum of 7 and 9
Save the result to a variable called
calc_c
Divide the square of 7 by the square root of 49
Save the result to a variable called
calc_d
# YOUR CODE HERE
raise NotImplementedError()
assert calc_a
assert isinstance(calc_a, float)
assert calc_b
assert isinstance(calc_b, float)
assert calc_c
assert isinstance(calc_c, float)
assert calc_d
assert isinstance(calc_d, float)
Calling Functions from Functions¶
In the example above, we were able to refactor our code into re-useable functions.
We were then able to use these functions and chain them together to flexibly and extensibly do computation.
Next we’ll dive into another aspect of writing good modular code: dividing complex tasks into independent functions and then using them together.
In practice, this will look like writing lots of and small and specific functions to do simple tasks.
We can then use these functions from within other functions build up to being able to do more complex tasks.
Q6 - Functions for Even & Positive Numbers (0.5 points)¶
Recall Q13 from A2, when we wanted to check a series of conditions across items in a list.
We can consider that checking each of these conditions is really a separate task.
When writing modular code, these separate tasks should therefore be organized as separate functions.
For this question, write two functions, one called is_even
, and the other called is_positive
.
Each function should take in a single parameter, a number called value
:
is_even
will check ifvalue
is even, and returnTrue
if so, andFalse
otherwise.is_positive
will check ifvalue
is positive, and returnTrue
if so, andFalse
otherwise.Note: for our purposes here, ‘positive’ numbers are all numbers greater than 0 (so 0 is not considered positive).
# YOUR CODE HERE
raise NotImplementedError()
assert callable(is_even)
assert isinstance(is_even(3), bool)
assert is_even(3) == False
assert callable(is_positive)
assert isinstance(is_positive(3), bool)
assert is_positive(-2) == False
Q7 - Functions Using Functions (0.5 points)¶
In this section, your are going to recreate a function called make_new_list
which takes a list called data_list
as its input.
This function will use is_positive
and is_even
to mimic the task from A2-Q13.
That is, this function will check each value in data_list
to see if they are even or odd and whether they are positive or negative.
If they are both positive and even, encode this as the number 1
If they are both negative and odd, encode this as the the number -1
Otherwise, encode this as the number 0
Store the result for each value into a list called
output
and return it.
# YOUR CODE HERE
raise NotImplementedError()
assert callable(make_new_list)
data_list = [-1, 20, -100, -40, 33, 97, -101, 45, -79, 96]
assert isinstance(make_new_list(data_list), list)
assert(len(make_new_list(data_list)) == len(data_list))
assert callable(make_new_list)
Part 3: Algorithms¶
This part covers working with algorithms.
Q8 - Algorithms (0.5 points)¶
For each of the tasks below, indicate whether you think it is something that a human or a computer would be better at doing.
Answer each question by setting each requested variable to the string either ‘human’ or ‘computer’.
Set the variable to reflect the answer of which of them you think would be better at the task.
a) Recognize whether a sentence is sarcastic and/or ironic.
Answer in a variable called
algo_q_a
b) Reply to a question with information about a topic, replying with the exact wording from a wikipedia article.
Answer in a variable called
algo_q_b
c) Keep answering messages for an arbitrarily long period of time, without demonstrating fatigue.
Answer in a variable called
algo_q_c
d) Interpret the tone of what was said, to infer if someone is angry.
Answer in a variable called
algo_q_d
For each, try to think through if and how you could write an algorithm to do this task - and if you could not, what about it is hard to formalize.
We can use these questions to start to think through what might be easy and hard to program our chatbot to do.
# YOUR CODE HERE
raise NotImplementedError()
assert algo_q_a in ['human', 'computer']
assert algo_q_b in ['human', 'computer']
assert algo_q_c in ['human', 'computer']
assert algo_q_d in ['human', 'computer']
Part 4: Chatbots¶
This part is an application of all the tools we have covered so far, to the problem of creating a chatbot.
A chatbot is a piece of software that tries to have a conversation with a human.
While today’s chatbots are powerful learners, traditional chatbots are much simpler.
Traditional chatbots follow a “rule-based” approach that is defined for them (by you, the programmer), usually without any learning.
These rules can be very simple or sometimes quite complex - but everything is pre-defined.
These types of chatbots can handle simple conversations but do tend to fail at more complex ones.
Chatbot functions¶
In order to make our chatbot, we will create a series of functions that our eventual chatbot will use together to try and chat with a user.
At the end, we will test that these functions do indeed allow us to have simple conversations with our chatbot.
Below are some more example chatbots to talk to. Remember to comment these lines back out if you want to be able to Restart and Run All
.
Example Chatbot - Eliza¶
The following demo is from the Natural Language ToolKit (nltk), a Python package available through Anaconda.
Uncomment the line below, and run the code to be able to have a chat with Eliza.
More information on Eliza: https://en.wikipedia.org/wiki/ELIZA
# Run a demo of a chatbot, with Eliza
#nltk.chat.eliza.demo()
Example Chatbot - Iesha¶
The following is another demo chatbot from nltk, this one called Iesha.
# Run a demo of a chatbot, with Iesha
#nltk.chat.iesha.demo()
As you try the chatbot demos with Eliza and Iesha, see if you can notice any patterns that might help you figure out how they work.
That is, can you guess at what kind of programming structures these programs might use?
Chatbots: Words & Rules¶
So, how do these kinds of chatbots work? Most broadly, they combine two simple but powerful approaches:
Rule Based Artificial Intelligence (GOFAI)
Bag-Of-Word Language Models
Rule based AI, sometimes called ‘Good Old Fashion Artificial Intelligence’, or ‘GOFAI’, is an approach to making artificial agents that tries to write down a set of rules to follow to perform some task. In practice, this often looks like using a lot of conditionals: if X
happens, do Y
. If we can write down enough logical procedures (call them algorithms) to follow to complete some task, then we can create an artificially intelligent agent (for that task).
Bag-Of-Word language models are an approach to language that takes the simple approach of saying ‘lets try and figure out what someone is saying simply by checking and counting which words they use’. If someone says the word ‘dog’ three times in conversation, they are probably talking about dogs. This ignores many many things about language, and how it works, but is a good ‘first guess’ for what is being said.
From our perspective, this means two things:
We can broadly try to figure out the topic simply by checking which words are used
We can choose a response based on a rule that defines what to do if and when we identify particular topics
In code then, this looks like:
taking input as strings of continuous text, and splitting this up into lists that contain all the words we see
use conditionals (if/elif/else) that choose an output based on what words appear in those lists
As we work through and create all the function in the next section to create our chatbot, try to think through how these functions relate to this approach.
Q9 - Is It a Question (0.5 points)¶
One thing we might want to know, given an input to a chatbot, is if the input is a question.
We are going to use a very simple heuristic to check this: we will consider any input that has a question mark (‘?’) in it to be a question.
To do so, write a function called is_question
.
This function should have the following inputs, outputs and internal procedures:
Input(s):
input_string
- string
Output(s):
output
- boolean
Procedure(s):
if there is a ‘?’ in
input_string
, setoutput
to Trueotherwise, set output to False.
return output
# YOUR CODE HERE
raise NotImplementedError()
assert callable(is_question)
assert isinstance(is_question('abc'), bool)
assert is_question('what?') == True
assert callable(is_question)
Example: string.punctuation¶
When working with strings, it can be useful to check what kind of things particular characters are.
To do things like this, Python offers some collections of items, that we can check against.
For example, we can ask if a particular character is a punctuation mark, by asking if it is in the collection of punctuation characters.
# Print out list of punctuation
print(string.punctuation)
print() # Print blank line
# Check if a particular symol is a punctuation mark
print('@' in string.punctuation)
Q10 - Removing punctuation (0.5 points)¶
Once we know if an input is a question, we are going to get rid of all punctuation.
To do so, write a function called remove_punctuation
.
This function should have the following inputs, outputs and internal procedures:
Input(s):
input_string
- string
Output(s):
out_string
- string
Procedure(s):
define a new variable
out_string
as an empty stringloop through each character in
input_string
if this character is not in
string.punctuation
then append the current character to
out_string
return
out_string
# YOUR CODE HERE
raise NotImplementedError()
assert callable(remove_punctuation)
assert isinstance(remove_punctuation('a'), str)
assert remove_punctuation("Hey! It's Tom!") == "Hey Its Tom"
assert callable(remove_punctuation)
Q11 - Preparing Text (0.5 points)¶
Now we want a more general function to prepare the text inputs for processing.
Inside this function, we will use some string methods as well as our new remove_punctuation
function.
Write a function called prepare_text
.
This function should have the following inputs, outputs and internal procedures:
Input(s):
input_string
- string
Output(s):
out_list
- list of string
Procedure(s):
make the string all lower case (use a string method called
lower
)note that you will have to assign the output to a variable. You can use a variable name like
temp_string
remove all punctuation from the string (use your new function
remove_punctuation
)this can also assign out to
temp_string
split the string into words (look for and use a string method called
split
)note that split will return a list of strings. Assign this as
out_list
return
out_list
# YOUR CODE HERE
raise NotImplementedError()
assert callable(prepare_text)
assert isinstance(prepare_text('One two three.'), list)
assert prepare_text('Hi! Also, howdy.') == ['hi', 'also', 'howdy']
assert callable(prepare_text)
Q12 - Echo a Response (0.5 points)¶
We will define a function that will return a string that has been repeated a specified number of times, with a given separator.
We will also want to deal with the case where the input to this function may be None
.
Write a function called respond_echo
.
This function should have the following inputs, outputs and internal procedures:
Input(s):
input_string
- string, or Nonenumber_of_echoes
- integerspacer
- string
Output(s):
echo_output
- string, or None
Procedure(s):
if
input_string
is notNone
:set a variable
echo_output
to beinput_string
, repeated the number of times specified bynumber_of_echoes
, joined by thespacer
.Hint: to do so, recall what “*” does to strings
otherwise (if
input_string
is None)set
echo_output
toNone
return
echo_output
Note that a simple version of this version will end up appending the spacer to the end of the list as well. For our purposes here, implement that simple version.
So, for example, respond_echo('bark', 2, '-')
should return: ‘bark-bark-‘
# YOUR CODE HERE
raise NotImplementedError()
assert callable(respond_echo)
assert isinstance(respond_echo('ha', 2, ' '), str)
assert respond_echo('meow', 3, '~') == 'meow~meow~meow~'
assert respond_echo(None, 2, '') == None
assert callable(respond_echo)
Example: random.choice¶
We want our chatbot to have some variation in it’s responses - not only anwering the same thing.
So, we want to be able to choose an output from a list of options.
We can use the random.choice
function to so.
An example of using random.choice
is offered below.
# Given a list of inputs, randomly choose and return one of them (re-run this to see different outputs)
random.choice(['first option', 'second option', 'third option'])
Q13 - Selector (0.5 points)¶
Next we will write a function that will help us select an output for the chatbot, based on the input it got.
The overall goal of this function is to take a list of words that we got as input, a list of words to check for if they appear in the input, and a list of possible outputs to return if something from the list to check is in the input list.
Define a function, called selector
.
This function should have the following inputs, outputs and internal procedures:
Input(s):
input_list
- list of stringcheck_list
- list of stringreturn_list
- list of string
Output(s):
output
- string, or None
Procedure(s):
Initialize
output
toNone
Loop through each element in
input_list
Use a conditional to check if the current element is in
check_list
If it is, assign
output
as the returned value of calling therandom.choice
function onreturn_list
Also, break out of the loop
At the end of the function, return
output
Note that if we don’t find any words from input_list
that are in check_list
, output
will be returned as None
.
# YOUR CODE HERE
raise NotImplementedError()
assert callable(selector)
assert selector(['in', 'words'], ['words'], ['yes']) == 'yes'
assert selector(['in', 'words'], ['out'], ['yes']) == None
assert callable(selector)
Q14 - String Concatenator Function (0.5 points)¶
Create a function that will concatenate two strings, combining them with a specified separator.
To do so, write a function called string_concatenator
.
This function should have the following inputs, outputs and internal procedures:
Input(s)
string1
- stringstring2
- stringseparator
- string
Output(s)
output
- string, or None
Procedure(s):
concatenate
string1
tostring2
withseparator
in between them.return the result
# YOUR CODE HERE
raise NotImplementedError()
assert callable(string_concatenator)
assert isinstance(string_concatenator('hello', 'world', ' '), str)
assert string_concatenator('hello', 'world', ' ') == 'hello world'
assert callable(string_concatenator)
Q15 - List to String (0.5 points)¶
Since we are often dealing with a list of strings, it would be useful to have a function to turn a list of strings back into one single concatenated string.
This function will return a string that is each element of input_list
concatenated together with each separated by the string seperator
.
For example, the following function call:
`list_to_string(['This', 'is', 'fun'], ' ')`
shoud return:
'This is fun'
To do this, write a function called list_to_string
.
This function should have the following inputs, outputs and internal procedures:
Input(s):
input_list
- list of stringseparator
- string
Output(s):
output
- string
Procedure(s):
assign a variable called
output
to be the first (index 0) element frominput_list
loop through the rest of
input_list
, looping from the 2nd element (index 1) through to the end of the listWithin the loop, use
string_concatenator
to combineoutput
with the current element, separated byseparator
Assign the output of this to be the new value of
output
return
output
, which should now be a list of the elements ofinput_list
, joined together into a a single string
# YOUR CODE HERE
raise NotImplementedError()
assert callable(list_to_string)
assert isinstance(list_to_string(['a', 'b'], '|'), str)
assert list_to_string(['a', 'b'], '|') == 'a|b'
assert callable(list_to_string)
Q16 - End Chat (0.5 points)¶
The last thing we need is a way to end the chat with our chatbot.
We will use the same convention that nltk
uses - namely, that we will end the conversation if the word quit
appears.
To be able to do so, write a function called end_chat
This function should have the following inputs, outputs and internal procedures:
Input(s):
input_list
- list
Output(s):
output
- boolean
Procedure(s):
This function should return
True
if the string ‘quit’ is ininput_list
, and returnFalse
otherwise.
# YOUR CODE HERE
raise NotImplementedError()
assert callable(end_chat)
assert isinstance(end_chat(['a', 'b']), bool)
assert end_chat(['quit']) == True
assert callable(end_chat)
Pulling it all Together¶
If everything has gone well with writing everything above, then we are ready to pull all these functions together to create our chatbot.
The next few cells define a bunch of code, all provided for you. This code adds a couple more functions we can use and then defines some lists of inputs and outputs that our chatbot will know about. After that, there is a big function that pulls everything together and creates the procedure to use all of this code together as a chatbot.
You don’t have to write anything in the cells below (or in the rest of the assignment).
Do have a quick read through the code though, to see how our chatbot works, and to see how all the functions you just wrote are used to create the chatbot.
If you need, revisit the information at the beginning of this section about the logic our chatbot uses.
You don’t have to understand everything about what happens here, but try to have a first-pass look through it.
We will build up to understanding and writing this kind of code that brings a lot of things together as we continue through the course.
If the code seems intimidating, just scroll down to the bottom, and test out talking to our chatbot.
# These are a couple more function, provided to you, to be used by our chatbot.
def is_in_list(list_one, list_two):
"""Check if any element of list_one is in list_two."""
for element in list_one:
if element in list_two:
return True
return False
def find_in_list(list_one, list_two):
"""Find and return an element from list_one that is in list_two, or None otherwise."""
for element in list_one:
if element in list_two:
return element
return None
# This cell defines a collection of input and output things our chatbot can say and respond to
GREETINGS_IN = ['hello', 'hi', 'hey', 'hola', 'welcome', 'bonjour', 'greetings']
GREETINGS_OUT = ["Hello, it's nice to talk to you!", 'Nice to meet you!', "Hey - Let's chat!"]
COMP_IN = ['python', 'code', 'computer', 'algorithm', ]
COMP_OUT = ["Python is what I'm made of.", \
"Did you know I'm made of code!?", \
"Computers are so magical", \
"Do you think I'll pass the Turing test?"]
PEOPLE_IN = ['turing', 'hopper', 'neumann', 'lovelace']
PEOPLE_OUT = ['was awesome!', 'did so many important things!', 'is someone you should look up :).']
PEOPLE_NAMES = {'turing': 'Alan', 'hopper': 'Grace', 'neumann': 'John von', 'lovelace': 'Ada'}
JOKES_IN = ['funny', 'hilarious', 'ha', 'haha', 'hahaha', 'lol']
JOKES_OUT = ['ha', 'haha', 'lol']
NONO_IN = ['matlab', 'java', 'C++']
NONO_OUT = ["I'm sorry, I don't want to talk about"]
UNKNOWN = ['Good.', 'Okay', 'Huh?', 'Yeah!', 'Thanks!']
QUESTION = "I'm too shy to answer questions. What do you want to talk about?"
def have_a_chat():
"""Main function to run our chatbot."""
chat = True
while chat:
# Get a message from the user
msg = input('INPUT :\t')
out_msg = None
# Check if the input is a question
question = is_question(msg)
# Prepare the input message
msg = prepare_text(msg)
# Check for an end msg
if end_chat(msg):
out_msg = 'Bye!'
chat = False
# Check for a selection of topics that we have defined to respond to
# Here, we will check for a series of topics that we have designed to answer to
if not out_msg:
# Initialize to collect a list of possible outputs
outs = []
# Check if the input looks like a greeting, add a greeting output if so
outs.append(selector(msg, GREETINGS_IN, GREETINGS_OUT))
# Check if the input looks like a computer thing, add a computer output if so
outs.append(selector(msg, COMP_IN, COMP_OUT))
# Check if the input mentions a person that is specified, add a person output if so
if is_in_list(msg, PEOPLE_IN):
name = find_in_list(msg, PEOPLE_IN)
outs.append(list_to_string([PEOPLE_NAMES[name], name.capitalize(),
selector(msg, PEOPLE_IN, PEOPLE_OUT)], ' '))
# Check if the input looks like a joke, add a repeat joke output if so
outs.append(respond_echo(selector(msg, JOKES_IN, JOKES_OUT), 3, ''))
# Check if the input has some words we don't want to talk about, say that, if so
if is_in_list(msg, NONO_IN):
outs.append(list_to_string([selector(msg, NONO_IN, NONO_OUT), find_in_list(msg, NONO_IN)], ' '))
# IF YOU WANTED TO ADD MORE TOPICS TO RESPOND TO, YOU COULD ADD THEM IN HERE
# We could have selected multiple outputs from the topic search above (if multiple return possible outputs)
# We also might have appended None in some cases, meaning we don't have a reply
# To deal with this, we are going to randomly select an output from the set of outputs that are not None
options = list(filter(None, outs))
if options:
out_msg = random.choice(options)
# If we don't have an output yet, but the input was a question, return msg related to it being a question
if not out_msg and question:
out_msg = QUESTION
# Catch-all to say something if msg not caught & processed so far
if not out_msg:
out_msg = random.choice(UNKNOWN)
print('OUTPUT:', out_msg)
Talking to our Chatbot¶
To talk to our chatbot, uncomment and run the cell below.
If anything seems to go weird, note that you can always interrupt the code from running with chat with kernel - interrupt from the menu.
If this happens, it probably means there is some issue with one of the functions you wrote for the chatbot.
# Talk to our chatbot
have_a_chat()
Extending Our Chatbot¶
You might notice that our chatbot, right now, is pretty limited in how many things it can respond to.
To respond to more topics, we could re-use these same functions, adding more input & output options for our chatbot to respond to, using the basic approaches and functionality we have defined here.
If you are interested in this topic, extending this chatbot (or ones like it) will be one of your project options.
The End!¶
After you’ve explored chatting to the chatbot, you are done!
Have a look back over your answers, and also make sure to Restart & Run All from the kernel menu to double check that everything is working properly.
When you are ready to submit your assignment, upload it to TritonED under Assignment-3.