Students who complete this lab will demonstrate that they can:
for
statements
Our problem in this lab exercise is to write an interactive song program that produces the the well-known (and over-sung) “Bottles of Beer” song:
99 bottles of beer on the wall, 99 bottles of beer. Take one down, pass it around, 98 bottles of beer on the wall. 98 bottles of beer on the wall, 98 bottles of beer. Take one down, pass it around, 97 bottles of beer on the wall. ... 1 bottle of beer on the wall, 1 bottle of beer. Take one down, pass it around, 0 bottles of beer on the wall. 0 bottles of beer on the wall, 0 bottles of beer. Go to the store and buy some more. 99 bottles of beer on the wall. finis
There are two problems with singing this song: (1) We shouldn’t be singing songs that celebrate the over-consumption of anything, particularly alcohol; and (2) we shouldn’t be wasting our time and our voices singing pointless repetitive songs. A “solution” to these problems is to write an interactive program that allows the user to specify the number of verses, the container and the desired beverage/food. This would allow us to automatically create a “3 bags of chips” song, or a “10,000 barrels of monkeys” song.
edu.institution.username.lab07
ConsumptionSongConsoleDriver
.
For graphical applications in Processing, we often started by sketching what our program should produce. With non-graphical applications, it’s still important to think about our goals for the program, but we must specify them in non-graphical ways. For example, a console-based interface to a configurable consumption song generator might look something like the following:
Please enter the following quantity: 3 container: bag substance: chips 3 bags of chips on the wall, 3 bags of chips. Take one down, pass it around, 2 bags of chips on the wall. 2 bags of chips on the wall, 2 bags of chips. Take one down, pass it around, 1 bag of chips on the wall. 1 bag of chips on the wall, 1 bag of chips. Take one down, pass it around, 0 bags of chips on the wall. 0 bags of chips on the wall, 0 bags of chips. Go to the store and buy some more. 3 bags of chips on the wall. finis
In this scenario, the user may choose any integer quantity, string container and substance. Note the control issues in the song:
To implement a program that addresses these issues, you’ll build a console-based Java application that handles the input and output and produces the songs. When you’re finished, you can exercise its functionality with the following test “songs”:
If the application can handle these test cases properly, you can be reasonably confident in its capabilities.
You’ll start implementing this application by building its console-based user interface. To simplify matters, you’ll postpone implementing the actual lyrics of the song until the next section.
Write a
main()
driver method in the
ConsumptionSongConsoleDriver
class that implements this algorithm:
As you do this, note the following things:
nextLine()
method reads a word or phrase up to the new-line
character and consumes the new-line, the Scanner’s nextInt()
method reads an
integer but doesn’t eat up the new-line character. To make your interface consistent, read
your integers as follows:
System.out.print("\tquantity: "); // Prints a prompt, leaving space at the end of the line for user input. int quantity = keyboard.nextInt(); // Reads the integer entered by the user but doesn't read the new-line character. keyboard.nextLine(); // Eats up and ignores the new-line character.
You’ll add the song lyrics in the next section.
With your console driver in hand, you can turn to the (more interesting)
makeSong()
method. You’ll implement this in a couple of iterations.
As a way to get started, it is often a good idea to write a stub version of a method before implementing its complete functionality. The stub declares and empty version of the method and invokes it appropriately, which allows you to verify the method signature before embarking on the full definition of the method’s functionality.
Implement a stub version of
makeSong()
as a sibling method to
main()
inside the
ConsumptionSongConsoleDriver
class. Use the following algorithm:
quantity
, container
and substance
.
result
= ""
, an empty string.
result
string.
Obviously, something interesting will eventually happen between steps 2 & 3, but for
now implement just this much and include the method invocation in main()
in the appropriate place
(i.e., step 4 of the algorithm in exercise 7.2). Because makeSong()
returns a string, step 4 of
main()
should invoke makeSong()
and print the result. The program should run without
error and print a song with no lyrics.
With the stub in place, you can move on to the core functionality of the method.
Extend your
makeSong()
implementation to include the core functionality, specified in the new step 3 shown in this
augmented algorithm:
quantity
, container
and substance
.
result
string to ""
,
an empty string.
count
in the range quantity
down to 0:
result
:count
+ “ ” + container
+
“s of ” + substance
+ “ on the wall, ” + count
+ container
+ “s of ” + substance
+
“.” +count
- 1
) + " " + container
+ “s ” + “ of ” + substance
+ “ on the wall.\n”result
string.
Here, steps 1, 2 & 4 are repeated, though perhaps renumbered, from the previous version of the algorithm. When this implementation is finished, run it on your test cases.
Your implementation should work on the “0 pieces of eight” and “-1 lumps of coal” test cases, but the “3 bags of chips”) is likely to behave something like this:
Please enter the following quantity: 3 container: bag substance: chips 3 bags of chips on the wall, 3 bags of chips. Take one down, pass it around, 2 bags of chips on the wall. 2 bags of chips on the wall, 2 bags of chips. Take one down, pass it around, 1 bags of chips on the wall. 1 bags of chips on the wall, 1 bags of chips. Take one down, pass it around, 0 bags of chips on the wall. 0 bags of chips on the wall, 0 bags of chips. Take one down, pass it around, -1 bags of chips on the wall. finis
You’ll deal with the grammatical and lyrical errors in the last couple of verses in the next section.
makeSong()
Method
In this section, you’ll fix two problems with the algorithm. First, the last verse should read as follows:
0 bags of chips on the wall, 0 bags of chips. Go to the store and buy some more. 3 bags of chips on the wall.
This version should be handled as a special case because it’s unlike the other versions.
Extend your
makeSong()
implementation to handle the last verse properly, as specified in the modified contatenation
operation shown in step 3 of this augmented algorithm:
quantity
, container
and substance
.
result
string to ""
,
an empty string.
count
in the range
quantity
down to 0:
count
+ “ ” + container
+ “s of ” + substance
+ “ on the wall, ” + count
+ container
+ “s of ” + substance
+ “.” +count - 1
) + container
+ “s”quantity
+ " "
+ container
+ “s”substance
+ “ on the wall.\n”result
string.
When this implementation is finished, run it on your test cases.
One last problem one can see in this output is the pluralization of the container word. The algorithm should generally add the “s” to the container to make it plural but when the count is 1, no “s” should be added (e.g., “1 bag of chips”).
One rather simple way to fix this problem would be to add another
if
statement that adds the “s” only when
count!=1
. The problem with this solution is that you’d have to write a new
if
statement each time the container is expressed, which for this method would require four identical
if
statements. This would not be a good approach because it would make the code harder to understand
and harder to maintain.
A better way to solve the problem is to “factor out” this pluralization function into a separate method that receives a word and the number and returns the appropriate string. We could use this new function as follows:
song += count + " " + pluralize(container, count) + " of ";
This method should receive a word and a number, and return a pluralized version of the word if the number is not 1. For example, if the word is “bag” and the number is 1, then the method should return“bag”, otherwise it should return “bags”. The method will assume that the word is a noun in singular form with regular pluralization rules.
Address the pluralization problem by doing the following:
pluralize()
method that implements the behavior
just described. We haven’t given you an algorithm for this method, but you’ll find
that it’s a rather straightforward use of the two-branch-if-statement pattern shown above.
pluralize()
in each situation where the container is
included in the song string.
The resulting program should handle all the test cases properly.
Your lab solution now integrates all the basic control structures (sequence, selection, repetition) and methods in a Java application.
Submit all the code and supporting files for the exercises in this lab. We will grade this exercise according to the following criteria: