Lab 10 In-Class: More Loops

As usual, create a lab10 subdirectory for today's lab, open up Mozilla Firefox and the Web version of this handout, and open Eclipse.

A Menu-Driven Program Using a Do Loop

Program Account.java contains a simplified version of the Account class we used in two earlier labs. As you probably recall, the Account class models a simple bank account. In Lab 8 you wrote a GUI that simulated a simple ATM machine. In this exercise you will write a menu driven program that simulates a simple ATM machine - it lets the user deposit money, withdraw money, and check the balance as much as he/she wishes.

  1. Save Account.java to your directory.

  2. The file ATM.java contains a skeleton of the program described above. Complete the program as follows (as indicated by the comments in the program):
    1. Declare and instantiate an Account object with the information read in.
    2. Add a do...while loop that executes until the user chooses to quit. The loop should print out a menu of options in the following format:
               Options:
               1. Deposit
               2. Withdraw
               3. Check the balance
               4. Quit
      
               Enter your choice (1,2,3, or 4): 
      
    3. Then read in the user's choice (in the choice variable already declared) and do what the user requests (which requires using the appropriate method from the Account class). Note that if the user chooses deposit or withdraw, the program must ask for and read in the amount. Also, if the user types in an incorrect choice (such as a 6) the program should print a message telling the user to try again.

  3. Thoroughly test your program.

  4. Print ATM.java to turn in.

For Loops - Hot Streaks

Sports fans often get excited over a team or player who is having a "hot streak." However it turns out that long runs of events, even random ones, occur more often than many people think. In this exercise you'll write a program to find the longest run of heads in a sequence of coin flips. The Coin class from Listing 5.4 in the text (pages 221-222) is in the file Coin.java (the same class you used in last week's lab). Copy it to your directory, then write a program to find the length of the longest run of heads in 100 flips of the coin. A skeleton of the program is in the file Runs.java. You will add to the skeleton as follows (see the comments in the program):
  1. Create a coin object.
  2. Inside the loop, use the flip method to flip the coin, the toString method (implicitly -- just print the coin object, and it will call the toString method automatically) to print the results of the flip, and the isHeads method to see if the result was HEADS.
  3. To keep track of the current run length (the number of times in a row that the coin was HEADS), note that if the coin is HEADS on this flip, the current run is one longer than it was; if it's not HEADS, then the counter starts over. Be sure to update the maxRun variable as necessary.
  4. While you're checking for HEADS, if it's HEADS also print the number it is in the current run. For example, your output might start like this, indicating a longest run (so far) of 4:
    Heads 1
    Heads 2
    Tails
    Tails
    Tails
    Heads 1
    Heads 2
    Heads 3
    Heads 4
    Tails
    Heads 1
    ...
    
    You'll have to work a little on the formatting to get this to come out right (think about where you'll use print and where you'll use println).

  5. After the loop, print the length of the longest run (clearly labeled, of course).

  6. Print Runs.java to hand in.

Processing Strings & Nested Loops

