CS367 Programming Assignment 1
Lecs 1 & 2, Fall 2008
Due by 4:00 pm on Wednesday, October 1 Friday, October 3

Announcements

Check here periodically.

9/30/2008  The due date has been extended to Friday, October 3 (because of all the CS server/email problems the last week).
9/24/2008  Information about Java I/O is now available in both a long version and a short version. Examples of file input are linked to in those documents.
9/23/2008  Minor wording revisions in three places: the removeDestination description in the Itinerary class and steps #5 and #9 in the description of the main method of the ItineraryApp class.  In all places the orginal (unrevised) text is struck out.
9/18/2008  Program released.
9/18/2008  Here are some problems commonly seen in Programming Assignment 1 that we want to warn you about:
  • Handing in extra files or files with the wrong names and/or capitalization,
  • Not following the commenting and style guidelines,
  • Not following the program output format as shown in the sample output file,
  • Having additional output other than what is specified (especially debug related), and
  • Having poorly-written code, even if it works (e.g., redundancy, convoluted methods, poor modularity).

Overview

Why are we doing this program?

Description

For this assignment you will write a program that processes an arbitrary number of itineraries. Each itinerary consists of a list of destinations along with the number of days spent at each destination. The itineraries are stored in a text file that must be loaded (read and stored) by your program.  Your program will process this text file, specified as a command-line argument, and then apply a prescribed set of operations and display the resulting output on the console window. For Programming Assignment 1 you will not be building a data structure from scratch. Instead, you will use Java's ArrayList class to implement the itinerary class specified below and in your main class to manage a list of itineraries.

Goals

The goals of this assignment are to:

  • Practice compiling and running Java programs in Linux and optionally Eclipse.
  • Become familiar with Java's List interface by using Java's ArrayList class.
  • Use Java's Iterator interface.
  • Use command-line arguments.
  • Review basic file and console I/O.

Specifications

What are the program requirements?

The Destination class

Each itinerary contains a list of destinations.  The Destination class represents a single destination that keeps track of the name of the destination (as a String) and the number of days spent at that destination (as an int).  The Destination class implements the following methods (do not add any other public methods than those listed below):

