CISC 3115
Introduction to Modern Programming Techniques
Lab #4
Exception Handling and More Classes

How to Develop and Submit your Labs

Recall, there are three elements to exception handling: detection, notification, and processing/handling:

Lab 3.1 — Line Scanners and Data Validation)

This lab is basically just a review, and variation of the data validation discussion of Lecture 4. The first part is nothing more than practice using a dual scanner approach (line-oriented input of the file, followed by token oriented input of the line). The second part uses the approach to perform data validation of a somewhat similar nature than what was done in the lecture.

Lab 3.1.1 — A Clever Use of Scanner (LineScanner)

If you look at the API for Scanner, you will see a constructor that accepts a String as it's argument. The semantics of this constructor is that the passed string is treated like an input source upon which you can then call the various Scanner methods: next, nextInt, etc. Thus, for example, if one had the file:
1 2 3
4
5 6 7
one could read in a line at a time, and then using each line as an input source, you could then process the integers on each line.

The basic code structure of this technique is:

…
Scanner fileScanner = new Scanner(new File(filename);

while (fileScanner.hasNextLine() {				// while there are lines left to read
	String line = fileScanner.nextLine();		// read next line of file
	Scanner lineScanner = new Scanner(line);	// set up a Scanner to read the 'contents of the line'
	…
	// use lineScanner just like any other Scanner object
	// i.e., you can call all the hasNext and next  methods
	…
}
This technique can be useful when one want to limit their processing of data to that on a single line of a file. Using next or nextInt doesn't work because those methods treat newlines like blanks (i.e., all whitespace is treated in the same fashion), so one doesn't know when the end of the line has been reached. While there are several ways of handling this, the above-described technique of reading in a line at a time — using nextLine and then creating a new Scanner object from the resulting string returned is a fairly straightforward way of accomplishing this.

Write an application class, named LineScanner, that opens the file numbers.text and prints out the number of integers on each line of the file. Again, to accomplish this, read each line into a String using nextLine and then create a second Scanner object using that string as the constructor's argument.

Sample Test Run

For example if the file numbers.text contains (notice the blank third line):

1 2 3
5 10 15 20 25

10 9 8 7 6 5 4 3 2 1
the program should produce the following output:
There are 3 numbers on line 1
There are 5 numbers on line 2
There are 0 numbers on line 3
There are 10 numbers on line 4

Some Guidance and Notes

Submitting to CodeLab

Lab 3.1.2 — Data Validation (DataChecker) (Approval)

This lab builds on the technique presented in Lab 3.1.1, and uses it to validate structured data in a file.

The file numbers.text contains data in the following format:

header1 int1 int2header2 int1 int2 …
…
i.e., each line begins with a header value, followed by that number of integers. Your program's task is to print out the average of each of these sequences.

However, the file contents is often corrupted by the time it gets to your program, so the data must be validated. Here are the possible problems:

Each of these situations must be detected and if present, an exception should be thrown, no average is calculated, and processing proceeds to the next sequence.

Sample Test Run

For example if the file numbers.text contains:

3 1 2 3

0
1 12
-12
14 1 2 3 
5 1 2 3 4 5 6
4 10 20 30 40
the program should produce the following output:
The average of the values on line 1 is 2.0
*** Error (line 2): Line is empty - average can't be taken
*** Error (line 3): Header value of 0 - average can't be taken
The average of the values on line 4 is 12.0
*** Error (line 5): Corrupt line - negative header value
*** Error (line 6): Corrupt line - fewer values than header
*** Error (line 7): Corrupt line - extra values on line
The average of the values on line 8 is 25.0

There were 3 valid lines of data
There were 5 corrupt lines of data

Some Guidance and Notes

Submitting to CodeLab

Lab 3.2 — User Authentication

In this labe you will define several classes that will comprise the basis of a very simple form of user authentication. User objects will be defined containing user ids, passwords, and password hints. These will then be verified by an Authetication object, Finally, an authentication app will set up an accept, reject and hint protocol.

Lab 3.2.1 — A User Class (User)

Implement the following User class: Sample Test Run

In CodeLab, I will be supplying a UserApp class to test your class by reading in Users from a file using your read method, print out the User using your toString, and makes sure the password is not the same as the username by calling verifyPassword passing it the username.

For example if the file users.data contains:

weiss	puppy2	woof-woof
arnow	java		cuppa
tenenbaum tenenbaum	da-same
sokol	brooklyn	college
the program (i.e., UserApp) should produce the following output:
User weiss hint: woof-woof
OK -- the password is different than the user name

User arnow hint: cuppa
OK -- the password is different than the user name

User tenenbaum hint: da-same
*** Error the password should not be the same as the user name

User sokol hint: college
OK -- the password is different than the user name

Some Notes

Submitting to CodeLab

Lab 3.2.2 — An Authenticator Class (Authenticator)

Implement the following class name Authenticator: Again — as in the previous lab — in CodeLab, I will be supplying an application class testing the Authenticator class by supplying it with a user data file, and then a sample login session. The login session consists of:

Sample Test Run #1

For example if the file users.data contains:

weiss	puppy2	woof-woof
arnow	java		cuppa
sokol	brooklyn	college
execution of the program should look like:
username? arnow
password? java
Welcome to the system

Sample Test Run #2

Given the same users.data file as above, execution of the program should look like:

username? weiss
password? dontremember
*** Invalid password - hint: woof-woof
username? weiss
password? puppy2
Welcome to the system

Sample Test Run #3

Given the same users.data file as above, execution of the program should look like:

username? sokol
password? CUNY
*** Invalid password - hint: college
username? sokol
password? SUNY
*** Invalid password - hint: college
username? sokol
password? BC
*** Invalid password - hint: college
Too many failed attempts... please try again later

Some Guidance and Notes

Submitting to CodeLab

  • More exception-handling (actually exception 'throwing') practice
  • A glimpse into a 'real-life' application
  • Lab 3.2.3 — An Authenticator Application (AuthenticatorApp)

    Assuming the existence of the Authenticator class of Lab 4.2.2, code an AuthenticatorApp application that reproduces the behavior of the sample runs of Lab 4.2.2, i.e., your app should instantiate an Authenticator object passing it the filename users.data, and then proceed to prompt the user at the keyboard for a user name and password; handling any exceptions in the manner described in Lab 4.2.2.
  • Exception-handling practice — this app catches the exceptions thrown by the Authenticator class.
  • The 'other side of the coin' if Lab 4.4 — there you write the class; here you write an app using the class.
  • Submitting to CodeLab

    Lab 3.3 — A Variation on the File Opener (FileOpener)

    Write an app class that accepts a filename as its single command-line argument and opens the file. If no command-line argument is provided, or the file does not exist (i.e., throws a FileNotFoundException, prompt the keyboard for another file name. This process repeats until a valid (i.e., existing) file name is provided.

    Here is a small writeup on how to use command=line arguments in a Java app.

    Here are some sample test runs trying to open the file FileOpener.java. We'll highlight the command-line argument in green

    Sample Test Run #1

    Here is a sample execution of the program.
    User input is in bold. Your program should replicate the prompts and output:

    java FileOpener FileOpener.java
    FileOpener.java opened successfully

    Sample Test Run #2

    Here is a sample execution of the program.
    User input is in bold. Your program should replicate the prompts and output:

    java FileOpener
    filename? FilOpener.java
    *** Error *** FilOpener.java (No such file or directory)
    filename? FileOpener.java
    FileOpener.java opened successfully

    Sample Test Run #3

    Here is a sample execution of the program.
    User input is in bold. Your program should replicate the prompts and output:

    java FileOpener FilOpener.java
    *** Error *** FilOpener.java (No such file or directory)
    filename? FileOpener.java
    FileOpener.java opened successfully

  • Some interesting logic involving command-line processing and exception-handling
  • Lab 3.4 — The Phonebook Revisted

    Lab 3.4.1 — A Name Class (Name)

    Code a Name with the following behavior:

    Submitting to CodeLab

    Lab 3.4.2 — A Phone Number Class (PhoneNumber)

    Code a PhoneNumber class (similar but not necessarily identical to the one on the exam): and the following behavior:

    I will be using an app class similar to the one provided for Name.

    Lab 3.4.3 — A Phone Book Entry Class (PhonebookEntry) (Approval)

    This lab has you using composition on the Name and PhoneNumber classes of the previous two labs to create a third, more complex class named PhonebookEntry. The basic structure is the same — only now you will be employing (leveraging) methods of the previous two classes when coding this new class. The state for this class is: and the behavior is: Here class files for the Name and PhoneNumber classes … feel free to use your own (as long as they conform to the specs, of course).

    And again, I will be using an app class similar to the one provided for Name.

    Some Guidance and Notes

    • Coding a class that uses composition
      • In particular, the chaining of methods calls from the outer class to the corresponding methods of the instance variable's class.

    Lab 3.4.4 — An Enhanced Phone Book (Phonebook) (Approval)

    In this version, you are to reimplement the functionality of the previous Phonebok class, but now using composition of the previous three classes: Name, PhoneNumber and PhonebookEntry. The basic output is identical to that of the previous version, but now:
    • You should be reading in the entries using the read method of your PhonebookEntry class (which in turn uses the read methods of the Name and PhoneNumber classes).
    • Use the equals methods of the Name and PhoneNumber classes in your lookup and reverseLookup methods.
    • Use the toString methods to print out information.
    • Make 100 the capacity of your Phonebook array
    • Throw an exception (of class Exception) if the capacity of the Phonebook array is exceeded.
    • Place a try/catch around your entire main and catch both FileNotFoundExceptions and Exceptions (remember, the order of appearance of the exception types in the catch blocks can make a difference).

    Sample Test Run #1

    For example if the file phonebook.text contains:

    Arnow       David    (123)456-7890
    Harrow      Keith    (234)567-8901
    Jones       Jackie   (345)678-9012
    Augenstein  Moshe    (456)789-0123
    Sokol       Dina     (567)890-1234
    Tenenbaum   Aaron    (678)901-2345
    Weiss       Gerald   (789)012-3456
    Cox         Jim      (890)123-4567
    Langsam     Yedidyah (901)234-5678
    Thurm       Joseph   (012)345-6789
    
    here is a sample execution of the program:

    lookup, reverse-lookup, quit (l/r/q)? l
    last name? Arnow
    first name? David
    David Arnow's phone number is (123)456-7890

    lookup, reverse-lookup, quit (l/r/q)? r
    phone number (nnn-nnn-nnnn)? (456)789-0123
    (456)789-0123 belongs to Moshe Augenstein

    lookup, reverse-lookup, quit (l/r/q)? l
    last name? Weiss
    first name? Jerrold
    -- Name not found

    lookup, reverse-lookup, quit (l/r/q)? l
    last name? Weiss
    first name? Gerald
    Gerald Weiss's phone number is (789)012-3456

    lookup, reverse-lookup, quit (l/r/q)? r
    phone number (nnn-nnn-nnnn)? (111)123-4567
    -- Phone number not found

    lookup, reverse-lookup, quit (l/r/q)? q

    3 lookups performed
    2 reverse lookups performed

    Sample Test Run #2

    If the file phonebook.text contains:

    …
    …
    …
    More than 100 entries
    …
    …
    …
    
    here is a sample execution of the program:

    *** Exception *** Phonebook capacity exceeded - increase size of underlying array

    Sample Test Run #3

    If the file phonebook.text is missing, here is a sample execution of the program:

    *** IOException *** phonebook.text (No such file or directory)

    Implementation Notes

    Lookup

    • The lookups now use the equals methods of the classes.

    Submitting to Codelab

    • We've introduced classes and exceptions, it's time to use them in the application

    Lab 3.4.5 — An Enhanced Phone Book App (PhonebookApp) (Approval)

    Code the app for the Phonebook class.