From 48534d6db859d9bd320ad59f67308fdaff542bd4 Mon Sep 17 00:00:00 2001 From: Saki-Ali Date: Tue, 21 Oct 2025 13:31:20 +0200 Subject: [PATCH] Hausaufgabe 1 fertig --- .../java/htw/berlin/prog2/ha1/Calculator.java | 93 ++++++++++++++++--- .../htw/berlin/prog2/ha1/CalculatorTest.java | 47 ++++++++++ 2 files changed, 128 insertions(+), 12 deletions(-) diff --git a/src/main/java/htw/berlin/prog2/ha1/Calculator.java b/src/main/java/htw/berlin/prog2/ha1/Calculator.java index 84c04f2..5c51fb4 100644 --- a/src/main/java/htw/berlin/prog2/ha1/Calculator.java +++ b/src/main/java/htw/berlin/prog2/ha1/Calculator.java @@ -14,6 +14,11 @@ public class Calculator { private String latestOperation = ""; + // --- NEU für wiederholtes "=" ----------------------------------------- + private double lastOperand = Double.NaN; // <<< NEW: merkt den zuletzt benutzten 2. Operanden + private String lastOperator = ""; // <<< NEW: merkt den zuletzt benutzten Operator + + /** * @return den aktuellen Bildschirminhalt als String */ @@ -60,7 +65,19 @@ 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); + if ("*".equals(operation)) operation = "x"; + + double current = Double.parseDouble(screen); + + // FALL: Es gibt bereits einen Operator, aber der 2. Operand wurde NOCH NICHT eingegeben + // -> nur den Operator austauschen (kein Rechnen, kein Zustand sonst ändern) + if (!latestOperation.isEmpty() && latestValue == current) { + latestOperation = operation; + return; + } + + // normaler Fall: ersten Operanden übernehmen und Operator setzen + latestValue = current; latestOperation = operation; } @@ -118,16 +135,68 @@ public void pressNegativeKey() { * und das Ergebnis direkt angezeigt. */ public void pressEqualsKey() { - var result = switch(latestOperation) { - case "+" -> latestValue + Double.parseDouble(screen); - case "-" -> latestValue - Double.parseDouble(screen); - case "x" -> latestValue * Double.parseDouble(screen); - case "/" -> latestValue / Double.parseDouble(screen); - default -> throw new IllegalArgumentException(); - }; - 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); + if (latestOperation == null) latestOperation = ""; + if (lastOperator == null) lastOperator = ""; + + double current = Double.parseDouble(screen); + + // Fall A: aktiver Operator vorhanden -> erste Ausführung (z. B. 2 + 3 = 5) + if (!latestOperation.isEmpty()) { + double result = switch (latestOperation) { + case "+" -> latestValue + current; + case "-" -> latestValue - current; + case "x" -> latestValue * current; + case "/" -> { + if (current == 0.0) { + screen = "Error"; + latestOperation = ""; + yield Double.NaN; // ✅ use yield instead of return + } + yield latestValue / current; + } + default -> throw new IllegalArgumentException(); + }; + + screen = Double.toString(result); + if (screen.equals("Infinity") || screen.equals("-Infinity") || screen.equals("NaN")) screen = "Error"; + if (screen.endsWith(".0")) screen = screen.substring(0, screen.length() - 2); + if (screen.contains(".") && screen.length() > 11) screen = screen.substring(0, 10); + + // Für wiederholtes "=" merken + lastOperand = current; + lastOperator = latestOperation; + + // Ergebnis als Basis; aktiven Operator „verbrauchen“ + latestValue = result; + latestOperation = ""; + return; + } + + // Fall B: Kein aktiver Operator -> letzte Operation wiederholen (z. B. 5 = -> 8) + if (!lastOperator.isEmpty() && !Double.isNaN(lastOperand)) { + double base = Double.parseDouble(screen); + + double result = switch (lastOperator) { + case "+" -> base + lastOperand; + case "-" -> base - lastOperand; + case "x" -> base * lastOperand; + case "/" -> { + if (lastOperand == 0.0) { + screen = "Error"; + yield Double.NaN; // ✅ use yield instead + } + yield base / lastOperand; + } + + default -> throw new IllegalArgumentException(); + }; + + screen = Double.toString(result); + if (screen.equals("Infinity") || screen.equals("-Infinity") || screen.equals("NaN")) screen = "Error"; + if (screen.endsWith(".0")) screen = screen.substring(0, screen.length() - 2); + if (screen.contains(".") && screen.length() > 11) screen = screen.substring(0, 10); + + latestValue = result; // Basis für weiteres "=" + } } } diff --git a/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java b/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java index ddff0da..eb6ccbb 100644 --- a/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java +++ b/src/test/java/htw/berlin/prog2/ha1/CalculatorTest.java @@ -87,6 +87,53 @@ void testMultipleDecimalDots() { assertEquals(expected, actual); } + @Test + @DisplayName("should subtract two positive numbers correctly") + void testSimpleSubtraction() { + Calculator calc = new Calculator(); + + calc.pressDigitKey(9); + calc.pressBinaryOperationKey("-"); + calc.pressDigitKey(4); + calc.pressEqualsKey(); + + assertEquals("5", calc.readScreen()); + } + + @Test + @DisplayName("should repeat last operation when pressing equals multiple times") + void testRepeatOperation() { + Calculator calc = new Calculator(); + + calc.pressDigitKey(2); + calc.pressBinaryOperationKey("+"); + calc.pressDigitKey(3); + calc.pressEqualsKey(); // 2 + 3 = 5 + calc.pressEqualsKey(); // should repeat +3 => 8 + + String expected = "8"; + String actual = calc.readScreen(); + + assertEquals(expected, actual); + } + @Test + @DisplayName("should use the new operator if user changes it before entering second operand") + void testChangeOperatorBeforeSecondOperand() { + Calculator calc = new Calculator(); + + calc.pressDigitKey(7); + calc.pressBinaryOperationKey("+"); + calc.pressBinaryOperationKey("*"); // Nutzer ändert Meinung: + -> * + calc.pressDigitKey(3); + calc.pressEqualsKey(); + + String expected = "21"; // 7 * 3 + String actual = calc.readScreen(); + + assertEquals(expected, actual); + } + + //TODO hier weitere Tests erstellen