Loops and user input validation in java, again - java

So, I think about two days back I asked a question about input validation, and how to loop programs until the user gave a valid input..
So I made a calculator and I wanted to loop every step of the program so that if the user didn't put a double (69, 42.0) or the appropriate operator char (/, *, +, -) they would be stuck on that step till they got it right or otherwise closed the app entirely.
So one thing I got from the last question about this is that I could make a boolean value called "restart" or something and encapsulate my entire code except for the main method obviously and at the end I could make a question that they could answer true or false and the entire app could run again. While I admit having a "start over" button on my app is cool and useful for all my other a projects (probably not, I'm sure this can be done more efficiently), It still didn't satiate me and my original problem.
SO...
I got to trying everything I could (I know stack likes people who show that they at least tried).
EXAMPLE 1
Scanner input = new Scanner(System.in);
double valX;
System.out.println("Calculator Activated.");
do
{
System.out.print("Value X: ");
valX = input.nextDouble();
}while (!input.hasNextDouble());
{
System.out.println("Invalid number!");
}
//Didn't work ¯\_(ツ)_/¯
EXAMPLE 2
Scanner input = new Scanner(System.in);
double valX;
System.out.println("Calculator Activated.");
while (!input.hasNextDouble())
{
System.out.println("Value X: ");
valX = input.nextDouble();
}
//neither this one...
Note that the solution you guys give me has to apply to every step of the program.
And for a bit more clarity is the entire src code without the stuff I tried and the "restart" loop.
import java.util.Scanner;
public class CalTest
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
double valX, valY, divided, multiplied, added, subtracted; //Declared all my variables...
char operator;
boolean restart; //Didn't need to declare it true or false since I'm using a Scanner anyway
do //Start of the entire program
{
System.out.println("Calculator Activated.");
System.out.print("Value X: "); //I need a loop here...
valX = input.nextDouble();
System.out.print("Operator: "); //And here...
operator = input.next().charAt(0);
System.out.print("Value Y: "); //And here too..
valY = input.nextDouble();
divided = valX / valY;
multiplied = valX * valY;
added = valX + valY;
subtracted = valX - valY;
if (operator == '/')
System.out.println("Result: " + divided );
else if (operator == '*')
System.out.println("Result: " + multiplied); //<--Not sure if I need a loop with the if's
else if (operator == '+')
System.out.println("Result: " + added);
else if (operator == '-')
System.out.println("Result: " + subtracted);
else
System.out.println("Invalid operator!");
System.out.print("Try again? "); //I also need a loop here, I think.
restart = input.nextBoolean();
} while (restart); //End of it if you declared false.
System.out.println("Calculator terminated.");
}
}
At one point I tried to use the same "restart the app" concept and made a boolean variable for every single step in the code and it honestly was tiresome and not worth it.
Also I'm just a beginner if it's a concept of the loops that I'm missing then I'm happy to learn it from you guys.
Again, gracias to anyone who answers and helps contribute to my learning.

In your final code example in the class called CalTest where you assign valX = input.nextDouble(); you could a call recursive method that handles the exception until the input is what you want. Something like this:
private static double getNextDouble(Scanner input) {
try {
return input.nextDouble();
} catch (InputMismatchException e) {
System.out.println("Value X must be a number: ");
input.next();
return getNextDouble(input);
}
}
You'll replace valX = input.nextDouble(); with valX = getNextDouble(input);.
You can tidy this up and make it work for your other potential error cases, perhaps creating a parameter for the output message and passing it in as an argument.

public static void main(String[] args) {
double valX=0,valY=0;
char operator='0';//dummy default
Scanner input = new Scanner(System.in);
System.out.println("Calculator Activated.");
Double dX = null;
do
{
System.out.print("Value X: ");
dX = getDouble(input.next());
}while (dX==null);
{
valX = dX;
}
Character op = null;
do
{
System.out.print("Operator: ");
op = getOperator(input.next());
}while (op==null);
{
operator=op;
}
Double dY = null;
do
{
System.out.print("Value Y: ");
dY = getDouble(input.next());
}while (dY==null);
{
valY = dY;
}
System.out.println("Done: "+ valX + " "+operator + " " +valY);
}
static Double getDouble(String input) {
Double d = null;
try {
d = new Double(input);
}catch(NumberFormatException ex){
}
return d;
}
static Character getOperator(String input) {
Character c = null;
if("+".equals(input) || "-".equals(input) || "*".equals(input) || "/".equals(input)){
c = input.charAt(0);
}
return c;
}

Related

nextDouble creating a loop in a different method [duplicate]

