CS1110    Spring 2010   Assignment A1    
Submit on the CMS by midnight on Saturday, 13 February
Monitoring Rhinos

Endangered species

Website http://msnbc.msn.com/id/10877076/ says that, "the rhinoceros population has declined by 90 percent since 1970, with five species remaining in the world today, all of which are endangered. The white and black rhinos are the only species left in Africa... . " Lately, Kenya (with less than 500 rhinos left!) relocated 33 rhinos to Meru National Park, where they hope to protect them from poachers. Poachers kill the rhinos for their horns.

Rhinos are not the only endangered species. Web page http://www.redlist.org/ will tell you that the number of endangered vertebrates (mammals, birds, reptiles, amphibians, and fishes) grew from 3,314 in 1996/98 to 5,188 in 2004. Of the 22,733 evaluated species 23% were endangered. See http://www.worldwildlife.org/endangered for more info on endangered species. Some of the rhino pictures in this assignment were downloaded from www.birdingafrica.net.

When an animal population is small, the animals can be monitored. Sometimes they will be captured and tagged. Some tags emit a signal, so that one can track the animal. Even in populated places, animals are tagged. Here in Ithaca, one can see deer with tags on their ears wandering in the fields. Gries sees them often in his back yard near Community Corners.

This assignment is the first of two that, together, illustrate how Java's classes and objects can be used to maintain data about a collection of things —like individual rhinos in a park. Read the whole handout before you begin to do the assignment. For this assignment, you will design and implement a class Rhino, which is used by to keep track of rhinos, and a class RhinoTester, which is a JUnit class to test the methods of class Rhino. Pay careful attention to the order in which you write and test class Rhino. Follow the instructions given below in order to complete the assignment as quickly and efficiently as possible.

Learning objectives

Iterative grading feedback (revise-and-resubmit cycle)

To help ensure that the learning objectives above are met, we will engage in an iterative feedback process. If an objective has not been met, we will give you feedback so you can update your code and resubmit it. This process will ensure that every student completely masters this material. We will look at your code in several steps.

1. If the field specifications, javadoc specifications, or formatting are not appropriate, we will ask you to fix them and resubmit.

2. If the field and javadoc specs are ok, we will look at your test cases. If they are inadequate, we will ask you to fix them, test your program again yourself with the new cases, and resubmit.

3. If the test cases are adequate, we will test your program with our own testing program. If there are errors, we will ask you to correct them and resubmit.

Rhinos' DinnerUntil mastery is achieved, your "grade" on the CMS will be the number of revisions so far, so that we can keep track of your progress. Don't be alarmed if you see a "1" for the assignment! The assignment will be considered completed when it passes all three steps outlined above.

Your chances of completing the assignment in 1 or 2 rounds will be increased by reading this handout carefully and following all instructions. Many requests for resubmission are caused not by confusion about programming but simply by not following instructions.

Working with a partner

You may do this assignment with one other person. If you are going to work together, then, as soon as possible, get on the CMS for the course and do what is required to form a group. Both people must do something before the group is formed: one proposes, the other agrees. If you do this assignment with another person, you must work together. It is against the rules for one person to do some programming on this assignment without the other person sitting nearby and helping. You should take turns "driving" —using the keyboard and mouse.

HELP

If you don't know where to start, if you don't understand testing, if you are lost, see someone immediately —Gries, a TA, a consultant. Do not wait. Over half the class never programmed before, and it is reasonable to expect that you may not fully grasp everything immediately. But a little one-on-one help can do wonders.

How to do this assignment

Read the whole assignment before starting.

Develop and test classes Rhino and RhinoTester in the following incremental, methodologically sound way. This will help you complete this (and other) programming tasks quickly and efficiently. If we detect that you did not develop it this way, we may ask you to start from scratch and do a different assignment.

  1. Make sure your preferences in DrJava are set to indent 4 spaces (if necessary, use menu item Preferences->Miscellaneous and change the first entry, "Indent Level", to 4). This makes understanding the structure of a program much easier. Also, as you work, break long lines in your code (including comments) so that the reader does not have to scroll right to read them.
  2. Start a new directory on your hard drive to contain the files for this project. (Create a new directory for every assignment in this course.) In DrJava, write a skeleton class definition for class Rhino, with no methods or fields in it, and save it in the new directory, and compile it.
  3. Next, in class Rhino, declare the following fields (you can choose the names), which are meant to hold information describing a single rhino. Make these fields private and properly comment them (see the "The class invariant" section below). Compile often as you proceed. An instance of class Rhino maintains information about a particular rhino, using these fields, which should be private:

Here are some details about these fields:

The class invariant. Recall that comments should accompany the declarations of the fields to describe what each field means, what constraints hold on the fields, and what the legal values are for the fields. For example, for the gender field, state in a comment that the field represents the gender and it must be 'F' (for female) or 'M' (for male). The collection of the comments on these fields is called the class invariant.

