Execution of do while loop in the Java Calculator program - java

In my Java Program, I have used a Boolean variable 'decision' which should execute the actual calculator code in the 'do loop code block' only when the variable is true, but the do while loop is executed anyways even when the decision variable is false. I am using Eclipse IDE for Java and JDK 10 (both are recent versions). Please help me with a solution. The code is as below
import java.util.Scanner;
public class apples {
public static void main(String[] args) {
int option,a,b,c;
boolean decision;
System.out.println("We are here to create a calculator");
System.out.print("Do you want to switch on the calculator:");
Scanner yogi = new Scanner(System.in);
decision = yogi.nextBoolean();
do {
System.out.println("Following operations are available to perform:");
System.out.println("1. Addition");
System.out.println("2. Subtraction");
System.out.println("3. Multiplication");
System.out.println("4. Division");
System.out.print("Enter the operations do you want to perform:");
option = yogi.nextInt();
System.out.println("Choice of operation is:"+option);
switch(option) {
case 1:
System.out.println("Enter two numbers to be added:");
a = yogi.nextInt();
b = yogi.nextInt();
c = a + b;
System.out.print("Addition:"+c);
break;
case 2:
System.out.println("Enter two numbers to be subtracted:");
a = yogi.nextInt();
b = yogi.nextInt();
c = a - b;
System.out.print("subtracted:"+c);
break;
case 3:
System.out.println("Enter two numbers to be multiplied:");
a = yogi.nextInt();
b = yogi.nextInt();
c = a * b;
System.out.print("multiplied:"+c);
break;
case 4:
System.out.println("Enter two numbers to be divided:");
a = yogi.nextInt();
b = yogi.nextInt();
c = a / b;
System.out.print("divided:"+c);
break;
default:
System.out.println("This is a wrong choice");
break;
}
}while(decision==true);
}
}

the do while loop is executed anyways even when the decision variable
is false
A do...while will executes the body once before checking the condition.
Either modify your code for while or add an if-else enclosing do...while.

You can add another case 5 and in that write System.exit(0) for the successful termination of the program.
In the while part pass (option != 5). This should run the program.
You don't need decision variable.

Related

do while loop with a Yes/No user prompt

Im having issues with my code. The code is to find a factorial of a number, then ask if you want to run the program again, its suppose to run again then exit. However, when I enter Y to restart the program it breaks and wont restart and when I enter N to exit it wont exit the program.
private static Object Cont;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Greetings
System.out.println("Welcome to my factorial program! ");
System.out.println("Please choose from the following: ");
//Menu
System.out.println("1. Run Program");
System.out.println("2. Exit Program");
int choice = scanner.nextInt();
switch (choice) {
case 1:
System.out.println("This program will determine the factorial value of positive integers.");
do {
System.out.println("The starting number is 1.");
System.out.println("Please enter an ending integer value:");
int n = scanner.nextInt();
for (int i = 1; i <= n; i++) {
System.out.println(i + "! = " + fact(i));//call to function
}
System.out.println("Run factorial program again? (Y for Yes, N for No): ");
String Cont = scanner.next();
if (Cont.equals("N")) {
break;
}
} while (Cont.equals("Y"));// do while loop
break;
//Menu Exit
case 2:
System.out.println("Thank you for using the program.");
System.out.println("Goodbye");
default:
System.exit(1); // remebered from last week to set this to one
System.out.println("Goodbye");
break;
}
}//Factorial Math
static long fact(int x) {
long f = 1;
for (int i = 1; i <= x; i++) {
f = f * i;
}
return f;
} //End Main Method
What am I missing or doing wrong?
You have a couple of problems here.
The first problem is that you have declared two distinct Cont variables. The first one is a static field. The second one is a local variable that is declared in the body of the loop.
I don't know why you declared the static field, but I imagine you did it because the } while (Cont.equals("Y")); didn't compile without it. (That is because the Cont variable declared in the loop is not in scope outside of the loop's body.) Unfortunately, it was not the correct solution. Because, you now have code that is assigning to one variable and tests a different one. Naturally, that doesn't work.
To my mind, the correct solution is to get rid of the static field, and the declaration in the loop body. Than add a declaration for Cont before the start of the loop. (It shouldn't have an initialization). Finally, in the loop you just need to read (using the scanner) and assign a string to Cont so that you can test in the loop condition.
The second problem is that you have a redundant test in there. If you are going to test to see if you need to continue using } while (Cont.equals("Y")); you don't also need to test if Cont is "N" and break.
Relatedly, equals("Y") is not the same as not equals("N"). (Consider "Hello" ... or "n". They are neither "Y" or "N".) So if you really want to stop the loop when the user types N, then the loop termination condition should be:
} while (!Cont.equals("N")); // keep looping while not 'N'
Finally there are a couple of significant style-related issues.
Declaring a static field is usually a mistake.
It is a mistake to use a field when you should be using a local variable. State that is only relevant to a single execution of a method should be1 represented using a local variable.
It is a major stylistic error for a variable to start with an uppercase letter. Cont should be cont.
If you ever work in a professional Java development team that pays attention to style, you will get a hard time for ignoring Java identifiers conventions. And (IMO) your teacher should dock style marks for this mistake.
1 - Reasons: 1) It makes the method harder to read because the variable declaration is further away from its use. 2) It typically makes the code non-reentrant. 3) It opens you up to unwanted coupling between methods; e.g. if two methods accidentally share the same "local variable declared as a field". 4) In many cases it uses more memory.
You need an additional break and declare Cont before the do loop:
//private static Object Cont; This is is not declared on the right location, we'll declare it later
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Greetings
System.out.println("Welcome to my factorial program! ");
System.out.println("Please choose from the following: ");
//Menu
System.out.println("1. Run Program");
System.out.println("2. Exit Program");
int choice = scanner.nextInt();
switch (choice) {
case 1:
System.out.println("This program will determine the factorial value of positive integers.");
String Cont = null; // Cont must be declared here
do {
System.out.println("The starting number is 1.");
System.out.println("Please enter an ending integer value:");
int n = scanner.nextInt();
for (int i = 1; i <= n; i++) {
System.out.println(i + "! = " + fact(i));//call to function
}
System.out.println("Run factorial program again? (Y for Yes, N for No): ");
Cont = scanner.next();
if (Cont.equals("N")) {
break;
}
} while (Cont.equals("Y"));// do while loop
break;
//Menu Exit
case 2:
System.out.println("Thank you for using the program.");
System.out.println("Goodbye");
break; // requires this additional break
default:
System.exit(1); // remembered from last week to set this to one
System.out.println("Goodbye");
break;
}
}//Factorial Math
static long fact(int x) {
long f = 1;
for (int i = 1; i <= x; i++) {
f = f * i;
}
return f;
} //End Main Method

