• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Paul Clapham
  • Ron McLeod
Sheriffs:
  • Jeanne Boyarsky
  • Liutauras Vilda
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Roland Mueller
  • Piet Souris
Bartenders:

Nested while loop inside do...while loop?

 
Ranch Hand
Posts: 76
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am brand new to Java and have no previous programming experience-period. So, please bear with me. I study hard. I work hard. Sometimes, though, those two things are not enough.

My problem is that I have a program written to prompt for and receive employee information: name, hourly rate, hours worked. It would then display this info on the screen and repeat the process until the user entered the sentinel value "stop" in the name field. (That worked fine.) I then had to modify it so the program would check that hourly rate and hours worked were not negative numbers. I used if...else statements and they worked fine. Once. The 2nd successive negative number was accepted.

My code is as follows:



I've gone back to my textbook and our assigned reading. I cannot find the answer I'm looking for. The textbook is an electronic version, and we are only given specific portions of the textbook. No index, no Table of Contents, no appendices. While I have ordered a hard copy of the book, that doesn't help me, now. I take my classes online and my instructor has 24 hours in which to answer my question, but he has no Friday or Saturday office hours. Hence, my mounting frustration and desperation.

Can anyone help me?
[ May 08, 2008: Message edited by: fred rosenberger ]
 
Marshal
Posts: 80874
506
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Suggest changing the bit about !name.equals("stop") to !name.equalsIgnoreCase("stop"). You will have to find the String class in the API, both to check what equalsIgnoreCase does, and to find out whether I have spelled it correctly.

You are using a do-while loop it would appear.

Lose the bit about if(name.equals("stop") . . . else in the middle of the loop. The simplest way to sort this out with a do-while loop unfortunately requires duplication of code.

Move the bit which asks for name to the end of the loop, just before
} while (!name.equals("stop"));

Now the only problem is, you will have to write more code just before the do to get a name before the loop starts.

There is a way run a while loop whereby you can get the input inside the () after "while" but that is a bit more complicated to read. Leave that until after you get that do-while working properly, I suggest.
 
Robin Lane
Ranch Hand
Posts: 76
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Lose the bit about if(name.equals("stop") . . . else in the middle of the loop.



Unfortunately, I cannot. It is stipulated in the class syllabus that the loop must be able to terminate when the user enters "stop" in the name field. And that part works fine.

Initially, inside the do...while loop, I had the following:

System.out.println();
System.out.print( "Enter hourly rate of pay: ");
hourlyRate = input.nextDouble();

if ( hourlyRate <= 0 );
{
System.out.print( "Re-enter hourly rate of pay: ");
hourlyRate = input.nextDouble();
}
else

This worked fine as long as a negative number was only entered once. If the user made a mistake and entered -25 once, the re-enter prompt displayed and the program accepts another value. However, if the user makes two mistakes in a row, the 2nd negative value is accepted. So, while it worked it, it only worked once. So, my instructor suggests I change my if...else to a while loop. Hence, the following code:

System.out.println();
System.out.print( "Enter hourly rate of pay: ");
hourlyRate = input.nextDouble();

while ( hourlyRate <= 0 );
{
System.out.print( "Re-enter hourly rate of pay: ");
hourlyRate = input.nextDouble();
}//end while



It compiles, but as soon as I run the execution file and enter a negative number the program freezes. I'm assuming that it is a logic error (believe me, I'm soooo still learning the very, very basics). But I can't figure out what I've done wrong and what to do differently.

I've read the API. I have a copy of it on my hard drive! <starts laughing at self> API doesn't tell me how to effectively nest a while loop inside a do...while loop. It might tell someone else with a lot more experience, but it doesn't "speak" to me the same way.

You will have to find the String class in the API, both to check what equalsIgnoreCase does, and to find out whether I have spelled it correctly.



Regarding equalsIgnoreCase, I did happen to find that in the API and it does allow "stop" to be any mixture of upper and lower case letters and perform the exact same way. I appreciate the suggestion, because I was wondering about that myself. However, I would just like to get this nested repetition statement worked out first.

Any thoughts?
 
Campbell Ritchie
Marshal
Posts: 80874
506
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Repeat: Lose the bit about if (name.equals("stop")) . . . else. Your loop terminates at the end with the while (!name.equals("stop")); bit.

A while loop tests for repetition at its beginning and a do-while loop at its end. So to test whether the name is "stop" you have to have an opportunity to enter "stop" just before the end of the loop. The only problem is that you have to enter the name before the start of the loop. A private String getName() method and employeeName = getName(); in two places would sort that out without the duplicated code I mentioned earlier.

Look very closely at your bit about while <= 0.00. See the ; afterwards? Were you told that putting a ; after a while or if is almost always a mistake? What happens is the compiler interprets that as "while you have a negative number, do nothing then do it again . . . " That is the cause of your problem.
 
Campbell Ritchie
Marshal
Posts: 80874
506
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Robin Lane:
API doesn't tell me how to effectively nest a while loop inside a do...while loop. It might tell someone else with a lot more experience, but it doesn't "speak" to me the same way.

That's not in the API at all. Now, the Java Tutorials, that probably hasn't got nested loops, but you should find something useful there.
 
Robin Lane
Ranch Hand
Posts: 76
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Look very closely at your bit about while <= 0.00. See the ; afterwards? Were you told that putting a ; after a while or if is almost always a mistake? What happens is the compiler interprets that as "while you have a negative number, do nothing then do it again . . . " That is the cause of your problem.





Of course! The semicolon marks the end of a statement. My while loop doesn't end at the end of the line but at the end of the statement! Thank you!
 
Campbell Ritchie
Marshal
Posts: 80874
506
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You're welcome. And have you worked out why you don't need that if . . . else in the middle of your loop yet?
 
Robin Lane
Ranch Hand
Posts: 76
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
<thinks carefully and speaks slowly> Is it because... I have it as a while condition? Therefore, the loop will terminate, anyway? So, a while loop would work just as well as my do...while? Would it be even more efficient to change it to a while loop?
 
Campbell Ritchie
Marshal
Posts: 80874
506
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes, but one thing at a time.

You have worked out why the if block is unnecessary.
Then remember you have to lose the else (but keep the rest of the code) because you can't have an else on its own.