This question already has answers here:
Scanner - java.util.NoSuchElementException
(3 answers)
Closed 4 months ago.
I'm working on a program for my Java class and things were going really well until I inputted a number in the getSideLength method. If the number is valid, it will skip everything back to main and start a new loop on the first quesiton. I honestly have know idea what is going on and neither did my teacher. I'm running of of VS Code if that makes a difference.
package week7;
import java.util.Scanner;
import java.lang.Math;
public class Lab7b {
static void calculateSideA(){
double b = getSideLength("B");
double c = getSideLength("C");
double a = Math.sqrt(Math.pow(c,2)-Math.pow(b,2));
System.out.println("A right triangle with sides 'B' = "+b+" and 'C' (hypotenuse) = "+c+", has a side 'A' which has a length of: "+a);
}
static void calculateSideB(){
double a = getSideLength("A");
double c = getSideLength("C");
double b = Math.sqrt(Math.pow(c,2)-Math.pow(a,2));
System.out.println("A right triangle with sides 'A' = "+a+" and 'C' (hypotenuse) = "+c+", has a side 'B' which has a length of: "+b);
}
static void calculateSideC(){
double a = getSideLength("A");
double b = getSideLength("B");
double c = Math.sqrt(Math.pow(a,2)+Math.pow(b,2));
System.out.println("A right triangle with sides 'A' = "+a+" and 'B' = "+b+", has a side 'C' (hypotenuse) which has a length of: "+c);
}
static double getSideLength(String letter){
Scanner entry = new Scanner(System.in);
boolean valid = false;
double sideLength = 0;
do{
try{
System.out.print("Please enter the length of the "+letter+" side: ");
sideLength = entry.nextDouble();
entry.nextLine();
valid = true;
}catch(Exception e){
System.out.println("Please enter a number.");
valid = false;
entry.nextLine();
}
}while(!valid);
entry.close();
return sideLength;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
boolean rerun = false;
boolean valid = false;
do{
String letter = "";
do{
try{
System.out.print("Enter the side of the triangle would you like to calculate: (A/B/C) ");
letter = input.nextLine();
if(letter.equalsIgnoreCase("A")||letter.equalsIgnoreCase("B")||letter.equalsIgnoreCase("C")){
valid = true;
if(letter.equalsIgnoreCase("A")){
calculateSideA();
}
else if(letter.equalsIgnoreCase("B")){
calculateSideB();
}
else if(letter.equalsIgnoreCase("C")){
calculateSideC();
}
else{
System.out.println("Something has gone wrong.");
}
}
else{
System.out.println("Please enter A, B, or C.");
valid = false;
}
}catch(Exception e){
System.out.println("Please enter A, B, or C.");
valid = false;
}
}while(!valid);
valid = false;
do{
System.out.print("Would you like to play again? (Y/N) ");
String answer = input.nextLine();
if(answer.equalsIgnoreCase("Y")||answer.equalsIgnoreCase("N")){
if(answer.equalsIgnoreCase("Y")){
valid = true;
rerun = true;
}
else{
System.out.println("Thank you. Come Again.");
rerun = false;
valid = true;
}
}
else{
System.out.println("Please enter either Y or N");
valid = false;
}
}while(!valid);
}while(rerun);
input.close();
}
}
Here's what a run looks like:
Enter the side of the triangle would you like to calculate: (A/B/C) c
Please enter the length of the A side: 5
Enter the side of the triangle would you like to calculate: (A/B/C) Please enter A, B, or C.
Enter the side of the triangle would you like to calculate: (A/B/C) Please enter A, B, or C.
Enter the side of the triangle would you like to calculate: (A/B/C) Please enter A, B, or C.
and on and on.
Any ideas?
The output
Enter the side of the triangle would you like to calculate: (A/B/C) A
Please enter the length of the B side: 3.0
Please enter the length of the C side: 4.0
A right triangle with sides 'B' = 3.0 and 'C' (hypotenuse) = 4.0, has a side 'A' which has a length of: 2.6457513110645907
Would you like to play again? (Y/N) Please enter either Y or N
Would you like to play again? (Y/N) N
Thank you. Come Again.
The problem:
Once you call close() in your Scanner object, you are closing the input stream. Once you do that, you can't reopen it in the life of the application. You need to work with the same Scanner object throughout. The fact your teacher didn't know that, scares me.
The solution:
Pass the Scanner object to the methods that need to use it.
static double getSideLength(String letter, Scanner entry) {
boolean valid = false;
double sideLength = 0;
do {
try {
System.out.print("Please enter the length of the " + letter + " side: ");
sideLength = entry.nextDouble();
valid = true;
} catch (Exception e) {
System.out.println("Please enter a number.");
valid = false;
}
} while (!valid);
return sideLength;
}
And of course, you need to pass it thru the methods that wraps this one. There might be other (minor) bugs with your application. You will need to clean up those.

