Exception Thread in Do-While Loop - java

I'm working on a project that calculates the value of a bank account based on starting balance(b), interest rate(IR), and quarters to display. My entire code works perfectly, but the very last portion is to make sure the variables like interest rate are within the confines of the boundaries my professor gave me. I do need to display an error message if the user enters a value outside the boundaries and ask for the value again.
For example, the number of quarters to display needs to be greater than zero, and less or equal to 10.
As you can see, pretty much all of my program is in a do-while loop. I know I can have nested loops, but what would I be able to put in my do-while loop that would work in this situation? An if-else statement? Try and catch block? Another while loop?
If I used a try-catch, then could anyone give me an example of how I could do that? Thank you very much for your time, and all help is appreciated! The below is my code for reference.
import java.util.Scanner;
public class InterestCalculator
{
public static void main(String[] args)
{
Scanner scannerObject = new Scanner(System.in);
Scanner input = new Scanner(System.in);
int quartersDisplayed;
double b, IR;
do
{
Scanner keyboard=new Scanner(System.in);
System.out.println("Enter the numbers of quarters you wish to display that is greater than zero and less or equal to 10: ");
quartersDisplayed = keyboard.nextInt();
System.out.println("Next enter the starting balance. ");
System.out.println("This input must be greater than zero: ");
b = keyboard.nextDouble();
System.out.println("Finally, enter the interest rate ");
System.out.println("which must be greater than zero and less than or equal to twenty percent: ");
IR = keyboard.nextDouble();
System.out.println("You have entered the following amount of quarters: " + quartersDisplayed);
System.out.println("You also entered the starting balance of: " + b);
System.out.println("Finally, you entered the following of interest rate: " + IR);
System.out.println("If this information is not correct, please exit the program and enter the correct information.");
double quarterlyEndingBalance = b + (b * IR/100 * .25);
System.out.println("Your ending balance for your quarters is " + quarterlyEndingBalance);
System.out.println("Do you want to continue?");
String yes=keyboard.next("yes");
if (yes.equals(yes))
continue;
else
break;
}
while(true);
}
}

