Statistician (Statistician)
CSCI 162 - Spring 2019

Due: Wednesday Feb 6th at 11:59pm

Goals
- to practice reading specifications carefully
- to understand the importance of good data representation
- to understand the need for each method to maintain the class invariant

Overview
This program is a solution to problems 2 and 3 of Chapter 2 of Main (p. 95), but if there are any conflicts between the book and this handout, rely on the handout.

You should create a Statistician class that maintains and reports information about a series of real numbers (type double in Java). Methods provided include the length of the series, the sum of all numbers, the mean, and the smallest and largest values. There is also a reset feature so that you can start a fresh series. Note that, unlike the book, we are not keeping the most recent value.

Problem 3 has you provide a union method that adds the contents of this statistician and another statistician and returns a new statistician as if all the values from the two had been put in the new one. This is like the + operator. It is good style to implement a += operator whenever you implement +. We'll call that add where the values of a statistician are added to an existing statistician. Doing that first makes the implementation of union easier and more efficient. Implement those after you have the rest working. That portion of the assignment counts for 15 of the 100 points.

We are providing you with a detailed outline for the statistician class, two console user interface classes to test the statistician, and a JUnit test class to test the statistician automatically. We'll discuss JUnit in another handout. The class is in Statistician.java which has extensive comments describing what each method does. The ConsoleMenuUI class lets you add numbers to the statistician and ask about its state. It is described further below.

The Representation
At first it might seem necessary to keep all the numbers in the series. But it is not. You should not keep all the numbers because you do not know how many will be input. Instead, the instance/member variables will hold just enough information to be able to provide the features of the class.

Suppose the input is the series: 5 15 10. You can easily see the length of the series, the sum, the smallest value, and the largest value. The mean is the sum divided by the number of values. What changes when the value 30 is added to the series? You didn't need the earlier values to provide the needed information.

Therefore, four instance variables are enough to hold the state of the statistician class. Near the beginning of the class file, they are listed as: sumOfValues, count, smallestValue, and largestValue. Think about how those instance variables hold the state of the class. We have included a set of rules, the class invariant, that state what should be true of the instance variables outside the method. For example, if one or more numbers are in the series, smallestValue holds the smallest value in the series.

Understand that class invariant. It should be true after you construct the class object. Every method can rely in its being true. Every method should ensure that it is true when the method ends.

The Tester Program
The ConsoleMenuUI class uses the Statistician class. It is an example of a driver program that provides an easy way to test the class's actions. It allows the user to create a statistician and then take the following actions:

  q: quit the testing program
  ?: print this menu
  +: add a value to the statistician
  p: print a summary of the statistician values
  r: reset the statistician
  u: runs the union tests which also test clone and equals
You can test your class with this driver. You do not write it. It runs, but doesn't do anything useful, as is.

Steps for Completing the Assignment
Copy code and create project. Copy the ~rogers162/labs/Statistician directory from your instructor. Create a new project. There are four files in that directory:

Make all of your changes in Statistician.java. Do not change method names.

Start implementing the methods incrementally. Implement each of the methods starting with the constructor and reset. Think about what happens in the reset. You can call that from the constructor. Insert is probably the hardest one to do. Maybe do the easy ones (the getters) that return simple values.

You shouldn't do all the functions at once. As you implement each function, think about which instance variables it needs to access or change. Think about the state of the statistician and how it changes. Think of the class invariant as a checklist of what must be done to the instance variables to keep the state of the class correct.

When you have enough implemented to do some tests, run it. It will be boring until you implement the insert method.

Carefully test the class focussing on the functions you have implemented most recently and avoiding those you haven't completed yet.

Implement the other methods. Continue building methods until you have all of them except add and union implemented. Refer back to your class invariant to be sure it is true whenever you finish a member function.

Implement add and union. For the add method, you are implementing the actions for the statistician that is being assigned to (the c in c += a which is called in Java as c.add(a)). If you refer to count, that is c's count. To refer to a's count, use addend.count. Note that you have access to a's instance variables. Carefully consider what happens if a is empty, c is empty, or neither is empty. Test and implement the easy ones first. Carefully consider the properties the sum statistician should have. Consider all the instance variables. Getting it right takes some calculation.

When you have the add working, you can implement the union by making a clone of this statistician, using add on the clone with the other statistician, and returning the combined statistician.

Note that union and add can both throw a NullPointerException. However, that will happen automatically. You do not need to test for or throw that.

Test the program and submit. Now that you have implemented all the member functions, check them out more thoroughly using the various options in ConsoleMenuUI. Understand how to run the JUnit tests and do that. We will discuss that separately. Run several detailed test cases.

Submit
When you are satisfied that your program works as expected, submit your directory as Statistician. Only your Statistician.java file will be submitted.