• Post Reply Bookmark Topic Watch Topic
  • New Topic

ending my loop  RSS feed

 
Alex Houser
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello,

My head hurts from pounding it on my desk and I realize I am probably doing something really stupid here, but I am stumped.  I have a WHILE loop that runs if the answer to my question (do you want to add a name and grade) is yes, adding data to a hashmap. If I answer no, the loop ends, no problem.  If I say yes, I can add my name, get prompted to continue, then enter more.  So far so good.  However, if I answer my DO YOU WANT TO CONTINUE question as no, it stays in the enter name loop.

What am I doing wrong here?  Thanks in advance!

Output if I say yes:


run:
Would you like to add a student?  Type YES or NO:
YES
Enter a new name:
JOE
Enter a new grade:
EE
Do you want to continue?
YES
Enter a new name:
JOEJOE
Enter a new grade:
22
Do you want to continue?
NO
Enter a new name:
  //NOTICE WHAT HAPPENS HERE...

Output if I say NO:

run:
Would you like to add a student?  Type YES or NO:
NO
THIS IS A TEST, THE LOOP CLOSES!!!  //WORK FINE...


My code:

 
Bear Bibeault
Author and ninkuma
Marshal
Posts: 66260
151
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Where, inside your first loop, does the value of a get changed? If the value never changes, how can the loop ever exit?
 
Liutauras Vilda
Marshal
Posts: 4800
330
BSD
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Do you need second loop for the no case?
 
Alex Houser
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Liutauras Vilda wrote:Do you need second loop for the no case?


That's what I was attempting with that second while statement, but it didn't work.
 
Alex Houser
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Bear Bibeault wrote:Where, inside your first loop, does the value of a get changed? If the value never changes, how can the loop ever exit?


You're right it doesn't, but I wasn't sure where to put my "no" statement.  Should that be included inside the loop?  If so, how? 
 
Campbell Ritchie
Marshal
Posts: 56209
171
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, what will happen if you ever get into the loop with “no”?

If your input equals “yes”, it can't equal “no”. You can test for either, but testing for both is liable to cause confusion
 
Alex Houser
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:

Well, what will happen if you ever get into the loop with “no”?

If your input equals “yes”, it can't equal “no”. You can test for either, but testing for both is liable to cause confusion


That's what I was attempting with the "DO YOU WANT TO CONTINUE?"  question.  I want the loop to end if the user says no so I can move to the next step in the program.  Is a WHILE loop the right thing to use here?  It doesn't seem like anything else will do what I need.  I need to allow the user to enter an unknown amount of entries, one at a time as they answer yes, but then end the loop if they say NO. 
 
Alex Houser
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You guys got me thinking some more about my loop and a light came on.  I made some changes to my code to tie in my "NO" and a break and it worked.  Now to add this code into my real program and see if it works.  Thanks guys.




I got a much better output:
run:
Would you like to add a student?  Type YES or NO:
yes
Enter a new name:
hank
Enter a new grade:
33
Do you want to continue?
yes
Enter a new name:
joe
Enter a new grade:
55
Do you want to continue?
no
THIS IS A TEST, THE LOOP CLOSES!!!
BUILD SUCCESSFUL (total time: 14 seconds)
 
Fred Kleinschmidt
Bartender
Posts: 567
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In your original post, you have the loop:

Iff "a" is "yes" then you will enter the loop. But since you never modify "a" in the loop, you will stay in the loop forever.
 
Campbell Ritchie
Marshal
Posts: 56209
171
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
. . . and if you ever get into the second loop, you will be stuck there forever too.
 
Junilu Lacar
Sheriff
Posts: 11434
176
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Alex Houser wrote:You guys got me thinking some more about my loop and a light came on. I made some changes to my code to tie in my "NO" and a break and it worked.

Sorry to rain on your parade but that light that came on was a little dim and dirty because that solution is a kludge (an awkward, inelegant solution)

You got some hints as to what the problem was (a was never assigned a different value) but that didn't seem to help so here's another hint. Look at this:

Line 19: You prompt the user to enter "yes" or "no"
Line 20: You read in what the user typed (but then throw away whatever it was)

If you still don't get it, ask yourself where did the value that in.nextLine() returned go? What variable did it get assigned to? Your kludgy solution was to introduce another variable, b.  Your while-loop, however, is checking variable a. There is no need for variable b or that if-statement with the break in it. That's kludgy.

