why is calculator.getValue() always 0? - java

I am a java student and I am working to make my code more object oriented. I can easily code calculator in main but I'm really struggling to implement it with methods. The following code will always return 0...but the goal is to create a program which allows a user to enter an operator and a number in one line (example +5) the code should output the previous value, the new value, and allow for resetting. I believe I am really close to solving this and just need a point in the right direction..
output
Enter an operator and a number:
+5
0.0
Calculator class
import java.util.Scanner;
public class Calculator {
private final int RESET = 0;
private double number = 0;
private double result = 0; // I believe this is the issue but how can I resolve it?
private char operator;
private static Scanner keyboard = new Scanner(System.in);
public Calculator(double number)
{
this.number = number;
}
// this method invokes the whatOperator() to create a new result
// the edited method still returns 0
public double aResult(Calculator other)
{
other.whatOperator();
this.result = other.result;
return result;
}
// I created this method in hopes that it would do most of the work..when I invoke it and enter my operator and number it does not seem to function correctly
public void whatOperator()
{
String operator = null;
operator = enterNumber();
double theNumber = Double.parseDouble(operator);
char theOperator =operator.charAt(0);
operator = null;
operator += theOperator;
// switch method to find the operator
switch(operator){
case "*":
result = getNumber() * theNumber;
break;
case "/":
result = getNumber() / theNumber;
break;
case "+":
result = getNumber() + theNumber;
break;
case "-":
result = getNumber() - theNumber;
break;
case "R":
result = RESET;
break;
}
}
// methods for operation...I was hoping to not use these
public double add(double secondNumber)
{
result = number + secondNumber;
return result;
}
public double divide(double secondNumber)
{
result = number / secondNumber;
return result;
}
public double multiply(double secondNumber)
{
result = number * secondNumber;
return result;
}
public void subtract(double secondNumber)
{
result = number - secondNumber;
}
public double getNumber()
{
return number;
}
// method for getting input
public static String enterNumber()
{
System.out.println("Enter an operator and a number:");
String toString = keyboard.nextLine();
return toString;
}
public static void main (String[] args) {
// the calculator is initialized at 0
Calculator a = new Calculator(0);
// now I create a second calculator with the result from the aResult()
Calculator b = new Calculator(a.aResult(a));
// why is b.getNumber() = 0 at this point?
String theString = String.valueOf(b.getNumber());
// prints 0 every time
System.out.println(theString);
}
}

There are some mistakes in your code.
public double aResult(Calculator other)
{
other = new Calculator(getNumber());
other.whatOperator();
this.result = result;
return result;
}
The line this.result = result doesn't make any sense. I think you wanted the method whatOperator() to return a result e.g.
this.result = other.whatOperator();
I also think that you don't want to override the "other" calculator. You never use the new calculator. But you want to print the output of the new calculator in your main method. Because you never used the new calculator, the output is 0.

In your aResult method you are initiating another new instance of Calculator
public double aResult(Calculator other) {
//other = new Calculator(getNumber()); // this should not be here
other.whatOperator();
this.result = result;
return result;
}

The solution to the problem:
//change
this.result = result; //this does nothing
//to
this.result = other.result; //this changes the result to the new value
//erase this line
other = new Calculator(getNumber()); // do not need to create a new calculator
change the method whatOperator to a double and return a double with it

Related

How to aggregate methods from another class?

