Lab 8 In-Class: While Loops
As usual, create a subdirectory for this lab, open up the Web version of
this handout in Mozilla Firefox, and open emacs.
This lab is designed to teach you the basics of writing while loops. A
while loop is an example of a repetition statement (also called a loop)
which allows a sequence of statements to be executed multiple times.
The number of times the execution is repeated depends on a boolean
condition. The basic syntax of a while statement is as follows:
...
while ( boolean expression )
{
... the statements to be repeated - the body of the loop
}
...
As with an if statement when execution reaches the while statement,
the boolean expression is evaluated. If it is true all statements in
the body of the loop are then executed. After the body has been executed
the boolean condition is evaluated again. If it is true the body
is executed again. This is repeated until the boolean expression is
false at the time it is evaluated.
The following is a basic loop that prints the
numbers from 1 to LIMIT and finds their sum:
final int LIMIT = 100; // setup
int count = 1; // - initialize the loop control variable
int sum = 0; // - and the summing variable
while (count <= LIMIT) // condition
{ // body
System.out.println(count); // -- perform task
sum = sum + count; // (print and sum)
count = count + 1; // -- update condition
}
System.out.println ("The sum of the integers from 1 to " +
LIMIT + " is " + sum);
There are three parts to a loop:
- The setup, or initialization. This comes before the
actual loop, and is where variables are initialized in preparation for
the first time through the loop.
- The condition, which is the boolean expression that
controls the loop.
- The body of the loop. The body typically needs to do two things:
- Do some work toward the task that the
loop is trying to accomplish. This
might involve printing, calculation, input and output, method calls -- this
code can be arbitrarily complex.
- Update the condition. Something has to happen inside the loop so
that the condition will eventually be false -- otherwise the loop will
go on forever (an infinite loop). This code can also
be complex, but often it simply involves
incrementing a counter or reading in a new
value.
Sometimes doing the work and updating the condition are related. For example,
in the loop above, the print statement and the assignment statement
for the sum are doing work, while the
statement that increments count is both doing work (since the loop's task
is to print and sum the values of count) and updating the
condition (since the loop stops when count hits a certain value).
The loop above is an example of a count-controlled loop,
that is, a loop that
contains a counter (a variable that increases or decreases by
a fixed value -- usually 1 -- each time through the
loop) and that stops when the counter reaches a certain value.
Exercise #1: Summing in a Loop One task that often takes place
in a loop is adding up some values. In the example above, the variable
sum is keeping a running total of the integers 1, 2, 3, ... up
to the limit. Note the key elements in getting this task done:
- There is a variable (in this case named sum) that keeps
the running total.
- The summing variable is initialized to 0 before the loop (nothing
has been added in yet).
- Each time through the loop the new value is added to the sum.
In this exercise we will take a count-controlled loop that prints
out vacation days (the exercise we didn't have time for in last
week's lab) and add code so it will read in the amount of
money spent each day and find the sum. The main part of the program
containing this loop is as follows (with blanks we will fill in to
add the summing):
int numDays; //total number of days of vacation
int dayCount; //counter for the vacation days
___________________________; //total amount spent on vacation
___________________________; //one day's expenditure
System.out.println ("Vacation Days!!!");
System.out.print ("How many days is your vacation? ");
numDays = scan.nextInt();
// Initialize the day counter and the total spent
dayCount = 0;
____________________________________________________;
// Count-controlled loop - executes numDays times
while (dayCount < numDays)
{
// Update the counter variable and print a message
dayCount++;
System.out.println ("Having fun on day " + dayCount + "!");
// Get the amount spent this day
System.out.print ("How much did you spend today? ");
______________________________________________________;
// Update the total spent
______________________________________________________;
}
// After the loop - print a message and the total spent
System.out.println ("Out of the loop - vacation over!");
___________________________________________________________;
Observe that unlike the earlier example the counter
variable starts at 0. It is standard to start counters either at
0 or 1 - which you choose makes some difference in the order of
statements in the body of the loop (you'll see this in exercise 3).
We want to add code above so the program will determine the total amount
of money spent on vacation. That requires the following (fill in the
blanks to do each step):
- Two new variables are needed - one to hold each day's expenditure
(so it changes each day) and another to keep a running total. Fill in the
blanks above to declare a variable totalSpent to store the total amount
spent on vacation and a variable daysExpenditure to store a single
day's expenditures.
- The summing variable totalSpent must be initialized before the loop.
- Update totalSpent inside the loop - this involves two steps:
first prompt for (that's already there)
and read in the amount spent in one day. Then add
that amount to the total amount spent.
- Print the total spent after the loop.
The file VacationDays.java has basically the
same loop as above with some extra comments and prompts to read in the
date that vacation starts. Do the following.
- Save VacationDays.java to your directory then compile and run it
to see how it works at this point (it is incomplete!).
- Open VacationDays.java in emacs and type in the code to compute
the total amount spent on vacation as directed in the comments with
a single *. DO NOT add code in the comments with three asterisks ***
(these are related to Date objects and you'll do that below).
- Compile and run the program. Be sure to have vacations of more
than a couple of days so you can see if the program is correctly
computing the total spent.
- To get more practice with objects we are going to add a Date object
to the program (this is what was planned for last week's lab). So, do
the following:
- Date.java needs to be in your current directory to use it (you
will use it but not change it in any way!).
Copy Date.java from your lab7 directory to your lab8 directory
using the cp command - if you are currently in your lab8 directory
one way to do this is:
cp ../lab7/Date.java .
(Be sure you understand each part of this command!)
- In VacationDays.java declare and instantiate a Date object
named vacationDay for the date read in.
- In the body of the loop modify the print statement to print
the date (as directed in the comment).
- Also in the body of the loop but after the print statement (and
after the comment telling you what to do!) write a statement to
advance vacationDay to the next day.
- After the loop add a print statement to print the message
"Back to work on ..." with the first date after vacation in place of the
"...".
- Compile and run the program. Test it thoroughly.
- Print out VacationDays.java to hand in.
Exercise #2: A loop that isn't count-controlled Not all loops are
count-controlled. Often there is some other condition, rather than a
counter having reached some limit, that determines how many times a
loop executes. For example, suppose that instead of knowing how many
days a vacation is (and computing how much money is spent in those days)
we instead know how much money we have to spend and want to stay on
vacation until we reach or exceed that limit. Just a few changes to
the above program can answer the new question. The basic outline
is as follows:
int dayCount; // counter for the vacation days
double spendingLimit; // amount of money available to spend
double totalSpent; // total amount spent so far
double daysExpenditure; // one day's expenditure
System.out.println ("Vacation Days!!!");
System.out.print ("What is your spending limit? ");
spendingLimit = scan.nextDouble();
// Initialize the loop count and the total spent
dayCount = 0;
totalSpent = 0;
// Loop continues until the total spent reaches the limit
while ( _____________________________________________________ )
{
// everything in here is exactly the same as before
}
// After the loop - print a message
System.out.println ("Out of the loop - vacation over!");
___________________________________________________________;
To modify the program to answer the "how many days until I reach my
spending limit?" question you need to fill in the two blanks (of course
the program needed to change the original question asked from how
many days to how much money):
- Fill in the loop control condition.
- Write a print statement after the loop letting the user know
when he/she ran out of money.
Now do the following:
- Copy VacationDays.java to VacationDays2.java, open VacationDays2.java
in emacs and make the necessary changes (note there are a few additional
changes other than the two blanks above).
- Compile and run the program.
- Note that the program will let the user overspend. We can't totally
prevent that but we can add some code to help. Do the following:
- Add a statement inside the loop after the total spent has been
updated that prints a message letting the user know the total spent
so far.
-
After the loop add a statement
to print a message if the user spent more than the limit
(and tell him/her how much over).
- Test your revised program.
- Print the completed program.
Exercise #3: Infinite Loops and Loop Counters
Breaking out of infinite loops: One of the first things you need
to learn about loops is how to break out of infinite loops! Different
systems have different keys for doing this. In Linux,
CTRL-C stops a program that is running.
The program in LoveCS.java should print
"I love Computer Science!!" as many times as the user wishes.
Copy it to your directory and
compile and run it to see how it works.
Clearly the program has a problem and it is a typical one when
writing loops - there is no update of the loop control
variable. Modify the program as follows:
- Fix the loop so it will execute exactly the number of times
specified by the limit.
- Number each line in the output, and add a message at the
end of the loop that
says how many times the message was printed.
So if the user enters 3, your program should
print this:
1 I love Computer Science!!
2 I love Computer Science!!
3 I love Computer Science!!
Printed this message 3 times.
- After the above works, add a second loop after the one that is
there that does exactly the same thing but initialize the loop control
variable count to 0 instead of 1. You should NOT adjust the
print statement; you will need to make some other adjustments
to make sure that you get the same output.
(HINT: think about the order in which the statements inside the loop
are executed).
When successful, Your program should print the numbered message
the given number of times twice (print a blank line in between!).
- Now add a third loop after the others that again prints the
"I love Computer Science" message the given number of times but
this time count down. So if the user wants to print the message
three times the program would print (after the other printing from
the other two loops):
3 I love Computer Science!!
2 I love Computer Science!!
1 I love Computer Science!!
The END!!!
Again, this change should come by changing the operation of the loop, not the
print statement.
Print this program to turn in.
Exercise #4: Computing Products in a Loop
The factorial of n (written n!) is the product of the integers
between 1 and n. Thus 4! = 1*2*3*4 = 24. By definition, 0! = 1. Factorial
is not defined for negative numbers.
-
The file Factorial.java contains a skeleton of
a program that will ask the user for a non-negative integer and
compute and print the
factorial of that integer.
Open the file and complete it.
You'll need a while loop to do most of the work --
this is a lot like computing the sum of the numbers from 1 to some limit,
but it's a product instead. You need to declare two variables
for your calculation (one to hold the product - what is the role of the
other?), initialize them before the loop, then write the correct loop.
Print the answer after the loop.
- Run your program to make sure it works. What do you get when
you enter 0? If the program doesn't get 1 then modify the loop control
(and perhaps your initializations) so that it does get 1 when the
user enters 0 (you should not need to add any ifs to get the program
to correctly compute 0!). Make sure the program still works for integers
greater than 0 (be sure to test 1 and another integer).
- Using a loop to verify input Often a loop is used in an
interactive program to force the user to enter valid input - when the
user enters an invalid input value the loop keeps asking for and
reading in a new value until something correct is entered. The general
structure of the loop is as follow:
... Prompt for and read in the input
while ( ... the input is not valid ...)
{
Let the user know the input is not valid
Ask them to try again
Read in the new value
}
... continue the program - now the input is guaranteed to be valid
Now modify your factorial program so that it checks to see if the
user entered a
negative number. If so, the program should print a message saying that
a nonnegative number is required and ask the user to enter another number.
The program should keep doing this until the user enters a nonnegative
number, after which it should compute the factorial of that number.
Hint:
Add another while loop before the loop that computes the
factorial. You should not need to change any of the code that computes
the factorial.
- As we discussed in class, when a value is too big (in the positive
or negative direction) to fit in the number of bits available, overflow
occurs. Factorials get big very fast, so they are a good place to see
overflow. Do the following:
- The loop that computes n! is actually computing the factorial of each
number from 1 to n-1 along the way. Add statements to your loop to print
the current value of the integer
and its factorial in each loop iteration. So if the
user entered 4, your program should now print
1!=1
2!=2
3!=6
4!=24
Add comments to your code to Answer the following question
- A Java
int
is represented with 32 bits using two's
complement. The largest value that can be stored in an int
is 231 - 1 which is 2,147,483,647.
Run your program with an input of 20 and look at the values that
are printed. At some point the factorial becomes negative, which is
clearly wrong, but overflow actually occurs before this -- what is the
highest integer for which your program computes factorial correctly,
and what is its factorial?
Does this make sense given the largest possible int? Explain.
Exercise #5: A Guessing Game
File Guess.java contains a skeleton for a
program to play a guessing game with the user. The program should randomly
generate an integer between 1 and 10, then ask the user to try to
guess the number. As long as the
user guesses incorrectly, the program should ask him or her
to try again; when the guess is correct,
the program should print a
congratulatory message.
- Using the comments as a guide, complete the program so that it plays
the game as described above.
- Modify the program so that if the guess is wrong, the program
says whether it
is too high or too low. You will need an if statement (inside
your loop) to do this.
- Now add code to count how many guesses it takes the user to get
the number, and print this number at the end with the congratulatory message.
- Finally, count how many of the guesses are too high, and how many are too low;
print these values, along with the total number of guesses, when the user
finally gets it.
- Print this program to turn in.
Exercise #6: Flipping a Coin
The file CoinFlips.java has the outline
of a program that will flip two coins until at least one of them
comes up heads 10 times. The coins will be objects defined in the
Coin class on pages 221 - 222 of the textbook. The class is in the file
Coin.java. Do the following
to complete the program.
- Save CoinFlips.java and Coin.java to your directory.
- Open your book to pages 220 - 222 to study the Coin class and
a simple program that uses it (that example does not use a loop).
- Open CoinFlips.java in emacs and add code as directed by
the comments.
- Compile and run the program. Test it thoroughly. Be sure your
final messages after the loop have all the required information.
You may format the output as you wish but an example would be:
Coin 1 beat Coin 2 getting to 10 heads. It took 23 flips.
Coin 2 had 7 heads.
OR
Coin 1 and Coin 2 tied - they reached 10 heads in 19 flips.
- Print out CoinFlips.java to hand in.
What to Hand In
- Hardcopy of VacationDays.java, VacationDays2.java, LoveCS.java,
Factorial.java, Guess.java, CoinFlips.java.
- Tar up your lab8 directory and e-mail it to your instructor with
cpsc120 lab8 in the subject line.