Magpie ChatbotName______
Magpie Chatbot is one of the three official AP Computer Science labs from the College Board. This is a shorter version, edited by me (Haas), with the intent of removing some of the extraneous material. The original lab is 12 pages - not including the code!
The Magpie code to get started is at the end of this document.
In this lab, you will explore some of the basics ofNatural Language Processing (NLP) through the use of Chatbots.
Show Haas the running program after each activity is complete.
Activity 1: Play around with some Chatbots
Activity 2: Modify a Chatbot.
In this activity, you will work Magpie, with a simple implementation of a chatbot. You will see how it works with some keywords and add keywords of your own.
In BlueJRun The Main Method
Try it out … how does it respond to:
My mother and I talked last night.
I said no!
The weather is nice.
Do you know my brother?/*** There is a problem with this one.***/
q /*** IMPORTANT q exits the program ***/
Look at the code. Make sure you understand how it works.
Exercises - Add the following responses to the getResponse method.
- Have it respond “Tell me more about your pets” when the statement contains the word “dog” or “cat.”
For example, a possible statement and response would be:
Statement: I like my cat Mittens.
Response: Tell me more about your pets.
- Have it respond favorably when it sees the name of your computer science teacher.
For example, a possible statement and response would be:
Statement: Mr. Haasalways talks about pizza.
Response: He sounds like a good teacher.
- Have the code guard against an empty String. Hint: use the String method trim(). Thetrim method to remove spaces from the beginning and end. If there are no characters, the response should tell the user to entersomething. For example, a possible statement and response would be:
Statement:
Response: Say something, please.
- Complete the method getRandomResponse(). The method is supposed to return a random response from the following options:
Interesting, tell me more.
Hmmm.
Do you really think so?
You don't say.
How does that make you feel?
Activity 3: Better Keyword Detection
The Magpie class has a methodfindKeyword to detect keywords. Notice that it has a problem with statements like:
I know all the state capitals.
I like vegetables smothered in cheese.
This is because a keyword is embedded in a longer word. Run it!
Exercise: Modify the methodfindKeyword .
Improve the method findKeyword so that it only detects a keyword if it is not within another word. A keyword should not have letters around it.
Hint - check for non-letter:
String letters = "abcdefghijklmnopqrstuvwxyz";
(letters.indexOf(“!”)== -1) // is true: !is not a letter
Activity 4: Responses that Transform Statements
Single keywords are interesting, but better chatbots look for groups of words. Statements like “I like cats,” “I like math class,” and “I like Spain” all have the form “I like something.” The response could be “What do you like about something?” This activity will respond to groupings of words.
How does Magpie respond to:
I want to build a robot.
I want to understand French.
Do you like me?
You confuse me.
Exercises:
Look at the code. See how it handles “I want to” and you/me statements. Add code to respond to “I want...”, and “I…you…” statements.
- Have it respond to “I want something” statements with “Would you really be happy if you had something?” In doing this, you need to be careful about where you place the check. Be sure youunderstand why. For example:
Statement: I want fried chicken.
Response: Would you really be happy if you had fried chicken?
- Have it respond to statements of the form “I something you” with the restructuring “Why do yousomething me?” For example:
Statement: I like you.
Response: Why do you like me?
See Magpie code on the next page:
Cut and paste in into BlueJ - It’s all one class!
/**
* A program to carry on conversations with a human user.
*/
importjava.util.Scanner;
public class Magpie
{
/**
* Gives a response to a user statement
*
* @param statement - the user statement
* @return a response based on the rules given
*/
public String getResponse(String statement)
{
if (statement.length() == 0)
{
return "Say something, please.";
}
if (findKeyword(statement, "no") >= 0)
{
return "Why so negative?";
}
if (findKeyword(statement, "mother") >= 0
|| findKeyword(statement, "father") >= 0
|| findKeyword(statement, "sister") >= 0
|| findKeyword(statement, "brother") >= 0)
{
return "Tell me more about your family.";
}
/*** ------Activity 2 ------
* Add new responses here.
*
* 1. Add response for: "cat" or "dog"
* 2. Add response for: teacher name "Haas"
* 3. Handle empty string
*
***/
/** < Add your code for Activity 2 here > **/
/***
* Responses that Transform Statements
*/
if (findKeyword(statement, "I want to") >= 0)
{
returntransformIWantToStatement(statement);
}
if (findKeyword(statement, "I want") >= 0)
{
returntransformIWantStatement(statement);
}
if (findKeyword(statement, "you") != -1 &
findKeyword(statement, "you") < findKeyword(statement, "me"))
{
returntransformYouMeStatement(statement);
}
if (findKeyword(statement, "I") != -1 &
findKeyword(statement, "I") < findKeyword(statement, "you"))
{
returntransformIYouStatement(statement);
}
returngetRandomResponse();
}
/*** ------Activity 2 ------
* Pick a random response to use if nothing else fits.
* @return a random string from the following options:
* "Interesting, tell me more."
* "Hmmm."
* "Do you really think so?"
* "You don't say."
*/
private String getRandomResponse()
{
/** < Add your code for Activity 2 here > **/
return "~~~ change the code to return a random response ~~~";
}
/**
* runs the method: findKeyword passing in a default value of 0
*/
privateintfindKeyword(String statement, String goal)
{
returnfindKeyword (statement, goal, 0);
}
/**
* This method returns the index of a given goal in a longer string.
*
* @param statement the string to search
* @param goal the string to search for
* @paramstartPos the character of the string to begin the search at
* @return the index of the first occurrence of goal in statement or -1 if it's not found
*/
privateintfindKeyword(String statement, String goal, intstartPos)
{
/*** ------Activity 3 ------
* Improve this method so that it only detects a keyword if it
* is not within another word.
* A keyword should not have letters around it.
*/
/** convert to lower case **/
statement = statement.toLowerCase();
goal = goal.toLowerCase();
/** remove the following line when you implement Activity 3 ***/
returnstatement.indexOf(goal,startPos);
/** < Add your code for Activity 3 here > **/
}
/** --- This method is complete!!! --
* Take a statement with "I want to <something>." and transform it into
* "What would it mean to <something>?"
* @param statement the user statement, assumed to contain "I want to"
* @return the transformed statement
*/
private String transformIWantToStatement(String statement)
{
// Remove the final period, if there is one
statement = statement.trim();
String lastChar = statement.substring(statement.length() - 1);
if (lastChar.equals(".")) {
statement = statement.substring(0, statement.length() - 1);
}
intpsn = findKeyword(statement, "I want to", 0);
String restOfStatement = statement.substring(psn + 9).trim();
return "What would it mean to " + restOfStatement + "?";
}
/** ------Activity 4 ------
* Take a statement with "I want <something>." and transform it into
* "Would you really be happy if you had <something>?"
* @param statement the user statement, assumed to contain "I want"
* @return the transformed statement
*/
private String transformIWantStatement(String statement)
{
// < Complete the code >
return" --- temporary code --- "; // temporary code
/** < Add your code for Activity 4 here > **/
}
/** --- This method is complete!!! --
* Take a statement with "you <something> me" and transform it into
* "What makes you think that I <something> you?"
* @param statement the user statement, assumed to contain "you" followed by "me"
* @return the transformed statement
*/
private String transformYouMeStatement(String statement)
{
// Remove the final period, if there is one
statement = statement.trim();
String lastChar = statement.substring(statement.length() - 1);
if (lastChar.equals(".")) {
statement = statement.substring(0, statement.length() - 1);
}
intpsnOfYou = findKeyword(statement, "you", 0);
intpsnOfMe = findKeyword(statement, "me", psnOfYou + 3);
String restOfStatement = statement.substring(psnOfYou + 3, psnOfMe).trim();
return "What makes you think that I " + restOfStatement + " you?";
}
/** ------Activity 4 ------
* Take a statement with "I <something> you" and transform it into
* "Why do you <something> me?"
* @param statement the user statement, assumed to contain "I" followed by "you"
* @return the transformed statement
*/
private String transformIYouStatement(String statement)
{
/** < Add your code for Activity 4 here > **/
return " --- temporary code --- "; // temporary code
}
/**
* Create a Magpie, give it user input, and print its replies.
*/
public static void main(String[] args)
{
Magpie maggie = new Magpie();
System.out.println("Hello, let's talk.");
Scanner in = new Scanner (System.in);
String statement = in.nextLine();
while (!statement.equals("q"))
{
System.out.println(maggie.getResponse(statement));
statement = in.nextLine();
}
}
}