Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Lab in Java The Social Security Administration provides a list of popularity ran

ID: 3873829 • Letter: L

Question

Lab in Java

The Social Security Administration provides a list of popularity ranking of baby names since 18793. You are provided with a version of this list, which has 5870 names of male and female baby names. The list also ranks the top 1000 baby names for each gender for 13 decades starting from 1890.

Each line in the file provides a name, a gender and the ranking of the name for the decades between 1890 to 2010. A ranking of 1 indicates that the name was the most popular, while a ranking of 1000 indicates that the name was the least popular (out of 1000) for its gender. A ranking of 0 represents that the name did not make it the top 1000 for that decade.

For instance, the line below indicates that the name Brianna for a female baby was not ranked in the top 1000 during the decades of 1890 – 1970. From 1980 to 2010, it ranked 340, 61, 15 and 30 out of 1000, respectively. Thus, the name was most popular during the decade of 1980.

BriannaF 000000 0 0 034061 15 30

The objective is to ask the user for a baby name and gender and display the raking of that name throughout history and to display the decade the name was most popular.

You are to ask the user for a file name to read the data. If the user enters: “names.txt”, you are to open this file and then read and store its data into corresponding arrays. You can then search these arrays for the desired behavior. The examples below illustrate the expected behavior of your program.

The assignment tests your understanding of exception handlers (try/catch), file input and two- dimensional arrays.

Enter a filename: wrongfile.txt
Exception at getFile: wrongfile.txt not found. File I/O error at main()

Enter a filename: names.txt
Enter the name to search for: voldermort Enter the gender to search for, M or F: m Name could not be located in given file.

Enter a filename: names.txt
Enter the name to search for: mark
Enter the gender to search for, M or F: f
1890:0 1900:0 1910:0 1920:0 1930:0 1940:0 1950:0 1960:919 1970:932 1980:0 1990:0 2000:0 2010:0
Name was most popular in the decade of 1960, ranking #919/1000.

Enter a filename: names.txt
Enter the name to search for: mark
Enter the gender to search for, M or F: m
1890:169 1900:153 1910:200 1920:219 1930:219 1940:149 1950:23 1960:6 1970:9 1980:30 1990:46 2000:79 2010:161
Name was most popular in the decade of 1960, ranking #6/1000.


Here is the link to the Java code:

https://drive.google.com/open?id=0BwuDVy83jWPuMTJkMEMzMFRFUzA

Explanation / Answer

import java.util.Scanner;
import java.io.*;


