Create a Calculator class that implements the provided StackCalculator interface
ID: 3849266 • Letter: C
Question
Create a Calculator class that implements the provided StackCalculator interface. Java program must use the signature and follow each of the requirements. Thanks in advance
Feature
Signature
Requirement
Constructor
Calculator()
Precondition: none
Postcondition: a new calculator with an empty number stack
Methods
public void enter(String entry)
Precondition: entry is either
a double value
a recognized operator [ +, -, *, /]
Postcondition: if the entry is a double, the value is pushed onto the calculator’s number stack. If an operator, the top two values are popped from the stack, the operation performed, and the result pushed onto the stack. Note: the second operand is popped first.
double peek()
Precondition: number stack is not empty, otherwise throws EmptyStackException
Looks at the number at the top of this stack without removing it from the stack.
double pop()
Precondition: number stack is not empty, otherwise throws EmptyStackException
Removes the number at the top of this stack and returns that value.
void clear()
Removes all numbers from this stack. The stack will be empty after this call returns
boolean isEmpty
Tests If the number stack of this calculator is empty
int size()
Returns the number of values in this calculators number stack.
Feature
Signature
Requirement
Constructor
Calculator()
Precondition: none
Postcondition: a new calculator with an empty number stack
Methods
public void enter(String entry)
Precondition: entry is either
a double value
a recognized operator [ +, -, *, /]
Postcondition: if the entry is a double, the value is pushed onto the calculator’s number stack. If an operator, the top two values are popped from the stack, the operation performed, and the result pushed onto the stack. Note: the second operand is popped first.
double peek()
Precondition: number stack is not empty, otherwise throws EmptyStackException
Looks at the number at the top of this stack without removing it from the stack.
double pop()
Precondition: number stack is not empty, otherwise throws EmptyStackException
Removes the number at the top of this stack and returns that value.
void clear()
Removes all numbers from this stack. The stack will be empty after this call returns
boolean isEmpty
Tests If the number stack of this calculator is empty
int size()
Returns the number of values in this calculators number stack.
Explanation / Answer
Calculator.java
import java.util.EmptyStackException;
import java.util.Stack;
public class Calculator implements StackCalculator {
protected Stack<String> numberStack;
private String topValue = null;
/**
* Creates a new Calculator object with a new Stack to hold the values
*/
public Calculator() {
numberStack = new Stack<String>();
}
@Override
public void enter(String entry) {
Entry input = new Entry(numberStack);
if (input.isDouble(entry)) {
numberStack.push(entry);
}
if (input.isOperator(entry)) {
input.performOperation(entry);
}
}
@Override
public double peek() {
if (this.isEmpty()) {
throw new EmptyStackException();
} else {
topValue = numberStack.get(this.size() - 1);
return Double.parseDouble(topValue);
}
}
@Override
public double pop() {
if (this.isEmpty()) {
throw new EmptyStackException();
} else {
topValue = numberStack.get(this.size() - 1);
numberStack.remove(topValue);
return Double.parseDouble(topValue);
}
}
@Override
public void clear() {
for (int i = this.size(); i >= 1; i--) {
numberStack.remove(i - 1);
}
}
@Override
public boolean isEmpty() {
if (this.size() == 0) {
return true;
} else {
return false;
}
}
@SuppressWarnings("unused")
@Override
public int size() {
int stackSize = 0;
for (String entry : numberStack) {
stackSize++;
}
return stackSize;
}
}
StackCalculator.java
public interface StackCalculator {
/**
* Processes an entry to the calculator. If a double value, the entry is
* pushed onto the stack. If an operator (+, -, /,or *), the operands are
* popped from the stack and the result of the operation is pushed onto the
* stack. Note: the second operand is popped first.
*
* @param entry
* entry to the calculator, either a double value or a valid
* operator
*
*/
void enter(String entry);
/**
* Looks at the number at the top of this stack without removing it from the
* stack.
*
* @return top number of this stack
* @throws EmptyStackException
* - if this stack is empty
*/
double peek();
/**
* Removes the number at the top of this stack and returns that value.
*
* @return the number at the the top of this stack
* @throws EmptyStackException
* - if this stack is empty
*/
double pop();
/**
* Removes all numbers from this stack. The stack will be empty after this
* call returns
*/
void clear();
/**
* Tests if the number stack of this calculator is empty
*
* @return true if and only if this calculator's stack has no values, false
* otherwise
*/
boolean isEmpty();
/**
* Returns the number of values in this calculators number stack.
*
* @return the number of values in this calculators number stack
*/
int size();
}
Entry.java
import java.util.Stack;
public class Entry extends Calculator {
/**
* Creates a new Entry object that will check for inputs as Double and
* choose the appropriate mathematical operation based on the user input
*
* @param numStack
* the Stack passed from Calculator()
*/
public Entry(Stack<String> numStack) {
numberStack = numStack;
}
/**
* Tries to parse the String entry to a Double
*
* @param entry
* The provided input as a String
* @throws NumberFormatException
* If entry cannot be parsed to Double
* @return true if entry can be parsed to Double, otherwise false
*/
public boolean isDouble(String entry) {
try {
Double.parseDouble(entry);
return true;
} catch (NumberFormatException nfe) {
return false;
}
}
/**
* Checks the entry for operators [+, -, *, /]
*
* @param entry
* The provided input as a String
* @throws IllegalArgumentException
* If entry is an illegal or non-operator character
* @return true if entry is an operator otherwise false
*/
public boolean isOperator(String entry) {
final String opPattern = "[-+*/]";
try {
if (entry.matches(opPattern)) {
return true;
} else {
return false;
}
} catch (IllegalArgumentException iae) {
return false;
}
}
/**
* Chooses the correct operation when given two distinct operands, operand 1
* and operand 2
*
* @param operator
* The provided operator
* @throws NullPointerException
* If An operator is passed with no values in the calculator
* @throws IllegalArgumentException
* Division by 0
* @return the calculated result
*/
public void performOperation(String operator) {
Double result = 0.0;
Double[] ops = new Double[2];
if (this.isEmpty()) {
throw new NullPointerException("The stack has no values");
} else if (this.size() == 1) {
ops[0] = this.pop();
ops[1] = ops[0];
} else if (this.size() > 1) {
ops[1] = this.pop();
ops[0] = this.pop();
}
switch (operator) {
case "+":
result = ops[0] + ops[1];
numberStack.push(result.toString());
break;
case "-":
result = ops[0] - ops[1];
numberStack.push(result.toString());
break;
case "*":
result = ops[0] * ops[1];
numberStack.push(result.toString());
break;
case "/":
if (ops[1] == 0) {
throw new IllegalArgumentException("Argument 'divisor' is 0");
} else {
result = ops[0] / ops[1];
numberStack.push(result.toString());
}
break;
}
}
}
Entries.java
import java.util.Stack;
public class Entries extends Calculator {
/**
* Creates a new Inputs object that will check for inputs as Double and
* choose the appropriate mathematical operation based on the user input
*
* @param numStack
* the Stack passed from Calculator()
*/
public Entries(Stack<String> numStack) {
numberStack = numStack;
}
/**
* Tries to parse the String entry to a Double
*
* @param entry
* the provided input as a String
* @throws NumberFormatException
* If entry cannot be parsed to Double
* @return true if entry can be parsed to Double, otherwise false
*/
public boolean isDouble(String entry) {
try {
Double.parseDouble(entry);
return true;
} catch (NumberFormatException nfe) {
return false;
}
}
/**
* Checks the entry for operators [+, -, *, /]
*
* @param entry
* the provided input as a String
* @throws IllegalArgumentException
* If entry is an illegal or non-operator character
* @return true if entry is an operator otherwise false
*/
public boolean isOperator(String entry) {
final String opPattern = "[-+*/]";
try {
if (entry.matches(opPattern)) {
return true;
} else {
return false;
}
} catch (IllegalArgumentException iae) {
return false;
}
}
/**
* Chooses the correct operation when given two distinct operands, operand 1
* and operand 2
*
* @param entry
* the provided operator
* @throws NullPointerException
* If An operator is passed with no values in the calculator
* @throws IllegalArgumentException
* Division by 0
* @return the calculated result
*/
public void performOperation(String entry) {
Double result = 0.0;
Double[] ops = new Double[2];
if (this.isEmpty()) {
throw new NullPointerException("The stack has no values");
} else if (this.size() == 1) {
ops[0] = this.pop();
ops[1] = ops[0];
} else if (this.size() > 1) {
ops[1] = this.pop();
ops[0] = this.pop();
}
switch (entry) {
case "+":
result = ops[0] + ops[1];
numberStack.push(result.toString());
break;
case "-":
result = ops[0] - ops[1];
numberStack.push(result.toString());
break;
case "*":
result = ops[0] * ops[1];
numberStack.push(result.toString());
break;
case "/":
if (ops[1] == 0) {
throw new IllegalArgumentException("Argument 'divisor' is 0");
} else {
result = ops[0] / ops[1];
numberStack.push(result.toString());
}
break;
}
}
}