Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Write a menu-driven Java application to do the activities shown in the example output. All of the activities involve reading the provided file, names.txt ,

Write a menu-driven Java application to do the activities shown in the example output. All of the activities involve reading the provided file, names.txt, which gives babies' names in the U.S. and their popularity rankings for 11 decades beginning in 1900. In this file a popularity of 0 indicates a ranking that was 1000 or more. Each of the 4429 lines in this file starts with a baby's first name and is followed by eleven (11) integers representing the popularity ranks for that name for the 11 decades from 1900 through 2005.

There are four (4) menu items the user may choose:

NOTE: Examine the example output with the goal of making your output look like the example output.

The user should NOT be able to crash the program by entering data. Examples: entering a letter when the program expects a number, entering a decade that does not exist, entering a name that is not in the file, entering a rank that is less than 1 or more than 999 None of these or any other erroneous inputs should be capable of crashing your application: your application must defend against user attempts to crash the application. The Scanner look-ahead methods will be useful to meet this requirement, along with error-checking methods of your own. an example Java app that uses the Scanner look-ahead methods is Robust.java. These methods allow the program to look into the input stream before actually reading and thereby avoiding exceptions cause by such things as reading an integer when there is text in the input stream. See the example output.

When a name entered by the user is not found on the file (for #1 and #2 above), inform the user of the problem and abort the task, i.e., loop back to a point where the main menu is displayed and another command is entered by the user. Ignore the case of user input; for example, "jOHn", "John", "JOHN", and "john" should all be the same name as far as the program is concerned.

Object-Oriented Design: You will create one class that is used to instantiate one line from the file. Each line contains one name followed by 11 integers. You can open your copy of the file in a text editor to see this format. You may NOT change the file; your application will be tested only with the original names.txt file. Each line in this file represents a child's name and the 11 integers are the popularity rankings for the 11 decades mentioned above (1900.. , 1910.. , 1920.. , 1930.. , 1940.. , 1950.. , 1960.. , 1970.. , 1980.. , 1990.. , 2000.. ). The class you will write to represent a line from the file will be named, Name, and the code for this class should be in the file, Name.java.

READ VERY CAREFULLY, but ONLY if you have read chapters 5 and 6 from the textbook: The class, Name, should contain instance variables for the name itself (a String) and the 11 popularity rankings (array of int). Your Name class must also have the following constructor and methods (with these exact names, return type and parameters):

public Name( String name, int[] popularityRanks ) Constructor taking the name and the list of popularity ranks for each decade public String getName() Accessor for name instance variable public int getPop( int decade ) Access popularity for a specific decade; 1 < decade < 11, return -1 if decade is invalid public String getHistoLine( int decade ) Return a decade's line (String) in the histogram Return null if the decade value is not valid public String getHistogram() Return a string that contains the entire histogram for this name Since a histogram is multiple lines, the returned String contains embedded newline characters

Note that NONE of the methods in the Name class are static since all methods in this class must always be applied to a specific name. Any other methods besides those listed above in the Name class should be marked as private and also should NOT be static. Conceptually, objects of this class are an abstraction of one line of data from the file, names.txt. There is NOTHING in this class about a list of names since this class is only about a single name. All of the instance variables and all of its methods relate ONLY to one single name.

Along with Name.java, you will also turn in NameApp.java. NameApp.java will contain a main method and other helper static methods. The purpose of main and its helpers is to implement the requirements in this document. The problem should be divided up neatly according to the four major tasks mentioned as part of the menu. Each of these tasks may be further subdivided however you see fit. You might also want to have special helper methods such as one to search the list for a particular name, one to read the file into an array and methods to verify various user inputs, including integer and string inputs. You should aim to achieve a solidly modular design in order to get a good grade on this project.

You should aim to organize the code using static methods to reduce redundancy and complexity. Complexity is conquered by dividing the work into smaller units (see module 1). Any tasks that are repeated should be organized as a separate static method, and then called by whatever section of code needs to use that task. You should never have the same code copied into different parts of the application: use help methods instead. No recursion may be used, either directly (A calls itself) or indirectly (A calls B calls A). Each method should have one return statement and System.exit must never be used. To give you an idea of the high-level design of main and the use of modularity, here is an outline of some of the responsibilities of main:

Print histogram for a name: The histogram line should be longer the more popular that name is. So, a rank of 1 gets the most stars (100) and a rank of 999 gets only one star. Names whose ranks are zero (0) should show no stars since the zero implies a popularity of 1000 or more. You should aim to get 100 stars for rank 1 and 1 star for rank 999. This can be done by accessing a name's rank for a specific decade and plugging it into the expression: (1000 - rank) / 10 + 1. If the entered name is not found in the list of names, then an error is printed and the menu is redisplayed for another user selection. See the example output.

Compare two names in a decade: The user should be prompted to enter each of the two names and the decade value (1 through 11). Handling of errors (a name is not found or an invalid entry for decade) is shown in the example output.

Print top ten names for a decade: List the top 10 names for a given decade in order of decreasing popularity (or increasing rank: first 1, then 2, then 3, etc.). The user should be prompted for the decade in which to search. NOTE: This will display 20 names since for each popularity rank there are two name. See the example output.

Quit (write anomalies): This menu choice causes the application to terminate. However, before terminating, the application must print all anomalies found in names.txt to an output file named anomalies.txt. The file's format is defined to have two names for every decade/rank pair. For example, if examining decade 7 (1960-1969) and the rank, 9, this would yield the names, Michelle and Thomas. Any pair of a decade and a rank should correspond to two names as in the previous example. However, there are anomalies in the file such that some decade/rank pairs have only one name and a few of these pairs have no name at all. Writing the anomalies to an output file means that your program will search the array of names looking for these anomalies and print a list of these problems with the file's format to the output file. As it turns out, there are 1,065 anomalies: in most cases, only one name with a particular rank in a decade or in a few cases, no names in a decade with a particular rank. Your code to do this will need to check each name in each decade for each rank in order to find all 1065 anomalies. The format of the two different kinds of anomalies you will write to the file named, anolamies.txt, follows: 23 - One name(Wilma) for 1900-1909, rank 139. 676 - No names for 1940-1949, rank 779. - Note: Write out one anomaly per line and number each anomaly written. In the two examples above, the first one was the 23rd anomaly found and the second was the 676th anomaly found. You may find them in a different order, but you numbers should go from 1 to 1065. - Also note, for the first type of anomaly that the one name found is given in the description of that anomaly.

 Name list = new Name[SIZE]; boolean done = false; loadNames( list ); // main app loop do { switch( getMenuSelection() ) { case HISTOGRAM: displayHistogram( list ); break; case COMPARE: compareNames( list ); break; case TOPTEN: displayTopTenNames( list ); break; case EXIT: done = true; break; } // end main app loop } while( !done ); writeAnomalies( list ); . . .

This example code above uses the named constants:

public static final char HISTOGRAM = 'a'; public static final char COMPARE = 'b'; public static final char TOPTEN = 'c'; public static final char EXIT = 'd';

The file, names.txt, must be read once only. This one reading of the file should be done to create an array of Name objects. This should be done at the beginning of the application (in a separate method), and only the array of Name objects should be used from that point (in other words, the file should NOT be used again during this run of the application). When loading the data from the file into the array of Name objects, you may either read a token at a time or a line at a time. If you read it one token at a time, then you will read a name from a line, then read the 11 ranks for that name into an 11-element integer array, then create one Name object from this data and store a reference to this Name object in the array of 4429 Name objects. You will do this 4429 times. If you process the file a line at a time, you would read an entire line (use Scanner's nextLine()), then you could tokenize this string using a Scanner and process the name and integers as you would for the token-based processing above. There are two examples of using a Scanner to tokenize a String in this module. No matter which approach you choose, you will create an array of Name objects with 4429 elements and you will need the help of an 11-element integer array. However, do NOT create and attempt to use any other large arrays of String or two-dimensional arrays of int, etc. Such approaches are woefully inadequate and exceedingly inefficient compared to approach described above as the preferred method of reading the file and populating the array of Name objects.

Use class constants wisely. Examples: starting year of the files data (1900), max or min rank, values and strings used in creating histograms or other data. You may also use constant arrays if you wish.

Every method should have a prolog comment that makes very clear what the task of the method is. Be sure the main prolog COMPLETELY and CLEARLY summarizes all the functionality of this application. Finally, use inline comments to make your code simple to read and understand. Again, make your execution resemble the example output as closely as possible.

Turn in, Name.java and NameApp.java via Canvas before the due date/hour.

HINTS:

Start this project ASAP, if not sooner. Read through the requirements (above) and the example output and list any questions you have along the way. Re-read both documents to answer questions; email me questions you cannot answer for yourself. Divide the problem into parts using the menu items: part a (print a histogram), part b (compare two names), etc. Do one part at a time. Write utility (helper) methods to keep from having redundant code.

Beginning and Completing this Project

Use stepwise refinement as your method of design and implementation. What this means is that you carve out a small part of the project, proceed to design it and then implement it. When this part is implemented, you should be able to compile it and run it. After testing the completed part, choose another chunk to design and add its implementation to what you already have. Now compile and test what you have completed so far. When you have gone back to design and implement all parts of the problem, you will be ready to do the final testing of the entire application.

For this project, here are the parts I would isolate and the order in which I would design, implement and test:

Design, implement and test Name.java

Use the instance variable and method requirements given above

Design, implement and test each method as I go

Using a temporary main method in the Name class for this

Read file into an array of Name objects

Begin NameApp.java by having main call a method to load a Name array with objects created by reading the text file, name.txt

Create the array in main, pass it to the loadNames method and let that method fill it with Name objects

Test this, by printing out various names and their popularity rankings

For example, if main named the array, list, then upon return from the readNamesFile method do something like:

System.out.println( list[0].getName() + list[0].getPop(1) );

this is why you want to do the Name class first!

So now you can run NameApp.java and load an array with the entire contents of names.txt

High-level menu and user-interface

Look back (above) at the idea for main's tasks with the switch using the menu selection to call a method to do a major task within the app. USE THIS IDEA HEAVILY!!!

NOTE: when you first implement this, the methods called inside the switch statement should ONLY BE STUBS so that you do not work at implementing them until later.

You should now be able to run NameApp and see that the menu and the interface loop are working properly.

Menu Option A: Displaying a Histogram for One Name

Design and implement the method, displayHistogram, and its helper methods

Since you will have to get a name from the user and search for it in the array, it would be a good idea to write these as two separate methods

Use the information that your search provides: if search can find the name, then have it return the index of this name in the array so that you can call its getHistogram method

Now you should be able to run NameApp, choose A and see a histogram for the name you enter.

You should also be able to quit (but withOUT writing the file anomalies YET!)

ONLY when everything above of working smoothly, go on to the next part

Menu Option B: Comparing Two Names

Design an implement the method, compareTwoNames( list ), and any help methods

Note that this methods needs two names from the user: you wrote a helper method for this when working on the previous part

Note that you must also search for each name before continuing: the search too was written for the previous part!

You will also need a decade value from the user: here is another helper that will be needed in the third (C) part!

You should now be able to run NameApp and do parts A and B and quit.

Menu Option C: Top Ten Names

Design and implement this part by designing and implementing the method that will do this work

Don't forget to DESIGN: use pseudocode to try various ideas

Proceed with the design, implementation and testing of this newest part

Make sure the first two parts are still working

Menu Option D: Finding File Anomalies and Quit

Now design and implement the method to find and write the anomalies to a text file

Call this method and set the do..while loop boolean to true

Now you can test the entire application

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

How To Make A Database In Historical Studies

Authors: Tiago Luis Gil

1st Edition

3030782409, 978-3030782405

More Books

Students also viewed these Databases questions