How to correct the scope of a variable that is created within a do-while loop?

I am struggling to get the correct scope for my variable "input".
I am making a calculator for a university task, and I've got everything working apart from when I tried to make it loop by wrapping my main code in a do-while loop. Because the variable "input" is declared in the "do" part of the loop, it didn't know what it was when I was trying to use it in the "while" condition. To fix this I then declared "input" as a string before my do-while loop to make it a global. However, now the scanner that takes the value of input will not work.
AM I doing something stupid or am I missing something?
import java.util.Scanner;
public class Calculator {
public static void main(String [] args) {
String input;
do {
System.out.println("Welcome to the calculator. Please enter an operator (+, -, /, *) below:");
Scanner myScanner = new Scanner(System.in);
String oper = myScanner.nextLine();
System.out.println("Now please enter two numbers:");
double a = myScanner.nextDouble();
double b = myScanner.nextDouble();
switch (oper) {
case "+" :
System.out.println(CalculatorUtils.add(a, b));
break;
case "-" :
System.out.println(CalculatorUtils.subtract(a, b));
break;
case "/" :
System.out.println(CalculatorUtils.divide(a, b));
break;
case "*" :
System.out.println(CalculatorUtils.multiply(a, b));
break;
}
System.out.println("Do you want to complete another calculation? (y/n)");
input = myScanner.nextLine();
}
while (input.contentEquals("y"));
}
}
I expect this to be the output:
Welcome to the calculator. Please enter an operator (+, -, /, *) below:
+
Now please enter two numbers:
32.5
12.5
45.0
Do you want to complete another calculation? (y/n)
y
(This is where the code would start again)
However I'm not being able to enter my input when being asked if I would like to do another calculation.
Here is the fix.
import java.util.Scanner;
public class Calculator {
public static void main(String[] args) {
String input;
do {
System.out.println("Welcome to the calculator. Please enter an operator (+, -, /, *) below:");
Scanner myScanner = new Scanner(System.in);
String oper = myScanner.nextLine();
System.out.println("Now please enter two numbers:");
double a = myScanner.nextDouble();
double b = myScanner.nextDouble();
switch (oper) {
case "+":
System.out.println(CalculatorUtils.add(a, b));
break;
case "-":
System.out.println(CalculatorUtils.subtract(a, b));
break;
case "/":
System.out.println(CalculatorUtils.divide(a, b));
break;
case "*":
System.out.println(CalculatorUtils.multiply(a, b));
break;
}
myScanner.nextLine();
System.out.println("Do you want to complete another calculation? (y/n)");
input = myScanner.nextLine();
myScanner.nextLine();
}
while (input.contentEquals("y"));
}
}
It happens because second time you call myScanner.nextLine() it just scans enter from before. It will happen after myScanner.nextDouble() but not after myScanner.nextLine() because myScanner.nextLine() reads/scans until including next newLine character (\n) whereas myScanner.nextDouble() will just scan a double and leave.
Here is similar thread
What you do not want to do is create a Scanner on every trip around the loop. Move the definition and initialization of your Scanner variable outside the loop:
String input;
Scanner myScanner = new Scanner(System.in);
do {
System.out.println("Welcome to the calculator. Please enter an operator (+, -, /, *) below:");
String oper = myScanner.nextLine();
// rest of loop...
} while (input.contentEquals("y"));
This may or may not solve you're immediate problem, but it's still the right thing to do in general.

