CS100J Fall 2000
Due in Lecture, Thursday, September 28
In this assignment, you implement an interactive database that contains
information about people: their names, sex, parents, spouses, and
children. 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
Create
a new b(oy) named name.
g name
Create
a new g(irl) named name.
m name1 name2
Record
the m(arriage) of name1 and name2
s name1 name2
Create
a s(on) named name2 one of whose parents is named name1 . If name1
is male, he is the father and his significant other is the mother.
Conversely, if name1 is female, she is the mother and her
significant other is the father.
d name1 name2
Create
a d(aughter) named name2 one of whose parents is named name1 . See
command s for mother/father determination.
? name
Display
information about the person named name.
p
List
information about the entire p(opulation) in the database.
q
q(uit).
Assume that the input is
well formed, i.e.,
(1) Commands have appropriate numbers of parameters.
(2)
No social
conventions need be imposed.
[Assume that the names
of all people are unique, i.e., you will never be asked to enter two people
into the database who have the same name.]
Information about a particular person in the database should be displayed
all on one line. The output format for
a married person is:
name:n sex:s mom: n dad: n other: n kids: k
and the output format for an unmarried person is
name:n sex:s mom: n dad: n kids: k
where each n is a name, s is either male or female, and k is a list
of 1 or more names, or the word none.
Each command is prompted
by the text "> ".
The database starts out empty. Here is a sample session:
> b tom
> g sue
> m tom sue
> d tom sarah
> s sue joe
> p
name:tom sex:male other:sue kids: joe sarah
name:sue sex:female other:tom kids: joe sarah
name:sarah sex:female mom:sue dad:tom kids: none
name:joe sex:male mom:sue dad:tom kids: none
> q
Notice
that both tom and sue have two kids, joe and sarah.
Your program must be implemented
as two separate classes --- class Person and an application class that
is a client of class Person.
Class Person offers its clients
exactly the public methods listed
below, and no others. All new fields that you add to class Person 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 "over limit". [Assume that no person with name s
has previously been created.]
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 is there is no
such Person.
public String toString() Return the string
representation of a Person in the format described above.
public static void child(Person mom, Person dad,
String s, Boolean m) Construct a Person with name s and maleness m, and
record that the "mother" and "father" of the person are mom and dad respectively. [Assume that
mom and dad are married, and that it
is acceptable for them to be called the "mother" and
"father" of the child.]
public static void marry(Person p1, Person p2) Record the information that p1 and p2 are married. [Assume p1 and
p2 are distinct people, neither is already married, and that it is acceptable
for them to be married to one another.]
public String name() Return the name of a Person.
public boolean male() Return true if a Person is male and false otherwise.
public Person other() Return the "significant
other" of a Person, i.e., the person to whom the Person is married.
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.)
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("over
limit");
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;
}
}
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 1. Create a project using the CUCS Java Application
stationery. Copy the initial implementation
of class Person into a file named Person.java and include it in your project. Let the body of the application's main be
System.out.println(new Person( "tom", true));
Compile and 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 your
application class (not in class Person) that prints out a line for each Person object. Change the body of your application'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 command loop, and commands b, g, p, and q.
You will find it useful to know these facts:
(1)
method readString() of class TokenReader reads the next
word of the input, and returns it as a String.
(2)
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.
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
static Person stringToPerson(String name)
in your application class (not in class Person) that returns a reference to the Person named name. This method must search through the database
to find a person with name name. Assume
that all names 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 marry (in class Person), command m, and extend toString appropriately.
Step 6. Implement method child (in class Person), commands s and d, and extend toString appropriately --- temporarily assuming
that no one ever has more than one child.
Step 7. Extend your code to support couples with more
than one child. A simple way to do this is to let each Person have a sibling field that refers to
his or her next "older" sibling, if any, or null. The next "older" sibling of a new
child is just the current "youngest" child of one of the child's
parents at the time the child is created.
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 class Person and a
printout of the application class.
·
A printout of a
sample session that demonstrates the correctness of your implementation. Note that the sample session given above is
far from adequate.
Optional. Please feel free
to write an elaborate private version of the assignment for additional practice
and your own enjoyment, but please hand in a program that does not exceed our specifications. For
example, throughout the write-up, various assumptions have appeared in square
brackets. You may wish to consider
relaxing one or more of those assumptions in a manner you deem appropriate. Relaxing some assumption may lead you to
detect and report usage errors, whereas relaxing other assumptions may lead you
to generalize the functionality of the database.
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 or
table.
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. 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.