I hope this lights up a brighter and cleaner light for you...
 
Alex Houser
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

I hope this lights up a brighter and cleaner light for you...


Thanks for the input, kludgy ain't good...   I think part of my problem (besides not being the sharpest tool in the shed) is that I don't fully understand in.nextLine and what it does.  I need to read up on that some more.

And please, y'all feel free to drop a few more hints.
 
Junilu Lacar
Sheriff
Posts: 11434
176
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In the kludge, you wrote:

Here, you assign the value returned by the method call to a variable, b.

Look at what you did on line 20 of the code that didn't work. See the difference? So, a better solution is not to introduce yet another variable to hold the user's answer but to use the one you declared in the first place, the one you were checking in the while loop.

A simple way to make your code more readable (variables like a and b are meaningless), you can use a name like answer instead. Choose good variable names that reflect their purpose/intent.
 
D Reges
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Alex Houser wrote:I think part of my problem (besides not being the sharpest tool in the shed) is that I don't fully understand in.nextLine and what it does.  I need to read up on that some more.

And please, y'all feel free to drop a few more hints.


Like others have noted already - your problem is the infinite loop, because you have provided no way of changing "a". Basically, something is missing in your code on line 20.
nextLine() does exactly what it says - it gets the next line ;) in your case, a String typed in the console.

I agree with Junilu - you could use better names for your variables. For example, instead of writing your Scanner as:


you could've used:


this way in.next() would've been userInput.next() - helps avoid confusion. Because in.nextLine() is not a command of some sorts, rather "in" is the name of your Scanner object and the "nextLine()" is the method you call on that object.

My suggestion is to replace all occurrences of "in" with "userInput" (except "System.in") and it should become much clearer.

you should read a bit more on the Scanner class. But in a nutshell, it would be best to use the right method for the right input. Besides next() and nextLine(), Scanner has nextInt() that would read integers, nextDouble(), etc.
In your code, for example, you use Scanner.next() to get the name of the student, but next() returns a token, thus if the user typed "Mike Smith", only "Mike" will be returned.
 
Alex Houser
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks everyone!  Still working through all your comments, but this was very helpful and greatly appreciated!
 
fred rosenberger
lowercase baba
Bartender
Posts: 12558
49
Chrome Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
One of the hardest things to learn is that programming should be about 90% thinking, and only 10% typing.  And further, you shouldn't be thinking in "java" terms, but in natural, human terms.  you should think through your problem, and literally write out in English (or whatever natural language you choose) the steps.

1)  Ask if you'd like to add a student
2)  get their response.
3)  If they say yes, add a student
4)  If they say no, tell them thanks and quit.

Once you've done that, look at it. Think about it. Does that do everything you need? Should you add other steps?  Do you know how to code all those steps?  Depending on these answers, you'll revise these many, many times, expanding on some, moving stuff around, cleaning it up.  So a second pass might be:

1)  Ask if you'd like to add a student
2)  get their response.
3)  if they say yes,
4)     add a student
5)     ask if they want to add another student
6)   if they still say yes, go back to line 4
7)   at this point, they must have said no...
8)   so thank them and quit.

Now we can start to see how the program should be laid out.  I can see what should be inside a loop.  I can maybe start to see what should be its own method (addStudent(), askForInput(), possibly others...)

You'd probably revise this a few more times.  THEN you start writing ONE method at a time, writing just enough other code to test that method (and some of that "skeleton" code will be thrown away eventually).  Once you have a single method done, tested, and working well, THEN start writing the next. At that point, you stop worrying about the first method, because you KNOW it works....so you can focus your attention on the new piece of the puzzle and not be distracted by the other....

THAT's how you write a program.

As you do it more, you can start taking shortcuts, because you learn the idioms.  But for now, you need to think more and type less.
 
Alex Houser
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Great advice Fred, thanks.  Thank you everyone.  I've taken this entire thread and printed it out so I can ponder everything in it. 
 
Randy Maddocks
Ranch Hand
Posts: 172
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As usual the responses from the esteemed forum staff to this post are bang on!

fred rosenberger wrote: And further, you shouldn't be thinking in "java" terms, but in natural, human terms


And the above quote, especially, I agree with 100%. When I started learning programming over 30 years ago a wise teacher started us off by writing out (by hand), line by line, how a problem would be approached and, ultimately, resolved. This was before he would allow us to do any coding whatsoever. It was my introduction to the term "pseudo code". I have been using that methodology ever since...