Switch statement returning wrong [duplicate]

This question already has answers here:
If-else working, switch not [duplicate]
(9 answers)
Closed 6 years ago.
I started to learn Java some time ago and I thought that making a calculator that works in the terminal. Lately I added an Array list to store the history, and then something went wrong.
Calculator program:
import java.util.Scanner;
import java.util.ArrayList;
public class calc_case {
public static void main(String[] args) {
System.out.println("Welcom to The Calculator!");
double a;
double b;
double c;
Scanner input0;
int input = 0;
ArrayList<Double> history = new ArrayList<Double>();
while (input != 6) {
try {Thread.sleep(2000);} catch(InterruptedException ex) {Thread.currentThread().interrupt();}
a = 0; b = 0; c = 0; input = 0;
System.out.println("#################################################");
System.out.println("How can I help you?");
System.out.println("1-Add\n2-Subtrackt\n3-Devide\n4-Multiply\n5-Show history\n6-Exit");
input0 = new Scanner(System.in);
input = input0.nextInt();
switch (input) {
case 1: //add
System.out.println("Input two numbers:");
input0 = new Scanner(System.in);
a = input0.nextDouble();
input0 = new Scanner(System.in);
b = input0.nextDouble();
c = a + b;
System.out.println("Calculating... \nThe answer is: " + c );
break;
case 2: //subtrackt
System.out.println("Input two numbers:");
input0 = new Scanner(System.in);
a = input0.nextDouble();
input0 = new Scanner(System.in);
b = input0.nextDouble();
c = a - b;
System.out.println("Calculating... \nThe answer is: " + c );
break;
case 3: //devide
System.out.println("Input two numbers:");
input0 = new Scanner(System.in);
a = input0.nextDouble();
input0 = new Scanner(System.in);
b = input0.nextDouble();
c = a/b;
System.out.println("Calculating... \nThe answer is: " + c );
break;
case 4: //multiply
System.out.println("Input two numbers:");
input0 = new Scanner(System.in);
a = input0.nextDouble();
input0 = new Scanner(System.in);
b = input0.nextDouble();
c = a*b;
System.out.println("Calculating... \nThe answer is: " + c );
break;
case 5: //history
for (int x = 0; x < history.size(); x++) {
System.out.println(history.get(x));
}
case 6: //exit
System.out.println("Goodbye!\n Killing process... " + " OK");
default:
history.add(c);
}
}
}
}
After adding case 5 as 'Show history' and moving case 5 'Exit' to case 6 'Exit' after choosing option 5 ('Show history') I get this:
Goodbye!
Killing process... OK
I tried recompiling the program, deleting the class file, and pasting the program to a new file. What is wrong with my program?
OS: Ubuntu 16.04 Java version:
Java version: openjdk version "1.8.0_91"
Two things:
You forget the break after case 5; so you always fall through to the next case. So does the next case 6.
Your history is printed; but you never add a value to that history! There is not much sense in keeping a history, if that variable is only read from, but never written to.
And from a "clean coding" perspective: read about the "single layer of abstraction" principle. You really do not want to have so much code in one method; for example: each of your case blocks ... should go into its own method. You want to create small "units" that can be understood with one glance. Something that goes over 10 lines or more always requires more work than something smaller!
And you know; when each code would like this:
...
case 3:
divide();
break;
case 4:
multiply();
break;
dont you think you would have spotted your problem yourself?!
You do not have break in case 5, that is why it executes case 6 after finishing case 5
You are missing a break after your for loop in case 5:, so it falls through into case 6:.
Also, case 6: appears to be missing a break after the System.out statement.

