I have a project for my AP Compsci class in which we are required to input the cost of an item from a soda machine and return the change for the amount paid.
I'm having a bit of problem with the input, however; I am using a while loop to ensure that the input is a double, and that the value for the amount paid is greater than or equal to the cost. When I test this out, it seems that the I have to enter the amount paid multiple times in order for it to be scanned (see lines 23-30).
I have tried moving the "scan.next()" to different places within the loop, as well as changing the "scan.next()" to a "scan.nextLine" but both have just introduced more problems. Does anyone happen to know a way that I can check if the input is either not a double or less than the cost, and if so prompt the user to input the value again? I've pasted my code below:
import java.util.Scanner;
import java.lang.Math;
public class Sodamachine
{
public static void main(String [] args)
{
Scanner scan = new Scanner(System.in);
System.out.println("SODA MACHINE: V1.2");
System.out.println("Input the cost of the soda can and the amount you put in and your change will");
System.out.println("be output.");
System.out.print("\nEnter cost of purchase below:\n$");
while (! scan.hasNextDouble())
{
System.out.println("ERROR: Input was not a real number.");
System.out.print("Enter cost of purchase below:\n$");
scan.nextLine();
}
double cost = scan.nextDouble();
//this is where the problem starts
System.out.print("Enter amount paid below:\n$");
while ((! scan.hasNextDouble()) || (scan.nextDouble() < cost))
{
System.out.println("ERROR: Improper input.");
System.out.print("Enter amount paid below:\n$");
scan.next();
}
double paid = scan.nextDouble();
}
}
Please try my very basic and similar solution.
Requirements: totalCost and totalPaid values have to be DOUBLE variables.
In case those variables are not DOUBLE, the program stops and you should run it again (of course you can add a loop of other logic and call totalCost and totalPaid many times).
Basic assumption of my solution: totalPaid > totalCost.
Of course you can change and improve my code. This solution is only an idea how your problem can be solved.
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
System.out.println("SODA MACHINE: V1.2");
System.out.println("Input the cost of the soda can and the amount you put in and your change will");
System.out.println("be output.");
double totalCost = 0.0;
System.out.print("\nEnter cost of purchase below:\n$");
try{
totalCost = scan.nextDouble();
}
catch (Exception e)
{
System.out.println("ERROR: Input was not a real number - please provide DOUBLE value.");
System.exit(0);
}
System.out.print("Enter amount paid below:\n$");
double totalPaid = 0.0;
try{
totalPaid = scan.nextDouble();
}
catch (Exception e)
{
System.out.println("ERROR: Input was not a real number - please provide DOUBLE value.");
System.exit(0);
}
System.out.println("Change:\n$" + (totalPaid - totalCost));
}
You want to avoid scanning multiple times in the while loop.Suppose your cost is 100 and paid is 90. So your while loop is going to go
scan.nextDouble() < cost) <-- first scan, which is less than cost,
scan.next(); <-- Second scan.
scan.nextDouble() < cost) <-- Back to the while loop condition and you have an extra scan!
double paid = scan.nextDouble(); <-- And when you exit the while loop, you have another extra scan!
Ideally, you scan once, and if your conditions are not met, scan again for the new input.
//method to check if String can be converted to Double
public static boolean isDouble(String input){
try{
Double.parseDouble(input);
}catch(NumberFormatException e){
return false;
}
return true;
}
String paid = scan.next(); //scan once
//while not double or paid less than cost, scan again
while (!isDouble(paid) || (Double.parseDouble(paid) < cost) ){
System.out.println("Wrong paid number");
paid = scan.next();
}
double paidDouble = Double.parseDouble(paid);
Related
First off, I'm sorry if I am making a duplicate post. I tried looking for the solution and could not find it. I'm making a grade calculator where the user inputs a double "x" amount of times via a scanner. I've got the basic fundamentals of it down, and I'm not trying to fix any issues that a user might have when inputting numbers.
public static void main(String args[]) {
double total = 0;
int counter = 0;
ArrayList<String> answerYes = new ArrayList<>();
answerYes.add("yes");
answerYes.add("y");
answerYes.add("yea");
Scanner answerCheck = new Scanner(System.in);
System.out.println("Would you like to submit a number to calculate the average? [y/n]");
String userInput = answerCheck.nextLine();
while (answerYes.contains(userInput)) {
Scanner numberInput = new Scanner(System.in);
System.out.println("Please input a number: ");
Integer number = numberInput.nextInt(); //Here is where I need to check for a non-integer.
total += number;
System.out.println("Would you like to submit another number to calculate the average? [y/n]");
userInput = answerCheck.nextLine();
counter++;
}
double average = total/counter;
System.out.println("The average of those numbers is: " + average);
}
I'm pretty certain I made this more complicated than this had to be, but I wanted to test my ability to make an average calculator the way I would without the internet. Hopefully I formatted this correctly.
Thanks,
Jordan
You only need one Scanner, and you can use String.startsWith instead of checking against a collection. Something like,
double total = 0;
int counter = 0;
Scanner scan = new Scanner(System.in);
System.out.println("Would you like to submit a number to calculate the average? [y/n]");
String userInput = scan.nextLine();
while (userInput.toLowerCase().startsWith("y")) {
System.out.println("Please input a number: ");
if (scan.hasNextInt()) {
total += scan.nextInt();
counter++;
}
scan.nextLine();
System.out.println("Would you like to submit another number to calculate the average? [y/n]");
userInput = scan.nextLine();
}
double average = total / counter;
System.out.println("The average of those numbers is: " + average);
I think what you're looking to do is something like this.
try {
int input = scanner.nextInt();
// remaining logic
} catch (InputMismatchException e) {
System.out.println("uh oh");
}
So if the user enters something which can't be read as an integer it will throw a InputMismatchException.
You could extend this by putting it in a loop forcing the user to enter a number before continuing.
Edit: my problem has been partially fixed. Now I am able to enter text, however nothing reads after I enter the 'shiphalf' value. Did I construct my if else statements incorrectly?
I am attempting to let people input a coupon code but I am unable to figure out how to let the console know that the user is inputting text. I feel that the error is somewhere in here:
System.out.println("Enter a Coupon Code: ");
String ship = input.nextLine();
But I am not entirely sure. Here is the whole source code below:
package pseudoPackage;
import java.util.Scanner;
public class PseudoCode {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int ship1 = 0;
int ship2 = 6;
int ship3 = 2;
String shiphalf = null;
System.out.print("How much will shipping cost you?");
System.out.println();
System.out.print("Enter your textbook cost in dollars without the $: ");
double cost = input.nextDouble();
if ( cost >= 100 ) {
System.out.println("Your shipping costs are $0");
} else if ( cost < 100 && cost > 50 ) {
System.out.println("Your shipping cost is $6");
} else if ( cost < 50 ) {
System.out.println("Your shipping cost is $2");
}
System.out.println("Enter a Coupon Code: ");
String ship = input.nextLine();
if ( ship == shiphalf && cost >= 100 ) {
System.out.println("Your shipping costs are $0");
} else if ( ship == shiphalf && cost < 100 && cost >50 ) {
System.out.println("Your shipping costs are $3 ");
} else if ( ship == shiphalf && cost < 50 ) {
System.out.println("Your shipping costs are $1");
}
}
}
You have 2 problems in your code:
1. Use input.next() instead of input.nextLine().
2. Change your if conditional to ship.equals("shiphalf"). Remember that you use .equals() to compare 2 strings.
Here is your final code:
package pseudoPackage;
import java.util.Scanner;
public class PseudoCode {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int ship1 = 0;
int ship2 = 6;
int ship3 = 2;
String shiphalf = null;
System.out.print("How much will shipping cost you?");
System.out.print("\nEnter your textbook cost in dollars without the $: ");
double cost = input.nextDouble();
if ( cost >= 100 ) {
System.out.println("Your shipping costs are $0");
} else if ( cost < 100 && cost > 50 ) {
System.out.println("Your shipping cost is $6");
} else if ( cost < 50 ) {
System.out.println("Your shipping cost is $2");
}
System.out.println("Enter a Coupon Code: ");
String ship = input.next();
if ( ship.equals("shiphalf") && cost >= 100 ) {
System.out.println("Your shipping costs are $0");
} else if ( ship.equals("shiphalf") && cost < 100 && cost >50 ) {
System.out.println("Your shipping costs are $3 ");
} else if ( ship.equals("shiphalf") && cost < 50 ) {
System.out.println("Your shipping costs are $1");
}
}
}
What happens here is the following:
when you call
double cost = input.nextDouble();
Your Scanner reads the next Double in the Console and then "stops" at the end of that double value. It does not enter a new Line.
Looking at the Java Documentation, we can see that the Method nextLine() is partly described the following way:
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
So if your Scanner still is in a line, and you call nextLine() it will simply return the rest of the line. In your case this would most likely just be an empty String, even though you wish to read the Coupon Code.
After that your Scanner points to the actual line in the console you wanted to read.
So what's the easiest way to work around this ? You can just invoke the Method nextLine() once more before you get the Input for the Coupon Code. This will set your Scanner to the beginning of the actual line you wish to read.
Another way to get text from a user is to use JOptionPane. Also if you are comparing text, you want to code ' ship.equals(shiphalf) '
String x = JOptionPane.showInputDialog(null, "Type something!");
if(ship.equals(x)){
System.out.println("Your code works");
}
Hope this kind of helps?
I am having a problem with this java project I am working on for tomorrow. I am supposed to make a while loop that prompts the user for the prices of items and end the loop with any negative number, that negative number cannot be counted. Then I have to prompt the user for their membership discount level plat 15% off/gold 7%/silver 3%/non member 0% off using variables 3,2,1,0 respectively. For invalid input of status of membership, the user needs to enter again with a valid one using a do-while loop. Then I use the appropriate discount % off the sum of the items then tax it. The last few steps are simple enough, but I am stuck at the loops.
I did some searching and found this block of code on this site that does the job for the first while loop but does not end in the way I need it to.
Using While Loop instead of a For Loop in Java to ask User Input
I modified it to fit my needs but I still cannot find a way to make the throwable = to any negative number ie <0. Is that even possible? I am pretty sure there is a way to do this much simpler without try/catch which I have not learned yet. Here is my very slightly modified version
Scanner askPrice = new Scanner(System.in);
BigDecimal totalPrice = new BigDecimal("0");
Scanner keyboard = new Scanner(System.in);
while (true) {
System.out.println("Enter item price or negative number to quit:") ;
try {
double price = askPrice.nextDouble();
totalPrice = totalPrice.add(new BigDecimal(String.valueOf(price)));
}
catch (Throwable t) {
break;
}
System.out.println(totalPrice.toString());
}
I tried turning the try and catch statements into if / else and replacing the catch throwable with else(askPrice <0), but I was getting tons of errors.
I greatly appreciate any help that can be offered.
Thanks.
This sounds like homework. I know a lot of teachers are against students using 'break' to exit a loop. Here is how I would do it. A try-catch statement is unnecessary.
public static void main(String[]args) {
Scanner keyboard = new Scanner(System.in);
double input = 0.0;
double totalPrice = 0.0;
do {
totalPrice += input;
input = keyboard.nextDouble();
}
while(input >= 0);
}
Using a while loop:
public static void main(String[]args) {
Scanner keyboard = new Scanner(System.in);
double totalPrice = 0.0;
double input = keyboard.nextDouble();
while(input >= 0) {
totalPrice += input;
input = keyboard.nextDouble();
}
}
Try/catch is for handling exceptions and totally unnecessary here.
Scanner askPrice = new Scanner(System.in);
BigDecimal totalPrice = new BigDecimal("0");
Scanner keyboard = new Scanner(System.in);
while (true) {
System.out.println("Enter item price or negative number to quit:") ;
double price = askPrice.nextDouble();
if (price<0)
break;
else {
totalPrice = totalPrice.add(new BigDecimal(String.valueOf(price)));
}
System.out.println(totalPrice.toString());
}
Here is a simple do while loop that you are looking for
double price = 0;
do {
try {
price = askPrice.nextDouble();
// if the price was > 0 we need to add it to the total
if(price > 0)
totalPrice = totalPrice.add(new BigDecimal(String.valueOf(price)));
} catch(InputMismatchException e) {
// exit our loop, if the user entered an invalid double. Maybe you want to display a message instead?
price = -1;
}
} while(price >= 0);
The key is a do-while loop vs a while loop. The do-while loop will always run one time prior to analysing the loop condition. This allows you to accept the users input inside the loop and keep your code clean. I belive it is good practice to avoid using the break statement when possible. It will generally keep you from writing bad code (with the exception of switch statements of course).
Edit: For the record I think the try catch statement is not only necessary but mandatory for any user input. When a user enters an invalid number do you want a nasty error with a stack trace being thrown or your program to gracefully handle the bad input and notify the user. Most important it gets new programmers thinking about error handling, a very important part of software development.
You don't you check for negative number.
And you need to move your last System.out outside the loop
Scanner askPrice = new Scanner(System.in);
BigDecimal totalPrice = new BigDecimal("0");
while (true) {
System.out.println("Enter item price or negative number to quit:");
try {
double price = askPrice.nextDouble();
if (price < 0)
break;
totalPrice = totalPrice.add(new BigDecimal(String.valueOf(price)));
} catch (Throwable t) {
break;
}
}
System.out.println(totalPrice.toString());
I'm not sure of understand, but if you want exit with a negative number as input, use this:
Scanner askPrice = new Scanner(System.in);
BigDecimal totalPrice = new BigDecimal("0");
Scanner keyboard = new Scanner(System.in);
double price = 0.0d;
try {
while (0.0d <= price) {
System.out.println("Enter item price or negative number to quit:") ;
price = askPrice.nextDouble();
totalPrice = totalPrice.add(new BigDecimal(String.valueOf(price)));
}
}catch (Throwable t) {
System.err.println(t.getMessage());
}
System.out.println(totalPrice.toString());
Some points:
try/catch always out of a cycle, beacuase the code is more readable and faster
inside catch, you have to put a syserr, not sysout
in the orginal code, the eternal lopp finish when the user put a dollar char, what throw an Exception in converting as number with instruction
askPrice.nextDouble()
In your case, the instructions
double price = askPrice.nextDouble();
totalPrice = totalPrice.add(new BigDecimal(String.valueOf(price)));
don't throw any exception with negative number.
Normally it is better to write your own code instead of copying code for simple examples. That way you will learn a lot. In the code you have a missing closing brace for while loop, I hope there is a brace closing later.
You can temporarily fix the code by throwing an exception after getting the price:
double price = askPrice.nextDouble();
if(price < 0) throw new ArithmeticException("Negative Price!");
I am not sure whether that is what you want.
I'd like to start off by saying that I'm a complete beginner when it comes to Java. What I know so far is what I've learn from my software development class at university. I've been messing about with it on my own and I managed to create an app which takes two doubles as inputs and calculates the BMI (body mass index) of the user.
This program works fine and does exactly what I want it to do however, if the user doesn't enter anything and presses enter, then an exception is thrown. If the user enters anything but a number, an exception is thrown. When an exception is thrown the program is stopped. I would like to stop these exceptions from stopping the program completely and instead, return the user to the input stage and present an error message.
I have an idea of how it's done. Some people have suggested using the try {..} catch (..) {..} construct and I have tried but I've always managed to break the program.
Anyone have any ideas?
So, here's the code I have so far, sorry if there's anything wrong, I've tried to add comments to make it easier.
import java.io.*;
public class bmi {
public static void main(String[] args) throws IOException {
/**
* User input of weight and height.
*/
BufferedReader in;
in = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Please enter how much you weigh in KG.");
double weight = Double.parseDouble(in.readLine()); //take weight input as double
System.out.println("Please enter how tall you are in meters.");
double height = Double.parseDouble(in.readLine()); //take height input as double
/**
* BMI calculation
*/
double bmi = weight / Math.pow(height,2); // weight divided by height squared
/**
* if else statements to find if person is underweight, at a healthy weight or overweight.
*/
if (bmi<18.5) { //if BMI is smaller than 18.5
System.out.println("Your BMI is " + bmi + ", you are underweight.");
}
else if (bmi>=18.5 && bmi<=25) { //if BMI is bigger than or equal to 18.5 and smaller than or equal to 25
System.out.println("Your BMI is " + bmi + ", you are at a healthy weight.");
}
else if (bmi>25) { //if bmi is bigger than 25
System.out.println("Your BMI is " + bmi + ", you are overweight");
}
}
}
Thanks.
Replace
System.out.println("Please enter how much you weigh in KG.");
double weight = Double.parseDouble(in.readLine()); //take weight input as double
System.out.println("Please enter how tall you are in meters.");
double height = Double.parseDouble(in.readLine()); //take height input as double
with a construct like this:
double weight = 0, height = 0;
boolean incorrectInput = true;
while(incorrectInput){
try{
System.out.println("Please enter how much you weigh in KG.");
weight = Double.parseDouble(in.readLine()); //take weight input as double
System.out.println("Please enter how tall you are in meters.");
height = Double.parseDouble(in.readLine()); //take height input as double
incorrectInput = false;
}catch(NumberFormatException nxe){
System.out.println("Incorrect value for weight or height provided. Please try again")
}
}
What you're essentially doing is as follows:
Declaring a boolean variable that would control whether the user would be asked to input information or not. Note that this needs to be true for the initial time and until the user enters correct values for both weight and height
The method parseDouble() throws a NumberFormatException if the input is not as expected. You would need to catch this input and tell the user that the input wasn't what is expected. This goes into your catch block. The parse part goes to inside the try block.
Assuming that the user enters expected input, what you would need to do is set the boolean variable such that the while-loop terminates.
Note: The other option would be to use a Scanner. You can read more about its usage in the Java Tutorial: Scanning
You can use Scanner for that. Scanner provides various methods to check appropriate types so you can use them. And there is no need to catch exceptions like NumberFormatException
Scanner scanner = new Scanner(System.in);
double weight = 0;
double height = 0;
System.out.println("Please enter how much you weigh in KG.");
while (scanner.hasNext()) {
if (scanner.hasNextDouble()) {
// correct value
weight = scanner.nextDouble();
} else {
System.out.println("Please enter correct value.");
scanner.next();
continue;
}
System.out.println("Please enter how tall you are in meters.");
if (scanner.hasNextDouble()) {
// correct value
height = scanner.nextDouble();
} else {
System.out.println("Please enter correct value.");
scanner.next();
continue;
}
break;
}
double bmi = weight / Math.pow(height, 2);
System.out.println("Your BMI :"+bmi);
//Rest of the code remains the same
I am having issues with a problem that I coded for a Java course I am taking, and I cannot figure out why it is behaving a certain way. Here is the problem from the book, both part A and part B:
A) Create a class named Purchase. Each Purchase contains an invoice number, amount of sale, and amount of sales tax. Include set methods for the invoice number and sale amount. Within the set() method for the sale amount, calculate the sales tax as 5% of the sale amount. Also include a display method that displays a purchase's details. Save the file as Purchase.java
B) Create an application that declares a Purchase object and prompts the user for purchase details. When you prompt for an invoice number, do not let the user proceed until a number between 1000 and 8000 has been entered. When you prompt for a sale amount, do not proceed until the user has entered a non-negative number, sale amount, and sales tax. Save the file as CreatePurchase.java.
Here is the code for the first part of the problem:
public class Purchase
{
int invoiceNumber = 1234;
double salePrice = 10.00;
double SalesTax;
public void setInvoiceNumber(int invoice)
{
invoiceNumber = invoice;
}
public void setSalePrice(double saleAmount)
{
salePrice = saleAmount;
SalesTax = (saleAmount * .05);
}
public void displaySalePrice()
{
System.out.println("Your invoice number is:" + invoiceNumber + ".");
System.out.println("Your sale amount is: " + salePrice + ".");
System.out.println("Your sales tax is: " + SalesTax + ".");
}
}
Here is the code for the second part of the problem:
import java.util.Scanner;
public class CreatePurchase
{
public static void main(String[] args)
{
int invoice;
double saleAmount;
invoice = 0;
saleAmount = 0.0;
Purchase completedPurchase = new Purchase();
Scanner input = new Scanner(System.in);
System.out.println("Please enter the invoice number: ");
invoice = input.nextInt();
System.out.println("Please enter the sale amount: ");
saleAmount = input.nextDouble();
do
{
System.out.println("You entered an invalid number.");
System.out.println("Please enter a number between 1000 and 8000.");
invoice = input.nextInt();
}
while (invoice < 1000 || invoice > 8000);
do
{
System.out.println("You entered an invalid number.");
System.out.println("Please enter a number greater than 0.");
saleAmount = input.nextDouble();
}
while (saleAmount < 0);
completedPurchase.setInvoiceNumber(invoice);
completedPurchase.setSalePrice(saleAmount);
completedPurchase.displaySalePrice();
}
}
When I compile CreatePurchase.java and run it, it works, but has to cycle through the loops first before it works. For instance, I will type in 7000 for the invoice value and 100 for the sale amount. Those two values should automatically call the completePurchase.displaySalePrice(); method because the invoice number is greater than 1000 and less than 8000, and the sale amount is greater than 0. That being the case, it still cycles through the do while loops once before calling that method.
I cannot for the life of me figure this out. It's probably something pretty simple I am missing. Any help would be greatly appreciated.
After the great guidance of everyone below, I changed the code for the loops to the following:
while (invoice < 1000 || invoice > 8000)
{
System.out.println("You entered an invalid number.");
System.out.println("Please enter a number between 1000 and 8000.");
invoice = input.nextInt();
}
while (saleAmount < 0)
{
System.out.println("You entered an invalid number.");
System.out.println("Please enter a number greater than 0.");
saleAmount = input.nextDouble();
}
It still isn't working correctly. Changing the loops to while loops certainly worked, but now when I enter a number for the invoice number that's in the correct range and an incorrect number for the saleAmount, the program finished and does not execute the while loop for saleAmount? I seem to be missing a concept here.
Also, can anyone recommend a better IDE than JGrasp. That is what we were told to use, but it's cumbersome. I have VisualStudio and Eclipse, but I feel that doing java homework in those two IDE's might be overkill. I will be taking more java courses and c++ courses, so maybe it's worth learning the basics in VS or Eclipse. Any suggestions would be appreciated.
That is because the do block always gets executed at least once. You should use a while loop instead:
while (invoice < 1000 || invoice > 8000)
{
System.out.println("You entered an invalid number.");
System.out.println("Please enter a number between 1000 and 8000.");
invoice = input.nextInt();
}
This way, you only ask for another number, if the invoice number is not between the range you defined.
That's how do...while loops work: the body is executed once, and then the condition is checked. Use a normal while loop instead.
It's because you're using do{ } while(...) instead of while(...) { }
The do while is guaranteed to run at least once, and then continue looping.
The while will never run if the initial condition is false.
In do-while loops, the body is executed before the condition is tested. You probably want to be using while loops, where the body is executed after the condition is tested.
I highly suggest you read about the difference from Sun's while and do-while tutorial.
Change your loops to whiles
while (invoice < 1000 || invoice > 8000)
{
...
}
When I complie CreatPurchase.java and run it, it works, but has to cycle through the loops first before it works.
That's because you're using a do...while loop. A do...while loop executes at least once, and checks the condition after executing the body of the loop.
What you want in this case is a simple while loop, so that the condition is checked before executing the body of the loop. ie:
while (invoice < 1000 || invoice > 8000)
{
...
}
There are several loop functions in Java, one is the do-while-loop which always executes once and then if the while-part is true it loops again.
Another, and better in this case, is the while-loop that works the same but checks the while-part before the first loop.
Check out the tutorial
You need a while (condition) {…} loop. This way the code in the loop will be executed only if the condition is true. In your code you have a do … while(condition) loop and the inside of the loop will always be executed at least once.
import java.util.Scanner;
public class CreatePurchase {
public static void main(String[] args) {
int invoice;
double amount;
Purchase sale1 = new Purchase();
System.out.println("Enter invoice number between 1000 and 8000 >>");
Scanner input = new Scanner(System.in);
invoice = input.nextInt();
while (invoice < 1000 || invoice > 8000) {
System.out.println("You entered a wrong invoice number");
System.out.println("Enter invoice number between 1000 and 8000 >>");
invoice = input.nextInt();
}
System.out.println("Enter sales amount >>");
amount = input.nextDouble();
while (amount < 0) {
System.out.println("Enter number greater than 0 ");
System.out.println("Enter sales amount >>");
amount = input.nextDouble();
}
sale1.setInvoiceNumber(invoice);
sale1.setAmount(amount);
sale1.display();
}
}