Analyzing Age and Weight
In this project you will combine the use of arrays and objects to perform some analysis of the age and weight relationships among a group of people. You have been contracted to write a program into which data about people, including their ages and weights, will be entered. As output the program will provide two listings of people who have particular characteristics within the group:
People who are both above the average age and above the average weight.
People who are both below the average age and below the average weight.
The program will ask the user for the number of people who need to be added to the list. It will then get the name, age, and weight data for that number of people. After the list has been entered it will analyze the data and generate lists of the people who fall into each of the categories listed above. If no one falls into one of these categories the program will just report "NONE" in place of the listing of people. The order that people appear in the lists is not important. Prior to displaying the two listings it will display the average age and average weight.
The following technical characteristics are requirements for the program:
The Person class from the previous program will be modified to include a weight field and the getter and setter for it.
The Person objects will be stored in an array.
Once the array has been created whenever the number of people in the array is needed by the program the length attribute will be used to provide that information.
The size of the array will the number of people to be added to the list.
A method named loadData() will be created to load all the data from the keyboard into a Person object. This method will take two parameters: a reference to the object to be loaded with data and a reference to a Scanner object to be used for input of the data.
A template program, AgeAndWeight.java is attached below. It provides some structure and guidance for the development of this program. You will use a modified version of the Person class developed for the previous project as the Person class for this project. I will make the sample solution for Person.java available to you as soon as you turn in the homework but you can alternatively use your own if you want to.
*****NOTE***** it is necessary to add a default constructor to the Person class. (in addition to the existing constructor that sets the name components). OR create the new Person objects inside the loadData() method and return the newly created and loaded object instead of receiving an empty object as a parameter and loading the data into it that will be OK. In that case Person would not have to have a default constructor and loadData() would receive only the Scanner object as a parameter. In the second case it is OK for Person to have a default constructor if you want one and you can use it instead of the parameterized constructor to create the new object if you want to and then load all the data into the object with the setters.
The following is a sample run of the program. User input is in bold blue text. Your input/output format should duplicate this as closely as possible.
Enter the number of people in the group: 4
Enter the data for the 4 people:
First name: George
Middle initial: M
Last name: Jones
First name: Elizabeth
Middle initial: H
Last name: Morton
First name: Alex
Middle initial: B
Last name: Butler
First name: Amy
Middle initial: C
Last name: Rockwell
Average age: 37.8
Average weight: 161.0
People above average age and weight:
Morton, Elizabeth H.
Rockwell, Amy C.
People below the average age and weight:
Jones, George M.
Butler, Alex B.
The following is a second data set that you can use for testing along with the expected results:
Arnold K. Smith, 56 yrs, 136.2 lbs
Joe S. Perez, 74 yrs, 136.0 lbs
Alice R. Styles, 17 yrs, 254.7 lbs
Rick E. Rudd, 23 yrs, 237.4 lbs
Average age: 42.5
Average weight: 191.1
People above average age and weight:
People below the average age and weight:
This solution requires creating modifying two Java classes: Person, AgeAndWeight. The Person class needs to have a new data member and associated getters/setters. The new data member is for storing a person's ...
This solution provides a complete Java program with arrays and objects. The primary class is a Person class. The main program creates an array of Person objects and does some basic statistics on the set of data.
Please do not use exception handling, not covered in this course. See note below.
Project 4 brings together all of the major concepts covered in the course in addition to providing some practice with string processing, file operations, and a little bit of object-oriented programming. In this project you will first study an existing, complete, working object-oriented program. After you have developed a good understanding of the existing program you will develop some modifications to it that make some important improvements.
The program in question is called SalesAwards.java which uses objects created from the SalesTeam and Person classes. You are already familiar with the Person class. The SalesTeam class uses Person objects to build up a model of a sales team consisting of any number of sales persons and their annual sales data for some number of years. The SalesAward main class creates an array of SalesTeam objects each of which represents one of the company's sales regions. It has the user load these objects with data for a selected time period and then it analyzes this data to determine which team had the highest total sales and which individual sales person had the highest total sales. This information is used to make awards to the highest performers.
Attached to this topic you will find the source code for these three classes and a Word document that contains detailed documentation of these classes. What you need to do in the first phase of this project is study the code provided and the documentation. Develop a good understanding of how this code works. You will need it in phase two of the project in which you will work on some modifications to make some improvements to it. Ask about anything you do not understand. You cannot move forward to make improvements if you do understand where you are beginning from.
Shortly I will post the instructions for the second phase which will include a specification for some updates to the SalesTeam class along with two complete, working main classes that use the upgraded SalesTeam class: A revised SalesAward class and a ListTeams class that generates a list of the teams and their team members. But you need to develop an understanding of the existing code first.
For those who are implementing the loadData() method for Project 4 as I described it note that you have to implement a default constructor in SalesTeam to make that work. Adding the default constructor is OK, of course. Actually you can add any additional methods you find useful as long as you implement the loadAllTeams() method as specified.
By now you should have studied the original version of the SalesAward and related classes. You should have a good understanding of the SalesTeam and SalesAward classes. You are already familiar with the Person class. Now what you need to do is update the SalesTeam class. Attached you will find the following three files:
This is a version of the SalesAwards class that is designed to use a new, upgraded version of the SalesTeam class. It will not compile with the old SalesTeam because the required method loadAllTeams() is not available in the old version. Your job is to create the loadAllTeams() method and add it to SalesTeam.java. Because you are adding a new method but not deleting or changing the existing methods the new version will work with the old version of SalesAward and any other programs that use the SalesTeam class. In other words, it is backwards compatible.
This is a second program that uses the new version of SalesTeam. It will display all of the teams and their members that are in the data file. It is provided for additional testing and to illustrate object re-use. The SalesTeam class can re-used in multiple programs. The work that went into creating it does not have to be duplicated. As long as each class that needs the SalesTeam functionality respects the standardized interface that SalesTeam implements they will all be able to use the same SalesTeam class.
This is a data file that contains the data for a set of sales teams. When loadAllData() is called it is given a String as its only argument. The content of this string will be the file name of the file that contains this data. The structure of the file is described below.
The loadAllTeams( ) Method
Your primary job in this project, along with studying the existing classes to understand how they work, is to program the loadAllTeams( ) method. Its header will be as follows:
public static SalesTeam loadAllTeams( String fileName ) throws Exception
This method declares a sting variable fileName as its only parameter. This variable will be used to pass the name of the data file to the method. The job of the method is to open the data file and read its contents. Using the data it finds in the file it will create an array of SalesTeam objects and will load them with all of the data required. It will load the team names, the team members, and the sales data for each member. When it is finished it will return a reference to the SalesTeam that it created. It will implement code that "understands" the file structure of the sales team data files described below.
Notice that this method is declared as static. That means that it will be called using the class name instead of a SalesTeam object reference as would be the case with an instance method. See how the method is called in SalesAwards2. No SalesTeam object has to already exist for this method to be called. This is what is known as a factory method. It is essentially a factory that manufactures an array of SalesTeam objects using the input file to obtain the raw resources needed to populate the SalesTeam objects with data.
Although it is not an absolute requirement, for maximum credit on the project you will also implement the following method:
public boolean loadData( Scanner input )
This is an instance method that declares as its only parameter a Scanner reference. It will use this Scanner to load all of the data that is required to populate one SalesTeam object assuming that the Scanner is positioned to read the team name of the next team to be loaded in the standard sales team data file format. Because this is an instance method it will require that a SalesTeam object have already been created. The creation of the SalesTeam objects to go into the array being created and filled by loadAllTeams() can supply the objects to be loaded with loadData(). Because this method is declared public it could also be used by other programs that need to load SalesTeam objects with data but that, for some reason, do not use the loadAllTeams() method.
Although it is not included as part of this project, consider that if saveAllTeams() and saveData() methods were also added then the SalesTeam class would be able to implement its own file-based database system that can load/save either full sets of teams or individual teams. This begins to become a very capable class.
The Standard Sales Team Data File Format (SSTDFF)
A key design objective of the new SalesTeam class was to implement support for a standardized file format for saving and reading sales team data. This allows us to have programs dedicated to maintaining the data and other programs dedicated to processing and displaying the data. Having to type in all the data for a group of sales teams every time we need to process that data is a major limitation to the old version. For that reason the SSTDFF was created.
SSTDFF stores the data for from one to any number of Sales teams. It is a simple ASCII text file format that can be read and edited in any text editor. The first line of the file has a number that indicates how many teams are stored in the file. Following that line are repetitions of the data for one team. If the first line specified 1 team there will be data for 1 team. If the first line specified 3 teams there will be data for 3 teams, etc. The following is a sample file which is also attached below that will be used to explain the file format. Line numbers are shown in red text and are not part of the file:
2: Northwest Region
10: Southeast Region
18: Southwest Region
Line 1 contains just the value 3 in this case. That specifies that the file contains data for 3 teams. You would read that first line and use the number to create an array of the correct size.
Lines 2 thru 9 provide the data for first team as follows:
Line 2 contains the team name, Northwest Region in this case.
Line 3 specifies how many members are on the team, 3 in this case. Following the line specifying how many members there are there will be pairs of lines with data for each person as follows:
Line 4 supplies colon-separated data for the Person object for this team member, George M. Jones in this case. This should look familiar. The name data plus the age and weight are supplied.
Line 5 supplies colon-separated data for the annual sales data for this member. The first number is always for year 2005 because that is when the company was created. The next will be for year 2006. The next for 2007, etc. There can be as many years worth of data as might be needed. You will find out how many years of data there are by reading and splitting the first one encountered and checking the size of the array generated by split(). SSTDFF guarantees that all sales data lines will contain the same number of years of data so you only have to check this once. If a member did not work for the company in a particular year that year will have zero for annual sales.
There will be as many repetitions of person and sales lines as are needed to supply the number of members specified. In this case 3 members were specified so there will be three pairs of lines: 4 & 5, 6 & 7, and 8 & 9.
Line 9 is the last line for the Northwest Region team. One you have read the last line for a team your are either positioned to read the team name of the next team if you have reached the end of the file.
In this file the team Southeast Region is contained on lines 10 thru 17 and Southwest Region on lines 18 thru 27. Note that Southwest Region has 4 team members.
Study this file structure until it is very clear how it works. I will post some additional material about processing this kind of file.
Turn in your modified SalesTeam.java file as an attachment.
It looks like I did not really explain why loadData() returns a boolean and under what circumstances it should return what value. This is the scoop:
It returns a boolean to indicate if the load operation succeeded or failed. If every thing went OK then you return true. But if something went wrong in the logical processing of the file then you return false to inform the calling code that there was a problem.
I am not concerned about file operation errors here such as failure to read the file itself (disk drive hit a bad spot, etc.). Those things will cause exceptions to be thrown and we do not discuss exception processing in this course.
What you need to detect and use to force a false return value are the following:
1. The team size is less than 1. How could that possibly be OK? It can't be. We must have a corrupt file or maybe we are not reading a SSTDFF file at all. Who knows what that goofy user is going to throw our way?
2. A data line for a Person object data does not contain 5 data elements. All such data lines must contain 5 elements: first name. middle initial, last name, age, and weight. If it is anything but 5 then something is wrong that the program just cannot deal with. Time to bomb out with a "false" return.
3. The number of data elements in a sales data line is less than 1. This cannot be correct. We could require that all sales data lines contain the same number of years of data as the first one encountered but that would be more complicated so you do not have to do that. But, if you see a reasonably easy way to do it it would be positively valued.
So that is basically it. If any of the three conditions above occur you should abort the load process by returning false. If we were covering exception processing I would show you a much cleaner, more elegant way of dealing with such situations but that is beyond the scope of this course.
This program should be a "B" or "C" with errors included and cannot be perfect. And no exception handling.