![]() Graphic by Keith Ohlfs |
Problem Set 7
|
[CS111 Home Page] [Syllabus] [Students] [Lecture Notes] [Assignments] [Programs] [Documentation] [Software Installation] [FAQ] [CS Dept.] [CWIS]
The purpose of this problem set is to give you a better understanding of lists by writing recursive lists methods. There are two problems on this assignment and each problem has several parts.
Homework Problems :
Turn in only one package of hardcopy materials. Staple your files together with the cover page, and submit your hardcopy package by placing it in the box outside of Jennifer's office (E104).
Reminders
In this problem, you are to implement the ObjectList methods specified below. Write all your code for this problem in the file ps7ObjectListOps.java within ps7_programs.
The Lists folder also contains the file ps7ObjectListOpsAnswers.class, which has correct solutions for all of the methods of this problem. Because the folder contains only the compiled file, and not the source file, you cannot look at the solutions. However, you can invoke the solutions from your program if you need them.This allows decoupling the solutions to methods where one method depends on another. For instance, suppose you would like to use remove() to implement removeDuplicates(), but you have not successfully completed the definition of remove(). You can still write and test removeDuplicates(), by referring to ps7ObjectListOpsAnswers.remove() instead. Later, you can implement your own version of remove(). Indeed, the file ps7ObjectListOps.java initially contains skeletons of the methods that invoke the correct implementations of the corresponding methods in ps7ObjectListOpsAnswers.class. Of course, you should replace these skeletons with your own definitions.
Use the ps7ObjectListOpsTest.html applet to test your solutions. This applet runs your implementations of the methods on several test cases, and writes the answers to the standard output window (stdout). Study these answers to make sure that your methods have the correct behavior. If you want to print out the contents of the stdout window, you first need to save it away as a file. To do this, open the pull down menu under the apple in the upper left-hand corner of the screen, select Java Runtime, and then select Save Text Window. You will be prompted for the name of a file. Once the window is save to a file, you can open the file and print it.
When giving examples below, we will assume the existence of the following test lists, each of which is a list of strings:
L0 = [ ] L1 = [Hello, there] L2 = [How, are, you] L3 = [I, am, what, I, am, you, are, what, you, are]
Part a [0.5 points] isMember()
public static boolean isMember (Object x, ObjectList L)
Returns true if x is in L and false otherwise. Uses .equals() to test for equality, not ==.For example:
isMember("I", L0) = false isMember("are", L0) = false isMember("you", L0) = false isMember("I", L1) = false isMember("are", L1) = false isMember("you", L1) = false isMember("I", L2) = false isMember("are", L2) = true isMember("you", L2) = true isMember("I", L3) = true isMember("are", L3) = true isMember("you", L3) = true
Part b [0.5 points] remove()
public static ObjectList remove (Object x, ObjectList L)
Returns a list containing all the elements of L (in the same order) except for occurrences of x, which have been removed. Uses .equals() to test for equality, not ==.For example:
remove("I", L0) = [ ] remove("are", L0) = [ ] remove("you", L0) = [ ] remove("I", L1) = [Hello, there] remove("are", L1) = [Hello, there] remove("you", L1) = [Hello, there] remove("I", L2) = [How, are, you] remove("are", L2) = [How, you] remove("you", L2) = [How, are] remove("I", L3) = [am, what, am, you, are, what, you, are] remove("are", L3) = [I, am, what, I, am, you, what, you] remove("you", L3) = [I, am, what, I, am, are, what, are]
Part c [1 point] removeDuplicates()
public static ObjectList removeDuplicates (ObjectList L)
Returns a list containing a single occurrence of each elements occuring in L. The order of the resulting elements is irrelevant. Uses .equals() to test for equality, not ==.For example (note, the strings in the lists could be in any order, not necessary the order shown below):
removeDuplicates(L0) = [ ] removeDuplicates(L1) = [Hello, there] removeDuplicates(L2) = [How, are, you] removeDuplicates(L3) = [I, am, what, you, are]
Part d [1 point] interleave()
public static ObjectList interleave (ObjectList L1, ObjectList L2)
Returns a list of the elements of L1 interleaved with the elements of L2. The resulting list should contain the first element of L1 followed by the first element of L2, followed by the second element of L1, followed by the second element of L2, etc. When one of the lists runs out of elements, all the elements of the other list should be included.For example:
interleave(L0, L0) = [ ] interleave(L0, L1) = [Hello, there] interleave(L1, L0) = [Hello, there] interleave(L1, L2) = [Hello, How, there, are, you] interleave(L2, L1) = [How, Hello, are, there, you] interleave(L2, L2) = [How, How, are, are, you, you] interleave(L2, L3) = [How, I, are, am, you, what, I, am, you, are, what, you, are] interleave(L3, L3) = [I,I, am, am, what, what, I, I, am, am, you, you, are, are, what, what, you, you, are, are]
In this problem, we will experiment with a very simple program that simulates a nondirective psychotherapist. This program is inspired by the celebrated Eliza program created by Joseph Weizenbaum at MIT in the early 1960s. Eliza was realistic enough to fool some people into thinking that they were conversing with another person, not a computer. Eliza has inspired a long line of programs that have grown in sophistication over the years.
A description of the doctor program follows. You should try out the program by executing appletviewer Doctor.html. You will quickly see that no one could be fooled into thinking that this program is a real human being. You will be working on making a few improvements to the program. Your changes will make the doctor a bit more human. A lot more work would be required to change the program to the point where it would fool people.
Doctor
programA patient engages in a "conversation" with the doctor program by typing sentences into the input field of the Doctor applet. These sentences are echoed in the text area of the applet, along with the doctor's replies. Below is a sample conversation that could take place in the program. For readability, the doctor's replies have been italicized, though in the actual program all sentences are in the same font.
Doctor: What is your name? Patient: Chandler Doctor: Hello, Chandler. What seems to be the trouble? Chandler: Joey moved out Doctor: Why do you say Joey moved out Chandler: He moved to another apartment Doctor: You seem to think he moved to another apartment Chandler: Yes, he moved out last week Doctor: Please continue. Chandler: I miss him Doctor: Many people have the same sorts of feelings. Chandler: Well I guess I can still see him Doctor: Earlier you said that he moved to another apartment Chandler: Yeah, but he doesn't live too far away Doctor: Please continue Chandler: And then there's the business with Janice Doctor: Why do you say and then there's the business with Janice Chandler: Goodbye Doctor: Goodbye, Chandler. See you next week!
The doctor program uses three simple strategies to respond to a patient:
These strategies are embodied in the reply()
method
of the Doctor
class which takes the patient's most
recent statement and a list of all the patient's previous statements
to decide how it should reply. It is important to understand that you
are NOT going to be writing the basic doctor program. We are giving
that to you! If you are curious, you can read the comments in the
source to understand how it works. For this problem, you will simply
be making modifications to the basic program. You do not need to
understand the details of the program in order to make the requested
modifications.
The way the Doctor
uses qualifiers is too simplistic
to fool even the most gullible person. For example, if the patient
says "I am unhappy with how they treated me", the doctor responds by
prefacing the same exact string prefixed with a qualifier --- e.g.,
"You feel I am unhappy with how they treated me".
A better approach would be to change various words in the response to indicate the change in person. The above response would be more realistic as "You feel you are unhappy with how they treated you".
Here is a table of the type of substitutions we want to add to the doctor program:
old world |
new word |
---|---|
I |
you |
me |
you |
my |
your |
mine |
yours |
am |
are |
you |
I |
are |
am |
Note that the first five substitutions are always valid, but the last two can sometimes be invalid. The word "you" could translate to either "I" or "me". For this problem we will "guess" it should be "I", but we could be wrong. We could also be wrong in the following situation: "are" could be a verb for the third person plural, as in "Clouds are pretty", in which case we really don't want to change it to "am". We would need a more sophisticated approach to handle these cases correctly.
The doctor program contains a parseWords()
method
that correctly parses a string into a list of strings that are its
component words and punctuation marks. For example, if
sentence
is the string
"You know, I really miss him!"
then parseWords(sentence)
yields an ObjectList of
strings with the following printed representation:
[You, know, ,, I, really, miss, him, !]
(Here ",," should be interpreted as the punctuation string ","
followed by a comma delimiting the components of the
ObjectList
. ) The "inverse" of parseWords()
is unparseWords()
, which glues a list of words and
punctuation marks back into a sentence that is a single string.
Using these methods, we can define a changePerson()
method that applies the above person-changing substitutions to a
sentence:
public String changePerson (String sentence) { return unparseWords(substitute(substitutions, parseWords(sentence))); }
Here, substitutions
is a class variable of
Doctor
containing a list of substitution pairs that
alternates between old words and the corresponding new words:
[I, you, me, you, my, your, mine, yours, am, are, you, I, are, am]
To make changePerson() work, you need to define the following two methods:
public static
String getSubstitute (ObjectList subPairs, String word);
AssumesubPairs
is a list of strings with alternating "old"/"new" word pairs. Ifword
is any "old" word insubPairs
, returns the corresponding"new" word in the pair. Otherwise, returns the givenword
unchanged.
public static
ObjectList substitute (ObjectList subPairs, ObjectList words);
AssumesubPairs
is a list of strings with alternating "old"/"new" word pairs, andwords
is a list of strings. Returns the list of strings that results from mapping thegetSubstitute
substitution process over every word inwords
.
Examples
Suppose we have the following test lists:
L0 = [ ] L1 = [A, green, book] L2 = [The, red, cat] L3 = [Five, dog, days] subPairs1 = [red, green, five, seven, green, yellow, cat, dog]
Then here are some test cases of these two methods:
getSubstitute(subPairs1, "red") = green getSubstitute(subPairs1, "five") = seven getSubstitute(subPairs1, "green") = yellow getSubstitute(subPairs1, "cat") = dog getSubstitute(subPairs1, "seven") = seven getSubstitute(subPairs1, "dog") = dog getSubstitute(subPairs1, "house") = house substitute(subPairs1, L0) = [ ] substitute(subPairs1, L1) = [A, yellow, book] substitute(subPairs1, L2) = [The, green, dog] substitute(subPairs1, L3) = [seven, dog, days]
Notes:
getSubstitute
and
substitute
methods are in the Doctor.java
file. Currently, it contain invocations to correct answers in the
file DoctorAnswers.class
. So, when you run the
program, it gives the right behavior. You will be replacing the
reference to the correct code with your own implementations for
the methods. Correct implementations of the methods are given to
you so that you can implement and test a version of
substitute()
in terms of
DoctorAnswers.getSubstitute()
before you have
implemented your own version of getSubstitute()
.
.equals()
to test two
strings for equality; ==
will not do
the right thing!
String
class
has methods toUpperCase and toLowerCase which
returns a new String
which is the original
String
converted to all uppercase or lowercase
letters, respectively. The original String
is not
changed. However, the String
class also contains a
method that does case-insensitive comparisons. You can browse the
String
API to find this method.
(String)
cast for any
expression that really is a String
but which Java
thinks is an Object
if you want to use the expression
as a String
.
DoctorOpsTest.html
applet. Of course, you are also
encouraged to test them in the context of the
Doctor.html
applet. With this simple change, the
doctor's responses improve significantly, although they are still
far from realistic.
Another way to make the doctor more sophisticated is to have the doctor notice when the patient keeps refering to the same words. For instance, if a patient says "I saw a cat in my dreams" and has mentioned "dreams" several times previously, the doctor could say "Several times now you have mentioned dreams" or "You seem to keep coming back to dreams".
Here is a method that can be used to detect words frequently used in a sentence:
public static ObjectList usedBefore (int minSize, int minOccur, String sentence, ObjectList sentences) { // Assume sentences is a list of sentence strings. // Returns a list of the words in sentence that are at least // minSize long and are used at least minOccur times in sentences. ObjectList words = mapLowerCase(filterSize(minSize, parseWords(sentence))); return wordsUsedBefore(minOccur, words, sentences); }
The usedBefore()
method depends on the following
methods, which you will define:
public static
ObjectList mapLowerCase (ObjectList L);
AssumesL
is a list of strings. Returns a list of strings whose elements are the lowercase versions of the strings inL
. Use the String instance methodtoLowerCase()
to find the lowercase version of a string.
public static
ObjectList filterSize (
int
wordSize, ObjectList L);
AssumesL
is a list of strings. Returns a list, in the same order, of the strings inL
whose lengths are at leastwordSize
characters. Use the String instance methodlength()
to measure the length of a string.
public static
ObjectList wordsUsedBefore (
int
minOccur, ObjectList words, ObjectList sentences)
Assumewords
is a list of word strings, andsentences
is a list of sentence strings. Returns the list of words inwords
that appear in at leastminOccur
sentences
.
For defining the methods above, it is also helpful to have the following auxiliary methods:
public static int
occurrences (String word, ObjectList sentences);
Assumesentences
is a list of sentence strings. Returns the number of sentences in whichword
appears.
public static boolean
isMember (String word, ObjectList sentence);
Assumessentence
is a list of words. Returns true if the word is in the sentence, false otherwise. isMember is case insensitive.
Here are test cases involving isMember, mapLowerCase and filterSize, using the following lists:
L4 = [ ] L5 = [You, are, not, LISTENING, to, me, !] L6 = [I, am, what, I, am, ;, you, are, what, you, are] L7 = [I, am, saying, that, my, goal, is, to, get, what, is, mine, .] isMember("I", L4) = false isMember("are", L4) = false isMember("you", L4) = false isMember("I", L5) = false isMember("are", L5) = true isMember("you", L5) = true isMember("I", L6) = true isMember("are", L6) = true isMember("you", L6) = true isMember("I", L7) = true isMember("are", L7) = false isMember("you", L7) = false mapLowerCase(L4) = [ ] mapLowerCase(L5) = [you, are, not, listening, to, me, !] mapLowerCase(L6) = [i, am, what, i, am, ;, you, are, what, you, are] mapLowerCase(L7) = [i, am, saying, that, my, goal, is, to, get, what, is, mine, .] filterSize(3, L4) = [ ] filterSize(4, L4) = [ ] filterSize(5, L4) = [ ] filterSize(3, L5) = [You, are, not, LISTENING] filterSize(4, L5) = [LISTENING] filterSize(5, L5) = [LISTENING] filterSize(3, L6) = [what, you, are, what, you, are] filterSize(4, L6) = [what, what] filterSize(5, L6) = [ ] filterSize(3, L7) = [saying, that, goal, get, what, mine] filterSize(4, L7) = [saying, that, goal, what, mine] filterSize(5, L7) = [saying]
Suppose we define testSentences
as a list of the
following sentences:
[Last night I had many dreams., I pursue my dreams., In my dreams, I win the lottery., I like the night., You are helpful. ]
Further suppose that we define testWords
as a list of
the following words:
[Last, night, I, had, many, dreams]
Then here are some test cases involving occurrences()
and wordsUsedBefore()
:
occurrences("I", testSentences) = 4 occurrences("dreams", testSentences) = 3 occurrences("night", testSentences) = 2 occurrences("lottery", testSentences) = 1 occurrences("cat", testSentences) = 0 wordsUsedBefore(1, testWords, testSentences) = [Last, night, I, had, many, dreams] wordsUsedBefore(2, testWords, testSentences) = [night, I, dreams] wordsUsedBefore(3, testWords, testSentences) = [I, dreams] wordsUsedBefore(4, testWords, testSentences) = [I] wordsUsedBefore(5, testWords, testSentences) = [ ]
DoctorAnswers.class
while writing your
definitions.DoctorOpsTest.html
applet to test your
methods. Also test your changes in Doctor.html
. (The
probabilistic behavior of the doctor makes such tests somewhat
tedious.)As you have seen on your assignments, BuggleWorld, TurtleWorld, and PictureWorld all allow the creation of very interesting patterns, especially with the introduction of recursion. For this challenge, we want you to use one (or more) of these worlds to create a picture or pictures that you find interesting. We will make a web page to exhibit all of the pictures exhibited. We will award extra credit of up to three problem set points for your picture(s). The amount of extra credit given will depend on the creativity, artistry, and technical expertise exhibited by your picture(s).
To begin this problem, start with a copy of folder for one of thes microworlds that we have used in a previous problem set (e.g., BagelQuilt from PS5 for BuggleWorld; Sierpinski from PS5 for TurtleWorld; Patchwork from PS6 for PictureWorld). Adapt the folder to your needs -- add or change code within existing files, or add new files of your own. (Make sure to add any new files to the project file). Don't hesitate to ask questions if you need help implementing your picture!
To submit extra credit work on this problem: