Duke CS Logo CompSci 6: Program Design & Analysis I
(Fall 2009)
Home
Course Information
Calendar
Assignments
Assign 1
Assign 2
Assign 3
Assign 4
Assign 5
Assign 6
Assign 7
Assign 8
Assign 9
APT problems
Resources
Help sessions
Discussion Forum
Blackboard
Oasis

NameSurfer Part 1

This nifty assignment was developed by Nick Parlante and updated for CompSci 6 by Robert Duvall. Mike Scott made some changes that we've incorporated here.

Against all bureaucratic stereotypes, the Social Security Administration, provides a fascinating web site showing the distribution of names chosen for babies born in the US since 1880. Every year, the data gives the 1000 most popular boy and girl names for kids born in the US.

In this assignment you will:

  1. Read in the names and ranks from the file
  2. Search for all of the names that match a query string and print out the names followed by the year that each name was most popular.

Ultimately, we want to graph each name's popularity as in a simplified version of the Baby Name Wizard Graph.

Loading Names

The data can be represented as a single text file as shown below. On each line we have the name, followed by the rank of that name in 1880, 1881, ... 2008 (129 numbers). A rank of 1 was the most popular name that year, while a rank of 997 was not very popular. A 0 means the name did not appear in the top 1000 that year at all. The elements on each line are separated from each other by a single space. Below is an excerpt from names-ranks.txt.
Sam 36 32 30 ... 463 453 458
Samantha 365 501 490 ... 10 12 11
Samara 0 0 0 ... 350 457 500
Samatha 0 0 0 ... 0 0 0
Samie 0 0 0 ... 0 0 0
Samir 0 0 0 ... 830 832 842
Samira 0 0 0 ... 0 0 0
Sammie 894 811 824 ... 0 0 0
Sammy 0 0 0 ... 942 0 979
Sampson 0 691 744 ... 0 0 0
Samson 0 0 0 ... 890 889 948
Samual 0 692 640 ... 0 0 0
Samuel 17 17 17 ... 25 25 28

We see that Sam has declined in popularity from #36 in 1880 to #458 in 2008, Samuel has declined far less going from #17 to #28, but Samantha has increased in popularity for girls from #501 in 1881 to #10 in 2006. Other versions like Samatha were not in the top 1000 in most years, but made the list from 1985-1990.

You should implement a class NameRecord that stores a name and the rank of the name for each of the 129 years from 1880-2008.

Suggested steps

  1. Create a new project, download names-ranks.txt, and import the file into your project.
  2. Copy the getScanner method used in the Natural Prestidigitation code and use that to select and open the data file.
  3. Using a Scanner, read in each line of the file. For example, you could do the following: Scanner in = getScanner(); while( in.hasNextLine() ){ String line = in.nextLine(); /* create a NameRecord object based on line and add it to the ArrayList of NameRecord objects */ }

  4. Each line of the file represents a name and the ranks associated with that name. You should implement a class NameRecord that stores a name (String) and the rank (int) of the name for each of the 129 years from 1880-2008. The class should have the following properties (you may add more methods if you wish):

    • A constructor that takes a String as in the file above and initializes the data for the NameRecord object. How do you parse the String into the name and the years? You should either user the split method from the String class or a Scanner object. If you use the split method from the String class the statement would be:

      String[] parsedData = data.split("\\s+"); //data is the input String

      This parses the String into its individual components using whitespace as delimiters. The name itself should be in the first element of the resulting array and the 11 ranks will be in the remaining elements, although they will be Strings. You will have to convert them to ints using the Integer.parseInt method..

      The other approach for parsing the input is to use a Scanner object.

      Scanner line = new Scanner(data);  //data is the input String

    • Implement a method getName() to get the name for this NameRecord.
    • Implement a method, getRank(int year) that returns this NameRecords rank for a given year. You can use the convention that 1880 is 0, 1881 is 1, and so forth. In other words the parameter will be between 0 to get the rank during 1880, 1 to get the rank during 1881, and so forth.
    • Implement a method, bestYear() that returns an int for this NameRecords best year. In other words it returns the decade this name was most popular, using the most recent decade in the event of a tie. Return the actual year, as in such as 1880, 1972, and so forth. Looking at the data, Samantha was most popular in 1998 (#3), while Sam's best decade was 1882 (#30). In case of a tie, return the most recent year. For example, Samuel was #17 in 1880-1884, so it should return 1884, the most recent year.

After completing all these methods you should thoroughly test the NameRecord class using individual lines from the names.txt file or with your own data. Include your testing code in your a main method class even though it will not be called when the program is run from another class. Part of the assignment grade will be based on the tests you write for the NameRecord class.

Search

Implement a search(String target) method in the main NameSurfer class that takes a String, and searches through all the names for any that contain that substring (not case-sensitive). Print out a line for each matching name to the console, printing the name followed by its best year. It's fine to search the most straightforward way -- looping through all of the NameRecords and checking to see if the query name matches the name of the name record.

A sample run is below:

Enter search name: Sam
Isam 1880
Isamar 1990
Rosamond 1912
Sam 1882
Samantha 1998
Samara 2006
Samatha 1989
Samie 1907
Samir 2005
Samira 2003
Sammie 1953
Sammy 1946
Sampson 1898
Samson 1988
Samual 1882
Samuel 1884

Implement a doSearch() method that loops, reading a string from the console, and then calling search() with that string to print all the matching names. Continue looping until the user types enter with no input (i.e., the input String is empty).

You can read from the console using the standard input stream, System.in. You can prompt the user and read the result with the following code.

Scanner console = new Scanner(System.in); System.out.print("Enter search name: "); String name = console.nextLine();

Your main method in NameSurfer should read the data, and then doSearch() should drive the search() method.

Submitting

Submit NameRecord.java, NameSurfer.java, your README, and any other files you created using assignment name assign7.
Last updated Wed Nov 18 14:00:36 EST 2009