CS 1401, Exam #4, 9:30 am version

Date: Friday, November 30, 2007
Name (please type legibly, ideally in block letters): ______________________________________________________________________

On this same day in 1974, anthropologists discovered the skeleton of Lucy, a 3.2 million years old human ancestor. Lucy was only 1.1 m tall and weighed 29 kilograms, but her bones showed that she walked erect. Her discoverers, Professor Donald Johanson and his student Tom Gray, named her after the famous Beatles song "Lucy in the Sky with Diamonds". Since then, many other human skeletons have been discovered. Let us help the anthropologists process the resulting data.

1-3. Let us start helping the anthropologists.

  1. Define a class HumanAncestors in which each object has three parameters: age, height, and weight. Include a constructor method, accessor methods, mutator methods, methods which compute and return the ancestor's height in inches and weight in pounds, and an appropriate toString method. Reminder: 1 inch is 2.54 cm, and 1 pound is 0.454 kg.

  2. In the main method, define Lucy as a new object of this class, and compute and print her weight in pounds (should be approximately 64 pounds). Use scientific notations to describe Lucy's age.

  3. Trace your code from Problem 2 step-by-step.


Solution:

public class HumanAncestors{
  protected double age;
  protected double height;
  protected int weight;
  public HumanAncestors(double aage, double aheight, int aweight)
    {age = aage; height = aheight; weight = aweight;}
  public double getAge(){return age;}
  public double getHeight(){return height;}
  public int getWeight(){return weight;}
  public void setAge(double aage){age = aage;}
  public void setHeight(double aheight){height = aheight;}
  public void setWeight(int aweight){weight = aweight;}
  public double heightInInches(){return height * 100.0 / 2.54;}
  public double weightInPounds(){return weight / 0.454;}
  public String toString(){return "This ancestor was " + age +
    " years long, was " + height + " tall and weighed " + weight + " kg.";}
}

public static void main(String[] args){
  HumanAncestor lucy = new HumanAncestor(3.2e8, 1.1, 29);
  double weightLb = lucy.weightInPounds();
  Systems.out.println(weughtLb);
}

Tracing: first, we call a constructor method:

 -----------------
|  -------------  |
| |   3.2e8     | |
|  -------------  |
|      aage       |
|  ------------   |
| |    1.1     |  |
|  ------------   |
|   aheight       |
|  ------------   |
| |    29      |  |
|  ------------   |
|    aweight      |
|-----------------|
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
 -----------------
  HumanAncestors

this method generates a new object

 -----------------
|  -------------  |
| |   3.2e8     | |
|  -------------  |
|       age       |
|  ------------   |
| |    1.1     |  |
|  ------------   |
|    height       |
|  ------------   |
| |    29      |  |
|  ------------   |
|     weight      |
 -----------------
     lucy

after applying the method weightInPounds to this object, we get

 ----------
|   64     |
 ----------
  weightLb

4. When we defined our class in Problems 1-3, we did not include the names of the anthropologists who discovered the skeleton. Define a subclass of the class HumanAncestors which contains a new field: a string discoverers which contains these names. In the main method, define a new object corresponding to Lucy.


Solution:

public class HumanAncestors2 extends HumanAncestors{
  private String discoverers;
  public HumanAncestors2(double aage, double aheight, int aweight,
    String adiscoverers){super(aage, aheight, aweight);
    discoverers = adiscoverers;}
  public String getDiscoverers(){return discoverers;}
  public void setDiscoverers(String adisc){discoverers = adic;}
}

HumanAncestors2 lucy = new HumanAncestors2(3.2e8, 1.1, 29,
  "Donald Johanson and Tom Gray");

5. Write a method that, given an array of objects of type HumanAncestors (defined in Problems 1-3), computes the height of the tallest ancestor from this array.

Solution:

public double tallest(HumanAncestors[] input){
  double tallestSoFar = input[0].getHeight();
  for (int i = 1; i < input.length; i++){
    {if (input[i].getHeight() > tallestSoFar)
      {tallestSoFar = input[i].getHeight();}
    }
  return tallestSoFar;
}

6. To relax, the anthropologists decided to play a game. Each of them selects an integer -- a predicted weight of the next ancestor. Then, they compute the average of these guesses. Whoever's number is the closest to this average wins. The guessed numbers are stored in a file game, line by line: Write a code that reads the values line by line, adds them up, computes the number of lines, and then computes the average. Use try-catch block to produce the meaningful error message when we are trying to divide by 0.


Scanner read = new Scanner(new FileReader("game"));
int guess;
int total = 0;
int number = 0;
while(read.hasNext()){
  guess = read.nextInt{};
  total += guess;
  number++;
}
try{
  int average = total / number;
  }
catch(ArithmeticException e){
  System.out.println("The file was empty, so we could not compute "+
    "the average.");
  }