Java conics calculator

Creating a Java calculator to determine what a conic is based on A and C. I've just barely started working in Java, haven't even finished a CodeAcademy course, so I need a bit of help debugging and rewriting this. Thank you!
public static void main (String[] args) throws java.lang.Exception
{
System.out.println("INPUT YOUR DESIRED EQUATION IN THE FORM Ax\u00B2 + Bxy + Cy\u00B2 + Dx + Ey + F = 0");
Scanner reader = new Scanner(System.in);
System.out.println("INPUT THE VALUE OF A: ");
int a = reader.nextInt();
Scanner reader = new Scanner(System.in); // Reading from System.in
System.out.println("INPUT THE VALUE OF C: ");
int c = reader.nextInt();
if (a = 0 || b = c) {
System.out.println("YOUR EQUATION IS A PARABOLA");
} else if (a = c) {
System.out.println("YOUR EQUATION IS A CIRCLE");
} else if (a*c > 0) {
System.out.println("YOUR EQUATION IS AN ELLIPSE");
}
else {
System.out.println("YOUR EQUATION IS A HYPERBOLA");
}
}
}
}
You should be using == in place of = in your conditional statements. == is a test for equality. = is the assignment operator. The way all of your conditional statements are currently written, they are assigning values to variables instead of comparing them, and, since assignment statements cannot return a boolean value, your code cannot compile.
Additionally, there is no need to declare reader twice. You actually can't do that. The second time it encounters this line:
Scanner reader = new Scanner(System.in);
The program has to create a NEW variable called reader, which it can't do because there is already an existing one with the same name. Now, it would be possible to do this the second time:
reader = new Scanner(System.in);
In this case, you are simply re-assigning reader to point to a new Scanner rather than attempting to create another variable.
However, doing so would be completely unnecessary, as reader already refers to a Scanner for System.in, so you should simply remove the second occurrence of that statement altogether.
#bethany-louise
Full input, along with the Ideone default code is this (apologies if the post/reply etiquette is off in any way)
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
System.out.println("INPUT YOUR DESIRED EQUATION IN THE FORM Ax\u00B2 + Bxy + Cy\u00B2 + Dx + Ey + F = 0");
Scanner reader = new Scanner(System.in);
System.out.println("INPUT THE VALUE OF A: ");
int a = reader.nextInt();
System.out.println("INPUT THE VALUE OF C: ");
int c = reader.nextInt();
if (a == 0 || c == 0) {
System.out.println("YOUR EQUATION IS A PARABOLA");
} else if (a == c) {
System.out.println("YOUR EQUATION IS A CIRCLE");
} else if (a*c > 0) {
System.out.println("YOUR EQUATION IS AN ELLIPSE");
}
else {
System.out.println("YOUR EQUATION IS A HYPERBOLA");
}
}
}

Do Loops to create read user input to repeat or exit program Java

This is my first post.
Using a Scanner class, I'm trying to let user input to choose to repeat the program or quit. The thing is my Do loop statement repeats the program and does not exit even if the Do Loop is false and should exit the program.
// loop repeat or quit
do {
//initialize variable
int integer;
int x = 1;
int factorial = 1;
System.out.print("Please enter an integer \n");
integer = getInt.nextInt();
//loop for factorial
//multiple each increment until it reaches the integer
while (x <= integer) {
factorial *= x;
x++;
}; // factorial=x*x
System.out.println("the factorial of the integer " + integer + " is " + factorial);
System.out.print("do you want to quit? y or n \n");
quit = getString.next();
} while(quit != yes);
System.exit(0);
}
There were a few mistakes in your code, so I rewrote it a little bit and used the correct functions where you used incorrect ones.
public static void main(String args[])
{
// Scanner is used to take in inputs from user
Scanner scan = new Scanner (System.in);
String quit = "";
// loop repeat or quit
do {
//initialize variable
int integer = 0;
int x = 1;
int factorial = 1;
// User needs to enter integer, or it'll throw exception.
System.out.println("Please enter an integer");
integer = scan.nextInt();
//loop for factorial
//multiple each increment until it reaches the integer
// factorial = x!
while (x <= integer) {
factorial *= x;
x++;
};
System.out.println("the factorial of the integer " + integer + " is " + factorial);
System.out.println("do you want to quit? y or n");
quit = scan.next();
// if quit is NOT equal to y, we do it again
} while(!quit.equals("y"));
System.exit(0);
}
I hope the comments helps :)
I've edited your code and it now runs.
For future reference: include more comprehensive snippets so viewers of your code can more easily discover mistakes.
Problem: There is no way to guarantee the user only inputs y without any spaces . THe easy solution to this problem is to use the string method contains(). I've modified your loop so that if the user input y the program will exit and it now works. Let me know if this works and happy coding!
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String quit ="";
do { //initialize variable
int integer; int x = 1; int factorial = 1;
System.out.print("Please enter an integer \n");
integer = in.nextInt();
//loop for factorial
//multiple each increment until it reaches the integer
while (x <= integer) {
factorial *= x;
x++;
}; // factorial=x*x
System.out.println("the factorial of the integer " + integer + " is " + factorial);
System.out.print("do you want to quit? y or n \n");
quit = in.next();
} while(!quit.contains("y"));
System.exit(0);
}
Shouldn't it be
while(quit != "y");
I also don't understand why you use System.out.print(); and then use \n when there's a perfectly good System.out.pritnln();
Also, since we're dealing with Strings the .nextLine(); is good enough for the Scanner. (You'll have to declare String quit as well.)