Whenever you write a method (see below), look through the class invariant and convince yourself that the class invariant still holds when the method terminates. This habit will help you catch or prevent bugs later on!

  1. Start a new JUnit class, calling it RhinoTester.Safari
  2. For each of the following groups of methods, do the following. (1) Write the Javadoc specifications for each method in that part. (2) Write the methods. (3) Unless otherwise specified, write one test procedure in class RhinoTester and add test cases to it for all the methods in the group. (4) Test the methods in the group thoroughly. Do not go on to the next group of methods until the group of methods you are working on is thoroughly tested and correct.

    The descriptions below, while informal, represent the level of completeness and precision we are looking for in your Javadoc comments. In fact, you may (should) copy and paste these descriptions to create the first draft of your Javadoc comments. If you do not cut and paste, please adhere to the conventions we use —such as using the prefixes "Constructor: ...", or "= ..." (the equals sign), or double-quotes to enclose an English boolean assertion. Consistency in such things makes it easier for us to communicate.

    The names of your methods must match those listed below exactly, including capitalization. The number of parameters and their order must also match. Our testing will expect those method names and parameter types, so any mismatch will cause our testing to fail, meaning that you will have to resubmit. Parameter names are not tested —you can change the parameter names if you want.

    Thorough testing involves the following principles. The more interesting or complex a method is, the more test cases you should have for it. What makes a method 'interesting' or complex can be the number of interesting combinations of inputs that method can have, the number of different results that the method can have when run several times, the different results that can arise when other methods are called before and after this method, and so on.

    For this assignment, you may not use if-statements; this constraint will help you see that there are often more elegant alternatives to if-statements and will give you practice with boolean expressions. Submissions containing if-statements will be returned for you to revise.

    Also, for this assignment, do not write code that checks whether preconditions hold. It is the responsibility of the caller to ensure that the preconditions are met. This means, for example, that you should not worry about (or write code that checks for) invalid gender.

    However, in general, you do need to check for "bad" conditions that aren't ruled out by preconditions. For example, if an argument may be null according to the specification, your code should check that the argument is not null before trying to perform an operation on it (otherwise, your code can crash due to a "null pointer exception"). There are no such examples in this assignment, but keep this in mind for the future.

    Group A: The first constructor and all the getter methods of class Rhino. When you write a constructor body, be sure that all the fields are set to appropriate values, e.g. what should the tag field contain? The main purpose of the testing procedure is to make sure that the constructor has set the fields properly. In order to do this, it must call the getter methods to retrieve the values of the fields.

Constructor Description
Rhino(String name, int month, int year, char gender) Constructor: a new Rhino. Parameters are, in order, the name of the rhino, the month and year of birth, and its gender. The new rhino is not tagged, its parents are not known, and its gender is 'F' or 'M'. It has no children.

 

Getter Method Description
getName() = the name of this rhino. (a String)
getGender() = the gender of this rhino ('M' for male, 'F' for female). (a char)
getMOB() = the month this rhino was born in the range 1..12. (an int)
getYOB() = the year this rhino was born. (an int)
getMother() = the name of (the folder containing) this rhinos’s mother. (of type Rhino)
getFather() = the name of (the folder containing) this rhino’s father. (of type Rhino)
getTag() = this rhino’s tag number (-1 if it has not been assigned one) (an int)
getNumberOfChildren() = the number of rhinos that have this one as a parent. (an int)

Group B: The second constructor. The purpose of the test procedure for group B is to make sure that the second constructor fills in all fields properly. To do that, the procedure will have create two Rhino objects (the mother and father) using the first constructor and then one Rhino object using the second constructor.

Constructor Description
Rhino(String name, int month, int year, char gender, Rhino father, Rhino mother, int tag) Constructor: a new Rhino. Parameters are, in order, the name of the rhino, the month and year of birth, its gender, its father, its mother, and a tag. It has no children. Precondition: father is not null and its gender is 'M'; and mother is not null and its gender is 'F'. The tag is >= 0.

Group C: the setter methods. When testing the setter methods, you need use the getter methods. Good thing you already tested the getters thoroughly!

Setter Method Description
setName(String s) set the name of this rhino to s.
setGender(char g) set the gender of this rhino to g ('M' for male, 'F' for female).
setMOB(int m) set the month this rhino was born to m in the range 1..12
setYOB(int y) set the year this rhino was born to y.
setMother(Rhino mom) set this rhino's mother to mom.
Precondition: this rhino's mother is null and mom is not null.
setFather(Rhino dad) set this rhino's father to dad.
Precondition: this rhino's father is null and dad is not null.
setTag(int tag) set this rhino’s tag number to tag.
Precondition: tag is non-negative and has not been assigned to another rhino.

It is possible for Rhino r1 to be r2's mother, and visa versa, at the same time. We do not check for such strange occurrences.

In writing methods setFather (and setMother), be careful! If F is becoming the father of this Rhino, then F has one more child, and its field that contains its number of children has to be updated accordingly.

Last check before submission

When you think you are ready to submit, in DrJava, go over the following points.

  1. Click the javadoc button to create html pages that contain the specfications of your two classes. Look carefully at all the specs of the methods in class Rhino and make sure they are appropriate. Can you understand precisely WHAT a method does from its specification? If not, the specification is no good and must be changed. After doing this, place a comment at the top of class Rhino, stating that you looked at the javadoc specifications and you believe that they appropriate.
  2. Make sure your program does not contain if-statements.
  3. Make sure your program is properly indented. To indent it properly, select everything (menu item Edit -> Select all) and hit the tab key (or use menu item Edit -> Indent lines).
  4. If you are working with a partner, make sure the group has been formed before you submit the assignment.

Submitting the assignment

Submit classes Rhino and RhinoTester on the CMS. Make sure you submit .java files. Do not submit a file with the extension/suffix .java~ or .class. You can ensure that you do this by setting your preferences in your operating system so that extensions always appear.