I have a class Fraction with the arithmetic operations for fractions. Here is an abstract of my class Fraction. (I've included only method of addition.)
package com.company;
import java.util.Scanner;
public class Fraction {
private int num; // numerator
private int denom; // denominator
public Fraction() {
super();
}
public Fraction(int num, int denom) {
super();
this.num = num;
this.denom = denom;
if (denom == 0) {
this.denom = 1;
}
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public int getDenom() {
return denom;
}
public void setDenom(int denom) {
if (denom > 0) {
this.denom = denom;
}
}
public void inputFraction() {
Scanner innum = new Scanner(System.in);
System.out.println("Input numerator: ");
num = innum.nextInt();
Scanner indenom = new Scanner(System.in);
System.out.println("Input denominator: ");
denom = indenom.nextInt();
}
public String toString() {
return num + "/" + denom;
}
// addition
public Fraction add(Fraction f2) {
int num2 = f2.getNum();
int denom2 = f2.getDenom();
int num3 = (num * denom2) + (num2 * denom);
int denom3 = denom * denom2;
Fraction f3 = new Fraction(num3, denom3);
f3.simplifyFraction();
return f3;
}
}
Now my second task is to make a class Calculator, which aggregates two instances of class Fraction as its attributes and create a complete set of arithmetic operations using instances of the class Fraction as operands. So, if I am correct, I basically have to use those methods from the class Fraction in my Calculator. I've attempted to do that but I do not get any output when I call for method add (from class Calculator) in main().
Here is an abstract of my Calculator class. (I've included only method of addition to give the general idea.)
package com.company;
public class Calculator {
private Fraction f1 = new Fraction();
private Fraction f2 = new Fraction();
private Fraction f;
public Calculator() {
super();
}
public Calculator(Fraction f) {
this.f = f;
}
public void input() {
f1.inputFraction();
f2.inputFraction();
}
public void view() {
f1.toString();
System.out.println("Fraction = " + f1.toString());
f2.toString();
System.out.println("Fraction = " + f2.toString());
}
public Calculator add() {
Calculator f = new Calculator(f1.add(f2));
return f;
}
}
And part of my main():
Calculator m = new Calculator();
m.input();
m.view();
System.out.println("Sum = " + m.add());
I'm assuming there are multiple places where I have gone wrong, so I'd be grateful for some advice.
Your add method is the problem here. It is returning a Calculator object and println calls that object's toString method so the toString method for Calculator is being called. The add method should not return a new Calculator but instead a new Fraction that represents your result. Then the code will print the toString method in your Fraction class which is what you want to display.
public class Calculator {
.
.
.
public Fraction add() {
return f1.add(f2);
}
}

Any alternative to the indexOfAny method?

I'm trying to find the index of a char that splits two numbers, the char can either be +, -, / or *. I'm making a simple calculator.
The process would be extremely trivial if i could use the indexofAny method, because i would be able to check for all 4 values in 1 line. Sadly, it's not available in Java.
NOTE: I do not want to use indexOf, since i would have to write 4 lines of nearly identical code.
My main class:
import java.util.Scanner;
public class Main {
static Scanner scanner = new Scanner(System.in);
public static MathUserInput readInput() {
String input = scanner.nextLine();
String[] parts = input.split("\\+|-|/|\\*");
int firstNumber = Integer.parseInt(parts[0]);
int secondNumber = Integer.parseInt(parts[1]);
char operation = input.charAt(1);
return new MathUserInput(firstNumber, secondNumber, operation);
}
public static void main(String[] args) {
System.out.println("This is a calculator.");
System.out.println();
System.out.println("Please provider a number, an operator and a number");
System.out.println();
MathUserInput input = readInput();
char operation = input.getOperation();
switch (operation) {
case '+':
System.out.println(input.getFirstNumber() + input.getSecondNumber());
break;
case '-':
System.out.println(input.getFirstNumber() - input.getSecondNumber());
break;
case '*':
System.out.println(input.getFirstNumber() * input.getSecondNumber());
break;
case '/':
System.out.println(input.getFirstNumber() / input.getSecondNumber());
break;
}
}
}
I'm currently using a switch statement, but i'm hoping that there's a better alternative. Essentially, i'm aiming to only have 1 line that outputs the result in the calculator.
Thank you!
You can use StringUtils#indexOfAny(CharSequence, char...) from Apache Commons Lang which does exactly what you want.
import org.apache.commons.lang3.StringUtils;
public static MathUserInput readInput() {
String input = scanner.nextLine();
int pos = StringUtils.indexOfAny(input, '+', '-', '/', '*');
return new MathUserInput(input.substring(0, pos), input.substring(pos + 1), input.charAt(pos));
}
If you don't want to include a library for this, you can always write your own utility. Have a look at the code of StringUtils to be inspired. They are basically looping over the characters of the input string and in a nested loop over the characters to be found. The index of the first match is then returned.
I think you can use enum for the operations and encapsulate logic in it:
public class Main {
public static void main(String... args) {
Scanner scan = new Scanner(System.in);
scan.useLocale(Locale.ENGLISH);
System.out.println("This is a calculator.");
System.out.println("Please provider a number, an operator and a number");
MathUserInput input = readInput(scan);
System.out.println(input.execute());
}
private static final Pattern PATTERN = Pattern.compile("(?<a>[^+\\-*\\/]+)(?<operation>[+\\-*\\/]+)(?<b>[^+\\-*\\/]+)");
private static MathUserInput readInput(Scanner scan) {
Matcher matcher = PATTERN.matcher(scan.nextLine());
if (!matcher.matches())
throw new RuntimeException("Incorrect expression");
double a = Double.parseDouble(matcher.group("a").trim());
double b = Double.parseDouble(matcher.group("b").trim());
Operation operation = Operation.parseSign(matcher.group("operation").trim().charAt(0));
return new MathUserInput(a, b, operation);
}
private static final class MathUserInput {
private final double a;
private final double b;
private final Operation operation;
public MathUserInput(double a, double b, Operation operation) {
this.a = a;
this.b = b;
this.operation = operation;
}
public double execute() {
return operation.execute(a, b);
}
}
private enum Operation {
SUM('+', Double::sum),
SUBTRACTION('-', (a, b) -> a - b),
MULTIPLY('*', (a, b) -> a * b),
DIVISION('/', (a, b) -> a / b);
private final char sign;
private final BiFunction<Double, Double, Double> func;
Operation(char sign, BiFunction<Double, Double, Double> func) {
this.sign = sign;
this.func = func;
}
public final double execute(double a, double b) {
return func.apply(a, b);
}
public static Operation parseSign(char sign) {
for (Operation operation : values())
if (operation.sign == sign)
return operation;
throw new EnumConstantNotPresentException(Operation.class, Character.toString(sign));
}
}
}

Java variable with rest of substraction

I've got 2 integer values, e.g. a = 10 and b = 20.
Now i want to substract them: a - b, but as a result i don't want to have negative values, so in this example i want the result 0 and a new integer variable with the rest (10 here).
Two more examples:
Input: a=40, b=20; Expected Output:20
input: a=25 b=50 Expected Output: 0 and a new int var = 25
How to do this in java without external libraries?
From what I understand, you want a variable to be holding the result if the result is greater than or equal to 0. Otherwise, that variable should hold 0 and another variable will hold a positive value of the result.
If this is the case, consider the following code snippet:
int result = a -b;
int otherVariable = 0;
if (result < 0) {
otherVariable = -result;
result = 0;
}
int aMinusB = a-b;
int output = Math.max(aMinusB,0);
int rest = aMinusB < 0 ? Math.abs(aMinusB) : 0;
https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html
There are two ways to solve this problem: -
First: -
If you don't want to create a method to return this value and only to display it, then you can do it by printing out the results of if-else block in the code below within the function itself.
Second: -
If you want to use the result somewhere else, go for an object based approach: -
// Main class
public class SubtractWithRest {
public static void main(String[] args) {
SubtractResultWithRest subtractResultWithRest = new SubtractResultWithRest();
subtraction(10, 20, subtractResultWithRest);
System.out.println("Result: " + subtractResultWithRest.getResult());
System.out.println("Rest: " + subtractResultWithRest.getRest());
}
private static void subtraction(int num1, int num2, SubtractResultWithRest subtractResultWithRest) {
if (num2 > num1) {
subtractResultWithRest.setResult(0);
subtractResultWithRest.setRest(num2 - num1);
} else {
subtractResultWithRest.setResult(num1 - num2);
}
}
}
// Object class
public class SubtractResultWithRest {
private int result;
private int rest = 0;
public int getResult() {
return result;
}
public void setResult(int result) {
this.result = result;
}
public int getRest() {
return rest;
}
public void setRest(int rest) {
this.rest = rest;
}
}

Cannot convert an ArrayList with my custom object as its data type into the corresponding regular array

As the title says, I cannot convert my ArrayList into an Array. The data type of my ArrayList is a custom object but I cannot seem to find what my problem is. The error that it gives doesn't show up as a problem until the program is run. The first two classes are the objects, then I have a class calle Tester where the main method is.
Class where error appears:
package backend;
import java.util.ArrayList;
public class Function {
Coefficient[] coefArray;
int constant;
public Function(ArrayList<Coefficient> coefFunction, int constant){
Coefficient[] coefArray = (Coefficient[]) coefFunction.toArray();
this.coefArray = sortArray(coefArray);
this.constant = constant;
}
private Coefficient[] sortArray(Coefficient[] newArray){
int tempPow = -1000000000;
Coefficient[] sortedArray = new Coefficient[newArray.length];
sortedArray = null;
for(int i=0; isFull(sortedArray); i++){
for(Coefficient coef : newArray){
if(coef.pow>tempPow){
tempPow = coef.pow;
sortedArray[i] = coef;
}
}
}
return sortedArray;
}
private boolean isFull(Coefficient[] anArray){
for(Coefficient i : anArray) {
if(i == null) return true;
}
return false;
}
public String toString(){
String compiledString="";
for(Coefficient coef : coefArray){
compiledString += coef.toString()+"+";
}
if(constant==0){
//No constant there
}else{
compiledString = compiledString + constant;
}
return compiledString;
}
}
Coefficient Class:
package backend;
public class Coefficient {
String stringVersion;
public int pow;
public int coefInteger;
public double coefDouble;
//Constructor for variable with a coefficient that is non-fractal and a power higher than 1
public Coefficient(int coef, int pow){
this.coefInteger = coef;
this.pow = pow;
switch(coef){
case 0:
//Do nothing here
case 1:
this.stringVersion = "x^"+pow;
break;
default:
this.stringVersion = coef+"x^"+pow;
break;
}
}
//Constructor for variable with a coefficient that is fractal and a power higher than 1
public Coefficient(double coef, int pow){
this.coefDouble = coef;
this.pow = pow;
this.stringVersion = coef+"x^"+pow;
}
//Constructor for variable with a coefficient but no power
public Coefficient(double coef){
this.coefDouble = coef;
this.pow = 1;
this.stringVersion = coef+"x";
}
//Constructor for variable with a coefficient but no power
public Coefficient(int coef){
this.coefInteger = coef;
this.pow = 1;
this.stringVersion = coef+"x";
}
public String toString(){
return stringVersion;
}
}
Tester:
package backend;
import java.util.ArrayList;
import java.util.Scanner;
public class Tester {
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
ArrayList<Coefficient> function = new ArrayList<Coefficient>();
Coefficient xVal;
Function printFunction;
System.out.println("Enter the degree of the equation:");
int pow = scan.nextInt();
System.out.println("Enter the x components of the function in the order of coefficient then power. Enter constant last:");
double coef = 0;
while(pow>0){
coef = scan.nextDouble();
if(pow==1){
if((int) coef == coef){
xVal = new Coefficient((int) coef);
}else{
xVal = new Coefficient(coef);
}
}else{
if((int) coef == coef){
xVal = new Coefficient((int) coef, pow);
}else{
xVal = new Coefficient(coef, pow);
}
}
function.add(xVal);
pow--;
}
System.out.println("Enter the constant:");
printFunction = new Function(function, scan.nextInt());
System.out.println(printFunction.toString());
}
}
Error:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object;
cannot be cast to [Lbackend.Coefficient;
at backend.Function.<init>(Function.java:11)
at backend.Tester.main(Tester.java:36)
Any and all help is greatly appreciated. If you see something else that needs to be fixed, please point it out.
The error is in this line:
Coefficient[] coefArray = (Coefficient[]) coefFunction.toArray();
If you read the javadoc of toArray(), you can see that it returns an Object[], which you cannot simply cast to Coefficient[].
Instead use toArray(T[] a):
Coefficient[] coefArray = coefFunction.toArray(new Coefficient[coefFunction.size()]);
Disclaimer: I did not review the rest of your code, so the absence of any remarks does not imply that everything else is fine.

Postfix evaluation in java with stack

I made this program that evaluates a postfix expression.
It works fine if only single digit numbers are used.
My problem is how do I push multiple-digit numbers if input has spaces?
ex. input: 23+34*- output is -7
but if I input: 23 5 + output is only 3(which is the digit before the space)
it should have an output of 28
my codes:
public class Node2
{
public long num;
Node2 next;
Node2(long el, Node2 nx){
num = el;
next = nx;
}
}
class stackOps2
{
Node2 top;
stackOps2(){
top = null;
}
public void push(double el){
top = new Node2(el,top);
}
public double pop(){
double temp = top.num;
top = top.next;
return temp;
}
public boolean isEmpty(){
return top == null;
}
}
public class ITP {
static stackOps2 so = new stackOps2();
public static final String operator = "+-*/^";
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter the infix:");
String s = input.next();
String output;
InToPost theTrans = new InToPost(s);
output = theTrans.doTrans();
System.out.println("Postfix is " + output + '\n');
System.out.println(output+" is evaluated as: "+evaluate(output));
}
public static double evaluate(String value)throws NumberFormatException{
for(int i=0;i<value.length();i++){
char val = value.charAt(i);
if(Character.isDigit(value.charAt(i))){
String v = ""+val;
so.push(Integer.parseInt(v));
}
else if(isOperator(val)){
double rand1=so.pop();
double rand2=so.pop();
double answer ;
switch(val){
case '+': answer = rand2 + rand1;break;
case '-': answer = rand2 - rand1;break;
case '*': answer = rand2 * rand1;break;
case '^': answer = Math.pow(rand2, rand1);break;
default : answer = rand2 / rand1;break;
}
so.push(answer);
}
else if(so.isEmpty()){
throw new NumberFormatException("Stack is empty");
}
}
return so.pop();
}
public static boolean isOperator(char ch){
String s = ""+ch;
return operator.contains(s);
}
}
This is a small, self-contained example that does all the string parsing and evaluation. The only difference from your example is that it accepts the whole string at once instead of using a Scanner. Note the use of Integer.parseInt -- that's missing in your example. I think you can easily extend this for your needs.
#SuppressWarnings({"rawtypes", "unchecked"})
public static void main(String[] args) {
final String in = "5 9 + 2 * 6 5 * +";
final Deque<Object> s = new LinkedList();
for (String t : in.split(" ")) {
if (t.equals("+")) s.push((Integer)s.pop() + (Integer)s.pop());
else if (t.equals("*")) s.push((Integer)s.pop() * (Integer)s.pop());
else s.push(Integer.parseInt(t));
}
System.out.println(s.pop());
}

Categories

Resources