This week's book giveaways are in the Java EE and JavaScript forums.
We're giving away four copies each of The Java EE 7 Tutorial Volume 1 or Volume 2(winners choice) and jQuery UI in Action and have the authors on-line!
See this thread and this one for details.
The moose likes Beginning Java and the fly likes Head first Beersong Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of The Java EE 7 Tutorial Volume 1 or Volume 2 this week in the Java EE forum
or jQuery UI in Action in the JavaScript forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Head first Beersong" Watch "Head first Beersong" New topic
Author

Head first Beersong

Besjamain Greenaway
Ranch Hand

Joined: Dec 21, 2007
Posts: 45
Hello all,

just started with programming in Java, and now ended up at the beerSong. I try to figure out what is going wrong (since the output shows "99 bottles of beer on the wall" twice before going on to "99 bottles of beer"), but I am as blind as a mole about the "little flaw". Anyone could give me a hint as to where I should look?

Thanks!
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38472
    
  23
Not familiar with that particular affliction; English kids sing, "Ten green bottles standing on the wall," and normally repeat the first line.

This sounds like a common kind of error called "out-by-one." Are you repeating the call? How are you repeating it? Show us what you have got, and tell us where you think the problem is. Then see if we can't help you.

CR
Besjamain Greenaway
Ranch Hand

Joined: Dec 21, 2007
Posts: 45
Thanks for replying! Well, this is what I have;




This is the code that's in the head first java book on page 14. There's a flaw in it, since it will output this:

2 bottles of beer on the wall
2 bottles of beer on the wall
2 bottles of beer
Take one down.
Pass it around.

While it should be:

2 bottles of beer on the wall
2 bottles of beer
Take one down.
Pass it around.
2 bottles of beer on the wall.

