CS367 Programming Assignment 1
Lecture 4, Fall 2016
Due by 11:59 pm on Tuesday, September 27, 2016

Announcements

9/8/2016  Program assigned. To ask questions about the homework and see questions posed by other students and their answers, go to: https:piazza.com/wisc/fall2016/cs3674 and sign-in using your wisc.edu account.

Here are some problems commonly seen in a first programming assignment 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 exactly 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

Epoch Systems of Anorev, Wi is a leading software firm. It often requires that employees visit customers to discuss implementation and integration issues. Such meetings are often called "Go Jive" sessions. To improve employee morale, Epoch has decided to allow employees to declare a "wish list" of destinations. Travel assignments will be matched against employee preferences (to the extent possible). Epoch is not quite ready to go live — it needs a way to manage employees and their wish lists. It has hired you to start working on a simple prototype.

For this assignment you will write a program that constructs a simple database of employees and wish lists containing destinations encoded as airport identification codes (e.g., MSN or ORD). (Click here for a utility that maps airport names and their three letter codes). Your program will process a text file, specified as a command-line argument, using it to construct an employee database. It will then repeatedly prompt the user to choose from a set of operations and display the resulting output on the console window. For Programming Assignment 1 you will not be building an abstract data type (ADT) from scratch. Instead, you will use Java's ArrayList class to implement the EmployeeDatabase class specified below.

Goals

The goals of this assignment are to:

  • Practice compiling and running Java programs in Eclipse.
  • Become familiar with Java's List interface by using Java's ArrayList class.
  • Gain experience using iterators (from Java's Iterator interface) to traverse lists.
  • Get practice throwing exceptions.
  • Use command-line arguments.
  • Review basic file and console I/O.

Specifications

What are the program requirements?

Input text files

Text files storing employees and destinations will be read by your program. Each line in the text file lists an employee (as a username) followed by the destinations (as airport id codes) in that employee's wish list in the following format:

employee,destination1,destination2,...,destinationN

where the employee and destinations 1 through N are sequences of characters excluding commas and spaces (i.e., "," and " "). You may assume that the text files are in the specified format and contain at least one employee. You may also assume that each employee has at least one destination in their wish list and that there are no duplicate destinations within a single employee's wish list (see this sample input file for an example). You may also assume that employee usernames and airport id codes are unique* and are to be represented by your program as lower-case Strings. *Note: for both employees and airport id codes, differences in capitalization should be ignored, e.g., UGM2016, ugm2016, and Ugm2016 should all be considered the same and represented in the database as ugm2016.

Note: employees are to be added to the employee database in the order in which they appear in the text file.

Information about Java I/O is available in both a long version and a short version. Examples of file input are linked to in those documents.

The Employee class

An Employee class is provided for you (see Employee.java). The Employee class represents a single employee that keeps track of a username (as a String) and the airport id codes in the employee's wish list (as a List of Strings). The Employee class has the following constructor and methods:

Constructor Description
Employee(String name) Constructs an employee whose username is name.
Method Description
String getUsername() Return the username of this employee.
List<String> getWishlist() Return the wish list for this employee.

You may not modify the Employee class. If you need to make a change to the wish list a particular employee has, use getWishList() to get the list of airport id codes in the employee's wish list and then use list operations to add, remove, etc.

The EmployeeDatabase class

The EmployeeDatabase class stores the employees.  The EmployeeDatabase class has the following constructor and methods (do not add any additional public methods other than those listed below):

Constructor Description
EmployeeDatabase() Constructs an empty employee database.
Method Description
void addEmployee(String e) Add an employee with the given username e to the end of the database. If an employee with username e is already in the database, just return.
void addDestination(String e, String d) Add the given destination d to the wish list for employee e in the database. If employee e is not in the database throw a java.lang.IllegalArgumentException. If d is already in the wish list for employee e, just return.
boolean containsEmployee(String e) Return true if and only if employee e is in the database.
boolean containsDestination(String d) Return true if and only if destination d appears in at least one employee's wish list in the database.
boolean hasDestination(String e, String d) Returns true if and only if destination d is in the wish list for employee e. If employee e is not in the database, return false.
List<String> getEmployees(String d) Return the list of employees who have destination d in their wish list. If destination d is not in the database, return a null list.
List<String> getDestinations(String e) Return the wish list for the employee e. If an employee e is not in the database, return null.
Iterator<Employee> iterator() Return an Iterator over the Employee objects in the database. The employees should be returned in the order they were added to the database (resulting from the order in which they are in the text file).
boolean removeEmployee(String e) Remove employee e from the database. If employee e is not in the database, return false; otherwise (i.e., the removal is successful) return true.
boolean removeDestination(String d) Remove destination d from the database, i.e., remove destination d from every wish list in which it appears. If destination d is not in the database, return false; otherwise (i.e., the removal is successful) return true.
int size() Return the number of employees in this database.

For the internal structure of the EmployeeDatabase 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 where appropriate (i.e., whenever you need to traverse a list). You may also write additional helper classes to be used by the EmployeeDatabase class.

Note: in addition to the information given in the table above, your EmployeeDatabase class will need to be able to recognize null parameter values and, when a null parameter value is passed, throw a java.lang.IllegalArgumentException.

The InteractiveDBTester class

The application program, InteractiveDBTester, creates and uses a EmployeeDatabase to represent and process information about employees and wish lists. The employee and wish list information is read from a text file (explained above) and then the program processes user commands. The application must make use of Java Iterators where appropriate (i.e., whenever a list is traversed).

The InteractiveDBTester.java file contains the outline of the InteractiveDBTester class. Download this file and use it as the starting point for your InteractiveDBTester implementation. Note that it contains all the necessary code to read user input from the console. You do not need to modify that part of the code. When we test your code we will only input legal commands in the appropriate format.

The main method of the InteractiveDBTester class does the following:

  1. Check whether exactly one command-line argument is given; if not, display "Please provide input file as command-line argument" 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 and use it to construct an employee database.
  4. Prompt the user to enter command options and process them until the user types q for quit.

The command options are:

Command format Description
d destination If destination is not in the database, display "destination not found". Otherwise, discontinue destination (i.e., remove the destination from all the wish lists in which it appears) and display "destination discontinued".
f employee If employee is not in the database, display "employee not found". Otherwise, find employee and display the employee (on one line) in the format:
employee:destination1,destination2,destination3
h Provide help by displaying the list of command options. This command has already been implemented for you.
i Display information about this database by doing the following:
  1. Display on a line: "Employees: integer, Destinations: integer"
    This is the number of employees followed by the total number of unique destinations.

  2. Display on a line: "# of destinations/employee: most integer, least integer, average decimal fraction"
    where most is the largest number of destinations that any employee has in their wish list, least is the fewest, and average is arithmetic mean number of destinations per employee rounded to the nearest tenth (e.g., 1.2 or 0.7).

  3. Display on a line: "# of employees/destination: most integer, least integer, average decimal fraction"
    where most is the largest number of employee wish lists in which any destination appears, least is the fewest, and average is arithmetic mean number of employees per destination rounded to the nearest tenth (e.g., 1.2 or 0.7).

  4. Display on a line: "Most popular destination: destination(s) [integer]"
    This is the destination that shows up in the greatest number of wish lists followed by the number of wish lists containing that destination in square brackets. If there is a tie for most popular destination, display all those tying in the order they appear in the database separated by commas.

s destination If destination is not in the database, display "destination not found". Otherwise, search for destination and display the destination along with the employees who have that destination in their wish list (on one line) in the format:
destination:employee1,employee2,employee3
r employee If employee is not in the database, display "employee not found". Otherwise, remove employee and display "employee removed".
q Display "quit" and quit the program. This command has already been implemented for you.

Command-line arguments

Recall that in Java, when you run a program, it is a main method that runs and that main method 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 command 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 InteractiveDBTester employeeData.txt

runs the Java interpreter on the main method of the InteractiveDBTester class, passing the string "employeeData.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 Configurations..." from the pop-up menu, which brings up the "Run Configurations" 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 these style and commenting standards that are used to evaluate your program's style.
  2. You may use the Java programming environment of your choice in CS 367, at level 5 or above. However, all programs must compile and run using the Java 8 SE for grading. We recommend that you use Eclipse. You may want to review the Eclipse tutorial to learn the basics.

  3. Download the following files to your programming assignment 1 directory:
  4. Implement and thoroughly test your EmployeeDatabase class and any additional supporting classes.
  5. Incrementally implement the InteractiveDBTester 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. Try this sample input file, sampleInput.txt, and make sure your program produces the exact same output, sampleOutput.txt. 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.
  6. 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 files to the Program 1 Dropbox on Learn@UW:

  • "InteractiveDBTester.java" containing your employee database processing application,
  • "EmployeeDatabase.java" containing your implementation of the EmployeeDatabase class, and
  • "*.java" additional classes (if any) that you've implemented for your program.

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

Last Updated: 8/10/2016     © 2016 Beck Hasti and Charles Fischer