Simple Calculator Java Coding Errors [duplicate]

This question already has answers here:
Simple Java calculator
(10 answers)
Closed 8 years ago.
Trying to make a simple calculator in Java but I keep getting errors when I try to compile it. Not sure if it's the coding or something I am doing when I compile it. Any help would be appreciated!
import java.util.Scanner;
class simple calculator { // simple calculator
public static void main(String args[]){
System.out.println("My simple calculator\n");
Scanner bucky= new Scanner(System.in);
double fnum,snum,ans;
System.out.print("Enter the first and second " +
"number : ");
a=bucky.nextFloat(); //assign the numbers
b=bucky.nextDouble(); // to respective variable
System.out.println("What operation u want to " +
"perform");
String operation;
operation=bucky.next();
switch(operation) {
case "+":
ans=a + b;
System.out.print("Sum of the two inputs = ");
System.out.print(ans);
break;
case "-":
ans=a - b;
System.out.print("Subtraction of the two inputs = ");
System.out.print(ans);
break;
case "*":
ans=a * b;
System.out.print("Multiplication of the two inputs = ");
System.out.print(ans);
break;
case "/":
ans=a / b;
System.out.print("Division of the two inputs = ");
System.out.print(ans);
break;
default : System.out.println("Give a proper operation " +
"symbol ");
break; // not required
}
}
}
Two compilation errors:
Your class name has whitespace in it: class simple calculator isn't valid, because "calculator" isn't a recognized token. Try: class SimpleCalculator. Also make it public and change the name of the file to match. (SimpleCalculator.java).
You declare variables a and b but don't give them types. Use float a = ... and double b = .... That one is a float and the other is a double is strange, but pressing on...
Other new-to-java issues to note:
You never close bucky, the scanner. This is a resource leak, and in a bigger application could be a major bug. Add bucky.close() after you read the last line from it, which is after operation = bucky.next()
the name bucky tells me absolutely nothing about what it is or what its use is. Try to use descriptive variable names. (The only main exception being single letter names for loop indices, etc).
fnum and snum are local variables that you declare but never use. Perhaps get rid of them?
Here's your code with edits made:
import java.util.Scanner;
public class SimpleCalculator { // simple calculator
public static void main(String args[]){
System.out.println("My simple calculator\n");
Scanner bucky= new Scanner(System.in);
double ans;
System.out.print("Enter the first and second " +
"number : ");
float a=bucky.nextFloat(); //assign the numbers
double b=bucky.nextDouble(); // to respective variable
System.out.println("What operation u want to " +
"perform");
String operation;
operation=bucky.next();
bucky.close();
switch(operation) {
case "+":
ans=a + b;
System.out.print("Sum of the two inputs = ");
System.out.print(ans);
break;
case "-":
ans=a - b;
System.out.print("Subtraction of the two inputs = ");
System.out.print(ans);
break;
case "*":
ans=a * b;
System.out.print("Multiplication of the two inputs = ");
System.out.print(ans);
break;
case "/":
ans=a / b;
System.out.print("Division of the two inputs = ");
System.out.print(ans);
break;
default : System.out.println("Give a proper operation " +
"symbol ");
break; // not required
}
}
}
I was able to compile it in the terminal with no trouble.

Trouble trying to restart my Java program