At least, that's what I'm thinking it should be (I'm Dutch)....
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38472
    
  23
Thank you. I tried it and it printed
campbell@campbell-laptop:~/java$ java BeerSong
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.
Suggest you put a "System.out.println("************");" at the end of each verse/stanza, as the second line in the "if (beerNum > 0)" block. Then you will have ************ separating verses which makes it easier to read.
There is another minor error; I am getting "1 bottles of beer . . ." as the last line of the penultimate verse/stanza. Check whether you are changing "bottles" to "bottle" at the right place.

Try that.

Is the line printing "no more bottles of beer on the wall" in the right place? I don't think so.

************************************************************************

As they say on "Red Dwarf": ADDITIONAL.

Is that really the form Head First suggest you program? This does not count as object-oriented programming. You are not creating any objects. But it can easily be converted to object-oriented programming . . .

You ought not to have so much code in the main method. You should only havein it. Put a fieldand set it up in the constructor. Then you can put the loop in the sing() method.
Dick Summerfield
Ranch Hand

Joined: Oct 04, 2007
Posts: 90
I had a look at your code:


and it appears that if you comment out the System.out.println shown, you get rid of the repeated line. I tried it with int beerNum = 3; to limit output. The repeated lines for 1 bottle gives you a clue - the first says "1 bottles" the second "1 bottle" indicating which System.out.println they come from.

The program could do with a bit of refactoring though after commenting out that line

Groetjes, Dick uit Eindhoven.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18757
    
  40

and it appears that if you comment out the System.out.println shown, you get rid of the repeated line.


Yes, you'll get rid of the repeated line, but that's not how the song goes!! The song does repeat lines -- the end of a (number of bottle) verse is the start of the next verse.

Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38472
    
  23
Agree with Henry Wong that the line should be repeated as the first line of the next verse. That is why I suggested a ***************line to break it up. I am getting
campbell@campbell-laptop:~$ cd java
campbell@campbell-laptop:~/java$ java BeerSong
9 bottles of beer on the wall
9 bottles of beer
Take one down.
Pass it around.
8 bottles of beer on the wall
************
8 bottles of beer on the wall
8 bottles of beer
Take one down.
Pass it around.
7 bottles of beer on the wall
************
7 bottles of beer on the wall . . .
. . . using what I copied and pasted from Besjamain Greenaway's 2nd post, plus the ********** line.

In fact the looping could be tidied up quite a lot, but there are no major errors in it. What worries me is that you get books which don't introduce creating objects at an early stage.
Bert Bates
author
Sheriff

Joined: Oct 14, 2002
Posts: 8815
    
    5
aw Campbell, you ought to have a little faith in us


Spot false dilemmas now, ask me how!
(If you're not on the edge, you're taking up too much room.)
Besjamain Greenaway
Ranch Hand

Joined: Dec 21, 2007
Posts: 45
Wow, thanks for all the replies. Yes, this is not OO programming yet, they will get to that: I've just started out in the book

Okay - I understand now how the verse goes: after "pass it around, take one down" it should then go "xx of bottles on the wall", where xx is allready minus 1 from the one it started with.

Thanks for all your help, I got a better understanding of where to go now!
Julia Adams
Greenhorn

Joined: Aug 06, 2010
Posts: 1
this is my solution
i added if (beerNum == 0) condition instead of the if (beerNum > 0)

Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38472
    
  23
Welcome to the Ranch Julia Adams
David Patrzeba
Greenhorn

Joined: Jun 08, 2010
Posts: 14
The flaw is that as you pass in 2 and take one down the program out puts:



The solution is to rearrange the code so that the qualifier is after you remove the bottle.
Sven Jansen
Greenhorn

Joined: Aug 12, 2010
Posts: 1
So this is the right solution?



cheers
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38472
    
  23
Sven Brocking wrote:So this is the right solution? . . . cheers
Does it work?

Welcome to the Ranch

There is no such thing as "the" correct solution, but if that code works, it may be one of many correct solutions. We usually avoid giving a complete solution here, but your code differs so little from what was posted previously, I shall look on it as a correction of previous postings.
Joel Christophel
Ranch Hand

Joined: Apr 20, 2011
Posts: 234
    
    1

I know I'm a year late, but none of the programs posted yet were correct. However, David Patrzeba was correct with what he said. Based off of what he said, I moved the location of the qualifier, and the issue was removed. Here is a, not the, correct solution:
jake dickens
Ranch Hand

Joined: Mar 23, 2011
Posts: 30
try removing 18-21 lines and see what happens then figure out why it made a double
Glenn Delostrico
Greenhorn

Joined: Sep 21, 2011
Posts: 7
Well, I just started myself and still no one go the answer right but one guy was very close. He forgot to add the comment block which was posted a while back so the code below should fix the problem.

Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38472
    
  23
Welcome to the Ranch

You have a test about whether beerNum > 0 inside a while (beerNum > 0) loop. It is much neater to move the "no more bottles" line outside the loop, then you don't need that test any more. You are duplicating a test with the change from "bottles" to "bottle", but that probably still fits better inside the loop.
By the way: your indentation is inconsistent. Sometimes you have { at the end of the line and sometimes on a line to itself. I prefer the line to itself convention, but that is a preference not a requirement. You should however be consistent about which convention you follow.
Keith Engwall
Greenhorn

Joined: Dec 02, 2011
Posts: 1
Campbell Ritchie wrote:Welcome to the Ranch

You have a test about whether beerNum > 0 inside a while (beerNum > 0) loop. It is much neater to move the "no more bottles" line outside the loop, then you don't need that test any more. You are duplicating a test with the change from "bottles" to "bottle", but that probably still fits better inside the loop.
By the way: your indentation is inconsistent. Sometimes you have { at the end of the line and sometimes on a line to itself. I prefer the line to itself convention, but that is a preference not a requirement. You should however be consistent about which convention you follow.


I tried what you suggested and I found that if you take out the test about whether beerNum > 0 , then it will print "0 bottle of beer on the wall" before it exits the while loop and prints "No more bottles of beer on the wall". That's not correct.

In my opinion, that if/else test is the most elegant way to represent the decision of what to print as the last line of each stanza... if it's any stanza but the last, print the number of bottles of beer left, but if it's the last stanza, print "No more bottles". Comments would help clarify the meaning, of course.



There may be a more efficient way in terms of computer cycles to handle the situation, but sometimes I find it's better to invest those cycles in making the code make more sense to someone down the line (often my future self) who has to figure out what I was trying to do.

And as for the original problem with bottles vs. bottle when beerNum is reduced to 1, I agree that setting word to "bottle" after beerNum is reduced to 1 makes a great deal of sense.

Here's my "final" code... I added punctuation to the first line, dividers between stanzas, and draw out the last line the way we used to do on those long car trips.



If you don't like my comments, blame the beer! ;-D
Nolan Lefler
Greenhorn

Joined: Mar 23, 2009
Posts: 8
I have just started with HF Java, and this is the code I wrote. It works for me.

Rebecca Herbert
Greenhorn

Joined: Feb 01, 2012
Posts: 3
while the 99 bottles of beer is an exception, the rest of the song is correct.

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


And so on.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38472
    
  23
Welcome to the Ranch
harinath cool
Greenhorn

Joined: Jan 23, 2013
Posts: 3

public class Onebeer {
public static void main(String[] args) {
int beerNum = 99;
String word = "bottles";
while (beerNum > 0)
{
if (beerNum == 1)
{
word = "bottle";
}
System.out.println(beerNum + " " + word + " of beer on the wall");
System.out.println(beerNum + " " + word + " of beer");
System.out.println("Take one down.");
System.out.println("Pass it around.");
beerNum = beerNum - 1;
}

if (beerNum > 0)
{
System.out.println(beerNum + " " + word + " of beer on the wall");
}
else
{
System.out.println("No more bottles of beer on the wall");


}
}
}
harinath cool
Greenhorn

Joined: Jan 23, 2013
Posts: 3
Just close the while loop before if loop start searching if beerNum>0 or not
harinath cool
Greenhorn

Joined: Jan 23, 2013
Posts: 3
3 bottles of beer on the wall
3 bottles of beer
Take one down.
Pass it around.
2 bottles of beer on the wall
2 bottles of beer
Take one down.
Pass it around.
1 bottle of beer on the wall
1 bottle of beer
Take one down.
Pass it around.
No more bottles of beer on the wall
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38472
    
  23
Welcome to the Ranch
Aftab Badsha
Greenhorn

Joined: Mar 24, 2013
Posts: 1
Hi,

I know am late,but dived into HF few years back,then got lost midway n finally decided to check Java once again.

How about this?


public class BeerSong
{
public static void main (String[] args)
{
int beerNum = 5;
String phrase = "bottles";

while(beerNum>0)
{
System.out.println(beerNum + " " + phrase + " of beer on the wall ");
System.out.println(beerNum + " " + phrase + " of beer ");
System.out.println("Take one down");
System.out.println("Pass it around");

beerNum=beerNum-1;

if(beerNum>0)
{
if(beerNum==1)
{
phrase="bottle";
}
System.out.println(beerNum + " " + phrase + " of beer on the wall ");
}
else
{
System.out.println("No more bottles of beer on the wall");
}
}
}
}
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38472
    
  23
Welcome to the Ranch
I hope it is not too late for an answer. I would have added code tags to your code, which would have improved it , but your code is not indented.
Paulo Couto
Greenhorn

Joined: Apr 07, 2013
Posts: 4
Here is my attempt to the same book exercise:

Joel Christophel
Ranch Hand

Joined: Apr 20, 2011
Posts: 234
    
    1

Paulo Couto wrote:Here is my attempt to the same book exercise


Welcome to the ranch, Paulo Couto! Your example is very good, but you are missing one thing. Listen to the song here at this link http://youtu.be/Z7bmyjxJuVY?t=40s. Follow closely using the output of your program, and you should see your mistake within a matter of seconds.
Paulo Couto
Greenhorn

Joined: Apr 07, 2013
Posts: 4
Thanks for the welcome Joel.

So here is my second attempt after listen all those drunks:


Line 12 is what I added to the code.
I sure that the code isn't as elegant as it should be, but today is my first day learning Java. I don't have any programming experience so bear with me please.
Joel Christophel
Ranch Hand

Joined: Apr 20, 2011
Posts: 234
    
    1

Paulo Couto wrote:
today is my first day learning Java. I don't have any programming experience so bear with me please.

Quite impressive for the first day. Your change did fix up the problem I was talking about. There's also a pluralization issue when you get to one bottle of beer, and "0 bottle of beer on the wall" shouldn't be there. But that's quite nit-picky.
Paulo Couto
Greenhorn

Joined: Apr 07, 2013
Posts: 4
Thanks Joel. For now I 'm just following the 'Head First Java' book and hopefully I will learn something from it. With the amount of resources out there, finding the ones that fit your style it's kinda hard (if that makes any sense).
There's also a pluralization issue when you get to one bottle of beer, and "0 bottle of beer on the wall" shouldn't be there. But that's quite nit-picky.

I will try my best to solve this issue. Working and solving little code 'bugs' like this, it's a great way to also train my attention to details.

P.S - Sorry for my poor english.
Joel Christophel
Ranch Hand

Joined: Apr 20, 2011
Posts: 234
    
    1

Paulo Couto wrote:
P.S - Sorry for my poor english.


I wouldn't even have guessed that English isn't you first language.
Paulo Couto
Greenhorn

Joined: Apr 07, 2013
Posts: 4
Here is my final code:


Pluralization issue and the "0 bottle of beer on the wall" output solved.
Even with all issues solved, code seems very repetitive. Lots of if's there and that doesn't seem right for me.
Any suggestions/critics are welcome.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38472
    
  23
Yes, you have some repeated code. I suggest you print that code out, correctly indented (the first if should be one place farther to the right, for example). Then get different coloured pens and mark the extent of the loop and each if. Then you can work out where to put the last three print statements so as to avoid the duplication. If you get them in the right location, you can reduce them to two. And they will look different from each other.
There is a good reason for several println statements at the beginning of that loop. Because println uses the platform‑specific line terminators, you get the correct line end every time you finish a println statement. Much better than messing around with \r and \n.
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4456
    
    6

When you see repetitive code, think "extract method refactoring" to eliminate duplication


Junilu - [How to Ask Questions] [How to Answer Questions]
Max Grossenbacher
Greenhorn

Joined: Apr 13, 2013
Posts: 5
This is how it worked for me, I get the repetition of and the word bottle is spelled correctly when there is only 1 (ONE) bottle:


Hope this helps
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38472
    
  23
Welcome to the Ranch
Why do you have the last if-else? You can get rid of that and still print no more bottles…
Johan Fourie
Greenhorn

Joined: Sep 10, 2013
Posts: 14
This is my attempt. I do not know the song at all.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Head first Beersong