CS100J Fall 2002
Due in Lecture, Thursday, October 3
In this assignment, you implement an interactive database that contains
information about people: their names, sex, and friends. Users enter new information and make queries
by typing commands.
The program will be
written in an object-oriented style (using classes,
objects, and methods). We provide some code, and you must complete the program
by adding new code, some of which involves adapting the supplied code.
The input consists of zero or more commands (other than command q) followed by command q. The
commands are:
b name
If
there is not already an existing person named name, create a new
b(oy) named name; otherwise print an appropriate error message.
g name
If
there is not already an existing person named name, create a new
g(irl) named name; otherwise print an appropriate error message.
f name1 name2
If
name1 and name2 are people who already
exist, and name1 has no more than one friend, and name1
is not name2, record the fact that name1
considers name2 a f(riend); otherwise, print an
appropriate error message.
u name1 name2
If
name1 and name2 are people who already
exist, and name1 considers name2 a friend,
remove any record of that fact; otherwise print an appropriate error message.
? name
If
there is a person named name, display current information about that
person; otherwise print an appropriate error message
p
List
information about the entire p(opulation) in the database.
q
q(uit).
Assume that the input is
well formed, i.e., commands have appropriate numbers of parameters. The notion of “appropriate error message” is
illustrated by the example in the Section 4, Sample Session.
Information about a particular person in the database should be displayed
all on one line. The output format for
a person with two friends is
name:n; sex: s; friends: f1 and f2
the output format for a person with one friend is
name:n; sex: s; friend: f1
and the output format for a person with no friends is:
name:n; sex: s; no friends
where each n, f1, or f2 is a name,
and s is either “male” or “female”. Each
command is prompted by the text "> ".
The database starts out empty. Here is a sample session:
> b tom
> g sue
> f tom sue
> f tom sue
ERROR: tom already considers
sue a friend
> f tim bettysue
ERROR: No such person as tim
ERROR: No such person as
bettysue
> b tim
> f tom tim
> b paul
> f tom paul
ERROR: tom already has two
friends
> f sue tom
> p
name:tom; sex:male; friends:
sue and tim
name:sue; sex:female; friend:
tom
name:tim; sex:male; no friends
name:paul; sex:male; no
friends
> f tim sue
> u tom tim
> u tom tim
ERROR: tom does not consider
tim a friend
> f tim tim
ERROR: You can’t be your own
friend
b sue
ERROR: There already is a
person named sue
> p
name:tom; sex:male; friend:
sue
name:sue; sex:female; friend:
tom
name:tim; sex:male; friend:
sue
name:paul; sex:male; no
friends
> q
Your program must be implemented
as two separate classes --- class Person
and an application class Program3
that is a client of class Person. A specification
is not merely a hint for how you might solve the problem; it is a requirement
that must be followed.
Class Person maintains a database of people. It does not output any error messages
(except for "Person: too many.").
Rather, it communicates with its client via return codes, and lets the
client (which is in charge of the user interface) emit appropriate messages.
Class Person offers its clients exactly the public methods listed below, and no others. If you
define any other auxiliary methods, they should be private.
All fields of class Person, including any new
fields that you add, should be private.
public Person(String s, Boolean m) Construct a Person with name s and maleness m, e.g.,
evaluation of expression
new
Person("tom", true)
creates a male Person named "tom". The database can store records of up to 100
people. Each attempt to create more
than 100 people is ignored and outputs the message "Person: too
many.".
public static
int numberOfPeople() Return the number of Person objects in the database.
public static
Person intToPerson(int i) Return the ith Person to have been created in the
database. Return null if there is no such Person.
public
String toString() Return the string representation of a Person in the format defined in
Section 3, Output.
public int
newFriend(Person p) Return a non-zero integer error code if
argument p is not valid for a Person; otherwise, make p the Person’s friend, and return 0.
public boolean removeFriend(Person
p) Return false if p is not the
Person's friend; otherwise make p no longer the Person's friend, and return
true.
public
String name() Return the name of a Person.
public
boolean male() Return true if a Person is male and false otherwise.
A partial implementation of class Person is given below.
Do not change either the constructor Person or the methods numberOfPeople and intToPerson. In fact, they use some Java that you are not
expected to understand yet. However,
you do not need to understand the implementation; it is sufficient just to
understand the specifications. You will have to modify method toString.
import java.io.*;
public class Person
{
// max # of people in database.
private final static int maxN = 100;
// folks[0..n] are people in database.
private static Person[] folks =
new Person[maxN];
private static int n = 0;
private String name;
// person's name.
private boolean male; // person's maleness.
// Construct Person named s of
maleness m.
public Person(String s, boolean m)
{
name = s;
male = m;
if ( n >= maxN )
System.out.println("Person: too many.");
else {
folks[n] = this;
n++;
}
}
// # of people in database.
public static int numberOfPeople()
{
return n;
}
// i-th Person in database.
public static Person intToPerson(int i)
{
if (i < 0 || i >= n) return null;
else return folks[i];
}
// string representation of a Person.
public String toString()
{
String result;
result = "name:"+ name + "; ";
if (male)
result = result + " sex:male;";
else
result = result + " sex:female;";
return result;
}
}
Class Program3 reads commands and processes them. At a minimum, it should contain the following methods:
public static void
main() Process all commands.
public static
void showPeople() Display every person in the
database.
public static
Person stringToPerson(String name) Return a reference to the Person named name, or null if there is no
such person.
However, you should define other methods, as necessary, to avoid writing redundant and duplicate code.
Although it is a good idea to think through the program thoroughly before
sitting down at a computer, it is an equally good idea to enter the program
into the computer a little at a time, and test each little bit thoroughly
before moving on. Careful incremental testing will save you time. Although it is
tempting to enter a lot of code all at once, this is not a win because it makes
it harder to track down errors since you must deal with more untested code. You
are urged to enter and test your program a little at a time. Although you are free to break the problem
into whatever steps you would like, we suggest the following:
Step 0. Create a project using the Java Application
stationery. Rename class TrivialApplication to Program3, and
set the CodeWarrior target accordingly.
Run the program to confirm that you have set the target correctly.
Step 1. Copy the initial
implementation of class Person into a
file named Person.java and include it in your project. Let the body of the main of Program3 be
System.out.println(new
Person( "tom", true));
Run the program, which should output
name:tom;
sex:male;
See the discussion on toString
below if you don't understand why this code should produce the given output.
Step 2. Implement a static method showPeople() in class Program3 that
prints out a line for each Person
object. Change the body of Program3’s main to:
new Person( "tom", true);
new Person( "sue", false);
showPeople();
Compile and run the program, which should output
name:tom; sex:male;
name:sue;
sex:female;
Step 3. Implement the application’s
command loop, and commands b, g, p, and q. For
this step, ignore the possibility of errors, e.g., assume no name is given
twice. You should now be able to support the following sample session:
> b tom
> g sue
> p
name:tom; sex:male;
name:sue; sex:female;
>
q
Step 4. Implement a method name()to provide read-only access to the private name field of a Person object.
Then implement method StringToPerson in your Program3 application class (not in class Person) that returns a reference to a named
person. This method must search through
the database to find a person with a given name. Assume that all names in the database are unique. Use method numberOfPeople to know how many people there are in the
database, and method intToPerson(i) to obtain a
reference to the ith person in the database.
Then use stringToPerson to implement
command ?.
Step 5. Implement method personExists and use it to add error checking for the b and g commands.
Step 6. Implement the
remaining commands.
7. Useful Facts
·
Method readString() of class TokenReader
reads the next word of the input, and returns it as a String.
·
Let s and t
be two String expressions.
The boolean expression
s.equals(t) is
true if s and t are the same sequence
of letters, and is false otherwise. In contrast, the boolean expression
s==t is true if and only if s and t both refer
to the same String object.
·
Method System.out.flush() forces the display of a partial line of output,
e.g., “> ”.
·
Every object has a
public method toString() for converting it
to a String. For example, if p is a variable containing a reference to an object, then System.out.println(p); is a legal statement: Java automatically calls p.toString() to get the string representation of p to print without your mentioning toString explicitly. If there is no definition of a
public method toString(), some default text
is printed.
It is good practice for each class to define an appropriate version of toString() for displaying its objects. The initial version of class Person has a definition of toString() that you should extend as you change the class.
·
A
printout of the final version of the two classes.
·
A
printout of a sample session that demonstrates the correctness of your
implementation.
Programs are due at the end of lecture on the day given
above. No late assignments will be accepted. Programs will not be accepted in Carpenter on the day
they are due, but you may hand in your program to a consultant in Carpenter
until the close of business the day before
the program is due. You must give the program to a consultant
personally. Do not just leave it on
a desk.
Program listings must be printed. Output must be printed and be exactly as produced by the program handed in. All printouts must be separate pages, without perforated edges, and stapled together in order with a cover page obtained from the web. The first comment in the program must contain your (and your partner's) name, Cornell ID#, section's day & time & instructor, and the assignment number. These cannot be written in by hand. You (both) must sign the first page of the program.