ML - Better Keyword Detection (Lesson)

APCompSci_LessonTopBanner.png

Better Keyword Detection

Introduction

The previous lesson brought to light that with the current Magpie program, there are instances where it does not always work as intended. For example, a sentence containing the word “know” would have the same response as a sentence containing the word “no”, since “no” is contained in “know”. This gives a response that doesn’t make sense.

How can that be fixed?

Better Keyword Detection

Question:

How can we tell if when we find “no” in a sentence it is actually “no” and not just part of another word that contains the combination of letters “no”?

Answer:

Check for space in front and behind the word so that we can be sure that it isn’t part of a larger word.

We will be adding a method named findKeyword to detect keywords. This method will only find exact matches of the keyword, instead of cases where the keyword is embedded in a longer word.

Add the following two overloaded findKeyword methods to your Magpie code as follows. Be sure to type carefully. If your code does not compile, you have probably made a typing error. Contact your teacher if you need further assistance.

Duck saying Overloaded methods have the same name but different parameter lists. 

This lab is from AP Central Collegeboard Links to an external site..

/**
* Search for one word in phrase.  The search is not case
*sensitive.  This method will check that the given goal
*is not a substring of a longer string (so, for 
* example, "I know" does not contain "no").
*
*@param statement
*    the string to search
* @param goal
*     the string to search for
*@param startPos
*   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
*/ private int findKeyword(String statement, String goal, int startPos)
{
String phase = statement.trim();
//The only change to incorporate the startPos is in the line below
int psn = phrase.toLowerCase().indexOf(goal.toLowerCase(), startPos);

//Refinement--make sure the goal isn't part of a word
while (psn >= 0)
{
//Find the string of length 1 before and after the word
String before = " ", after = " ";
if (psn > 0)
{
before = phrase.substring(psn - 1, psn).toLowerCase();
}
if (psn + goal.length() < phrase.length())
{
after = phrase.substring(psn + goal.length(), psn + goal.length() + 1).toLowerCase();
} // If before and after aren't letters, we've found the word
if (((before.compareTo("a") < 0) || (before.compareTo("z") > 0)) // before is not a
// letter
&& ((after.compareTo("a") < 0) || (after.compareTo("z") > 0)))
{
return psn;
}

//The last position didn't work, so let's find
//the next, if there is one.
psn = phrase.indexOf(goal.toLowerCase(), psn + 1);

}
return -1;
} Code3_BetterKeywordDetection.png /**
* Search for one word in phrase. The search is not case
* sensitive. This method will check that the given goal
* is not a substring of a longer string (so, for
* example, "I know" does not contain "no"). The search
* begins at the beginning of the string.
*
* @param statement
* the string to search
* @param goal
* the string to search for
* @return the index of the first occurrence of goal in
* statement or -1 if it's not found
*/
private int findKeyword(String statement, String goal)
{
return findKeyword(statement, goal 0); 
} Change the code for getResponse so that it utilizes the findKeyword method. For example, instead of:

if (statement.indexOf("no") >= 0) 

You should type:

if (findKeyword (statement, "no") >= 0) 

You will need to make these changes for all the if conditions that are currently using indexOf in getResponse.

Better Keyword Detection

Test your Magpie class several times to be sure the code works as intended. Compile and Run the MapgieRunner.java file and enter different responses. Check to make sure the responses are what you expect.

APCompSci_LessonBottomBanner.pngIMAGES CREATED BY GAVS