It has doubtless saved me countless hours of having made the mistake of jumping right into coding without any thought or consideration to the scope, potential challenges, a complete understanding (or at the very least a good grasp) of the problem (whether it was back in my school days with computer assignments, or after I graduated and got out into the working world).

This rings especially true for this topic of "loops", where possibly multiple decisions need to be made based on a particular condition (or conditions). Fred's numbered outline of the loop in plain English perfectly exemplifies that.
 
Campbell Ritchie
Marshal
Posts: 56209
171
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
D Reges wrote:. . . you use Scanner.next() to get the name of the student, but next() returns a token, thus if the user typed "Mike Smith", only "Mike" will be returned.
What happens if you combine next() and nextLine() or nextInt() and nextLine()? What does your book say nextLine() does?

And welcome to the Ranch
 
Alex Houser
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It was my introduction to the term "pseudo code". I have been using that methodology ever since...

You know, I learned that in the beginning of my first class, and even had to submit pseudo code with a few assignments, then just stopped using it.  Great point.
 
Alex Houser
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

What happens if you combine next() and nextLine() or nextInt() and nextLine()? What does your book say nextLine() does?

And welcome to the Ranch


Book definition:

"The java.util.Scanner.nextLine() method advances this scanner past the current line and returns the input that was skipped. This method returns the rest of the current line, excluding any line separator at the end. The position is set to the beginning of the next line."

Thanks for the welcome

What happens if you combine next() and nextLine() or nextInt() and nextLine()?[/quote

I will mess around some with this.
 
Randy Maddocks
Ranch Hand
Posts: 172
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Alex Houser wrote:You know, I learned that in the beginning of my first class, and even had to submit pseudo code with a few assignments, then just stopped using it.  Great point.


Thanks Alex, and welcome to the Ranch!  
 
Campbell Ritchie
Marshal
Posts: 56209
171
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Alex Houser wrote:. . . "The java.util.Scanner.nextLine() method advances this scanner past the current line and returns the input that was skipped. This method returns the rest of the current line, excluding any line separator at the end. The position is set to the beginning of the next line."
Ooooooooh, a book which actually got it right. Which book was it? I have seen lots of books get it wrong. That looks almost identical to what it says in the API documentation.
Thanks for the welcome
That's a pleasure
. . . I will mess around some with this.
Good idea
 
Alex Houser
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

I went back, thought a bit, and took another shot at the code.  It works as shown below, and I took that second input variable and the if statement.  Junilu is this a bit less kludgy? 




Final output:

run:
Would you like to add a student?  Type YES or NO:
yes
Enter a new name:
Joe
Enter a new grade:
65
Would you like to continue?(YES/NO)
yes
Enter a new name:
Fred
Enter a new grade:
98
Would you like to continue?(YES/NO)
yes
Enter a new name:
Harold
Enter a new grade:
78
Would you like to continue?(YES/NO)
no
FINAL STUDENT GRADE LIST: {Joe=65, Harold=78, Fred=98}
BUILD SUCCESSFUL (total time: 4 minutes 54 seconds)
 
Campbell Ritchie
Marshal
Posts: 56209
171
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Why are you calling newLine() repeatedly? There is no need for that. You can remove all those nextLine() calls. Only call next() or nextLine() on a Scanner to assign to something, or when you need to discard the next something. I can see no need to discard anything here.
Declare your Map as Map not hash map:
Map<String, String> list = new HashMap<>();
That way you are not constraining yourself about the actual implementation.
Don't call a Map list; that can be very confusing. Give it a descriptive name so readers will know what it is there for.
Minor point: I am sure everybody else would make users write YES/NO, but you are actually testing for YES/yes, not no. Consider a different continuation message (minor point only).

I would suggest those enhancements, but you shou‍ld be able to see for yourself whether the code is now any better

Have you considered a do loop instead of a while?
 
Alex Houser
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


Why are you calling newLine() repeatedly? There is no need for that. You can remove all those nextLine() calls. Only call next() or nextLine() on a Scanner to assign to something, or when you need to discard the next something. I can see no need to discard anything here.
Declare your Map as Map not hash map:
Map<String, String> list = new HashMap<>();


Done, thanks.  She is quite a beauty now, I've never seen code so nice!  (just kidding)    This has been a huge help, I'm appreciative of all the feedback, it's been a great learning experience.
 
Campbell Ritchie
Marshal
Posts: 56209
171
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well done
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!