A Memory Calculator Program - java

I have this program that asks user to enter a value and it calculates it as the user like to initial value of zero, then it ask the user what process to do again and ask the user to enter a value again and it calculates it to the last value of the instance, the problem is every time it asks the user to enter value it calculates it to zero not to the last entry. Please help me find the bug:
The program has to has two classes, one for the calculator and the other for the methods:
FIRST CLASS
public class MainClass {
public static void main(String[] args) {
MemoryCalculator calc = new MemoryCalculator();
calc.getCurrentValue();
displayMenu();
}
public static int displayMenu() {
Scanner input = new Scanner(System.in);
int choice;
do {
System.out.println("Menu");
System.out.println("1.Add");
System.out.println("2.Subtract");
System.out.println("3.Multiply");
System.out.println("4.Divide");
System.out.println("5.Clear");
System.out.println("6.Quit");
System.out.println("");
System.out.println("What would you like to do?");
choice = input.nextInt();
if (choice > 6 || choice < 1) {
System.out.println("Sorry," + choice + " was not an option");
return displayMenu();
}
} while (choice > 6 || choice < 1);
MemoryCalculator calc = new MemoryCalculator();
if (choice == 5) {
calc.clear();
return 0;
} else if (choice == 6) {
System.out.println("Goodbye! ");
System.exit(0);
}
System.out.println("What is the second number? ");
double operand2 = input.nextDouble();
switch (choice) {
case 1:
calc.add(operand2);
break;
case 2:
calc.subtract(operand2);
break;
case 3:
calc.multiply(operand2);
break;
case 4:
calc.divide(operand2);
break;
}
return displayMenu();
}
public static double getOperand(String prompt) {
return 0;
}
}
SECOND CLASS
public class MemoryCalculator {
private double currentValue;
public double getCurrentValue() {
System.out.println("The current value is " + currentValue);
return 0;
}
public void add(double operand2) {
currentValue = currentValue + operand2;
getCurrentValue();
}
public void subtract(double operand2) {
currentValue -= operand2;
getCurrentValue();
}
public void multiply(double operand2) {
currentValue *= operand2;
getCurrentValue();
}
public void divide(double operand2) {
if (operand2 == 0) {
System.out.println("Sorry, you can not divide by 0");
}
currentValue /= operand2;
getCurrentValue();
}
public void clear() {
currentValue = 0;
getCurrentValue();
}
}

You probably want to keep the last value stored in "calc". I see 3 bugs.
Move this line before the start of your "do" loop. This will keep it from reseting the value inside this variable/class.
MemoryCalculator calc = new MemoryCalculator();
Move your ending "while" loop line to the bottom of your method(right before the return statement). It only appears to be working because in your return statement you are calling your method again...see #3. Also you will want to change the "or" to the "and" operator in the while statement "choice>6 && choice<1"
}while(choice>6 && choice<1);
In you displayMenu method change the return statement, because you don't want it to call itself in an infinite loop... now that the do while loop is fixed.
return displayMenu();
to this
return choice;

Related

I have a problem with do while loop in my project

