-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#1 Stop counter thread and #2 Two counter threads and refactored #7 …
…Calculator from Design-patterns
- Loading branch information
Showing
20 changed files
with
358 additions
and
155 deletions.
There are no files selected for viewing
73 changes: 40 additions & 33 deletions
73
...-patterns/src/main/java/com/ontotext/javacourse/designpatterns/calculator/Calculator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,46 +1,53 @@ | ||
package com.ontotext.javacourse.designpatterns.calculator; | ||
|
||
import lombok.NoArgsConstructor; | ||
import com.ontotext.javacourse.designpatterns.calculator.commands.*; | ||
import java.util.ArrayDeque; | ||
import java.util.Deque; | ||
import java.util.List; | ||
|
||
/** | ||
* Defines a calculator that can perform addition,subtraction,multiplication,division and | ||
* exponentiation and return the result. | ||
* The Calculator class contains a method that takes a given reverse polish notation expression and | ||
* returns its result. | ||
*/ | ||
@NoArgsConstructor | ||
public class Calculator { | ||
private double result; | ||
private double operand; | ||
public final class Calculator { | ||
|
||
public void setOperand(double operand) { | ||
this.operand = operand; | ||
private Calculator() throws IllegalAccessException { | ||
throw new IllegalAccessException("Calculator class is not meant to be instantiated!"); | ||
} | ||
|
||
public void add() { | ||
result += operand; | ||
} | ||
|
||
public void subtract() { | ||
result -= operand; | ||
} | ||
|
||
public void multiply() { | ||
result *= operand; | ||
} | ||
|
||
/** Divides the result by the given operand if the divisor is not zero. */ | ||
public void divide() { | ||
if (operand == 0) { | ||
System.out.println("Division by zero!"); | ||
} else { | ||
result /= operand; | ||
/** | ||
* Evaluates the given expression. | ||
* | ||
* @param reversePolishNotationExpression the reverse polish notation expression | ||
* @return the result of the expression | ||
*/ | ||
public static double evaluateExpression(List<String> reversePolishNotationExpression) { | ||
Deque<Double> stack = new ArrayDeque<>(); | ||
double firstOperand; | ||
double secondOperand; | ||
Double result; | ||
for (String item : reversePolishNotationExpression) { | ||
if (RPNEvaluator.isNumeric(item)) { | ||
stack.push(Double.parseDouble(item)); | ||
} else { | ||
secondOperand = stack.pop(); | ||
firstOperand = stack.pop(); | ||
Command command = getCommand(item); | ||
result = command.execute(firstOperand, secondOperand); | ||
stack.push(result); | ||
} | ||
} | ||
return stack.pop(); | ||
} | ||
|
||
public void exponentiate() { | ||
result = Math.pow(result, operand); | ||
} | ||
|
||
public double getResult() { | ||
return this.result; | ||
private static Command getCommand(String action) { | ||
return switch (action) { | ||
case "+" -> new AddCommand(); | ||
case "-" -> new SubtractCommand(); | ||
case "*" -> new MultiplyCommand(); | ||
case "/" -> new DivisionCommand(); | ||
case "^" -> new ExponentiateCommand(); | ||
default -> throw new IllegalArgumentException("Action is invalid!"); | ||
}; | ||
} | ||
} |
52 changes: 15 additions & 37 deletions
52
...tterns/src/main/java/com/ontotext/javacourse/designpatterns/calculator/CalculatorApp.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,50 +1,28 @@ | ||
package com.ontotext.javacourse.designpatterns.calculator; | ||
|
||
import com.ontotext.javacourse.designpatterns.calculator.commands.*; | ||
import java.security.InvalidParameterException; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.Scanner; | ||
|
||
/** | ||
* The CalculatorApp class contains a method that starts the calculator and begins to accept | ||
* operation and executes them. | ||
* The CalculatorApp class contains a method that starts the calculator and accepts an expression as | ||
* input. | ||
*/ | ||
public class CalculatorApp { | ||
private final CalculatorView calculatorView; | ||
private final Calculator calculator; | ||
private final CalculatorInvoker calculatorInvoker; | ||
private final Scanner scanner; | ||
|
||
public CalculatorApp(Calculator calculator) { | ||
calculatorView = new CalculatorView(); | ||
this.calculator = calculator; | ||
calculatorInvoker = new CalculatorInvoker(); | ||
public CalculatorApp() { | ||
scanner = new Scanner(System.in); | ||
} | ||
|
||
/** Starts accepting user input from the console. */ | ||
public void startCalculator() { | ||
calculatorView.displayAvailableCommands(); | ||
double startingNumber = calculatorView.promptNumberInput(); | ||
calculatorInvoker.setCommand(new AddCommand(this.calculator, startingNumber)); | ||
calculatorInvoker.executeCommand(); | ||
int operationNumber = calculatorView.promptOperationNumber(); | ||
double operand = 0; | ||
while (operationNumber != 6) { | ||
operand = calculatorView.promptNumberInput(); | ||
Command command = getOperationCommand(operationNumber, operand); | ||
calculatorInvoker.setCommand(command); | ||
calculatorInvoker.executeCommand(); | ||
calculatorView.displayCurrentResult(calculator.getResult()); | ||
operationNumber = calculatorView.promptOperationNumber(); | ||
} | ||
calculatorView.displayEndResult(calculator.getResult()); | ||
} | ||
|
||
private Command getOperationCommand(int operationNumber, double operand) { | ||
return switch (operationNumber) { | ||
case 1 -> new AddCommand(this.calculator, operand); | ||
case 2 -> new SubtractCommand(this.calculator, operand); | ||
case 3 -> new MultiplyCommand(this.calculator, operand); | ||
case 4 -> new DivisionCommand(this.calculator, operand); | ||
case 5 -> new ExponentiateCommand(this.calculator, operand); | ||
default -> throw new InvalidParameterException("Invalid operand number!"); | ||
}; | ||
System.out.println("Enter an expression with a space between each number and symbol:"); | ||
String input = scanner.nextLine(); | ||
List<String> expression = Arrays.stream(input.split(" ")).toList(); | ||
List<String> reversePolishNotationExpression = | ||
RPNEvaluator.getReversePolishNotation(expression); | ||
double result = Calculator.evaluateExpression(reversePolishNotationExpression); | ||
System.out.printf("Result: %.2f%n", result); | ||
} | ||
} |
83 changes: 82 additions & 1 deletion
83
...atterns/src/main/java/com/ontotext/javacourse/designpatterns/calculator/RPNEvaluator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,83 @@ | ||
package com.ontotext.javacourse.designpatterns.calculator;public class RPNEvaluator { | ||
package com.ontotext.javacourse.designpatterns.calculator; | ||
|
||
import java.util.*; | ||
|
||
/** | ||
* The RPNEvaluator class contains methods that return the reverse polish notation of a given | ||
* expression. | ||
*/ | ||
public final class RPNEvaluator { | ||
private RPNEvaluator() throws IllegalAccessException { | ||
throw new IllegalAccessException("RPNEvaluator class is not meant to be instantiated!"); | ||
} | ||
|
||
public static List<String> getReversePolishNotation(List<String> expression) { | ||
return transformExpression(expression); | ||
} | ||
|
||
/** | ||
* Determines whether the given item is a valid number. | ||
* | ||
* @param item the item which to check the type of | ||
* @return whether the item is a valid number or not. | ||
*/ | ||
public static boolean isNumeric(String item) { | ||
try { | ||
Double.parseDouble(item); | ||
return true; | ||
} catch (NumberFormatException exception) { | ||
return false; | ||
} | ||
} | ||
|
||
private static List<String> transformExpression(List<String> expression) { | ||
if (expression.isEmpty()) { | ||
throw new IllegalArgumentException("Empty input!"); | ||
} | ||
Deque<String> stack = new ArrayDeque<>(); | ||
List<String> output = new ArrayList<>(); | ||
for (String item : expression) { | ||
if (isNumeric(item)) { | ||
output.add(item); | ||
} else if (item.equals("(")) { | ||
stack.push(item); | ||
} else if (item.equals(")")) { | ||
while (!stack.isEmpty() && !stack.peek().equals("(")) { | ||
output.add(stack.pop()); | ||
} | ||
stack.pop(); | ||
} else { | ||
while (!stack.isEmpty() | ||
&& getPrecedence(item) <= getPrecedence(stack.peek()) | ||
&& hasLeftAssociativity(item)) { | ||
output.add(stack.pop()); | ||
} | ||
stack.push(item); | ||
} | ||
} | ||
emptyStack(stack, output); | ||
return output; | ||
} | ||
|
||
private static int getPrecedence(String item) { | ||
return switch (item) { | ||
case "+", "-" -> 1; | ||
case "*", "/" -> 2; | ||
case "^" -> 3; | ||
default -> -1; | ||
}; | ||
} | ||
|
||
private static boolean hasLeftAssociativity(String item) { | ||
return item.equals("+") || item.equals("-") || item.equals("/") || item.equals("*"); | ||
} | ||
|
||
private static void emptyStack(Deque<String> stack, List<String> output) { | ||
while (!stack.isEmpty()) { | ||
if (stack.peek().equals("(")) { | ||
throw new IllegalArgumentException("This expression is invalid"); | ||
} | ||
output.add(stack.pop()); | ||
} | ||
} | ||
} |
15 changes: 6 additions & 9 deletions
15
.../src/main/java/com/ontotext/javacourse/designpatterns/calculator/commands/AddCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,13 @@ | ||
package com.ontotext.javacourse.designpatterns.calculator.commands; | ||
|
||
import com.ontotext.javacourse.designpatterns.calculator.Calculator; | ||
import lombok.NoArgsConstructor; | ||
|
||
/** The AddCommand class is a command that executes the addition operation. */ | ||
public class AddCommand extends BaseOperation { | ||
|
||
public AddCommand(Calculator calculator, double operand) { | ||
super(calculator, operand); | ||
} | ||
/** The AddCommand class is a command that adds two given operands. */ | ||
@NoArgsConstructor | ||
public class AddCommand implements Command { | ||
|
||
@Override | ||
public void execute() { | ||
super.getCalculator().add(); | ||
public Double execute(Double firstOperand, Double secondOperand) { | ||
return firstOperand + secondOperand; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 9 additions & 9 deletions
18
...main/java/com/ontotext/javacourse/designpatterns/calculator/commands/DivisionCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,16 @@ | ||
package com.ontotext.javacourse.designpatterns.calculator.commands; | ||
|
||
import com.ontotext.javacourse.designpatterns.calculator.Calculator; | ||
import lombok.NoArgsConstructor; | ||
|
||
/** The DivisionCommand class is a command that executes the division operation. */ | ||
public class DivisionCommand extends BaseOperation { | ||
|
||
public DivisionCommand(Calculator calculator, double operand) { | ||
super(calculator, operand); | ||
} | ||
/** The DivisionCommand class is a command that divides two given operands. */ | ||
@NoArgsConstructor | ||
public class DivisionCommand implements Command { | ||
|
||
@Override | ||
public void execute() { | ||
super.getCalculator().divide(); | ||
public Double execute(Double firstOperand, Double secondOperand) { | ||
if (secondOperand == 0) { | ||
throw new IllegalArgumentException("Division by zero!"); | ||
} | ||
return firstOperand / secondOperand; | ||
} | ||
} |
17 changes: 6 additions & 11 deletions
17
.../java/com/ontotext/javacourse/designpatterns/calculator/commands/ExponentiateCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,12 @@ | ||
package com.ontotext.javacourse.designpatterns.calculator.commands; | ||
|
||
import com.ontotext.javacourse.designpatterns.calculator.Calculator; | ||
|
||
/** | ||
* The ExponentiateCommand class is a command that raises the current result to a given exponent. | ||
*/ | ||
public class ExponentiateCommand extends BaseOperation { | ||
public ExponentiateCommand(Calculator calculator, double operand) { | ||
super(calculator, operand); | ||
} | ||
import lombok.NoArgsConstructor; | ||
|
||
/** The ExponentiateCommand class is a command that exponentiates two given operands. */ | ||
@NoArgsConstructor | ||
public class ExponentiateCommand implements Command { | ||
@Override | ||
public void execute() { | ||
super.getCalculator().exponentiate(); | ||
public Double execute(Double firstOperand, Double secondOperand) { | ||
return Math.pow(firstOperand, secondOperand); | ||
} | ||
} |
15 changes: 6 additions & 9 deletions
15
...main/java/com/ontotext/javacourse/designpatterns/calculator/commands/MultiplyCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,12 @@ | ||
package com.ontotext.javacourse.designpatterns.calculator.commands; | ||
|
||
import com.ontotext.javacourse.designpatterns.calculator.Calculator; | ||
|
||
/** The MultiplyCommand class is a command that executes the multiplication operation. */ | ||
public class MultiplyCommand extends BaseOperation { | ||
public MultiplyCommand(Calculator calculator, double operand) { | ||
super(calculator, operand); | ||
} | ||
import lombok.NoArgsConstructor; | ||
|
||
/** The MultiplyCommand class is a command that multiplies two given operands. */ | ||
@NoArgsConstructor | ||
public class MultiplyCommand implements Command { | ||
@Override | ||
public void execute() { | ||
super.getCalculator().multiply(); | ||
public Double execute(Double firstOperand, Double secondOperand) { | ||
return firstOperand * secondOperand; | ||
} | ||
} |
15 changes: 6 additions & 9 deletions
15
...main/java/com/ontotext/javacourse/designpatterns/calculator/commands/SubtractCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,12 @@ | ||
package com.ontotext.javacourse.designpatterns.calculator.commands; | ||
|
||
import com.ontotext.javacourse.designpatterns.calculator.Calculator; | ||
|
||
/** The SubtractCommand class is a command that executes the subtraction operation. */ | ||
public class SubtractCommand extends BaseOperation { | ||
public SubtractCommand(Calculator calculator, double operand) { | ||
super(calculator, operand); | ||
} | ||
import lombok.NoArgsConstructor; | ||
|
||
/** The SubtractCommand class is a command that subtracts two given operands. */ | ||
@NoArgsConstructor | ||
public class SubtractCommand implements Command { | ||
@Override | ||
public void execute() { | ||
super.getCalculator().subtract(); | ||
public Double execute(Double firstOperand, Double secondOperand) { | ||
return firstOperand - secondOperand; | ||
} | ||
} |
Oops, something went wrong.