Constructor Description
Destination(String loc, int days) Constructs a destination whose name is loc and number of days is days.
Method Description
String getDestination() Return the name of this destination.
int getDays() Return this destination's number of days.
void setDestination(String s) Replaces the destination's name with s.
void setDays(int n) Replaces the destination's number of days with n.
boolean equals(Object o) Returns true iff the given object o is equal to this destination, i.e., it has the same name and number of days. Note: differences in capitalization and spacing do not count as different names, e.g., "New York", "new york", "NEW york", and "New              York" should all be considered the same.
String toString() Returns a String representation of this destination.
The string format is: name (#days)

The Itinerary class

The Itinerary class stores a list of destinations.  The Itinerary class implements the following methods (do not add any other public methods than those listed below):

Constructor Description
Itinerary() Constructs an itinerary containing no destinations.
Method Description
boolean containsDestination(String dest) Return true iff a destination whose name is d is in the itinerary. If dest is null throw a java.lang.IllegalArgumentException.
void addDestination(String dest, int num) Adds a destination whose name is dest and number of days is days to the end of the itinerary. If dest is already in the itinerary, change the destination's number of days to num. If dest is null, throw a java.lang.IllegalArgumentException. If num is less than 1, throw a java.lang.IllegalArgumentException.
void removeDestination(String dest) Remove the destination whose name is dest from the database itinerary. If dest is not in the itinerary just return. If dest is null throw a java.lang.IllegalArgumentException.
void setDays(String dest, int num) Sets the number of days for the destination in the itinerary with the name is dest to the given number of days num. If dest is null, or if num is less than 1, or if a destination with the name dest is not in the itinerary throw a java.lang.IllegalArgumentException.
int getDays(String dest) Returns the number of days for the destination in the itinerary with the name is dest. If dest is not in the itinerary, return 0. If dest is null throw a java.lang.IllegalArgumentException.
int size() Return the number of destinations in this itinerary.
int days() Return the total number of days for this itinerary.
boolean isEmpty() Return true iff the itinerary has size 0.
Iterator iterator() Return an Iterator over the destinations in the itinerary. The destinations should be returned in the order they were added to the itinerary (resulting from the order in which they are in the text file).

For the internal structure of the Itinerary class, you may write your own ArrayList class or use Java's ArrayList class that implements Java's List interface. You must also make use of Java Iterators (or ListIterators) where appropriate. You may also write additional helper classes to be used by the Itinerary class.

The ItineraryApp class

Your application program, ItineraryApp, creates and uses a list of Itinerary objects read from a text file explained below. The application must make use of Java Iterators (or ListIterators) where appropriate.

The command line format is:

    java ItineraryApp FileName

where FileName is the name of the text file to be processed.

The main method of the ItineraryApp class does the following tasks:

  1. Check whether exactly one command-line argument was given; if not, display "Usage: java ItineraryApp FileName" and quit.
  2. Check whether the input file exists and is readable; if not, display "Error: Cannot access input file" and quit.
  3. Load the data from the input file.
  4. Display on a line: "Itineraries: <integer>, Total Destinations: <integer>, Unique: <integer>"
    This is the number of itineraries followed by the total number of destinations including duplicates, and the number of unique destinations (not including duplicates). For example, given itinerary A destinations (Madison, Chicago, Iowa City, Minneapolis, Rockford), itinerary B destinations (Milwaukee, Minneapolis, Fargo), itinerary C destinations (Madison, Rockford) the output would be: "Itineraries: 3, Total Destinations: 10, Unique: 7
  5. Display on a line: "Length of itineraries: longest <integer>, average <integer>, shortest <integer>"
    where longest is the largest number of total days that any itinerary has, shortest is the smallest, and average is arithmetic mean number of songs days per list (use integer division when calculating: total_number_of_days / number_of_itineraries).
  6. Display on a line: "Most Common: <destination name(s)> <integer>"
    This is the name of the destination(s) appearing in the most itineraries followed by the number of itineraries to which it belongs. If there is a tie for the most common, display all those tying in the order they appear in the itineraries data structure separated by commas.
  7. Display on a line: "Most Popular: <destination name(s)> <integer>"
    This is the name of the destination that has greatest number of total days (i.e., in all the itineraries combined) followed by the total number of days for that destination. If there is a tie for the most popular, display all those tying in the order they appear in the itineraries data structure separated by commas.
  8. Display on a line: "Least Popular: <destination name(s)> <integer>"
    This is the name of the destination that has least number of total days (i.e., in all the itineraries combined) followed by the total number of days for that destination. If there is a tie for the least popular, display all those tying in the order they appear in the itineraries data structure separated by commas.
  9. Display on a line the last destination in the first itinerary in the data base data structure: "Destination: <destination name>"
    where name is the name of the destination. Then remove that destination from every itinerary in the itineraries data structure.
  10. Again display on a line: "Itineraries: <integer>, Total Destinations: <integer>, Unique: <integer>"
  11. Again display on a line: "Length of itineraries: longest <integer>, average <integer>, shortest <integer>"
  12. Again display on a line: "Most Popular: <destination name(s)> <integer>"
  13. Remove the first itinerary in the itineraries data structure and display on a line: "Removed first itinerary"
  14. Again display on a line: "Itineraries: <integer>, Total Destinations: <integer>, Unique: <integer>"
  15. Again display on a line: "Length of itineraries: longest <integer>, average <integer>, shortest <integer>"

Itinerary text files

Text files storing lists of itineraries read by your program. Each line in the text file represents one itinerary and lists the destinations followed by the number of days at each destination:

destination name 1:days1:destination name 2:days2:...:destination name N:days N

where the destination names 1 through N are sequences of any characters excluding colons (i.e., ":"). You may assume the text files are in the specified format, and contain at least one itinerary with a minimum of one destination. You may also assume that destination names are unique and are to be represented by your program as Strings. Note differences in capitalization and spacing should be considered the same as in this example: New York vs. NEW YORK vs. new   york

Note, destinations are to be added to itineraries in the order in which they appear in the text file and itineraries are to be added to the list in the main application in the order in which they appear in the text file.

Command-line arguments

Recall that in Java, when you run a program it is a main method that runs, and it always has the following header:

	public static void main(String[] args)

The array-of-Strings parameter, args, contains the command-line arguments that are specified when the program is run. If the program is run from a Linux prompt (i.e., not from a programming environment like Eclipse), the command-line arguments are simply typed after the name of the class whose main method is to be executed. For example:

	java ItineraryApp itineraries1.txt

runs the Java interpreter on the main method of the ItineraryApp class, passing the string "itineraries1.txt" as the command-line argument.

To use command-line arguments when you run a Java program using Eclipse:

  1. Right click on the source file that contains the main class you want to run in the "Package Explorer" window.
  2. Select "Run As" from the pop-up menu.
  3. Select "Run ..." from the pop-up menu, which brings up the "Run" window.
  4. Click on the "(x)= Arguments" tab.
  5. Enter the arguments in the "Program arguments:" text box.
  6. Click either the "Run" button, or the "Apply" and "Run" buttons.

How to proceed

After you have read this program page and given thought to the problem we suggest the following steps:

  1. Review the collaboration policy concerning pair programming.
  2. Review these style and commenting standards that are used to evaluate your program's style.
  3. You may use the Java programming environment of your choice in cs367. However, all programs must compile and run on the lab computers for grading. If you are going to use the CS lab computers, we recommend that you use Eclipse. You may want to review the Eclipse tutorial to learn the basics. Note that on the Linux lab computers, enter "eclipse&" at the prompt instead of what is described in the tutorial.
  4. Implement and thoroughly test the Destination class and any additional supporting classes.
  5. Implement and thoroughly test the Itineraries class and any additional supporting classes.
  6. Incrementally implement the ItineraryApp class as specified in the main program section above. Test each step to ensure your program is working correctly before implementing the next step. Create small text files for testing (it will be easier to debug than larger ones) and make sure you test all the boundary and negative cases as well as the positive cases. Once you've got your program working on small text files, create larger text files and make sure your program works on those as well.
  7. If you are not using the lab computers to develop your program, make sure you compile and run your program to ensure that it works on the Linux lab computers. You can compile your Java source files using javac in a terminal window as in this example:
        javac *.java
    
    and the run your program using java as in:
        java ItineraryApp itineraries1.txt
    
  8. Submit your work for grading.

Handing in

What should be handed in?

Make sure your code follows the style and commenting standards used in CS 302 and CS 367.

Electronically submit the following file to your In "handin" directory by the due date and time (or refer to the late policy):

  • "ItineraryApp.java" containing your itinerary processing application,
  • "Itinerary.java" containing your implementation of the Itinerary class,
  • "Destination.java" containing your implementation of the Destination class, and
  • "*.java" additional classes that you've implemented for your program.

Please turn in only the file named above. Extra files clutter up the "handin" directories.

Enrichment: Mutual Exclusion

How are data structures shared in large systems?

Scenario: Ben and Jerry work together in accounting.  One day they both get to work and open up the same spreadsheet from the server.  Ben loads it at 9:30 a.m., Jerry loads it at 10.  They both spend all day making changes to different parts of the spreadsheet.  Ben saves it at 4:30 p.m., Jerry saves it at 5.  What happens to each person's work?  How could they ensure that they never overwrite anyone else's work?

One solution would be, if someone needs to edit the spreadsheet, first they look around and see if anyone else is working on it.  If someone is, they have to wait; if nobody is, they tell everyone to stay out until they're done.

Enter the world of multithreaded computing.  Suddenly, the spreadsheet is a data structure, Ben and Jerry are hundreds of threads vying to change the same data, working on one spreadsheet per day becomes performing hundreds, maybe thousands of changes per second, probably more.  Suddenly, the remote chance of two threads working on the same space in memory--and corrupting it--becomes a definite possibility, and when it happens, unpredictable things occur.  This problem, whether two people sharing one spreadsheet or a million threads sharing an ArrayList, is called the Mutual Exclusion problem, and it's hard.

Interesting enough, Ben and Jerry's solution is a real way of solving this problem, preventing two threads from making changes at the same time.  But there are other questions we can ask, like: How can we make sure everyone gets to accomplish their work, and one thread doesn't monopolize access to the data?

Computer Scientist Edsger Dijkstra originally posed one example of this problem as the Dining Philosophers problem, and it remains an interesting puzzle, any many solutions have been offered since.

The Dining Philosophers and related problems raised by multi-threading are presented in CS 537, Introduction to Operating Systems.  Methods of synchronizing threads and controlling their access to data structures is called thread-safe development, and is also discussed at length in CS 537.

Last Updated: 9/23/2008     © 2008 Rebecca Hasti and Jim Skrentny, CS367 Instructors, hasti@cs.wisc.edu