Then remember for a do loop you will need name entry before the loop and just before the end. That way you can do this
  • Enter Campbell
  • Start do loop
  • Enter $250.00 per hour
  • Enter 168 hours worked this week
  • See wages!
  • Enter stop near the end of the loop
  • Finish loop.
  • Yes, a while loop would be more efficient, but the syntax for that is so confused-looking your teacher will never believe you worked it out yourself.
     
    Robin Lane
    Ranch Hand
    Posts: 76
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    <mulling over what I read> Okay, I'll stick with the do...while loop because I actually want to be able to write it myself.

    Now, I only posted my do...while loop. I didn't paste all of it. It's a sad, dinky little program but we all have to start somewhere, don't we?

    To be honest, I was uncertain about the private String but everything compiled and executed. My entire code is as follows:



    Is this what you meant? Do I need a setEmployeeName method?
    [ May 08, 2008: Message edited by: fred rosenberger ]
     
    Campbell Ritchie
    Marshal
    Posts: 80874
    506
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    No, I think for that sort of program the idea is to practise writing loops, so you don't need to make your name a field.
    But you do need to ask for the name immediately before the beginning of the do loop and immediately before it ends. Then you can have a real-looking name and still get a response to "stop."
     
    lowercase baba
    Posts: 13091
    67
    Chrome Java Linux
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hey Robin,

    I've edited a few of your posts to make them more legible. whenever you are posting code, try to use the code tags... you can press one of those "Instant UBB Code" buttons to drop the tags in, then paste your code between them. or, you can manually do this:

    [ code]
    //source code goes here
    [ /code]

    only don't use the spaces. this preserves your formatting and indentation, making it much easier to read.
     
    Robin Lane
    Ranch Hand
    Posts: 76
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Okay. So... would I leave the following?



    I take out the if...else statement.

    Move or copy the statement that prompts and reads name input from the user to right before the display of employee information toward the end of the loop? Or should I place it after and before while? If I put it right before the while, the info will still be available for the display statement because it is entered prior to the loop?

    I think I'm getting tangled up... (tries to find the end of her String). But we start on new chapters next week, and I simply have to get this right before I move on.


    ( Thank you, Fred. I hope I did it right this time. I'm a complete UBB novice. Don't even know exactly what it is. )
    [ May 08, 2008: Message edited by: Robin Lane ]
     
    Campbell Ritchie
    Marshal
    Posts: 80874
    506
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Nearly . . .
    Yes, you get rid of the if . . . else, but keep what follows the else.
    Yes, you move the prompt for name entry to just before the end of the do-while loop.
    Then you will need another prompt for name entry just before the start of the do-while loop.

    If you write a private String getName() method you can call that method instead of the two name prompts.
     
    Robin Lane
    Ranch Hand
    Posts: 76
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Originally posted by Campbell Ritchie:
    [QBIf you write a private String getName() method you can call that method instead of the two name prompts.[/QB]



    Alright... (pauses to collect thoughts)... would I change the public String getName() to private? Then, use method... what would I use to call it? Would I write name=input.next(getName);?

    You are being so amazingly patient and helpful. I want you to know I really appreciate this!
     
    Campbell Ritchie
    Marshal
    Posts: 80874
    506
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Not got a lot of time, sorry. You can have a public method instead.

    But I suggest, for the time being:

    Write an "enter name" block just before the do loop.
    Write another "enter name" block just before the end of the do loop.

    Get that lot working. Note that if you enter "stop" the very first time, you will be asked how much stop's wages are.

    Then consider refining it with a getName() method.
     
    Campbell Ritchie
    Marshal
    Posts: 80874
    506
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    I am having a bad day; I had to sit an exam and have spent 3 hours writing for the first time in many years.

    If you use a do-while loop you need to enter the name before you start the loop, then name or "stop" as the last part of the loop. Sorry to repeat myself. A getNameFromKeyboard() method can make you code neater. I called it getName(), but of course that sort of name is reserved for the ordinary accessor methods, so sorry for that mistake.
     
    Robin Lane
    Ranch Hand
    Posts: 76
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Three hours? That must have been... not fun. I'm so sorry. Taking the time to help me out with my little problem has probably only made your day worse. I am immensely grateful.

    I have been working on it today, just so you don't think I'm sitting around waiting on someone else to hand me the answer. I'll keep plugging away with the fabulous advice you've given me and see how I do. Hopefully, I won't misplace anymore ; and come here to show it off to the entire Java Ranch community. That was so embarrassing!
     
    Robin Lane
    Ranch Hand
    Posts: 76
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    I had a thought, though admittedly it may be a bad one (laughs)...

    Could I put an if (employeeName.equalsIgnoreCase("stop")) (then) exit system after the prompt for employee name that comes immediately before the do...while loop? This would then prevent entering the do...while loop and, thus, I wouldn't have a prompt to enter wages, etc., for the "stop" employee. Or is that just like a novice to think it would be a good idea?
     
    Robin Lane
    Ranch Hand
    Posts: 76
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    It worked! It worked!

    Cheers, Mate! (starts laughing)
     
    Campbell Ritchie
    Marshal
    Posts: 80874
    506
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    No, helping you made me feel better.

    Better to put if(!employeeName.equalsIgnoreCase("stop"))
    {
    } round the entire do loop, rather than an exit() call.

    You asked whether it is more efficient to use a while loop. The answer is yes. But the syntax looks very confusing. You know a while loop has its test at the beginning? Well you can get both reading the name and testing whether it equals stop inside the test.

    You have to declare name first . . .
    String name;
    . . .
    Then you can get name from your Scanner

    name = inScan.next()

    I have left out the ; for a reason.

    You can test whether name.equalsIgnoreCase("stop") in the same statement. All you have to do is add .equ--l---...

    But you can't add .equals, can you?

    Yes, you can but only with the help of ()

    You end up with

    (name = inScan.next()).equalsIgnoreCase("stop")

    The pair of round brackets/parentheses() around name = means that the = and therefore the reading call are done before the equalsIgnoreCase call. It won't work otherwise.

    Then you put all that lot inside the () after the while, and it will work beautifully . . . .











    Once you work out which bit I have quietly omitted.
     
    Robin Lane
    Ranch Hand
    Posts: 76
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    All you have to do is add .equ--l---...



    I love a mystery! First, is the key to the puzzle actually the .equ--l---... part? If so, do the dashes stand for missing letters? The exact number of missing letters? And will I find it in the API?
     
    Campbell Ritchie
    Marshal
    Posts: 80874
    506
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Originally posted by Robin Lane:


    I love a mystery! First, is the key to the puzzle actually the .equ--l---... part? No
    If so, do the dashes stand for missing letters? No
    The exact number of missing letters? No
    And will I find it in the API? No

    Yes, you've got a mystery. It is really something simple, and I wouldn't have given you it if I had thought it would take you more than 10 minutes to solve.

     
    Robin Lane
    Ranch Hand
    Posts: 76
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    It is really something simple, and I wouldn't have given you it if I had thought it would take you more than 10 minutes to solve.



    (cracks up laughing)
     
    Robin Lane
    Ranch Hand
    Posts: 76
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Campbell, haven't you noticed that I can be really bad at simple? Remember the misplaced semicolon? (starts laughing at self again)

    You're about 5 hours ahead of me, aren't you?
     
    Campbell Ritchie
    Marshal
    Posts: 80874
    506
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    No, I'm about 4 years ahead of you, in programming experience.

    Put together what you can, try it with "Robin" and try it with "stop". Then work out what I have missed out.

    And if anybody else is reading, don't you dare tell him the answer.
     
    Robin Lane
    Ranch Hand
    Posts: 76
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    You're more like 40 years ahead of me in programming expertise! But you're more like Neo from the Matrix in terms of guessing gender.
     
    Campbell Ritchie
    Marshal
    Posts: 80874
    506
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Sorry, but in this country Robin is a boy's name.
     
    Robin Lane
    Ranch Hand
    Posts: 76
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    It's okay. (warm smile) It can be a boy's name here, too. Usually, though, my sparkling personality gives me away!
     
    Robin Lane
    Ranch Hand
    Posts: 76
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Okay... (rubs hands together) (cracks knuckles)

    Here's what I've got... (loosens shoulders and neck)

    I've got code that a) compiled, b) executed correctly, but c) is probably a mess! I couldn't get the program to exit immediately after stop was entered without the if (employeeName.equalsIgnoreCase("stop")) then display Exit Message and System.exit(0);;.

    I know. I know. Smack my hand for it. (holds out left hand to be smacked)

    Anyway, here's my code in all it's Java Kindergartner glory:



    Well, oh Java Guru? How did I do for a total programming novice?
     
    Campbell Ritchie
    Marshal
    Posts: 80874
    506
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Not bad. You solved my little mystery, but you have still got the unnecessary if-else. Delete from
    if(name.equals("stop")
    to
    else.

    You also have two loops redundantly nested inside each other. If you have the while(!(name = loop then you can lose the beginning and end of the do-while altogether. Just move the bit about "Thank you for using Payroll Pro III" to after the end of the while loop, and you can see how it still works.

    If you are using printf print "%nThank you for using PayrollPro III%n" then you can dispense with the two println() calls.

    But surely it's Payroll Pro IV now?
     
    Robin Lane
    Ranch Hand
    Posts: 76
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    As it is abundantly clear, I'm positive you've noticed I still get tangled up in my loops. You've helped me immensely, Campbell, and I'm very grateful. Did you notice the kudos in my program description?


    //variable employeeName. Many thanks go to my instructor, Srini, and Campbell Ritchie
    //a member of Java Ranch who very patiently guided me through to a better
    //understanding of loops in Java.



    Thanks for pointing out my redundancy. (Redundancy is only good in networks! And maybe a good beer.) I had gotten so caught up in working out how to get the name input and test it against the condition (your little mystery) that I had forgotten we were trying to replace the whole do...while loop with just a while repetition statement. (chuckles nervously)

    I'll get that bit cleaned up and, yet again, (because you just can't be too polite! ) Thank You.

    [ May 10, 2008: Message edited by: Robin Lane ]
    [ May 10, 2008: Message edited by: Robin Lane ]
     
    Robin Lane
    Ranch Hand
    Posts: 76
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Here's the most recent (and hopefully final) version.



     
    Campbell Ritchie
    Marshal
    Posts: 80874
    506
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Well done . . . and a girl who likes beer!

    I find lots of people asking me for help and it is surprising how much time I spend telling them "delete this" or "delete that" because those bits are unnecessary. See how neat and tidy the code looks when you get it sorted out.
     
    Robin Lane
    Ranch Hand
    Posts: 76
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    It does look so much better. I would have written it out in pseudocode first and that would have eliminated a bunch of the code mangling. However, I learned how to write pseudocode using keywords that are less like Java than plain old pseudocode is supposed to be. (Does that sound right?) In other words, I learned to pseudocode with display instead of System.out.print-whatever, for example. Now, I know that Java's "display" is System.out.print-whatever, but I'm still trying to get used to the language of Java. Writing pseudocode with display instead of System.out.print-whatever doesn't help me to learn Java. Writing System.out.print-whatever does! I also learned loop keywords like repeat-until, and the equal sign could be used with strings. So, I'm trying to get to a comfort zone with some small knowledge of Java's language, before I go back to writing real pseudocode again.

    What I want most is to do my best, whatever I'm doing. If it's writing Java, I want to write the best code possible. Yes, it takes time because there is so much to learn. And I want to learn it all.

    I'm not at all ambitious.

    And I love a good beer! But I drink responsibly! (starts laughing)
     
    Robin Lane
    Ranch Hand
    Posts: 76
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    before I go back to writing real pseudocode again.



    That's an oxymoron, isn't it?
     
    reply
      Bookmark Topic Watch Topic
    • New Topic