This is the program, I designed it to be a phone store, and the problem I am facing is that after you choose to go back, the program will go back normally, but after you choose to buy the next time it restarts the program. What I want is to make it stop at buy directly.
import java.util.Scanner;
public class MyStore {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
Phones phOne = new Phones("iPhone 13.");
phOne.phs(256);
phOne.php(904);
Phones phTwo = new Phones("Galaxy s22.");
phTwo.phs(512);
phTwo.php(1199);
Phones phThree = new Phones("Huawei p50 pocket.");
phThree.phs(512);
phThree.php(1699);
System.out.println("Welcom To My Store!\n-------*****-------");
int i = 1;
do {
System.out.println("Choose a phone please:");
System.out.println("1-iPhone 13.\n2-Galaxy s22.\n3-Huawei p50 pocket.");
int a = scan.nextInt();
System.out.println("-------*****-------");
switch(a) {
case 1:
phOne.print();
System.out.println("1-buy.\n2-go back.");
int bg1 = scan.nextInt();
if(bg1 == 1) {
System.out.println("Congratulations! we will deliver it to you.");
--i;
}
else if(bg1 == 2){
++i;
}
else {
System.out.println("Please choose 1 or 2.");
}
break;
case 2:
phTwo.print();
System.out.println("1-buy.\n2-go back.");
int bg2 = scan.nextInt();
if(bg2 == 1) {
System.out.println("Congratulations! we will deliver it to you.");
--i;
}
else if(bg2 == 2){
++i;
}
else {
System.out.println("Please choose 1 or 2.");
}
break;
case 3:
phThree.print();
System.out.println("1-buy.\n2-go back.");
int bg3 = scan.nextInt();
if(bg3 == 1) {
System.out.println("Congratulations! we will deliver it to you.");
i-=2;
}
else if(bg3 == 2){
++i;
}
else {
System.out.println("Please choose 1 or 2.");
}
break;
default:
System.out.println("Please choose 1, 2, or 3.");
}
}while(i >= 1);
}
}
And this is the rest of the program if you need it.
import java.text.NumberFormat;
public class Phones {
NumberFormat nf = NumberFormat.getCurrencyInstance();
String name;
int storage;
double price;
public Phones(String name) {
this.name = name;
}
public void phs(int phs) {
storage = phs;
}
public void php(double php) {
price = php;
}
public void print() {
System.out.println("Model: "+name);
System.out.println("Storage: "+storage+"G");
System.out.println("Price: "+nf.format(price));
}
}
If you want the program to stop after buying a phone you'd want to implement the do-while loop with a boolean value, then after the user buys a phone set the boolean value to false.
boolean loop = true;
do {
System.out.println("Choose a phone please:");
System.out.println("1-iPhone 13.\n2-Galaxy s22.\n3-Huawei p50 pocket.");
int a = scan.nextInt();
System.out.println("-------*****-------");
switch(a) {
case 1:
phOne.print();
System.out.println("1-buy.\n2-go back.");
int bg1 = scan.nextInt();
if(bg1 == 1) {
System.out.println("Congratulations! we will deliver it to you.");
loop = false;
}
......
while(loop);
I'd recommend taking better care of your variable names. Make them obvious and meaningful, makes it easier to debug in the end!

Java first attempt on simple calculator (what's happened?) [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
Main.java (Main Class)
package com.indie;
import java.util.InputMismatchException;
import java.util.Scanner;
import static com.indie.Operations.*;
public class Main {
private static double Number1;
private static double Number2;
private static double Total;
private static String Symbol;
private static boolean noError;
private static boolean exceptioncaught;
public static void main(String[] args) throws InterruptedException{
noError = false;
while (!noError) {
exceptioncaught = false;
while (!exceptioncaught) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter your number:");
try {
Number1 = scanner.nextDouble();
} catch (InputMismatchException ex) {
System.out.println();
System.out.println("TypeERROR: You didn't input a vaild number!");
exceptioncaught = true;
System.out.println();
Thread.sleep(3000);
break;
}
System.out.println("What do you want to do:");
Symbol = scanner.next();
if (!Symbol.contains("+") && !Symbol.contains("-") && !Symbol.contains("*") && !Symbol.contains("x") && !Symbol.contains("/") && !Symbol.contains("÷")) {
System.out.println();
System.out.println("TypeERROR: You didn't input a valid symbol!");
exceptioncaught = true;
System.out.println();
Thread.sleep(3000);
break;
}
System.out.println("Enter your second number:");
try {
Number1 = scanner.nextDouble();
} catch (InputMismatchException ex) {
System.out.println();
System.out.println("TypeERROR: You didn't input a vaild number!");
exceptioncaught = true;
System.out.println();
Thread.sleep(3000);
break;
}
System.out.println();
if (Symbol.contains("+")) {
Total = Add(Number1, Number2);
noError = true;
break;
} else if (Symbol.contains("-")) {
Total = Subtract(Number1, Number2);
noError = true;
break;
} else if (Symbol.contains("*") || Symbol.contains("x")) {
Total = Multiply(Number1, Number2);
noError = true;
break;
} else if (Symbol.contains("/") || Symbol.contains("÷")) {
Total = Divide(Number1, Number2);
noError = true;
break;
}
}
}
System.out.println(String.valueOf(Number1)
+Symbol+String.valueOf(Number2)
+"="+String.valueOf(Total));
}
}
Operations.java (2nd Class)
package com.indie;
public class Operations {
public static double Add(double x, double y) { return x+y; }
public static double Subtract(double x, double y){ return x-y; }
public static double Multiply(double x, double y){ return x*y; }
public static double Divide(double x, double y){ return x/y; }
}
Got this result
Any way of fixing it? How did it end up with 2.0+20.0=2.0? Please Help.
Any way of preventing it from giving that type of results?
Other results:
result 1:
Enter your number:
2
What do you want to do:
+5
Enter your second number:
56
56.0+50.0=56.0
result 2:
Enter your number:
1
What do you want to do:
+1
Enter your second number:
1
1.0+10.0=1.0
On this part of the code, you should change this:
...
System.out.println("Enter your second number:");
try {
Number1 = scanner.nextDouble();
}
...
to this:
...
System.out.println("Enter your second number:");
try {
Number2 = scanner.nextDouble();
}
...
You never change the value of Number2 in your code.
Something it is goood to have a second pair of eyes
In your code you never assign value to Number2
System.out.println("Enter your second number:");
try {
Number2 = scanner.nextDouble();

Methods in subclass aren't working

I have an assignment that was to make a subclass which adds on to the existing super class, and this is run by a third class with a main method which creates an object of the subclass and calls appropriate methods.
My problem is that calling methods in the super class works correctly, but calling the two additional methods I have written in the subclass gets ignored.
I've checked, and the main method IS getting to the if statement which calls the new method in the subclass, but this method is not executing.
Specifically the superclass is a memory calculator with basic add, subtract, divide, and multiply options, as well as an option to clear the current value.
The subclass is a scientific memory calculator that overrides the menu method in the superclass to include options for power and logarithm, and has methods for both.
When I choose the option for power, it is simply returning the current value and not raising that power to the number specified.
Superclass:
import java.util.Scanner;
public class MemoryCalc {
private double currentValue = 0;
public static int displayMenu() {
Scanner input = new Scanner(System.in);
System.out.print("Menu\n1. Add\n2. Subtract\n3. Multiply\n4. Divide\n5. Clear\n6. Quit\nWhat would you like to do? ");
int menuChoice = input.nextInt();
while (menuChoice < 1 || menuChoice > 6) {
System.out.print("Please enter a valid option.\n\n");
System.out.print("Menu\n1. Add\n2. Subtract\n3. Multiply\n4. Divide\n5. Clear\n6. Quit\nWhat would you like to do? ");
menuChoice = input.nextInt();
}
return menuChoice;
}
public static double getOperand(String prompt) {
Scanner input = new Scanner(System.in);
System.out.print(prompt);
double operand = input.nextDouble();
return operand;
}
public double getCurrentValue() {
return currentValue;
}
public void add(double operand2) {
currentValue = currentValue + operand2;
}
public void subtract(double operand2) {
currentValue = currentValue - operand2;
}
public void multiply(double operand2) {
currentValue = currentValue * operand2;
}
public void divide(double operand2) {
if (operand2 == 0) {
currentValue = Double.NaN;
}
else currentValue = currentValue / operand2;
}
public void clear() {
currentValue = 0;
}
}
Subclass:
import java.util.Scanner;
public final class ScientificMemCalc extends MemoryCalc {
private double currentValue = 0;
public static int displayMenu() {
Scanner input = new Scanner(System.in);
int menuChoice = -1;
while (menuChoice < 1 || menuChoice > 8) {
System.out.println();
System.out.println("Menu");
System.out.println("1. Add");
System.out.println("2. Subtract");
System.out.println("3. Multiply");
System.out.println("4. Divide");
System.out.println("5. Power");
System.out.println("6. Logarithm");
System.out.println("7. Clear");
System.out.println("8. Quit");
System.out.println();
System.out.print("What would you like to do? ");
menuChoice = input.nextInt();
if (menuChoice < 1 || menuChoice > 8) {
System.out.println(menuChoice + " wasn't one of the options");
}
}
return menuChoice;
}
public void power(double operand2) {
currentValue = Math.pow(currentValue, operand2);
}
public void logarithm() {
currentValue = Math.log(currentValue);
}
}
Main Method:
public class ScientificCalcDriver {
public static void main(String[] args) {
ScientificMemCalc calculator1 = new ScientificMemCalc();
int menuChoice = 0;
while (menuChoice != 8) {
System.out.print("The current value is " + calculator1.getCurrentValue() + "\n");
menuChoice = ScientificMemCalc.displayMenu();
if (menuChoice < 6) {
double Operand2 = ScientificMemCalc.getOperand("What is the second number? ");
if (menuChoice == 1) {
calculator1.add(Operand2);
}
if (menuChoice == 2) {
calculator1.subtract(Operand2);
}
if (menuChoice == 3) {
calculator1.multiply(Operand2);
}
if (menuChoice == 4) {
calculator1.divide(Operand2);
}
if (menuChoice == 5) {
calculator1.power(Operand2);
}
}
else if (menuChoice == 6) {
calculator1.logarithm();
}
else if (menuChoice == 7) {
calculator1.clear();
}
else if (menuChoice == 8) {
System.out.print("Goodbye!");
System.exit(0);
}
}
}
}
You've got two different currentValue variables, both private, one in the superclass and one in the subclass. The methods in your superclass are changing the value of its variable, and the methods of the subclass are changing the value of its variable.
Make currentValue protected in the superclass, and remove it from the subclass.
Update:
Based on the "must be private" comment: You still need to remove the extra currentValue variable in the subclass, but as Oleg points out, you can obtain and update the value of a private variable in a superclass using get and set methods defined in the superclass.

Java: Subclass can't get value of field in superclass

Here's the superclass:
public class MemoryCalc {
private double currentValue;
public double getCurrentValue() {
return currentValue;
}
public void setCurrentValue(double currentValue) {
this.currentValue = currentValue;
}
public int displayMenu() {
#SuppressWarnings("resource")
Scanner input = new Scanner(System.in);
int choice = -1;
while (choice < 1 || choice > 6) {
System.out.println();
System.out.println("Menu");
System.out.println("1. Add");
System.out.println("2. Subtract");
System.out.println("3. Multiply");
System.out.println("4. Divide");
System.out.println("5. Clear");
System.out.println("6. Quit");
System.out.println();
System.out.print("What would you like to do? ");
choice = input.nextInt();
if (choice < 1 || choice > 6) {
System.out.println(choice + " wasn't one of the options");
}
if (choice == 6) {
System.out.println("Goodbye!");
System.exit(0);
}
}
return choice;
}
public double getOperand(String prompt) {
#SuppressWarnings("resource")
Scanner input = new Scanner(System.in);
System.out.print(prompt);
return input.nextDouble();
}
public void add(double op2) {
currentValue += op2;
}
public void subtract(double op2) {
currentValue -= op2;
}
public void multiply(double op2) {
currentValue *= op2;
}
public void divide(double op2) {
if (op2 == 0) {
currentValue = Double.NaN;
} else {
currentValue /= op2;
}
}
public void clear() {
currentValue = 0;
}
}
Here's the Subclass:
class SciMemCalc extends MemoryCalc{
private double currentValue;
public int displayMenu(){
#SuppressWarnings("resource")
Scanner input = new Scanner(System.in);
int choice = -1;
while (choice < 1|| choice > 8){
System.out.println();
System.out.println("Menu:");
System.out.println("1. Add");
System.out.println("2. Subtract");
System.out.println("3. Multiply");
System.out.println("4. Divide");
System.out.println("5. Power");
System.out.println("6. Logarithm");
System.out.println("7. Clear");
System.out.println("8. Quit");
System.out.println();
System.out.println("What would you like to do?");
choice = input.nextInt();
if (choice < 1|| choice > 8){
System.out.println(choice +" wasn't one of the options");
}
if (choice == 8){
System.out.println("Thank you, good bye!");
System.exit(0);
}
}
return choice;
}
public void power(double op2){
Math.pow(currentValue, op2);
}
public void log() {
Math.log(currentValue);
}
}
Here's the Driver:
public class SciCalcDriver {
public static void main(String[] args) {
SciMemCalc calc = new SciMemCalc();
while (true){
System.out.println("The current value is " + calc.getCurrentValue());
int choice = calc.displayMenu();
double second = 0;
if (choice < 6) {
second = calc.getOperand("What is the second number? ");
}
if (choice == 1) {
calc.add(second);
} else if (choice == 2){
calc.subtract(second);
} else if (choice == 3){
calc.multiply(second);
} else if (choice == 4){
calc.divide(second);
} else if (choice == 5){
calc.power(second);
} else if (choice == 6){
calc.log();
} else if (choice == 7){
calc.clear();
}
}
}
}
Now the calculator can add, subtract, multiply, and divide fine but when I use the power or log method nothing happens. I've tried using the debugger and it says it get's all the necessary inputs, but the currentValue doesn't seem to change. I don't think I need to make any changes to the superclass. Advice?
class MemoryCalc {
private double currentValue;
}
class SciMemCalc extends MemoryCalc {
private double currentValue;
}
What is happening here is there are actually two variables declared with the same name. SciMemCalc does not have access to the variable declared in MemoryCalc because it is private.
Instead you would normally make currentValue protected or interact with it through setters and getters.
class MemoryCalc {
protected double currentValue;
}
class SciMemCalc extends MemoryCalc {
// SciMemCalc has access to currentValue
}
Remove private double currentValue; from the subclass and change private double currentValue; in the superclass to protected double currentValue;. If you have a private value, it can't be accessed by the superclass, and the duplicate value you have created just hides the original. Protected solves this.
You're shadowing your superclass' currentValue by re-declaring it in your subclass. To resolve the issue, in your subclass SciMemCalc, get rid of the line declaring currentValue:
private double currentValue;
And change all of SciMemCalc's accesses to currentValue to use the superclass' accessor (getter) and mutator (setter) methods:
public void power(double op2){
setCurrentValue(Math.pow(getCurrentValue(), op2));
}
public void log() {
setCurrentValue(Math.log(getCurrentValue()));
}
Alternatively, you could declare currentValue as protected in your superclass which would allow you to access it directly in your subclass. However, also in this case, you have to make sure that you assign the result of your calculation back to currentValue:
public void power(double op2){
currentValue = Math.pow(currentValue, op2);
}
public void log() {
currentValue = Math.log(currentValue);
}
You have declared the currentValue as a private member of class so it cannot be accessed by other
classes. when you make it protected or public then it will work. And will solve you problem.
just change that currentValue field in super class.
protected double currentValue // it will be only accessed by its child class
public double currentValue // it will be accessed by all classes in this package

Error in simple java program

I am working on teaching myself java and while working on a code using classes I ran into this error
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at java.util.Scanner.nextDouble(Unknown Source)
at StateCalculator.getOperand(StateCalculator.java:29)
at StateCalculator.main(StateCalculator.java:77)
Below is my code:
import java.util.Scanner;
public class StateCalculator {
private double currentValue = 0;
//Initialize to 0
public StateCalculator() {
}
public static int displayMenu() {
Scanner keyboard = new Scanner(System.in);
int menuChoice = 0;
do {
System.out.print("Menu\n 1. Add\n 2. Subtract\n 3. Multiply\n 4. Divide\n 5.Clear\n 6. Quit\n What would you like to do?: ");
menuChoice = keyboard.nextInt();
} while(menuChoice < 1 || menuChoice > 6);
keyboard.close();
return menuChoice;
}
public static double getOperand(String prompt) {
Scanner input = new Scanner(System.in);
double operand = 0;
System.out.print(prompt);
operand = input.nextDouble();
input.close();
return operand;
}
public double getCurrentValue() {
return currentValue;
}
public void add(double operand) {
currentValue += operand;
}
public void subtract(double operand) {
currentValue -= operand;
}
public void multiply(double operand) {
currentValue *= operand;
}
public void divide(double operand) {
if(operand == 0) {
currentValue = Double.NaN;
}
else {
currentValue /= operand;
}
}
public void clear() {
currentValue = 0;
}
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
StateCalculator calculator = new StateCalculator();
int option;
double operand;
do{
System.out.println("The current value is " + calculator.currentValue);
option = StateCalculator.displayMenu();
switch(option) {
case 1:
operand = getOperand("What is the second number?: ");
calculator.add(operand);
break;
case 2:
operand = getOperand("What is the second number?: ");
calculator.subtract(operand);
break;
case 3:
operand = getOperand("What is the second number?: ");
calculator.multiply(operand);
break;
case 4:
operand = getOperand("What is the second number?: ");
calculator.divide(operand);
break;
case 5:
calculator.clear();
break;
}
}while(option != 6);
keyboard.close();
}
}
I tried running the debug feature in eclipse and discovered the problem occurs on line 29 in my getOperand method when I attempt to set operand = input.nextDouble. However, I don't understand why this would be an issue.
Don't call keyboard.close(); when you close keyboard (which you defined)
Scanner keyboard = new Scanner(System.in);
it closes System.in, and then your other methods can't work (because the console will not re-open). You can have multiple scanners on System.in (as long as you don't close them), or pass one (or, but please don't, use a global).
Per the javadoc,
When a Scanner is closed, it will close its input source if the source implements the Closeable interface.

Categories