//TODO: document this class
public class PA2c {
  
/**
* Error to display if given name could not be located in the datafile
*/
final static String ERR_NONAME = "Name could not be located in given file.";
  
/**
* Error to display from main() if datafile cannot be opened
*/
final static String ERR_IOMAIN = "File I/O error at main()";
  
/**
* First year of data being available
*/
final static int STARTYEAR = 1890;
  
/**
* Number of lines in the given names list
*/
final static int NO_OF_LINES = 5870;
  
/**
* Number of decades of data given for each name
*/
final static int NO_OF_DECADES = 13;
  
/**
* User prompt to gather datafile name
*/
final static String pf = "Enter a filename: ";
  
/**
* User prompt to gather name to search for
*/
final static String p0 = "Enter the name to search for: ";
  
/**
* User prompt to gather the gender to search for
*/
final static String p1 = "Enter the gender to search for, M or F: ";
  
/**
* User prompt to repeat the search process
*/
final static String p2 = "Would you like to search again? y or n: ";

/**
* Displays given string to console and collects a String
*
* @param prompt String to display
* @param in Scanner object
* @return String collected from the user
*/
public static String displayStringGetString(String prompt, Scanner in ) {
System.out.print(prompt);
return in.nextLine();
}
  
/**
* Convert the user given name to valid format. For instance:
* "JACK" to "Jack"
* "bette" to "Bette"
* "TrOy" to "Troy"
* @param uname
* @return valid version of uname
*/
public static String formatName (String uname) {
return uname.substring(0, 1).toUpperCase() + uname.substring(1);
}

/**
* Given a file name, open a Scanner object to read this file.
* If file not found:
* -Catch the exception
* -Rethrow the exception, so that you can catch it again in main()
* @param filename name of the file to open
* @return Scanner object to be used to collect input from file
* @throws Exception
*/
public static Scanner getFile(String filename) throws Exception {
java.io.File file = new java.io.File(filename);
Scanner inputFromFile = null;
// ToDo: try/catch file opening errors
return inputFromFile;
}


/**
* Given an array of names and genders,
* find and return the index of user specified name / gender
* If no match is found: return -1.
* Note: it should work for an array of any size.
*  
* @param nameArray list of names read from datafile
* @param genderArray list of genders read from datafile
* @param name name to search for
* @param gender gender to search for
* @return index of name/gender or -1 if not found
*/
public static int findName(String[] nameArray, String[] genderArray, String name, String gender) {
for (int i = 0; i < nameArray.length && i < genderArray.length; i++) {
  
if (nameArray[i].equalsIgnoreCase(name) && genderArray[i].equalsIgnoreCase(gender)) {
return i;
}
}
return -1;
}

/**
* Given a 2D matrix of popularity of names throughout decades,
* and a name index
* print to console the most popular decade for the given name.
* If name does not exit:
* print ERR_NONAME and exit.
* @param pops 2D array of names ranking
* @param pi index of a name
*/
public static void printPopular (int[][] pops, int pi) {
int min = 0;
int minI = 0;
for(int j = 0; j < pops[pi].length; j++) {
if (min > pops[pi][j] ) {
min = pops[pi][j];
minI = j;
}
System.out.println(STARTYEAR*(10*(j+1)) + ":" + pops[pi][j] + " ");
}
System.out.println();
if (min > 0) {
System.out.println("Name was most popular in the decade of " + STARTYEAR*(10*(minI+1)) + ", ranking #" + pops[pi][minI] + "/1000." );
}
}

/**
* Main method to read a text file,
* store its information into arrays
* search these arrays to find a particular name/gender and to display its popularity.
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
  
Scanner inputFromConsole = new Scanner(System.in);

// Prompt the user to enter a file name
System.out.print(pf);
String filename = inputFromConsole.nextLine();

Scanner inputFromFile = null;
  
//Try to open file with getFile
//In case of error:
// Catch rethrown error and print ERR_IOMAIN and exit.
BufferedReader br = null;
FileReader fr = null;
try {
//br = new BufferedReader(new FileReader(FILENAME));
fr = new FileReader(filename);
br = new BufferedReader(fr);
} catch (IOException e) {
System.out.println(ERR_IOMAIN);
System.exit(-1);
} finally {
try {
if (br != null)
br.close();
if (fr != null)
fr.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
  
  
//read from file

//store names here
String[] names = new String[NO_OF_LINES];
//store genders here
String[] genders = new String[NO_OF_LINES];
//store ranking of each name here
int[][] pops = new int[NO_OF_LINES][NO_OF_DECADES];


int i = 0;
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null) {
String[] parts = sCurrentLine.split("\s+");
names[i] = parts[0];
genders[i] = parts[1];
for(int j = 2; j < parts.length; j++) {
pops[i][j-2] = Integer.parseInt(parts[j]);
}
}
  
inputFromConsole = new Scanner(System.in);
//Get a name using displayStringGetString()
String name = displayStringGetString(p0, inputFromConsole);
name = name.toLowerCase();
  
//Get a gender using displayStringGetString()
String gender = displayStringGetString(p1, inputFromConsole);
gender= gender.toUpperCase();
  
//Format both name and gender
name = formatName(name);
  
//Find name/gender index using findName
//Print ranking using printPopular
int index = findName(names, genders, name, gender);
if (index == -1) {
System.out.println(ERR_NONAME);
} else {
printPopular(pops, index);
}
  
inputFromFile.close();
inputFromConsole.close();
}
}