So here's some code to answer your questions and help get you started. However, there are problems with your logic that do not pertain to your question which I will address afterward.
Note: I have added comments to your code. Most of them start with "EDIT:" so that you can tell what I changed. I didn't use this prefix in all cases because some of it is new code and it's obviously my comment
import java.util.Scanner;
public class InterestCalculator {
public static void main(String[] args) {
// EDIT: you already have a scanner defined below with a more meaningful name so I removed this one
// Scanner scannerObject = new Scanner(System.in);
Scanner input = new Scanner(System.in);
//EDIT: defining userResponse outside the loop so we can use it everywhere inside
String userResponse = null;
do {
//EDIT: moved the variables inside the loop so that they are reset each time we start over.
//EDIT: initialize your variable to a value that is invalid so that you can tell if it has been set or not.
int quartersDisplayed = -1;
//EDIT: gave your variables more meaningful names that conform to java standards
double startingBalance = -1, interestRate = -1;
//EDIT: you don't need a second Scanner, just use the one you already have.
// Scanner keyboard = new Scanner(System.in);
do{
System.out.println("Enter the numbers of quarters you wish to display that is greater than zero and less or equal to 10: ");
userResponse = input.next();
try{
quartersDisplayed = Integer.parseInt(userResponse);
}catch(NumberFormatException e){
//nothing to do here, error message handled below.
}
if(quartersDisplayed <= 0 || quartersDisplayed > 10){
System.out.println("Sorry, that value is not valid.");
}else{
break;
}
}while(true);
do{
System.out.println("Enter the starting balance (must be greater than zero): ");
userResponse = input.next();
try{
startingBalance = Double.parseDouble(userResponse);
}catch(NumberFormatException e){
//nothing to do here, error message handled below.
}
if(startingBalance <= 0){
System.out.println("Sorry, that value is not valid.");
}else{
break;
}
}while(true);
do{
System.out.println("Enter the interest rate (greater than zero less than twenty percent): ");
userResponse = input.next();
try{
interestRate = Double.parseDouble(userResponse);
}catch(NumberFormatException e){
//nothing to do here, error message handled below.
}
//Note: I assume twenty percent is represented as 20.0 here
if(interestRate <= 0 || interestRate > 20){
System.out.println("Sorry, that value is not valid.");
}else{
break;
}
}while(true);
System.out.println("You have entered the following amount of quarters: "
+ quartersDisplayed);
System.out.println("You also entered the starting balance of: " + startingBalance);
System.out.println("Finally, you entered the following of interest rate: "
+ interestRate);
System.out.println("If this information is not correct, please exit the program and enter the correct information.");
double quarterlyEndingBalance = startingBalance + (startingBalance * interestRate / 100 * .25);
System.out.println("Your ending balance for your quarters is "
+ quarterlyEndingBalance);
System.out.println("Do you want to continue?");
//EDIT: modified your variable name to be more meaningful since the user's response doesn't have to "yes" necessarily
userResponse = input.next();
// EDIT: modified the logic here to compare with "yes" or "y" case insensitively.
// if (userResponse.equals(userResponse))
if("y".equalsIgnoreCase(userResponse) || "yes".equalsIgnoreCase(userResponse))
continue;
else
break;
} while (true);
Now to address other issues - your interest calculation doesn't seem correct to me. Your formula does not make use of the quartersDisplayed variable at all. I assume you're compounding the interest quarterly so you will definitely need to make use of this when calculating your results.
This may be beyond the scope of your project, but you should not use double or float data types to represent money. There is a stackoverflow question about this topic that has good information.
Possible improvements - since you're asking the user for two values of type double you could create a method to ask for a double value and call it twice instead of repeating the code. This is a better approach because it helps reduce the chance of mistakes and makes testing and maintenance easier.

You can do something like this in your do/while loop:
do
{
Scanner keyboard = new Scanner(System.in);
do
{
System.out.println("Enter the numbers of quarters you wish to display that is greater than zero and less or equal to 10: ");
quartersDisplayed = keyboard.nextInt();
}
while (quartersDisplayed < 1 || quartersDisplayed > 10);
System.out.println("Next enter the starting balance. ");
do
{
System.out.println("This input must be greater than zero: ");
b = keyboard.nextDouble();
}
while (b < 1);
// rest of code ...
}

With the Scanner#hasNextInt (and the equivalent for double), you can avoid having exceptions thrown, and thus don't need try-catch clauses. I think in general if you can avoid try-catch, it's good, because they are clumsy - but I might be wrong.
However, my approach is like this. Inside your outer do-while, have three other do-while-loops to get the three values. The reason is that you want to keep looping until you get a correct value. The explanation of why keyboard.nextLine() is important is covered here.
I didn't include all of your code, only the part in question. Here's my take on it:
import java.util.Scanner;
public class InterestCalculator {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
int quartersDisplayed = -1;
double b = -1.0;
double IR = -1.0;
do {
do {
System.out.println("Enter the number of quarters.");
if(keyboard.hasNextInt()) {
quartersDisplayed = keyboard.nextInt();
keyboard.nextLine(); //important
} else {
System.out.println("You need to enter an integer.");
continue;
}
} while(quartersDisplayed < 1 || quartersDisplayed > 10);
do {
System.out.println("Enter the starting balance.");
if(keyboard.hasNextDouble()) {
b = keyboard.nextDouble();
keyboard.nextLine();
} else {
System.out.println("You must enter a number.");
continue;
}
} while(b <= 0);
do {
System.out.println("Enter the interest rate.");
if(keyboard.hasNextDouble()) {
IR = keyboard.nextDouble();
keyboard.nextLine();
} else {
System.out.println("You must enter a number.");
continue;
}
} while(IR <= 0 || IR > 20.0);
//... rest of code
} while(true);
}
}

Related

Correct user input not matching array values

I've written a portion of code to take a user input, match it to a string value and then use a related double value to make calculations:
double [] currency = new double[] {0.05,0.10,0.20,0.50,1.00,2.00,5.00,10.00,20.00,50.00,100.00};
String [] currencytext = {"$0.05","$0.10","$0.20","$0.50","$1.00","$2.00","$5.00","$10.00","$20.00","$50.00","$100.00"};
Scanner keyboard = new Scanner(System.in);
for (int i = 0; i < currencytext.length; i++) {
boolean valid = false;
while(!valid){
System.out.format("$%.2f remains to be paid. Enter coin or note: ",sum);
String payment = keyboard.next();
if(payment.equals(currencytext[i])){
sum = sum - currency[i];
if(sum == 0) {
System.out.print("You gave " + payment);
System.out.print("Perfect! No change given.");
System.out.print("");
System.out.print("Thank you" + name + ".");
System.out.print("See you next time.");
}
}
if(!(payment.equals(currencytext[i]))) {
System.out.print("Invalid coin or note. Try again. \n");
}
if(payment.equals(currencytext[i]) && currency[i] > sum){
System.out.print("You gave " + payment);
System.out.print("Your change:");
}
}
}
The problem is that when it gets to user input, it doesn't match any string values except for $0.05. It seems to me like its not iterating through the array properly but I can't figure out why. Is anyone able to see a problem here?
This is a possible solution for your problem
Scanner keyboard = new Scanner(System.in);
double [] currency = new double[] {0.05,0.10,0.20,0.50,1.00,2.00,5.00,10.00,20.00,50.00,100.00};
String [] currencytext = {"$0.05","$0.10","$0.20","$0.50","$1.00","$2.00","$5.00","$10.00","$20.00","$50.00","$100.00"};
String payment = keyboard.next();
double sum = 100; // <- Working example - Read sum from keyboard entry
while (sum > 0) {
boolean paymentFound = false;
for (int i = 0; i < currencytext.length; i++) {
if (payment.equals(currencytext[i])) {
sum = sum - currency[i];
paymentFound = true;
if (sum == 0) {
System.out.println("You gave " + payment);
System.out.println("Perfect! No change given.");
// System.out.print("Thank you" + name + ".");
System.out.println("See you next time.");
break;
} else if (sum < 0) {
System.out.println("You gave " + payment);
System.out.println("Your change:" + (-1 * sum));
break;
}
}
}
if (!paymentFound) {
System.out.println("Invalid coin or note. Try again. \n");
}
if (sum > 0) {
System.out.format("$%.2f remains to be paid. Enter coin or note: ", sum);
payment = keyboard.next();
}
}
while-loop will continue until the payment is fullfilled.
for-loop traverse the arrays until a suitable payment is found
If suitable payment is found we substract it from sum. We use break to exit the for-loop in both cases. There is no need to keep searching.
If no suitable payment is found [!paymentFound], we keep on asking.
if (!paymentFound) {
System.out.println("Invalid coin or note. Try again. \n");
}
if (sum > 0) {
System.out.format("$%.2f remains to be paid. Enter coin or note: ", sum);
payment = keyboard.next();
}
The program will end when (sum < 0), in which case the while-loop exits.
I have use println instead of print to improve message legibility.
Too many flaws to point out.
However,
When the currencytext[i] does not match payment, it executes this code:
System.out.print("Invalid coin or note. Try again. \n");
System.out.format("$%.2f remains to be paid. Enter coin or note: ",sum);
payment = keyboard.next();
So, it executes this for all the times that your input does not match currencytext[i].
And, in this block, you have
payment = keyboard.next();
So, it asks for new input, in this block itself. Hence, you get the said output for all inputs except $0.05.
As far as $0.05 is concerned, your first if block executes successfully, and prints no output. So, it moves to the next iteration of the while loop, where again, payment remains the same ($0.05), but currencytext[i] becomes $0.10. SO they do not match, and you get the said output.
How to correct this:
With this code, you need to do a lot of corrections.
I suggest you again start from scratch.
If it doesn't fit, it sets valid to true, so the code just has the chance to check against the first item at currencytext[0], which is $0.05. Then !payment.equals(currencytext[i]) is also true, and your code prints the lines there. Your else ifs are also not properly nested.
I don't know how you are reading input. One improvement you can do is write reading input code in for loop.
Scanner scanner = new Scanner(System.in);
for (... ) {
....
String payment = scanner.nextLine();
....
}

Making if statements cancel other code. (java)

I am fairly new to programming Java. I want to make a lotto program. Here is the code:
package me.nutella;
import java.util.Scanner;
public class Lotto {
#SuppressWarnings("resource")
public static void main(String[] args) {
try {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter A Number Between 1-20!");
int choice = scanner.nextInt();
if (choice > 20)
System.out.print("Please Only Pick Numbers Between 1-20!");
int b = (int) (Math.random() * 20) +1;
if (choice == b)
System.out.print("You Win!");
else
System.out.print("You Lost! The correct answer was " + b);
}
catch(Exception E) {
System.out.print("Your Answer Must Be Numeric!");
}
}
}
Now, this part if what I am mainly concerned about:
if (choice > 20)
System.out.print("Please Only Pick Numbers Between 1-20!");
I want to make it so if someone puts the number over 20, it will print that message. Now this part does work, but when I put the number over 20, it still plays the lotto game. I want to make it so if they put their number higher than 20, it will not play the game and enter that message.
How can this be done?
Can be most elegantly done using a do {...} while(); loop. At the beginning, the user must always enter a number, so the loop MUST execute at least once. This is where a do {...} while(); loop comes in handy. You can display your message at the beginning of the loop, then read in the users input. If it is in an acceptable range, the loop never re-executes, and the code moves on. But, if it is not acceptable, we re-execute the loop until we get an acceptable value.
Below is how I would approach this problem:
Scanner scanner = new Scanner(System.in);
int choice = 0;
do {
System.out.print("Please Pick A Number Between 1-20!");
choice = scanner.nextInt();
} while(choice > 20 || choice < 1);
It is also worth noting that your message states that "Number between 1-20", but your code only checks that choice < 20, so if a user enter anything LESS THAN 20, it would be accepted. This includes 0, negatives, and of course the valid number range. I added the || choice < 1 check in my example.
What you need is a loop to keep getting inputs if input is not valid:
Scanner scanner = new Scanner(System.in);
System.out.print("Enter A Number Between 1-20!");
int choice = scanner.nextInt();
boolean validInput=false;
while(!validInput) {
int choice = scanner.nextInt();
if (choice > 20) {
System.out.print("Please Only Pick Numbers Between 1-20!");
} else {
validInput=true;
}
}
int b = (int) (Math.random() * 20) +1;
if (choice == b)
System.out.print("You Win!");
else
System.out.print("You Lost! The correct answer was " + b);

Why is my Java for/if/else statement outputting duplicates

I am practicing using loops in Java and I have created this if/else loop to continually ask if there is another customer, if the user input is
"Yes" then it asks for that customers bill.
"No" then I am going to total the bill (I haven't written code for that yet so ignore that part).
The problem I am having is after I enter the initial bill amount the code asks if there is another customer like it should, but then prematurely asks for their bill amount and then asks if there is another customer a second time?
My main question is, did I structure this wrong? How am I able to get the loop to not output something twice and/or prematurely?
Scanner input = new Scanner(System.in);
double total;
System.out.println("Please enter your bill amount.");
double bill0 = input.nextDouble();
for(int c = 0; c > -1; c++) {
System.out.println("Is there another customer?");
String customer = input.nextLine();
if (customer.equalsIgnoreCase("Yes")) {
System.out.println("Please enter their bill.");
double bill = input.nextDouble();
} else {
System.out.println("Okay, let's total your bill amount.");
}
}
for(int c = 0; c > -1; c++)
This loop will (basically) run forever as c will always be greater than -1.
(Actually this loop will run until overflow occurs because the value of c will be too big to fit in the available storage space allocated for this integer. You can refer here for more information: http://en.wikipedia.org/wiki/Integer_overflow)
A cleaner way to structure this would be to do something like:
String answer = "Yes";
while (answer.equals("Yes"))
{
System.out.println("Please enter your bill amount.");
double bill0 = input.nextDouble();
System.out.println("Is there another customer? (Yes or No)");
answer = input.nextLine();
}
Of course, you need to add error handling if the user enters inputs that you are not expecting. Also, this is more pseudocode than a true implementation.
After this while loop is when you would want to total the amount. Also, in the while loop you might want to have a variable keeping the total amount. Something like:
total += bill0;
after the line:
double bill0 = input.nextDouble();
might do the trick.
Matt Jones is correct - your loop (basically) runs forever - (overflow means it doesn't truly run forever, but it's close enough).
It seems you're trying to break the loop once the user enters "No". That means you don't know how many iterations you're going to need, so a while loop is more suited to this task than a for loop. So let's use a while loop to do that.
Scanner input = new Scanner(System.in);
double total;
System.out.println("Please enter your bill amount.");
double bill0 = input.nextDouble();
//loop until the user enters the phrase "No".
while(true) {
System.out.println("Is there another customer?");
String customer = input.nextLine();
if (customer.equalsIgnoreCase("Yes")) {
System.out.println("Please enter their bill.");
double bill = input.nextDouble();
} else if(customer.equalsIgnoreCase("No") {
System.out.println("Okay, let's total your bill amount.");
break; //End the loop
} else{
System.out.println("Sorry, unrecognized input. Please enter yes or no.");
}
}
//Do post-loop totaling and stuff.
I would use a while loop
while (scannerInput.equals("yes"))
//do your thing
}
Once the scanner input doesn't equal "yes" anymore, it will exit the while and do something else
for loops are more to iterate through a set of data, rather than a while, which is waiting for state change.
Scanner input = new Scanner(System.in);
double total;
System.out.println("Please enter your bill amount.");
double bill0 = input.nextDouble();
System.out.println("Is there another customer?");
while((String customer = input.nextLine()).equalsIgnoreCase("Yes")) {
System.out.println("Please enter their bill.");
double bill = input.nextDouble();
}
System.out.println("Okay, let's total your bill amount.");

Checking for negative values with scanner in

I have just written my first java program for a class I am taking which is used to give a student graduation information based on the credits for each class remaining. I have gotten everything to work except the required entry to check for negative values. Please see below and let me know if you have any ideas. Thanks in advance.
package txp1;
import java.util.ArrayList;
import java.util.Scanner;
public class txp1 {
public static void main(String[] args) {
// TODO code application logic here
System.out.println("Welcome to the University Graduation Calculator!");
System.out.println();
System.out.println("This calculator will help determine how many terms "
+ "you have remaining and your tuition total based upon credits"
+ " completed per semester.");
System.out.println();
double tuitionpersem = 2890;
System.out.println("We will begin by entering the number of credits for"
+ " each class remaining toward your degree.");
double sum = 0;
ArrayList<Double> credit = new ArrayList<>();
{
System.out.println("Please enter the number of credits for each individual class on a separate line and then press enter, Q to quit:");
Scanner in = new Scanner(System.in);
double number = 0;
number = Integer.parseInt(in.nextLine());
if (number <= 0);
{
System.out.println("The number of credits must be greater than zero!");
}
while (in.hasNextDouble()) {
credit.add(in.nextDouble());
}
for (int i = 0; i < credit.size(); i++) {
sum += credit.get(i);
}
System.out.println("Total credits remaining: " + sum);
}
int perterm = 0;
System.out.println("How many credits do you plan to take per term? ");
Scanner in = new Scanner(System.in);
perterm = Integer.parseInt(in.nextLine());
if (perterm <= 0);
{
System.out.println("The number of credits must be greater than zero!");
}
double totterms = sum / perterm;
totterms = Math.ceil(totterms);
System.out.print("Your remaining terms: ");
System.out.println(totterms);
double terms = (totterms);
System.out.print("The number of months to complete at this rate is: ");
System.out.println(6 * terms);
double cost = terms * 2890;
System.out.println("The cost to complete at this rate is: " + cost);
}
}
double number = 0;
number = Integer.parseInt(in.nextLine());
if (number <= 0);
The ";" at the end of if statement is the end of it. You are not doing anything with the result of number <=0. I believe you meant it to be like:
if (number <= 0){
//operations….
}
Notice that you create number of type double, then assign an int (parsed from String) to it. You can use nextDouble method to get a double directly, and if you plan this number to be an Integer anyway then use type int instead of double and nextInt instead of parsing. For more information about parsing from input, check Scanner documentation.
Your if statements terminate if you put a semi colon at the end of them. Effectively ending your logic right there. The program basically checks the condition and then moves on. Which in turn executes your second statement regardless of what number <= 0 resolves to.
//Does not get expected results
if (number <= 0);
{
//Gets executed regardless of condition
System.out.println("The number of credits must be greater than zero!");
}
//Gets expected results
if (number <= 0)
{
//Gets executed only if the condition returns true
System.out.println("The number of credits must be greater than zero!");
}
Edit: Changed due to some helpful input.
2nd Edit: I would also consider putting a loop in your code that makes the user re-enter input to get the desired value. If you put in a negative value your code will just spit the error message and keep running which can make you scratch your head. Unless your teacher isn't grading on that then forget all of what I just said. =p

How to end a while Loop via user input

package cst150zzhw4_worst;
import java.util.Scanner;
public class CST150zzHW4_worst {
public static void main(String[] args) {
//Initialize Variables
double length; // length of room
double width; // Width of room
double price_per_sqyd; // Total carpet needed price
double price_for_padding; // Price for padding
double price_for_installation; // Price for installation
String input; // User's input to stop or reset program
double final_price; // The actual final price
boolean repeat = true;
// Create a Scanner object for keyboard input.
Scanner keyboard = new Scanner(System.in);
while (repeat)
{
//User Input
System.out.println("\n" +"What is the length of the room?: ");
length = keyboard.nextInt();
System.out.println("What is the width of the room?: ");
width = keyboard.nextInt();
System.out.println("What is the price of the carpet per square yard?: ");
price_per_sqyd = keyboard.nextDouble();
System.out.println("What is the price for the padding?: ");
price_for_padding = keyboard.nextDouble();
System.out.println("What is the price of the installation?: ");
price_for_installation = keyboard.nextDouble();
final_price = (price_for_padding + price_for_installation + price_per_sqyd)*((width*length)/9);
keyboard.nextLine(); //Skip the newline
System.out.println("The possible total price to install the carpet will be $" + final_price + "\n" + "Type 'yes' or 'no' if this is correct: ");
input = keyboard.nextLine();
}
}
}
How would I make it so when the user says yes the program stop and if the user says no then the program just repeats? I don't know why I'm having so much trouble. I've searched for well over 4 hours. I am only supposed to use a while loop, I think.
You have to assign repeat in your while-loop so it becomes false if the user says yes:
repeat = !input.equalsIgnoreCase("yes");
You just need to set repeat to true or false based on user input. So in the end, compare input with yes or no. Something like this would work for you :
if ("yes".equals(input))
repeat = true; // This would continue the loop
else
repeat = false; // This would break the infinite while loop
boolean repeat = true;
// Create a Scanner object for keyboard input.
Scanner keyboard = new Scanner(System.in);
while (repeat)
{
-----------------------
-------------------------
System.out.println("Do you want to continue:");
repeat = keyboard.nextBoolean();
}
you also if you want your code to be more systematic , go and search about the interrupt , specially thread interrupt , these answers above is correct , find the more organic code and implement it
You can use a break statement to exit a while loop.
while (...) {
input = ...;
if (input.equals("Y")) {
break;
}
}

Categories

Resources