You mention the MessageMunger we wrote in class as a possible solution — it could rewrite his messages, substituting one word for another to help disguise his writing patterns. He's pretty paranoid though, and proposes an even sneakier approach: A modified MessageMunger in which the choice of replacement word is random. For example, when replacing the word "happy", it might select randomly from "pleased", "glad", or "delighted". Randomizing the substitutions should help keep Bill from using word frequency information to learn the author's identity!
println on a separate line from the for to keep the output prettier, but the codepad would require both to be on the same line.)
> TextRandomizer tr = new TextRandomizer();
> for(int i=0; i<10; i++)
System.out.println(tr.randomize("That's good news -- you must be happy"));
That's agreeable news -- you must be delighted
That's favorable news -- you must be delighted
That's agreeable news -- you must be glad
That's favorable news -- you must be pleased
That's positive news -- you must be thrilled
That's positive news -- you must be glad
That's favorable news -- you must be delighted
That's super news -- you must be pleased
That's favorable news -- you must be pleased
That's super news -- you must be thrilled
Before starting the assignment, make sure you read Chapter 5. Pay particular attention to the Responder class in the tech-support project. The book develops several versions, but one of them is very close to what you'll need for this assignment (the ArrayList-based version in tech-support2).
Responder class that will randomly generate synonyms, and the TextRandomizer class that will use Responder instances for each of the words it wants to replace:
Breaking the project into two classes will simplify the task. An instance of the Responder class is only responsible for handling a single word. It remembers a collection of possible alternatives for a word, and can select one randomly when asked. The TextRandomizer class is similar to the MessageMunger we wrote in class, except it maps words to Responder instances. To replace a word from the input sentence, the TextRandomizer first looks it up in a map, just like MessageMunger does, but now the associated value is an entire Responder object! Once the corresponding Responder has been retrieved from the map, it can be asked to randomly generate a replacement word.
Responder class from the tech-support2 project to the new project you've created. (You can use the "Add Class from File..." menu item under "File".) Open an editor and review the code. It keeps possible responses in an ArrayList of Strings, and selects one randomly when generateResponse() is invoked. One could imagine filling the ArrayList with "glad", "pleased", "thrilled", etc, and using the responder instance to supply a replacement for "happy".
Responder instance — we'll need one full of options for "happy", one full of options for "good", etc. Since different Responder instances need to store different sets of words, we can't rely on the current definition of fillResponses. (We could plug in synonyms for "happy", but then how would we create a Responder for "good"?)
Remove the fillResponses method, and replace it with a method called addResponse that takes a single String argument, and adds the String to the Responder's vocabulary. The interactions below show the updated Responder in use:
> Responder colors = new Responder();
> colors.addResponse("Red");
> colors.addResponse("Green");
> colors.addResponse("Blue");
> colors.generateResponse()
"Red" (String)
> colors.generateResponse()
"Blue" (String)
> Responder pets = new Responder();
> pets.addResponse("dog");
> pets.addResponse("cat");
> pets.generateResponse()
"cat" (String)
> pets.generateResponse()
"dog" (String)
toString() method to the Responder class. It should display all possible words that the responder can generate. Don't forget that ArrayLists have their own built-in toString method, so you don't need to write code to display the individual entries!
> Responder colors = new Responder();
> colors.addResponse("Red");
> colors.addResponse("Green");
> colors.addResponse("Blue");
> colors.toString()
"Options: [Red, Green, Blue]" (String)
> System.out.println(colors);
Options: [Red, Green, Blue]
Responder instances. (Below, we'll make sure that the Responders contain synonyms for the corresponding key word.)
Copy the field declaration (wordMap) and constructor from MessageMunger, and modify them so that the HashMap maps Strings to Responders instead of Strings to Strings.
Responder class built a set of fixed strings. Modify the constructor so that it adds mappings for at least two words (if you borrow the examples shown on this page, you need at least two more of your own). Each of these mappings should have at least three possibilities. For each word, you'll need to create a new Responder instance, fill it with synonyms, then add the word and its corresponding Responder to the wordMap.
randomize method. It takes a single String as its input, replaces specific words with randomly-selected alternatives, and returns the result. Note that this is very similar to what the munge method in MessageMunger does. The key difference is that munge retrieved a word from the HashMap, and here we need to retrieve a Responder instance and ask it to generate a word instead.
> TextRandomizer tr = new TextRandomizer();
> tr.randomize("That's good news -- you must be really happy")
"That's positive news -- you must be really thrilled " (String)
> tr.randomize("That's good news -- you must be really happy")
"That's agreeable news -- you must be really pleased " (String)
> tr.randomize("That's good news -- you must be really happy")
"That's positive news -- you must be really glad " (String)
toString() method to the TextRandomizer class so that we can see the details of its mappings. (If it takes you more than one line of code, you're making it too hard.)
> TextRandomizer tr = new TextRandomizer();
> tr.randomize("That's good news -- you must be really happy")
"That's positive news -- you must be really glad " (String)
> System.out.println(tr);
Mappings are: {good=Options: [favorable, positive, super, agreeable],
happy=Options: [delighted, glad, pleased, tickled, thrilled]}
/** ... */). For full credit, you should use the @param and @return tags as appropriate in these method comments. Each instance variable should have a brief comment as well. Don't forget the main comment at the top of the class either — I'm looking for more than just a sentence or two.
@param and @return directives) above each method. When you're convinced it's ready to go, submit the project electronically. Don't forget to put a copy of this file in your project folder before attempting to submit. (Submitting will work from off campus now.)