From 486a20cd7911ddc6bb4ebba82cccc76402d67ce7 Mon Sep 17 00:00:00 2001 From: Luca Date: Sun, 3 Nov 2024 22:47:28 +0100 Subject: [PATCH 1/7] Add failing test --- .../java/htw/berlin/prog2/ha1/CalculatorTest.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java b/app/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java index ddff0da..dba7e41 100644 --- a/app/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java +++ b/app/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java @@ -90,5 +90,19 @@ void testMultipleDecimalDots() { //TODO hier weitere Tests erstellen + + @Test + @DisplayName("should parse multiple operators") + void testMultipleOperators() { + Calculator calc = new Calculator(); + calc.pressDigitKey(9); + calc.pressBinaryOperationKey("+"); + calc.pressUnaryOperationKey("-"); + calc.pressDigitKey(3); + + String expected = "6"; + String actual = calc.readScreen(); + assertEquals(expected, actual); + } } From c59be3891e1214ed0f63ba9fbfddde48195d8778 Mon Sep 17 00:00:00 2001 From: Luca Date: Sun, 3 Nov 2024 23:12:24 +0100 Subject: [PATCH 2/7] Use better example for failing test --- app/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java b/app/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java index dba7e41..9f1c9df 100644 --- a/app/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java +++ b/app/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java @@ -97,10 +97,12 @@ void testMultipleOperators() { Calculator calc = new Calculator(); calc.pressDigitKey(9); calc.pressBinaryOperationKey("+"); - calc.pressUnaryOperationKey("-"); + + calc.pressUnaryOperationKey("1/x"); calc.pressDigitKey(3); - String expected = "6"; + + String expected = "3"; String actual = calc.readScreen(); assertEquals(expected, actual); } From 0a7b23bef99374f18708d854773013250a7b550e Mon Sep 17 00:00:00 2001 From: Luca Date: Sun, 3 Nov 2024 23:13:12 +0100 Subject: [PATCH 3/7] Add fix for failing test --- .../java/htw/berlin/prog2/ha1/Calculator.java | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/htw/berlin/prog2/ha1/Calculator.java b/app/src/main/java/htw/berlin/prog2/ha1/Calculator.java index 84c04f2..071cbd3 100644 --- a/app/src/main/java/htw/berlin/prog2/ha1/Calculator.java +++ b/app/src/main/java/htw/berlin/prog2/ha1/Calculator.java @@ -31,7 +31,10 @@ public String readScreen() { public void pressDigitKey(int digit) { if(digit > 9 || digit < 0) throw new IllegalArgumentException(); - if(screen.equals("0") || latestValue == Double.parseDouble(screen)) screen = ""; + var lastValueString = Double.toString(latestValue); + lastValueString = trimFloatingPoints(lastValueString); + + if(screen.equals("0") || lastValueString.equals(screen)) screen = ""; screen = screen + digit; } @@ -72,18 +75,17 @@ public void pressBinaryOperationKey(String operation) { * @param operation "√" für Quadratwurzel, "%" für Prozent, "1/x" für Inversion */ public void pressUnaryOperationKey(String operation) { - latestValue = Double.parseDouble(screen); latestOperation = operation; - var result = switch(operation) { + latestValue = switch(operation) { case "√" -> Math.sqrt(Double.parseDouble(screen)); case "%" -> Double.parseDouble(screen) / 100; case "1/x" -> 1 / Double.parseDouble(screen); + case "-" -> -Double.parseDouble(screen); default -> throw new IllegalArgumentException(); }; - screen = Double.toString(result); + screen = Double.toString(latestValue); if(screen.equals("NaN")) screen = "Error"; - if(screen.contains(".") && screen.length() > 11) screen = screen.substring(0, 10); - + screen = trimFloatingPoints(screen); } /** @@ -127,7 +129,16 @@ public void pressEqualsKey() { }; screen = Double.toString(result); if(screen.equals("Infinity")) screen = "Error"; - if(screen.endsWith(".0")) screen = screen.substring(0,screen.length()-2); - if(screen.contains(".") && screen.length() > 11) screen = screen.substring(0, 10); + screen = trimFloatingPoints(screen); + } + + + /** + * Trim floating point string. + */ + private static String trimFloatingPoints(String input) { + if(input.endsWith(".0")) input = input.substring(0,input.length()-2); + if(input.contains(".") && input.length() > 11) input = input.substring(0, 10); + return input; } } From 47152fb202a96f2d0aa5634c2858f92a76d21471 Mon Sep 17 00:00:00 2001 From: Luca Date: Sun, 3 Nov 2024 23:24:04 +0100 Subject: [PATCH 4/7] Fixing unary input --- .../main/java/htw/berlin/prog2/ha1/Calculator.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/htw/berlin/prog2/ha1/Calculator.java b/app/src/main/java/htw/berlin/prog2/ha1/Calculator.java index 071cbd3..bdb8ba1 100644 --- a/app/src/main/java/htw/berlin/prog2/ha1/Calculator.java +++ b/app/src/main/java/htw/berlin/prog2/ha1/Calculator.java @@ -14,6 +14,8 @@ public class Calculator { private String latestOperation = ""; + private boolean resetScreen = false; // Is used to controll reset from the binary operator + /** * @return den aktuellen Bildschirminhalt als String */ @@ -31,10 +33,9 @@ public String readScreen() { public void pressDigitKey(int digit) { if(digit > 9 || digit < 0) throw new IllegalArgumentException(); - var lastValueString = Double.toString(latestValue); - lastValueString = trimFloatingPoints(lastValueString); + if(screen.equals("0") || resetScreen) screen = ""; - if(screen.equals("0") || lastValueString.equals(screen)) screen = ""; + resetScreen = false; screen = screen + digit; } @@ -51,6 +52,7 @@ public void pressClearKey() { screen = "0"; latestOperation = ""; latestValue = 0.0; + resetScreen = false; } /** @@ -65,6 +67,7 @@ public void pressClearKey() { public void pressBinaryOperationKey(String operation) { latestValue = Double.parseDouble(screen); latestOperation = operation; + resetScreen = true; } /** @@ -75,15 +78,14 @@ public void pressBinaryOperationKey(String operation) { * @param operation "√" für Quadratwurzel, "%" für Prozent, "1/x" für Inversion */ public void pressUnaryOperationKey(String operation) { - latestOperation = operation; - latestValue = switch(operation) { + var value = switch(operation) { case "√" -> Math.sqrt(Double.parseDouble(screen)); case "%" -> Double.parseDouble(screen) / 100; case "1/x" -> 1 / Double.parseDouble(screen); case "-" -> -Double.parseDouble(screen); default -> throw new IllegalArgumentException(); }; - screen = Double.toString(latestValue); + screen = Double.toString(value); if(screen.equals("NaN")) screen = "Error"; screen = trimFloatingPoints(screen); } From b0c7504d0e2a680c1681e3cbcd3274584a5e21ac Mon Sep 17 00:00:00 2001 From: Luca Date: Sun, 3 Nov 2024 23:24:11 +0100 Subject: [PATCH 5/7] Add working test --- .../htw/berlin/prog2/ha1/CalculatorTest.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/app/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java b/app/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java index 9f1c9df..f1f2327 100644 --- a/app/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java +++ b/app/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java @@ -91,6 +91,22 @@ void testMultipleDecimalDots() { //TODO hier weitere Tests erstellen + @Test + @DisplayName("should parse percent") + void testPercent() { + Calculator calc = new Calculator(); + calc.pressDigitKey(5); + calc.pressBinaryOperationKey("+"); + calc.pressDigitKey(5); + calc.pressDigitKey(0); + calc.pressUnaryOperationKey("%"); + calc.pressEqualsKey(); + + String expected = "5.5"; + String actual = calc.readScreen(); + assertEquals(expected, actual); + } + @Test @DisplayName("should parse multiple operators") void testMultipleOperators() { From 7dbcd89a5f42343db50377bb35aaa96ad2e076b0 Mon Sep 17 00:00:00 2001 From: Luca Date: Sun, 3 Nov 2024 23:34:11 +0100 Subject: [PATCH 6/7] Make multiple operators work I know we still need operator precendence to order the operations. Multiplication should be treated higher then addition. --- .../java/htw/berlin/prog2/ha1/Calculator.java | 27 ++++++++++++++----- .../htw/berlin/prog2/ha1/CalculatorTest.java | 16 +++++++++++ 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/htw/berlin/prog2/ha1/Calculator.java b/app/src/main/java/htw/berlin/prog2/ha1/Calculator.java index bdb8ba1..45ac83d 100644 --- a/app/src/main/java/htw/berlin/prog2/ha1/Calculator.java +++ b/app/src/main/java/htw/berlin/prog2/ha1/Calculator.java @@ -1,5 +1,7 @@ package htw.berlin.prog2.ha1; +import java.util.OptionalDouble; + /** * Eine Klasse, die das Verhalten des Online Taschenrechners imitiert, welcher auf * https://www.online-calculator.com/ aufgerufen werden kann (ohne die Memory-Funktionen) @@ -10,7 +12,7 @@ public class Calculator { private String screen = "0"; - private double latestValue; + private OptionalDouble latestValue = OptionalDouble.empty(); private String latestOperation = ""; @@ -51,7 +53,7 @@ public void pressDigitKey(int digit) { public void pressClearKey() { screen = "0"; latestOperation = ""; - latestValue = 0.0; + latestValue = OptionalDouble.empty(); resetScreen = false; } @@ -65,7 +67,7 @@ public void pressClearKey() { * @param operation "+" für Addition, "-" für Substraktion, "x" für Multiplikation, "/" für Division */ public void pressBinaryOperationKey(String operation) { - latestValue = Double.parseDouble(screen); + latestValue = OptionalDouble.of(this.calculate()); latestOperation = operation; resetScreen = true; } @@ -122,6 +124,20 @@ public void pressNegativeKey() { * und das Ergebnis direkt angezeigt. */ public void pressEqualsKey() { + var result = calculate(); + screen = Double.toString(result); + if(screen.equals("Infinity")) screen = "Error"; + screen = trimFloatingPoints(screen); + } + + + private double calculate() { + if (latestValue.isEmpty()) { + return Double.parseDouble(screen); + } + + var latestValue = this.latestValue.getAsDouble(); + var result = switch(latestOperation) { case "+" -> latestValue + Double.parseDouble(screen); case "-" -> latestValue - Double.parseDouble(screen); @@ -129,9 +145,8 @@ public void pressEqualsKey() { case "/" -> latestValue / Double.parseDouble(screen); default -> throw new IllegalArgumentException(); }; - screen = Double.toString(result); - if(screen.equals("Infinity")) screen = "Error"; - screen = trimFloatingPoints(screen); + + return result; } diff --git a/app/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java b/app/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java index f1f2327..b400ef9 100644 --- a/app/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java +++ b/app/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java @@ -122,5 +122,21 @@ void testMultipleOperators() { String actual = calc.readScreen(); assertEquals(expected, actual); } + + @Test + @DisplayName("should calculate multiple binary operators") + void testMultipleBinaryOperators() { + Calculator calc = new Calculator(); + calc.pressDigitKey(9); + calc.pressBinaryOperationKey("+"); + calc.pressDigitKey(3); + calc.pressBinaryOperationKey("-"); + calc.pressDigitKey(2); + calc.pressEqualsKey(); + + String expected = "10"; + String actual = calc.readScreen(); + assertEquals(expected, actual); + } } From fca0c2a6fd414338057579631a266d4bff290b68 Mon Sep 17 00:00:00 2001 From: Luca Date: Sun, 3 Nov 2024 23:35:35 +0100 Subject: [PATCH 7/7] Add docs --- app/src/main/java/htw/berlin/prog2/ha1/Calculator.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/java/htw/berlin/prog2/ha1/Calculator.java b/app/src/main/java/htw/berlin/prog2/ha1/Calculator.java index 45ac83d..1514aec 100644 --- a/app/src/main/java/htw/berlin/prog2/ha1/Calculator.java +++ b/app/src/main/java/htw/berlin/prog2/ha1/Calculator.java @@ -131,6 +131,12 @@ public void pressEqualsKey() { } + /** + * Calculates the current value with the value in the screen. + * If there is no current value it will return the value of the screen, + * + * @return Result of the current calculation + */ private double calculate() { if (latestValue.isEmpty()) { return Double.parseDouble(screen);