Trying to restart a do-while loop with a String variable to equal "yes" or "no"

Very simple program calculating travel distance(just started a week ago) and I have this loop working for a true or false question, but I want it to work for a simple "yes" or "no" instead. The String I have assigned for this is answer.
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double distance;
double speed;
boolean again = true;
String answer;
do{
System.out.print("Tell me your distance in miles: ");
distance = input.nextDouble();
System.out.print("Tell me your speed in which you will travel: ");
speed = input.nextDouble();
double average = distance / speed;
System.out.print("Your estimated time to your destination will be: " + average + " hours\n\n");
if(average < 1){
average = average * 10;
System.out.println(" or " + average + " hours\n\n");
}
System.out.println("Another? ");
again = input.nextBoolean();
}while(again);
}
}
You need to use input.next() instead of input.nextBoolean(), and compare the result to a string literal "yes" (presumably, in a case-insensitive way). Note that the declaration of again needs to change from boolean to String.
String again = null;
do {
... // Your loop
again = input.nextLine(); // This consumes the \n at the end
} while ("yes".equalsIgnoreCase(again));
just do
answer = input.nextLine();
} while(answer.equals("yes"));
You might want to consider being more flexible though. For example:
while (answer.startsWith("Y") || answer.startsWith("y"));
String answer=null;
do{
//code here
System.out.print("Answer? (yes/no) :: ");
answer=input.next();
}while(answer.equalsIgnoreCase("yes"));
the above condition makes " while" loop run if user enter's yes and will terminate if he enters anything except yes.

I can't understand why scan does not work at this code

I just started to code for fun and tried to make a basic calculator,
but I got a problem.
There is my code at the bottom
import java.util.Scanner;
public class practice {
public static void main(String[] args) {
double temp1, temp2;
int temp4 = 1;
int end = 0;
**String temp3,temp5;**
calculator cal = new calculator();
Scanner scan = new Scanner(System.in);
while(end==0){
System.out.println("Please put your first number to calculate");
temp1 = scan.nextDouble();
System.out.println("Please put your second number to calculate");
temp2 = scan.nextDouble();
System.out.println("What arithmetic operation you want to do?(+,-,/,*)");
**temp3 = scan.nextLine();**
if(temp3.equals("+")){
System.out.println("Result is" + cal.add(temp1, temp2));
}
else if(temp3.equals("-")){
System.out.println("Result is" + cal.subtract(temp1, temp2));
}
else if(temp3.equals("*")){
System.out.println("Result is" + cal.multiply(temp1, temp2));
}
else if(temp3.equals("/")){
System.out.println("Result is" + cal.divide(temp1, temp2));
}
else
System.out.println("You got wrong operator");
while(temp4==1){
System.out.println("Now you want to quit(press y/n)");
temp5 = scan.nextLine();
if(temp5.equals("y")){
temp4=0;
end=1;
}
else if(temp5.equals("n")){
System.out.println("Then here we go again");
temp4=0;
}
else
System.out.println("You put wrong words");
}
}
}
}
I can't understand why temp3 didn't work.
I wanted to check I made mistake, so I made temp5 but it works.
Can anyone explain why?
The problem is that nextDouble() doesn't use up the new line character used when entering the second double. So nextLine() sees the newline already present and consumes it.
Add in an extra nextLine() call to consume the newline from the second number.
temp2 = scan.nextDouble();
// Add consuming of new line here.
String dummy = scan.nextLine();
System.out.println("What arithmetic operation you want to do?(+,-,/,*)");
temp3 = scan.nextLine();

Categories