In this exercise you will write a program that reads in a phrase or sentence and determines the percentage of letters in the phrase that are vowels. The program must count all the letters in the phrase and count the vowels (a, e, i, o, and u). The file Vowels.java contains the skeleton of the program. Open it and do the following as indicated in the comments:
  1. Add declarations for any additional variables you need and initialize them as appropriate.
  2. Change the phrase read in to all lower case for easier processing (so you don't have to test for both upper and lower case vowels).
  3. Write a for loop to go through the phrase character by character. In the body of the for loop you need to determine if the current character is a letter. If it is you need to count it and then see if it is a vowel. There are several ways to determine if a character is a letter including different ways of comparing characters. However, another way is to use the isLetter method from the Character class. The signature of the method is as follows:
          public static boolean isLetter(char c)
    
    Recall that a static method is called using the class name. Hence, a call would have the form
           Character.isLetter(ch)
    
    where ch is a variable of type char. Since a boolean is returned the above call should be placed in an appropriate place for a boolean such as an if.

  4. After the loop print out the number of vowels and the total number of letters, appropriately labeled.

  5. Also compute and print the percentage of letters that are vowels. Use a percent formatter object from the NumberFormat class to print the percent. To do this you need to do the following (see pages 131-132 for an example).
  6. [READ ALL BEFORE DOING ANYTHING!!] It would be nice to have the program let the user keep entering phrases rather than having to restart the program every time. To do this we need another loop surrounding the current code. That is, the current loop will be nested inside the new loop. Add an outer while loop that will continue to execute as long as the user does NOT enter Q or q for the phrase. Note that this makes the outer loop a sentinel controlled loop -- the program is processing phrases and a special value Q will stop it. The outline of the program is as follows:
         read in the first phrase
    
         while the phrase is neither "Q" nor "q"
         {
           initialize the counters etc. to set up the for loop
    
           for loop to count letters and vowels in the phrase
    
           print the number of vowels & letters and percentage of vowels
         
           read in the next phrase or "Q" to quit
         }
    
    
    Note that all you need to do is add the sentinel controlled while loop around the code you already have. Be sure the code to initialize the counters is inside the while loop (you start the counters over for each phrase).

    Be sure to format your code after adding the surrounding loop (SHIFT-CTRL-F) so it is properly indented.

Test your program thoroughly (enter more than one phrase!!!) then print the final version.

Reading Data from a File

Programs that read in lots of data and process it usually read the data from files rather than having the user enter it interactively from standard input or a GUI. The Scanner class in Java allows one to create Scanner objects that read from files. As you recall we have instantiated Scanner objects to read input from System.in (standard input which is the keyboard) as follows:
       Scanner scan = new Scanner (System.in);
The parameter for the constructor is System.in - the input stream we want to read from. Similarly we can instantiate a Scanner object to read from a file if given the name of the file (which is either a String literal or a String variable). Examples are:
       Scanner fileScan1 = new Scanner (new File ("myFile.txt"));

       // assume fileName is a String variable that already has a value
       Scanner fileScan2 = new Scanner (new File (fileName));
When running a program in Eclipse, the String for the filename needs to be the relative path to the file from the Project you are in (which is Labs). So, if the files are saved in your lab10 directory, the above would need to be modified as follows:
       Scanner fileScan1 = new Scanner (new File ("lab10/myFile.txt"));

       // assume fileName is a String variable that already has a value
       Scanner fileScan2 = new Scanner (new File ("lab10/" + fileName));
The usual Scanner class methods - next, nextLine, nextInt, etc. - are used to read data from a file. However the Scanner class has another method called hasNext that returns a boolean indicating whether or not there are more items in the file - this method is often used in the loop control for a loop that is reading through a file and processing the data in it. FileExample.java is an example program that reads a file. In this case the file consists of lines of data each containing an integer (a student grade) followed by a String (the student name - no spaces allowed). Some sample input files of data are grades1.txt and grades2.txt. [NOTE: A Scanner object is an example of an iterator which is discussed in Section 5.6 (pages 245 - 249) of the text.]

Do the following:

  1. Download the Java program and the two input files to your lab 10 subdirectory (right click on the link and choose Save Link As). Open the Java program and note the following:

  2. Open up grades1.txt to see what the data file looks like. You will see several lines with a number (the grade) followed by a String (the name).

  3. Run FileExample.java to see how it works.

  4. Note that currently the program only works for a file named grades1.txt. Modify the program so the file name is read in. A Scanner object is already instantiated to read from System.in and a String variable for the file name is already there. You need to:
    1. Prompt for and read in the file name.
    2. Change the instantiation of fileScan so it associates the Scanner object with the file just read in.

  5. Run the program and type in grades2.txt for the file name. How many students are in that file? Would you want to type all that in rather than read from a file?

  6. Read the whole description of the following problem before doing anything!

    The file nflStats.txt contains some statistics about how some of the NFL quarterbacks did in a recent week of play. Specifically, the file contains the name of the quarterback, the number of times he tried to pass the football and the outcome (in yards) of each pass attempt (note: an outcome of 0 means that the pass was incomplete). The file is organized as follows:

    
    QUARTERBACK_NAME
    NUMBER_OF_PASS_ATTEMPTS
    YARDAGE_1 YARDAGE_2 YARDAGE_3 ... YARDAGE_N
    
    
    Here's a simple example file:
    
        Bradshaw
        13
        12 0 35 23 0 0 8 57 0 14 27 21 0
        Stewart
        7
        0 0 0 13 0 67 8
    
    Your job is to write a program, named FootballStats.java, that reads the file and uses the data to compute some aggregate statistics. For each quartback, you should print a nicely formatted message that contains:

    Moreover, we are interested in identifying the "Best" Quarterback performance. After all the data has been read and processed, your program should print out a message that contains the name of the quarterback that had a) the largest total yards, b) the highest yards per attempt and c) the highest yards per complete pass.

    To accomplish this, you need to do the following for each player:

    Clearly you need a nested loop.

    Plan your program before starting it! You should not try to do everything at once - devise a strategy to complete and test the program in steps (the last exercise may give you a hint about a good strategy for writing a program with a nested loop).

  7. Print the completed program.

Hand in: