I understand that while the state is true the loop will keep running. I thought if I simply typed in loop=false, after the } bracket for the loop I could continue to code. Obviously I was wrong, it wont run anything. SOMEONE please show me how to get out of this hell of a while loop.
System.out.println("You total balance is 0.00, "
+ "please deposit coins and type done when finished");
while(loop){
if (input.hasNextInt()){
deposit = input.nextBigDecimal();}
String change = input.next();
switch (change){
case "quarter":
balance= quarter.multiply(deposit);
total=total.add(balance);
System.out.println("Your balance is "+ total +" :Make addiontal deposit(s)");
break;
case "dime":
balance=dime.multiply(deposit);
total=total.add(balance);
System.out.println("Your balance is "+ total +" :Make addiontal deposit(s)");
break;
case "nickel":
balance=nickel.multiply(deposit);
total=total.add(balance);
System.out.println("Your balance is "+ total +" :Make addiontal deposit(s)");
break;
case "penny":
balance=penny.multiply(deposit);
total=total.add(balance);
System.out.println("Your balance is "+ total +" :Make addiontal deposit(s)");
break;
case"done":
System.out.println("Your total is $"+total);
fee=total.multiply(feeRate);
System.out.println("The exchance fee is 9.1% which amounts to $"+fee);
grandTotal=total.subtract(fee);
System.out.println("Your total balance minus the exchange fee is $"+grandTotal);
break;
default: System.out.println("There is a issue at "+change);}
} System.out.println("4");
}
}
The key is to change the loop variable so that it becomes false and will thus have you exit the while loop. So change the loop variable in the case "done" block. In that block, set loop = false;
case"done":
System.out.println("Your total is $"+total);
fee=total.multiply(feeRate);
System.out.println("The exchance fee is 9.1% which amounts to $"+fee);
grandTotal=total.subtract(fee);
System.out.println("Your total balance minus the exchange fee is $"+grandTotal);
loop = false; // ************ add this ************
break;
Keep in mind that the key concept is that the thing that is causing the loop to continue must be changed somehow within the loop itself. Otherwise the while loop will never end.
Three methods to break a loop.
A) set your flag variable to false:
loop = false;
Since you already have this variable, this is the much nicer (and simpler) approach.
B) use a labeled break.
label: while(true) {
// ...
switch(something) {
break label; // Without a label, it would only leave the switch!
}
}
Some people will frown upon this last solution, because it is essentially a "goto".
C) use more modular code.
In many cases, the much cleaner way is to use methods. Then you can have "break" to exit an inner loop or switch and return to actually leave the subprocedure and return a result.
This leads to easier-to-understand code, and the semantics of a return are often much more appropriate than those of a break.
Your loop will continue to go round until the loop variable is set to false. In the "done" case, just set that to false. That way, it won't loop back around again.
case"done":
System.out.println("Your total is $"+total);
fee=total.multiply(feeRate);
System.out.println("The exchance fee is 9.1% which amounts to $"+fee);
grandTotal=total.subtract(fee);
System.out.println("Your total balance minus the exchange fee is $"+grandTotal);
loop = false; // This is the line to add.
break;
You have to change the value of the variable loop inside oft the while loop to false.
I guess this should be in the case when the user types done. So in this case add the following line:
loop = false;
anywhere in the case "done": block
Related
I apologize if this question is uber-simplistic, but I'm still in the early stages of learning Java. I have an example program that calls other methods within the class, and I'm not totally following a few of the elements - hoping someone can clarify. It's a simply random number guessing game and it works fine, but I want to better understand some components. Specifically:
There is a boolean variable (validInput) that is declared but never appears to be used anywhere in the methods
There are 2 methods (askForAnotherRound and getGuess) with a 'while' loop that just has 'true' as the variable(?) - i.e. "while (true)."
This code is directly from the example in the book and, again, it works. I just want to better understand those 2 elements above. (I think the validInput variable is not useful as when I 'comment out' that line the code still executes). I'm curious, though, about the "while (true)" element. There is an option to set, in the askForAnotherRound, to set the return value to false (ending the program). Are boolean methods defaulted to 'true' when they are first executed/called?
Again...understand this is probably a super-simple question for most folks on here, but as a newb I just want to understand this as best I can...
Thanks!!!
// Replicates the number guessing game using 4 separate methods.
import java.util.Scanner;
public class GuessingGameMethod2
{
static Scanner sc = new Scanner(System.in);
public static void main(String[] args)
{
System.out.println("Let's play a guessing game!");
do
{
playARound();
}while (askForAnotherRound());
System.out.println("Thanks for playing!");
}
public static void playARound()
{
boolean validInput;
int number, guess;
String answer;
//Pick a Random Number
number = getRandomNumber();
//Get a guess
System.out.println("\nI'm thinking of a number between 1 and 10.");
System.out.print("What do you think it is? ");
guess = getGuess();
//Check the guess
if (guess == number)
System.out.println("You're right!");
else
System.out.println("You're wrong! The number was " + number + ".");
}
public static int getRandomNumber()
{
return (int)(Math.random() * 10) + 1;
}
public static int getGuess()
{
while (true)
{
int guess = sc.nextInt();
if (guess < 1 || guess > 10)
{
System.out.print("I said, between 1 and 10. Try again");
}
else
return guess;
}
}
public static boolean askForAnotherRound()
{
while (true)
{
String answer;
System.out.print("\nPlay again? Y or N: ");
answer = sc.next();
if (answer.equalsIgnoreCase("Y"))
return true;
else if (answer.equalsIgnoreCase("N"))
return false;
}
}
}
I don't see boolean validInput being used either. But if it were to be used somewhere it would probably be to check that you guess satisfies 1 <= guess <= 10.
When it comes to askForAnotherRound and getGuess here's what you should know:
while(true) is always executed. One way you can get out of the while loop is if you use the break statement or if the loop is in a function you can return something. The method askForAnotherRound() will always return either true or false. Depending on the returned value of askForAnotherRound() you will either play another round or not. Note that when you have
`do{
...
someActions()
...
}while(booleanValue)`
someActions() will be executed at least once before it checks for the value of booleanValue which, if it turns out false you'll exit out of the do/while loop. Boolean methods do not default to anything, you have to give them a value.
Hope this helps! I'm also in the process of learning Java right now, so good luck!
As I see you're absolutely true about validInput - it isn't used. May be it will be used in the following chapters.
As for askForAnotherRound() - no, boolean methods don't evalute to true, by default. Even more, Java compiler throw an error if it find a method which does not return value and finish it execution in some cases.
while(true) - it's infinite loop, so it will be executed untill some instruction which interrupts loop, in general it's return statement.
askForAnotherRound() do the following:
- asks user if he/she want to play again
- returns true if user input "Y"
- returns false if user input "Y"
- asks again in all other cases(so it doesn't finish execution) and etc.
Hope it'll help
The validInput is indeed worthless.
The infinite loops are required to read from the console to get a valid input. e.g
while (true)
//start infinite loop
{
int guess = sc.nextInt();
if (guess < 1 || guess > 10)
{
//continue the loop the input is not between 1-10
System.out.print("I said, between 1 and 10. Try again");
}
else
//break out of infinite loop, valid int
return guess;
}
If we take this method without the infinite loop, and i recommend trying this, it will simply return the value read even if it was not valid.
For example.
return sc.nextInt();
will allow any int returned, if we returned anything outside of the bounds in the current impl it would loop again until you enter a value between 1-10
The same is also true for ask for next round, its looping until a valid input is given.
I would bet the next exercises will use the validInput var as both these methods loop until a valid input is given.
You are right about validInput. It is not used. And probably missed after some code change. Should be removed.
while(true) - true is not variable but a boolean constant. It will basically make program run for ever in this case unless somebody kills program. Another alternative would have been to use break to exit out of loop on some condition.
Please have a look on my code its showing code not reachable.
private static void createUser() {
HashMap<String, String> membership = new HashMap<String, String>();
System.out.println("Enter the Name of the User: ");
String nameOfUser=sc.next();
System.out.println("Enter the Membership tier which you prefer");
System.out.println("1. Member - 5 % discount \n 2. Bronze - 10 % discount \n 3. Silver - 15% discount \n "
+ "4. Gold - 20 % discount \n 5. Platinum - 25 % discount");
String typeOfMembership = null;
while(true){
int memberChoice=sc.nextInt();
switch(memberChoice){
case 1:
typeOfMembership="Member";
membership.put(nameOfUser,typeOfMembership);
break;
case 2:
typeOfMembership="Bronze";
membership.put(nameOfUser,typeOfMembership);
break;
default:
System.out.println("Please select one of the available Member Type.");
}
}
for (Map.Entry<String, String> entry : membership.entrySet()) {
System.out.println("Member Created Successfully with name "+entry.getKey()+" and "+entry.getValue()+" tier.");
}
}
Its showing code unreachable from this line onwards
for (Map.Entry<String, String> entry : membership.entrySet()) {
You have an infinite loop while(true) so you will never reach the for loop.
Note: the breaks you have will only break the switch.
Suggestion:
One way to fix it is to exchange the hard coded true, to something like isMemberSelected that you set to false in the default case. You could probably also switch to a do-while-loop.
You could even break it out to a separate method memberships = createMembers();
I think you have an infinite loop at while(true) this will always evaluate to true hence the execution of the script will stay in the loop. Try a different loop guard which shouldn't always evaluate to true.
I am working on a project in which I must calculate mortgage. It's supposed to have a loan selection menu in which 1) uses default values to calculate the mortgage. 2) will allow the user to enter in custom values. 3) allows the user to exit the program and have the calculated values displayed. I have a for loop to allow the program to run up to 10 times (it can be less though). I'm currently using a do-while loop to exit the program when 3 is the selection. However it's not exiting. I"m not sure what is wrong and am hoping for an explanation and some tweaks I could implement to ensure it does what it's supposed to.
do
{
int selection = 0;
for(int i=0; i<loanArray.length; i++)
{
System.out.println("Please choose from the following choices below: ");
System.out.println("\t1) Promotional Loan (preset loan amount, rate, term)");
System.out.println("\t2) Unique Loan (enter in loan values)");
System.out.println("\t3) Quit (Exit the program)");
System.out.println("Please enter your selection(1-3): ");
selection = s.nextInt();
if(selection ==1)
{
loanArray[i] = new Mortgage();
System.out.println(loanArray[i].toString());
}
else if (selection ==2)
{
loanArray[i].storeLoanAmount();
loanArray[i].storeInterestRate();
loanArray[i].storeTerm();
System.out.println(loanArray[i].toString());
}
else if(selection == 3)
{
programSelection = false;
programRunning = false;
}
}//end of for array loop
}while (programSelection == true); //end of selection while loop
System.out.println("Exit Test"); //print statement to test if selection screen exited
I haven't actually tested this, but I think the problem is exiting the for loop. The quickest way to test that is just to use a break statement with a label.
outerLoop:
do
// ...
else if(selection == 3)
{
break outerLoop;
}
}//end of for array loop
}while (programSelection == true); //end of selection while loop
Break statements with labels are discussed in the Java tutorial.
Add a break; after the programRunning = false;
you have got the correct the logic the reason is the for loop.
while (programSelection == true)
will only be executed after the for loop. Need to be cautious as well because if the loanArray length is 1 you might think the code works well,actually it doesnt.
I've nested an IF ELSE statement inside a WHILE statement, but am confused as to why the WHILE is interpreted before the ELSE (when the IF fails). A user is asked to enter a number from 1-10 (inclusive). If the number is inside that range, the program ends. If it's outside of that range, I want to display an error and then prompt them to again enter a number.
It works well if I put the "prompt" before the WHILE, but then I have to put it again inside the ELSE statement for it to show up again. I found this question, but it didn't appear to answer the issue I'm running into. I'm admittedly a Java novice, so I apologize if I'm missing some fundamental aspect of Java.
import java.util.Scanner;
public class Rangecheck {
private static int userNumber; //Number input by user
private static boolean numberOK = false; //Final check if number is valid
//String that will be reused in the DO statement
private static String enterNumber = "Please enter a number from 1 to 10: ";
public static void main(String[] args) {
//Print string
while(!numberOK) // Repeat until the number is OK
{ System.out.println(enterNumber);
Scanner input_UserNumber = new Scanner(System.in); //input integer
userNumber = input_UserNumber.nextInt();
if (10>= userNumber && userNumber >= 1) //Check if 10>=input>=1
{
/*
** If number was valid, congratulate the user and mark numberOK true
*/
System.out.println("Good job! The number you entered is "+userNumber+".");
numberOK = true; // Congratulate user / exit loop if successful
}
else ; //if (10 < userNumber && userNumber < 1)
{
System.err.println("The number entered was not between 1 and 10!");
System.err.print(enterNumber); // Error; user retries until successful
}
}
}
}
I'd expect the System.err.println() to be evaluated in the else statement and then the whileto be evaluated, so that this gets returned:
The number entered was not between 1 and 10!
Please enter a number between 1 and 10:
I've sort of worked around this by putting enterNumber just before while, then putting a second
println in the else statement immediately following the error. It returns what I expect, but I believe I'm fundamentally misunderstanding something.
Let's suppose you have the following code:
while (whileCondition) {
//Inside while, before if
if (ifCondition) {
//Inside if
} else {
//Inside else
}
}
This cycle will execute repeatedly, until the whileCondition becomes false. Whenever the ifCondition is true, the operations inside if will be executed, otherwise the operations inside else will be executed.
Back to your problem:
Your line of
System.out.println(enterNumber);
is at the start of the while. So before the code even gets to your if, the content of enterNumber is displayed on the console. Later, your if is evaluated and if you enter, let's say 22, the condition given to the if will be false and the content of the else block will be evaluated.
The else statement is repeated before the while statement. There can however sometimes be a problem with Streams. A Stream does not necessarily print the data immediately. Especially in the case one uses two different streams, the order of printing the output data can be interleaved.
You can use:
System.err.flush();
to ensure the data is written to the console first.
Add this statement in else body:
numberOk=false;
This feed method is supposed to first increase the energy state and decrease hungry state, use a dumplings meal (which can be purchased in the shop) then see that the item purchased from the shop, is a positive number or greater than 0. Then ensure that hungry and energy states do not go out of bounds (if it does print warning statements).
If it reaches the border of 100 then start increment overfeed, every time method is executed, if overfeed is greater than 4 then execute die method().
If it meets criteria running feed method will print Eating... and I have ate enough(...) statements.
#Override
protected void feed() {
decHungry(10);
incEnergy(10);
shop.useDumplingsMEAL();
do {
if (shop.dumplingsMEAL <= 0) {
JOptionPane.showMessageDialog(null, "You cannot eat right now, You need to purchase item in the shop");
}
else if (hungry <= 0 && energy >= 100) {
System.out.print("\nI have ate enough! My hungry state is " + hungry +
" and my energy state is " + energy + "." );
overfeed++;
while (overfeed>4)
{
die();
System.out.println("You have overfed me.");
}
}
else {
System.out.println("\nEating...");
System.out.println("I've just ate dumplings, my current energy state is " + energy
+" and hungry state is " + hungry + ".");
overfeed = 0;
}
}
You are calling a method called feed. This method looks like it should feed once if it can when it's called. Get rid of all the loops. If you want to keep it, read on do..while loop.
if(no food){
// nothing to feed
} else if (hunger level 0 or below & energy 100 or more){ // by the way hunger level should never go below 0 and energy should never go over 100
// increment overfeed
if(overfeed more than 4) {
// die
}
} else {
// feed
}
Just like the error message says, the syntax for do while is:
do {
// Do stuff
} while(some condition);
Also you seem to have some conditions that won't do what you want.
You are either having problem with your braces {} and indentation or don't understand properly how to use do-while loop.
Do-while should look like following:
do{
//making stuff
}
while(condition of loop);
At the moment your code looks like following:
do{
if(){
}
else{
while{
}
}
}