After looking up numerous ways to restart a Java program within itself, a while loop seemed like the easiest option. Here's an example of a basic calculator program I'm trying this with:
import java.util.Scanner;
class a {
public static void main(String args[]){
boolean done = false;
int oper;
Scanner input = new Scanner(System.in);
System.out.println("McMackins Calc v2.0 (Now with fewer crashes!)");
while (!done)
{
System.out.println("What operation? (0 for quit, 1 for add, 2 for subtract, 3 for multiply, 4 for divide, 5 for divide with remainder, 6 for average, 7 for account interest):");
while (!input.hasNextInt()){
System.out.println("Enter a valid integer.");
input.next();
}
oper = input.nextInt();
switch (oper){
case 0:
done = true;
break;
case 1:
add addObject = new add();
addObject.getSum();
break;
case 2:
sub subObject = new sub();
subObject.getDifference();
break;
case 3:
times multObject = new times();
multObject.getProduct();
break;
case 4:
divide divObject = new divide();
divObject.getQuotient();
break;
case 5:
remain remObject = new remain();
remObject.getRemainder();
break;
case 6:
avg avgObject = new avg();
avgObject.getAvg();
break;
case 7:
interest intObject = new interest();
intObject.getInterest();
break;
default:
System.out.println("Invalid entry.");
break;
}
}
input.close();
}
}
However, this seems to throw out a NoSuchElementException at the end of the first time through the loop, and crashes the program. The function of this class is to take the initial input from the user to determine which class to use, which will determine which mathematical operation to perform. Everything works fine without the while (!done) loop.
Example usage:
McMackins Calc v2.0 (Now with fewer crashes!)
What operation? (0 for quit, 1 for add, 2 for subtract, 3 for multiply, 4 for divide, 5 for divide with remainder, 6 for average, 7 for account interest):
1
How many addends?
1
Enter your numbers now.
1
You have entered 1 addend.
The sum is: 1.0
What operation? (0 for quit, 1 for add, 2 for subtract, 3 for multiply, 4 for divide, 5 for divide with remainder, 6 for average, 7 for account interest):
Enter a valid integer.
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at a.main(a.java:13)
I've also tried just having the other classes refer back to this one, but since main is a static method, I cannot access it the way I intended.
Note that I'm a bit of a beginner at Java, which is why my program is pretty simple, so try to keep it simple if it can be, or post code and then in DETAIL explain what it means so I can not only fix this problem, but future ones as well.
Thank you!
EDIT:
The code is formatted better within my editor. The braces came out in odd positions when I posted it here.
Since apparently a is written correctly, this is my add class. Hopefully this will clear something up.
import java.util.Scanner;
public class add {
public void getSum(){
Scanner input = new Scanner(System.in);
double total, addend;
int entries, count;
total = 0;
count = 0;
System.out.println("How many addends?");
while (!input.hasNextInt()){
System.out.println("Enter a valid integer.");
input.next();
}
entries = input.nextInt();
System.out.println("Enter your numbers now.");
while (count < entries){
while (!input.hasNextDouble()){
System.out.println("Enter a valid number.");
input.next();
}
addend = input.nextDouble();
total = total + addend;
count++;
if (count == 1){
System.out.println("You have entered " + count + " addend.");
}else if (count > entries){
System.out.println("You have entered too many addends! Contact program developer.");
}else{
System.out.println("You have entered " + count + " addends.");
}
}
System.out.println("The sum is: " + total);
input.close();
}
}
public static void main(String args[]){
boolean done = false;
int oper;
Scanner input = new Scanner(System.in);
System.out.println("McMackins Calc v2.0 (Now with fewer crashes!)");
while (!done) {
System.out.println("What operation? (0 for quit, 1 for add, 2 for subtract, 3 for multiply, 4 for divide, 5 for divide with remainder, 6 for average, 7 for account interest):");
while (!input.hasNextInt()){
System.out.println("Enter a valid integer.");
input.next();
}
oper = input.nextInt();
switch (oper){
case 0:
done = true;
break;
case 1:
System.out.println("1");
break;
case 2:
System.out.println("2");
break;
case 3:
System.out.println("3");
break;
case 4:
System.out.println("4");
break;
case 5:
System.out.println("5");
break;
case 6:
System.out.println("6");
break;
case 7:
System.out.println("7");
break;
default:
System.out.println("Invalid entry.");
break;
}
}
input.close();
}
This seemed to work for me so perhaps the error is something to do with your own classes (add, divide) etc.
Also, it's best to keep with convention when creating your own classes by capitalizing the first letter e.g. "add" should be "Add".
You could probably make this a little bit easier to read by building a general "Operations" class which holds an add method, a subtract method etc.
EDIT:
try this for your add method:
public static int add() {
Scanner s = new Scanner(System.in);
int counter = 0;
System.out.println("How many numbers to add?");
int numCount = s.nextInt();
for(int i = 0; i < numCount; i++) {
System.out.println("enter number");
counter += s.nextInt();
}
return counter;
}
Use bufferedreader and inputstream instead of Scanner class. This class creates a lot of bugs and errors, since sometimes it takes more arguments, that you expect it to take.
Also:
while (!input.hasNextInt()){
System.out.println("Enter a valid integer.");
input.next();
}
Your using hasNextInt method wrong, instead of it try to make simple while loop with Boolean and input.next() should be replaced with input.nextLine().
Another thing, you should check,if user typed integer instead of string or something in the while loop and it range. If everything is okay, you should change Boolean value to true and make him go out of the while loop.
For future users who are wondering how to fix this issue, through some reprogramming, I discovered that my problem was closing the input variable BEFORE the end of the loop. By having the program restart indefinitely and only close input when done, this program works fine.
Thanks to Benjamin's response, I am currently in the process of cleaning up and shortening my code by way of for loops.

Categories