From 9dee85d9fe116bb0895a229aae43238dae34757b Mon Sep 17 00:00:00 2001 From: linopino <lasse.pikkemaat@web.de> Date: Tue, 1 Apr 2025 19:18:56 +0200 Subject: [PATCH 1/9] Integration von Orlandos Code + Tests --- others/Orlando/reportOrlandosImp.md | 4 ++++ src/stringcalculator.py | 9 ++++++--- ...tringclaculator.py => testStringcalculator.py} | 15 +++++++++++++-- testsOthers/testsOrlando/reportOrlandosTests.md | 5 +++++ 4 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 others/Orlando/reportOrlandosImp.md rename tests/{test_stringclaculator.py => testStringcalculator.py} (84%) create mode 100644 testsOthers/testsOrlando/reportOrlandosTests.md diff --git a/others/Orlando/reportOrlandosImp.md b/others/Orlando/reportOrlandosImp.md new file mode 100644 index 0000000..504a41a --- /dev/null +++ b/others/Orlando/reportOrlandosImp.md @@ -0,0 +1,4 @@ +| Name | Interface break | Failed Testcases | +|---------|-----------------|-------------------------------------------------------------------------------------------------------------------------------| +| Orlando | no | test_add_multiple_negative_numbers (test_stringclaculator.TestStringCalculator) ... negatives not allowed: -10, -20, -30 FAIL | +| Orlando | no | test_add_single_negative_number (test_stringclaculator.TestStringCalculator) ... negatives not allowed: -2 FAIL | \ No newline at end of file diff --git a/src/stringcalculator.py b/src/stringcalculator.py index 4b8e76f..f48f2e8 100644 --- a/src/stringcalculator.py +++ b/src/stringcalculator.py @@ -1,7 +1,6 @@ from src.interfaces import IStringCalculator import re - class StringCalculator(IStringCalculator): def add(self, numbers: str) -> int: if not numbers: @@ -11,7 +10,11 @@ class StringCalculator(IStringCalculator): if "\n" not in numbers: raise ValueError("Ungültiges Format: Nicht vollständig") delimiter_end_index = numbers.index("\n") - delimiter = numbers[2:delimiter_end_index] + delimiter_part = numbers[2:delimiter_end_index] + if delimiter_part.startswith("[") and delimiter_part.endswith("]"): + delimiter = delimiter_part[1:-1] + else: + delimiter = delimiter_part numbers = numbers[delimiter_end_index + 1:] numbers = numbers.replace(delimiter, ",") @@ -29,4 +32,4 @@ class StringCalculator(IStringCalculator): numbers_list = [num for num in numbers_list if num <= 1000] - return sum(numbers_list) \ No newline at end of file + return sum(numbers_list) diff --git a/tests/test_stringclaculator.py b/tests/testStringcalculator.py similarity index 84% rename from tests/test_stringclaculator.py rename to tests/testStringcalculator.py index a0c1d76..718074c 100644 --- a/tests/test_stringclaculator.py +++ b/tests/testStringcalculator.py @@ -19,11 +19,18 @@ #Feature5 Zahlen größer 1000 nicht erkennen # Bei Eingabe von 2,1001 soll 2 ausgegeben werden # Bei Eingabe von 1002, 50200 soll 0 asugegeben werden +#Feature6 Begrenzungszeichen beliebig lang +# Bei Eingabe von //[**]\n1**2**3 soll 6 ausgegeben werden +# Bei Eingabe von //[###]\n10###20###30 soll 60 ausgegeben werden - +''' import unittest from src.interfaces import IStringCalculator from src.stringcalculator import StringCalculator +''' +import unittest +from others.Orlando.OrlandoInterfaces import IStringCalculator +from others.Orlando.OrlandoStringCalculator import StringCalculator class TestStringCalculator(unittest.TestCase): def setUp(self): @@ -71,8 +78,12 @@ class TestStringCalculator(unittest.TestCase): self.assertEqual(self.calculator.add("2,1001"), 2) self.assertEqual(self.calculator.add("1002,50200"), 0) + def test_add_with_custom_delimiter_multiple_characters(self): + self.assertEqual(self.calculator.add("//[**]\n1**2**3"), 6) + self.assertEqual(self.calculator.add("//[###]\n10###20###30"), 60) + if __name__ == "__main__": unittest.main() -# python -m unittest tests.test_stringcalculator +# python -m unittest tests.testStringcalculator -v # python -m unittest discover -s tests -v \ No newline at end of file diff --git a/testsOthers/testsOrlando/reportOrlandosTests.md b/testsOthers/testsOrlando/reportOrlandosTests.md new file mode 100644 index 0000000..a94c950 --- /dev/null +++ b/testsOthers/testsOrlando/reportOrlandosTests.md @@ -0,0 +1,5 @@ +| Name | Interface break | Failed Testcases | Comment | +|---------|-----------------|--------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Orlando | no | test_add_ignores_empty_entries (testsOthers.testsOrlando.OrlandoTestStringCalculator.TestStringCalculator) ... ERROR | Mit numbers.split(",") wird eine Liste mit leeren Strings wobei diese dann nicht in integer umgewandelt werden können. Lösungsansatz: Vor der Umwandlung leere Strings enfernen | +| Orlando | no | test_add_raises_exception_on_multiple_negatives (testsOthers.testsOrlando.OrlandoTestStringCalculator.TestStringCalculator) ... FAIL | | +| Orlando | no | test_add_raises_exception_on_negative_number (testsOthers.testsOrlando.OrlandoTestStringCalculator.TestStringCalculator) ... FAIL | | \ No newline at end of file -- GitLab From ba00132c04589b88a2692dd9bae1c109cbced6bd Mon Sep 17 00:00:00 2001 From: linopino <lasse.pikkemaat@web.de> Date: Tue, 1 Apr 2025 20:10:08 +0200 Subject: [PATCH 2/9] Integration von Danis Code + Tests --- others/Dani/DaniStringCalculator.py | 164 ++++++++++++++++++ others/Dani/reportDaniImp.md | 5 + others/Dani/reportDaniTests.md | 10 ++ others/Orlando/OrlandoInterfaces.py | 30 ++++ others/Orlando/OrlandoStringCalculator.py | 61 +++++++ tests/testStringcalculator.py | 7 +- .../OrlandoTestStringCalculator.py | 115 ++++++++++++ 7 files changed, 391 insertions(+), 1 deletion(-) create mode 100644 others/Dani/DaniStringCalculator.py create mode 100644 others/Dani/reportDaniImp.md create mode 100644 others/Dani/reportDaniTests.md create mode 100644 others/Orlando/OrlandoInterfaces.py create mode 100644 others/Orlando/OrlandoStringCalculator.py create mode 100644 testsOthers/testsOrlando/OrlandoTestStringCalculator.py diff --git a/others/Dani/DaniStringCalculator.py b/others/Dani/DaniStringCalculator.py new file mode 100644 index 0000000..150a50b --- /dev/null +++ b/others/Dani/DaniStringCalculator.py @@ -0,0 +1,164 @@ +# Bei einer leeren Eingabe "" soll die Zahl 0 ausgegeben werden. +# Bei der Eingabe "1" soll die 1 ausgegeben werden. +# Bei der Eingabe von 2 Zahlen als Strings separiert durch "," (z.B. "1, 2") soll die Zahl 3 ausgegeben werden +# Bei der Eingabe "0, 5" soll die Zahl 5 ausgegeben werden. +# Bei der Eingabe von Float-Werten z.B. 3.5 soll "only integers allowed" ausgegeben werden. +# Bei der Eingabe von Buchstaben z.B. 1, z soll "only integers allowed" ausgegeben werden. +# Bei der Eingabe von 2 Zahlen als Strings separiert durch "\n" (z.B. "1\n2,3") soll 6 ausgegeben werden +# Bei der Eingabe von negativen Zahlen (z.B. -3) soll "negatives not allowed" ausgegeben werden +# Bei der Eingabe von Zahlen mit einem benutzerdefinierten Trennzeichen soll die Summe der Zahlen berechnet werden (z.B. //;\n1;2 = 3) +# Bei Eingabe von Zahlen >1000 sollen diese ignoriert werden (z.B. 2 + 1001 = 2) +# Bei der Eingabe von Zahlen mit einem benutzerdefinierten Trennzeichen soll die Summe der Zahlen berechnet werden. Trennzeichen können unbegrenzt lang sein (z.B. “//[***]\n1***2***3†= 6). +# Bei der Eingabe mehrerer negativen Zahlen (z.B. -3, -4) sollen die Zahlen in der exception ausgegeben werden +# Bei der Eingabe von Zahlen mit Leerzeichen soll dennoch die Summe ausgegeben werden (z.B." 4 , 5" = 9) +# Bei der Eingabe "2, 1001, 5" soll die Zahl 7 ausgegeben werden +# Bei der Eingabe von Texten mit leeren Trennzeichen (z.B. "//;\n") soll die Zahl 0 ausgegeben werden +# Bei der Eingabe von "1, " soll die Zahl 1 ausgegeben werden +# Bei der Eingabe von "-2, 5" soll "negatives not allowed" ausgegeben werden +# Bei der Eingabe von "//;\n-1;2;1001;-3" soll "negatives not allowed [-1, -3]" ausgegeben werden + +import unittest +from abc import ABC, abstractmethod +from src.stringcalculator import StringCalculator #Auskommentieren, falls andere Implementierung genutzt wird +''' +class IStringCalculator(ABC): + @abstractmethod + def add(self, numbers: str) -> int: + pass + +class StringCalculator(IStringCalculator): + def add(self, numbers: str) -> int: + + if numbers == "": + return 0 + + delimiter = ";" + + if numbers.startswith("//"): + sep = numbers.split("\n", 1) + delimiter_sep = sep[0][2:] + + if delimiter_sep.startswith("[") and delimiter_sep.endswith("]"): + delimiter = delimiter_sep[1:-1] + + else: + delimiter = delimiter_sep[0] + + numbers = sep[1] + + numbers = numbers.replace("\n", delimiter).replace(delimiter, ",") + + list = numbers.split(",") + result = 0 + + negative_numbers = [] + + for num in list: + num = num.strip() + if num == "": + continue + + if "." in num: + return "only integers allowed" + + try: + number = int(num) + except ValueError: + return "only integers allowed" + + if number < 0: + negative_numbers.append(number) + + if number > 1000: + continue + + result += number + + if len(negative_numbers) > 1: + return "negatives not allowed " + str(negative_numbers) + elif negative_numbers: + return "negatives not allowed" + + return result +''' + +class TestStringCalculator(unittest.TestCase): + def setUp(self): + self.c = StringCalculator() + + def test_empty(self): + res = self.c.add("") + self.assertEqual(res, 0) + + def test_oneNumber(self): + res = self.c.add("1") + self.assertEqual(res, 1) + + def test_addingTwoNumbers(self): + res = self.c.add("1,2") + self.assertEqual(res, 3) + + def test_addingTwoNumbersWithZero(self): + res = self.c.add("0,5") + self.assertEqual(res, 5) + + def test_handleFloat(self): + res = self.c.add("3.5") + self.assertEqual(res, "only integers allowed") + + def test_handleLetter(self): + res = self.c.add("1, z") + self.assertEqual(res, "only integers allowed") + + def test_addWithBackslashN(self): + res = self.c.add("1\n2,3") + self.assertEqual(res, 6) + + def test_negativeValues(self): + res = self.c.add("-3") + self.assertEqual(res, "negatives not allowed") + + def test_delimiter(self): + res = self.c.add("//;\n1;2") + self.assertEqual(res, 3) + + def test_thousandone(self): + res = self.c.add("2, 1001") + self.assertEqual(res, 2) + + def test_multidelimiter(self): + res = self.c.add("//[***]\n1***2***3") + self.assertEqual(res, 6) + + def test_multi_negative(self): + res = self.c.add("-3, -4") + self.assertEqual(res, "negatives not allowed " + str([-3, -4])) + + def test_space_between_numbers(self): + res = self.c.add(" 4 , 5") + self.assertEqual(res, 9) + + def test_multiple_num_with_thousandone(self): + res = self.c.add(" 2, 1001, 5") + self.assertEqual(res, 7) + + def test_empty_text(self): + res = self.c.add("//;\n") + self.assertEqual(res, 0) + + def test_one_number_with_empty_string(self): + res = self.c.add("1,") + self.assertEqual(res, 1) + + def test_negative_with_positive(self): + res = self.c.add("-2, 5") + self.assertEqual(res, "negatives not allowed") + + def test_mixture(self): + res = self.c.add("//;\n-1;2;1001;-3") + self.assertEqual(res, "negatives not allowed " + str([-1, -3])) + +if __name__ == "__main__": + unittest.main() + +# python -m unittest others.Dani.DaniStringCalculator -v \ No newline at end of file diff --git a/others/Dani/reportDaniImp.md b/others/Dani/reportDaniImp.md new file mode 100644 index 0000000..07b2fda --- /dev/null +++ b/others/Dani/reportDaniImp.md @@ -0,0 +1,5 @@ +| Name | Interface break | Failed Testcases | Comment | +|------|-----------------|--------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------| +| Dani | no | test_add_multiple_negative_numbers (tests.testStringcalculator.TestStringCalculator) ... FAIL | | +| Dani | no | test_add_single_negative_number (tests.testStringcalculator.TestStringCalculator) ... FAIL | | +| Dani | no | test_invalid_custom_delimiter_format (tests.testStringcalculator.TestStringCalculator) ... ERROR | Implementierung für falsche Eingabe nicht vorhanden, es wird immer angenommen, dass es mit "" startet und mit \n endet. | \ No newline at end of file diff --git a/others/Dani/reportDaniTests.md b/others/Dani/reportDaniTests.md new file mode 100644 index 0000000..9b7e4b1 --- /dev/null +++ b/others/Dani/reportDaniTests.md @@ -0,0 +1,10 @@ +| Name | Interface break | Failed Testcases | Comment | +|------|-----------------|-----------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------| +| Dani | no | test_empty_text (others.Dani.DaniStringCalculator.TestStringCalculator) ... ERROR | Der Fehler tritt auf, weil die Eingabe //;\n im Code ist, was bedeutet, dass ein Benutzer nur einen Delimiter angibt, aber keine Zahlen folgen. | +| Dani | no | test_handleFloat (others.Dani.DaniStringCalculator.TestStringCalculator) ... ERROR | Die Eingabe 3.5 wird als Gleitkommazahl interpretiert, aber dein Code erwartet eine ganze Zahl (int). | +| Dani | no | test_handleLetter (others.Dani.DaniStringCalculator.TestStringCalculator) ... ERROR | Die Eingabe 1, z enthält einen Buchstaben (z), was zu einem Fehler führt, da der Code erwartet, dass nur Zahlen verarbeitet werden. | +| Dani | no | test_mixture (others.Dani.DaniStringCalculator.TestStringCalculator) ... ERROR | In diesem Test ist die Eingabe -1;2;1001;-3, was negative Zahlen enthält. Dein Code löst eine Fehlermeldung aus, weil negative Zahlen nicht erlaubt sind. | +| Dani | no | test_multi_negative (others.Dani.DaniStringCalculator.TestStringCalculator) ... ERROR | Hier wird eine ähnliche Situation wie in test_mixture festgestellt, nur mit zwei negativen Zahlen. | +| Dani | no | test_negativeValues (others.Dani.DaniStringCalculator.TestStringCalculator) ... ERROR | | +| Dani | no | test_negative_with_positive (others.Dani.DaniStringCalculator.TestStringCalculator) ... ERROR | | +| Dani | no | test_one_number_with_empty_string (others.Dani.DaniStringCalculator.TestStringCalculator) ... ERROR | Die Eingabe 1, enthält einen Fehler, da das letzte Komma keine Zahl nach sich zieht und somit beim Parsen ein leerer String ('') auftritt. | \ No newline at end of file diff --git a/others/Orlando/OrlandoInterfaces.py b/others/Orlando/OrlandoInterfaces.py new file mode 100644 index 0000000..be069d6 --- /dev/null +++ b/others/Orlando/OrlandoInterfaces.py @@ -0,0 +1,30 @@ +from abc import ABC, abstractmethod + +# Definition des Interfaces für den StringCalculator +class IStringCalculator(ABC): + @abstractmethod + def add(self, numbers: str) -> int: + """ + Addiert beliebig viele Zahlen, die durch Kommas getrennt sind. + Leere oder nur aus Leerzeichen bestehende Einträge werden ignoriert. + + :param numbers: String mit Zahlen (z.B. "1,2,3") + :return: Summe der Zahlen als int + """ + pass + +class ICounter(ABC): + @abstractmethod + def count_ed(self, s: str) -> int: + """Zählt die Buchstaben 'E' und 'D' in einem String (Case-Insensitive).""" + pass +class IRomanConverter(ABC): + @abstractmethod + def roman_to_int(self, s: str) -> int: + """Konvertiert eine römische Zahl (String) in eine Dezimalzahl.""" + pass + +class ICalculator(ABC): + @abstractmethod + def calculate(self, expression: str) -> float: + pass \ No newline at end of file diff --git a/others/Orlando/OrlandoStringCalculator.py b/others/Orlando/OrlandoStringCalculator.py new file mode 100644 index 0000000..66df70f --- /dev/null +++ b/others/Orlando/OrlandoStringCalculator.py @@ -0,0 +1,61 @@ +# Implementierung von IStringCalculator + +from others.Orlando.OrlandoInterfaces import IStringCalculator + + +class StringCalculator(IStringCalculator): + def add(self, numbers: str) -> int: + """ + Addiert beliebig viele Zahlen, getrennt durch Kommas, Zeilenumbrüche + oder einen benutzerdefinierten Delimiter. + Leere oder whitespace-only Einträge werden ignoriert. + + Beispiele: + - "" → 0 + - "1" → 1 + - "1,2" → 3 + - "1,2,3,4,5" → 15 + - "1,,2" → 3 + - "1, ,2" → 3 + - ",,1,,2,,," → 3 + + :param numbers: Zahlen als String, getrennt durch Komma + :return: Summe der gültigen Zahlen als int + """ + if not numbers: + return 0 + + delimiter = "," + + + if numbers.startswith("//"): + header, numbers = numbers.split("\n", 1) + + # Mehrzeichen-Delimiter: z. B. //[***] + if header.startswith("//[") and header.endswith("]"): + delimiter = header[3:-1] # Extrahiere z. B. "***" + else: + delimiter = header[2:] # Einzeichen-Delimiter + + # Ersetze \n durch Komma (Standard) + numbers = numbers.replace("\n", ",") + + # Delimiter ersetzen durch Komma (evtl. mehrere Zeichen) + numbers = numbers.replace(delimiter, ",") + + number_list = numbers.split(",") + + # Ignoriere leere oder whitespace-only Einträge + cleaned_numbers = [ + int(n.strip()) for n in number_list if n.strip() != "" + ] + + # Negativ-Prüfung + negatives = [n for n in cleaned_numbers if n < 0] + if negatives: + raise ValueError(f"negatives not allowed: {', '.join(map(str, negatives))}") + + # Zahlen > 1000 ignorieren + cleaned_numbers = [n for n in cleaned_numbers if n <= 1000] + + return sum(cleaned_numbers) \ No newline at end of file diff --git a/tests/testStringcalculator.py b/tests/testStringcalculator.py index 718074c..75214d7 100644 --- a/tests/testStringcalculator.py +++ b/tests/testStringcalculator.py @@ -24,13 +24,18 @@ # Bei Eingabe von //[###]\n10###20###30 soll 60 ausgegeben werden ''' +Eigener Code: import unittest from src.interfaces import IStringCalculator from src.stringcalculator import StringCalculator -''' + +Orlandos Code: import unittest from others.Orlando.OrlandoInterfaces import IStringCalculator from others.Orlando.OrlandoStringCalculator import StringCalculator +''' +import unittest +from others.Dani.DaniStringCalculator import IStringCalculator, StringCalculator class TestStringCalculator(unittest.TestCase): def setUp(self): diff --git a/testsOthers/testsOrlando/OrlandoTestStringCalculator.py b/testsOthers/testsOrlando/OrlandoTestStringCalculator.py new file mode 100644 index 0000000..ff7f29d --- /dev/null +++ b/testsOthers/testsOrlando/OrlandoTestStringCalculator.py @@ -0,0 +1,115 @@ +# Testfälle add(numbers: str) -> int – StringCalculator + +# 1. Leerer String +# Eingabe: "" → Erwartete Ausgabe: 0 + +# 2. Einzelne Zahl +# Eingabe: "1" → Erwartete Ausgabe: 1 + +# 3. Zwei Zahlen, getrennt durch Komma +# Eingabe: "1,2" → Erwartete Ausgabe: 3 + +# 4. Mehr als zwei Zahlen (beliebig viele erlaubt) +# Eingabe: "1,2,3" → Erwartete Ausgabe: 6 +# Eingabe: "1,2,3,4,5" → Erwartete Ausgabe: 15 + +# 5. Leere Einträge ignorieren +# Eingabe: "1,,2" → Erwartete Ausgabe: 3 +# Eingabe: "1, ,2" → Erwartete Ausgabe: 3 +# Eingabe: ",,1,,2,,," → Erwartete Ausgabe: 3 + +# 6. Zeilenumbrüche als Trennzeichen erlauben +# Eingabe: "1\n2,3" → Erwartete Ausgabe: 6 +# Eingabe: "1,2\n3" → Erwartete Ausgabe: 6 +# Eingabe: "1\n2\n3" → Erwartete Ausgabe: 6 + +# 8. Negative Zahlen → Exception mit allen negativen Werten +# Eingabe: "1,-2" → Exception mit Message "negatives not allowed: -2" +# Eingabe: "-1,-2,3" → Exception mit Message "negatives not allowed: -1, -2" + +# 9. Benutzerdefinierter Delimiter über Präfix: "//<delimiter>\n" +# Eingabe: "//;\n1;2" → 3 +# Eingabe: "//|\n4|5|6" → 15 +# Eingabe: "//_\n7_8_9" → 24 + +# 10. Zahlen größer als 1000 ignorieren +# Eingabe: "2,1001" → 2 +# Eingabe: "1000,1" → 1001 (1000 zählt noch mit) +# Eingabe: "1234,1001,3" → 3 + +# 11. Delimiter mit beliebiger Länge (Format: //[delimiter]\n) +# Eingabe: "//[***]\n1***2***3" → 6 +# Eingabe: "//[abc]\n4abc5abc6" → 15 +# Eingabe: "//[+]\n1+2+3" → 6 + +import unittest +from src.stringcalculator import StringCalculator + +class TestStringCalculator(unittest.TestCase): + def setUp(self): + # Vor jedem Test wird eine Instanz des Calculators erstellt + self.calc = StringCalculator() + + def test_add_empty_string(self): + # Leerer String → 0 + self.assertEqual(self.calc.add(""), 0) + + def test_add_single_number(self): + # Ein einzelner Wert → int + self.assertEqual(self.calc.add("1"), 1) + + def test_add_two_numbers(self): + # Zwei Zahlen → Summe + self.assertEqual(self.calc.add("1,2"), 3) + + def test_add_multiple_numbers(self): + # Mehr als zwei Zahlen → Summe + self.assertEqual(self.calc.add("1,2,3"), 6) + self.assertEqual(self.calc.add("1,2,3,4,5"), 15) + + def test_add_ignores_empty_entries(self): + # Leere Einträge ignorieren → Summe + self.assertEqual(self.calc.add("1,,2"), 3) + self.assertEqual(self.calc.add("1, ,2"), 3) + self.assertEqual(self.calc.add(",,1,,2,,,"), 3) + + def test_add_with_newlines_between_numbers(self): + # Zeilenumbrüche als Trennzeichen erlauben → Summe + self.assertEqual(self.calc.add("1\n2,3"), 6) + self.assertEqual(self.calc.add("1,2\n3"), 6) + self.assertEqual(self.calc.add("1\n2\n3"), 6) + + def test_add_raises_exception_on_negative_number(self): + # Negative Zahlen → Exception mit allen negativen Werten + with self.assertRaises(ValueError) as context: + self.calc.add("1,-2") + self.assertIn("negatives not allowed: -2", str(context.exception)) + + def test_add_raises_exception_on_multiple_negatives(self): + # Negative Zahlen → Exception mit allen negativen Werten + with self.assertRaises(ValueError) as context: + self.calc.add("-1,-2,3") + self.assertIn("negatives not allowed: -1, -2", str(context.exception)) + + def test_add_with_custom_delimiter(self): + # Benutzerdefinierter Delimiter über Präfix: "//<delimiter>\n" + self.assertEqual(self.calc.add("//;\n1;2"), 3) + self.assertEqual(self.calc.add("//|\n4|5|6"), 15) + self.assertEqual(self.calc.add("//_\n7_8_9"), 24) + + def test_add_ignores_numbers_greater_than_1000(self): + # Zahlen größer als 1000 ignorieren + self.assertEqual(self.calc.add("2,1001"), 2) + self.assertEqual(self.calc.add("1000,1"), 1001) + self.assertEqual(self.calc.add("1234,1001,3"), 3) + + def test_add_with_multi_char_delimiter(self): + # Delimiter mit beliebiger Länge (Format: //[delimiter]\n) + self.assertEqual(self.calc.add("//[***]\n1***2***3"), 6) + self.assertEqual(self.calc.add("//[abc]\n4abc5abc6"), 15) + self.assertEqual(self.calc.add("//[+]\n1+2+3"), 6) + +if __name__ == "__main__": + unittest.main() + +# python -m unittest testsOthers.testsOrlando.OrlandoTestStringCalculator -v \ No newline at end of file -- GitLab From 16545368d1bdbbc7d57732a05b80c69114d25ff4 Mon Sep 17 00:00:00 2001 From: linopino <lasse.pikkemaat@web.de> Date: Wed, 2 Apr 2025 00:08:42 +0200 Subject: [PATCH 3/9] Integration von Wasilis Code + Tests --- others/Wasili/WasiliStringCalculator.py | 113 ++++++++++++++++++++++++ others/Wasili/reportWasiliImp.md | 4 + others/Wasili/reportWasiliTests.md | 4 + tests/testStringcalculator.py | 5 +- 4 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 others/Wasili/WasiliStringCalculator.py create mode 100644 others/Wasili/reportWasiliImp.md create mode 100644 others/Wasili/reportWasiliTests.md diff --git a/others/Wasili/WasiliStringCalculator.py b/others/Wasili/WasiliStringCalculator.py new file mode 100644 index 0000000..cdc403a --- /dev/null +++ b/others/Wasili/WasiliStringCalculator.py @@ -0,0 +1,113 @@ +#Bei Eingabe des Strings "" liefert die Funktion 0 +#Bei Eingabe des Strings "1" liefert die Funktion 1 +#Bei Eingabe des Strings "1,2" liefert die Funktion 3 +#Bei Eingabe des Strings "1,2,3,4,5,6,7" liefert die Funkktion 28 +#Bei Eingabe des Strings "1\n2,3,4" liefert die Funkktion 10 +#Bei Eingabe des Strings "-5" liefert die Funkktion eine exception mit [“negatives not allowed†-5] +#Bei Eingabe des Strings "-5,-2,-2" liefert die Funkktion eine exception mit [“negatives not allowed†-5,-2,-2] +#Bei Eingabe des Strings "//;\n1;2" liefert die Funktion 3 wobei das Standard-Trennzeichen';' ist. +#Bei Eingabe des Strings "2,1001" liefert die Funktion 2 +#Bei Eingabe des Strings "2,10022\n6" liefert die Funktion 8 +#Bei Eingabe des Strings "//[***]\n1***2***3" mit dem Trennzeichen '***' liefert die Funktion 6 +#Bei Eingabe des Strings "//[*+*+*]\n1*+*+*2*+*+*3*+*+*220" mit dem Trennzeichen '***' liefert die Funktion 226 + +import unittest +from abc import ABC, abstractmethod +from src.stringcalculator import StringCalculator #Auskommentieren, falls andere Implementierung genutzt wird +''' +#Interface für StringCalculator +class IStringCalculator(ABC): + @abstractmethod + def add(self, numbers:str) -> int: + pass + +#Implementierung der Calculator Klasse +class StringCalculator(IStringCalculator): + def add(self, numbers:str) -> int: + if numbers == "": + return 0 + + #Prüfen, ob ein benutzerdefiniertes Trennzeichen definiert wurde + + if numbers.startswith("//"): + delimiter_end_index = numbers.index("\n") #Zeilenumbruchs Position finden + delimiter = numbers[2:delimiter_end_index] # Trennzeichen, also alles zwischen "//" und "\n" extrahieren + + if delimiter.startswith("[") and delimiter.endswith("]"): + delimiter = delimiter[1:-1] # "[" und "]" entfernen + + numbers = numbers[delimiter_end_index + 1:] #Zahlen nach "\n" extrahieren + numbers = numbers.replace(delimiter,",") #Benutzerdefiniertes Trennzeichen durch "," ersetzen + + #Zeilenumbrüche ebenfals durch "," ersetzen + numbers = numbers.replace("\n",",") + + # String anhand von Kommas splitten, eine Liste der einzelnen Zahlen(in str) erzeugen und in Int umwandeln -> Ergebnis wäre z.B. bei add("1\n2,3,4") -> [1,2,3,4] + num_list = list(map(int, numbers.split(",",))) + + #Prüfung auf negative Zahlen + negatives = [n for n in num_list if n<0] + if negatives: + raise ValueError(f"negatives not allowed: {','.join(map(str, negatives))}") #Alle negativen Zahlen durch Kommas in getrennte Strings darstellen + + #Zahlen größer als 1000 aus Liste entfernen + num_list = [n for n in num_list if n <= 1000] + + return sum(num_list) #Summe berechnen (bei einer Zahln wird immernoch dieselbe Zahl ausgegeben) + +''' +#mplementierung der Testklasse für StringCalculator +class TestStringCalculator(unittest.TestCase): + def test_add_empty(self): + c = StringCalculator() + self.assertEqual(c.add(""), 0) + + def test_add_one_string(self): + c = StringCalculator() + self.assertEqual(c.add("1"), 1) + + def test_add_two_string(self): + c = StringCalculator() + self.assertEqual(c.add("1,2"), 3) + + def test_add_multiple_string(self): + c = StringCalculator() + self.assertEqual(c.add("1,2,3,4,5,6,7"), 28) + + def test_add_new_lines(self): + c = StringCalculator() + self.assertEqual(c.add("1\n2,3,4"), 10) + + def test_add_exception(self): + c = StringCalculator() + with self.assertRaises(ValueError) as context: + c.add("-5") + self.assertEqual(str(context.exception), "negatives not allowed: -5") + + def test_add_negative_numbers(self): + c = StringCalculator() + with self.assertRaises(ValueError) as context: + c.add("-5,-2,-2") + self.assertEqual(str(context.exception), "negatives not allowed: -5,-2,-2") + + def test_add_different_delimiters(self): + c = StringCalculator() + self.assertEqual(c.add("//;\n1;2"), 3) + + def test_add_numbers_greater_than_1000(self): + c = StringCalculator() + self.assertEqual(c.add("2,1001"),2) + self.assertEqual(c.add("2,10022\n6"),8) + + def test_delimiters_of_any_length(self): + c = StringCalculator() + self.assertEqual(c.add("//[***]\n1***2***3"), 6) + + def test_delimiters_of_any_length2(self): + c = StringCalculator() + self.assertEqual(c.add("//[*+*+*]\n1*+*+*2*+*+*3*+*+*220"), 226) + +if __name__ == "__main__": + unittest.main() + +# python -m unittest others.Wasili.WasiliStringCalculator -v \ No newline at end of file diff --git a/others/Wasili/reportWasiliImp.md b/others/Wasili/reportWasiliImp.md new file mode 100644 index 0000000..de90e53 --- /dev/null +++ b/others/Wasili/reportWasiliImp.md @@ -0,0 +1,4 @@ +| Name | Interface break | Failed Testcases | +|--------|-----------------|----------------------------------------------------------------------------------------------------------------------------------| +| Wasili | no | test_add_multiple_negative_numbers (tests.testStringcalculator.TestStringCalculator) ... negatives not allowed: -10,-20,-30 FAIL | +| Wasili | no | test_add_single_negative_number (tests.testStringcalculator.TestStringCalculator) ... negatives not allowed: -2 FAIL | \ No newline at end of file diff --git a/others/Wasili/reportWasiliTests.md b/others/Wasili/reportWasiliTests.md new file mode 100644 index 0000000..263b6e2 --- /dev/null +++ b/others/Wasili/reportWasiliTests.md @@ -0,0 +1,4 @@ +| Name | Interface break | Failed Testcases | +|--------|-----------------|------------------------------------------------------------------------------------------------| +| Wasili | no | test_add_exception (others.Wasili.WasiliStringCalculator.TestStringCalculator) ... FAIL | +| Wasili | no | test_add_negative_numbers (others.Wasili.WasiliStringCalculator.TestStringCalculator) ... FAIL | \ No newline at end of file diff --git a/tests/testStringcalculator.py b/tests/testStringcalculator.py index 75214d7..110ba77 100644 --- a/tests/testStringcalculator.py +++ b/tests/testStringcalculator.py @@ -33,9 +33,12 @@ Orlandos Code: import unittest from others.Orlando.OrlandoInterfaces import IStringCalculator from others.Orlando.OrlandoStringCalculator import StringCalculator -''' + import unittest from others.Dani.DaniStringCalculator import IStringCalculator, StringCalculator +''' +import unittest +from others.Wasili.WasiliStringCalculator import IStringCalculator, StringCalculator class TestStringCalculator(unittest.TestCase): def setUp(self): -- GitLab From f6136f3f9fbb701c44d35ef8e1f368e91fd5e7fb Mon Sep 17 00:00:00 2001 From: linopino <lasse.pikkemaat@web.de> Date: Wed, 2 Apr 2025 00:24:30 +0200 Subject: [PATCH 4/9] Integration von Momos Code + Tests --- others/Momo/MomoStringCalculator.py | 139 ++++++++++++++++++++++++++++ others/Momo/reportMomoImp.md | 4 + others/Momo/reportMomoTests.md | 6 ++ tests/testStringcalculator.py | 5 +- 4 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 others/Momo/MomoStringCalculator.py create mode 100644 others/Momo/reportMomoImp.md create mode 100644 others/Momo/reportMomoTests.md diff --git a/others/Momo/MomoStringCalculator.py b/others/Momo/MomoStringCalculator.py new file mode 100644 index 0000000..2a3c8a6 --- /dev/null +++ b/others/Momo/MomoStringCalculator.py @@ -0,0 +1,139 @@ +#vorher im anderen projekt jetzt im neuen projekt +#test no string +#test add 1 string +#test adding 2 strings + +#add 3 strings +#add 4 strings +#add 6 strings + +#\n statt , bei 2 strings +#\n statt , bei mehreren strings + +# eine negative zahl +# mehrere negative zahlen + +# Delimiters: +# add numbers seperated by a custom delimiter +# Test with - Numbers + +#numbers over 1000 should be ignored +#1001 + 2 should return 2 +#1001 -2 should return negatives not allowed + +#custom delimiters +#input "//[***]\n1***2***3" +#output 6 + +import unittest +import re +from src.stringcalculator import StringCalculator #Auskommentieren, falls andere Implementierung genutzt wird +''' +class StringCalculator: + def __init__(self): + self.called_count = 0 + def add (self, numbers : str)-> int: #Erwartet Integer + if not numbers: + return 0 + + if numbers.startswith("//"): + delimiter_end_index = numbers.index("\n") + delimiter_section = numbers[2:delimiter_end_index] + numbers = numbers[delimiter_end_index +1:] + + if delimiter_section.startswith("[")and delimiter_section.endswith("]"): + delimiters = re.findall(r'\[([^\]]+)\]',delimiter_section) + else: + delimiters= [delimiter_section] + + for delimiters in delimiters: + numbers = numbers.replace(delimiters,",") + + numbers = numbers.replace("\n",",") + + number_list = numbers.split(',')#aufteilung der strings + negative = [] #array für die negativen nummern + numbers_to_add = [] + #total_sum = 0 + for number_str in number_list: #jedes element in der liste wird durch genommen + #if number_str: + number = int(number_str)# summierung der integer + if number <0: + negative.append(number) + elif number > 1000: + continue + else: + numbers_to_add.append(number) + #total_sum += number + + if negative: + print(f"Negative Zahlen:{negative} ")#ausgabe negative zahlen + raise ValueError(f"negatives not allowed: {','.join(map(str, negative))}") + self.called_count += 1 + return sum(numbers_to_add) + def get_called_count(self): + return self.called_count +''' + +class TestStingCalculator(unittest.TestCase): + def setUp(self): + self.calculator = StringCalculator() + def test_empty_string(self): + self.assertEqual(self.calculator.add(""), 0) #leerer string + 0 + def test_single_number(self): + self.assertEqual(self.calculator.add("5"),5) #eingabe von einem String + def test_multiple_numbers(self): + self.assertEqual(self.calculator.add("5,5"),10)#eingabe mehrere strings + def test_unknowen_amount_of_numbers(self): + self.assertEqual(self.calculator.add("1,2,3"),6) + self.assertEqual(self.calculator.add("10,20,30,40"),100) + self.assertEqual(self.calculator.add("1,2,3,4,5,6"),21) + def test_numbers_seperated_by_newline(self): + self.assertEqual(self.calculator.add("1\n2"),3) + self.assertEqual(self.calculator.add("1\n2\n3"),6) + self.assertEqual(self.calculator.add("10,20\n30"),60) + + def test_negative_number_exception(self): + + with self.assertRaises(ValueError) as e: + self.calculator.add("-1,2") + self.assertEqual(str(e.exception), "negatives not allowed: -1") + def test_multiple_negative_numbers_exception(self): + with self.assertRaises(ValueError)as e: + self.calculator.add("-1,-2,3") + self.assertEqual(str(e.exception),"negatives not allowed: -1,-2") + with self.assertRaises(ValueError) as e: + self.calculator.add("-1,-3,4") + self.assertEqual(str(e.exception),"negatives not allowed: -1,-3") + + with self.assertRaises(ValueError) as e: + self.calculator.add("-1\n-3,4") + self.assertEqual(str(e.exception),"negatives not allowed: -1,-3") + def test_add_numbers_with_custom_delimiter(self): + self.assertEqual(self.calculator.add("//;\n1;2;3"),6) + self.assertEqual(self.calculator.add("//;\n1,2,3"),6) + with self.assertRaises(ValueError) as e: + self.calculator.add("//;\n-3,4") + self.assertEqual(str(e.exception),"negatives not allowed: -3") + + def test_add_numbers_greater_than_1000(self): + self.assertEqual(self.calculator.add("1,1001,2,3"),6) + def test_add_numbers_greater_than_1000_1002(self): + self.assertEqual(self.calculator.add("1002,1,2,3"),6) + def test_add_numbers_greater_1000_and_minus(self): + with self.assertRaises(ValueError) as e: + self.calculator.add("//;\n-3,4;1001") + self.assertEqual(str(e.exception),"negatives not allowed: -3") + def test_custom_delimiter(self): + self.assertEqual(self.calculator.add("//[***]\n1***2***3"),6) + def test_custom_del(self): + self.assertEqual(self.calculator.add("//[+++]\n1+++2+++3"),6) + def test_custom_del2(self): + self.assertEqual(self.calculator.add("//[aa]\n1aa2aa3"),6) + + + +if __name__=='__main__': + unittest.main() + +# python -m unittest others.Momo.MomoStringCalculator -v \ No newline at end of file diff --git a/others/Momo/reportMomoImp.md b/others/Momo/reportMomoImp.md new file mode 100644 index 0000000..c8d4d2e --- /dev/null +++ b/others/Momo/reportMomoImp.md @@ -0,0 +1,4 @@ +| Name | Interface break | Failed Testcases | +|------|-----------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Momo | no | test_add_multiple_negative_numbers (tests.testStringcalculator.TestStringCalculator) ... Negative Zahlen:[-10, -20, -30] negatives not allowed: -10,-20,-30 FAIL | +| Momo | no | test_add_single_negative_number (tests.testStringcalculator.TestStringCalculator) ... Negative Zahlen:[-2] negatives not allowed: -2 FAIL | \ No newline at end of file diff --git a/others/Momo/reportMomoTests.md b/others/Momo/reportMomoTests.md new file mode 100644 index 0000000..efc777e --- /dev/null +++ b/others/Momo/reportMomoTests.md @@ -0,0 +1,6 @@ +| Name | Interface break | Failed Testcases | +|------|-----------------|----------------------------------------------------------------------------------------------------------| +| Momo | no | test_add_numbers_greater_1000_and_minus (others.Momo.MomoStringCalculator.TestStingCalculator) ... FAIL | +| Momo | no | test_add_numbers_with_custom_delimiter (others.Momo.MomoStringCalculator.TestStingCalculator) ... FAIL | +| Momo | no | test_multiple_negative_numbers_exception (others.Momo.MomoStringCalculator.TestStingCalculator) ... FAIL | +| Momo | no | test_negative_number_exception (others.Momo.MomoStringCalculator.TestStingCalculator) ... FAIL | \ No newline at end of file diff --git a/tests/testStringcalculator.py b/tests/testStringcalculator.py index 110ba77..28448a3 100644 --- a/tests/testStringcalculator.py +++ b/tests/testStringcalculator.py @@ -36,9 +36,12 @@ from others.Orlando.OrlandoStringCalculator import StringCalculator import unittest from others.Dani.DaniStringCalculator import IStringCalculator, StringCalculator -''' + import unittest from others.Wasili.WasiliStringCalculator import IStringCalculator, StringCalculator +''' +import unittest +from others.Momo.MomoStringCalculator import StringCalculator class TestStringCalculator(unittest.TestCase): def setUp(self): -- GitLab From 3720f98f5b335bc2c012b27a8dbb85451d41075d Mon Sep 17 00:00:00 2001 From: linopino <lasse.pikkemaat@web.de> Date: Wed, 2 Apr 2025 00:38:01 +0200 Subject: [PATCH 5/9] Integration von Almas Code + Tests --- others/Alma/AlmaStringCalculator.py | 98 +++++++++++++++++++++++++++++ others/Alma/reportAlmaImp.md | 5 ++ others/Alma/reportAlmaTests.md | 4 ++ tests/testStringcalculator.py | 5 +- 4 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 others/Alma/AlmaStringCalculator.py create mode 100644 others/Alma/reportAlmaImp.md create mode 100644 others/Alma/reportAlmaTests.md diff --git a/others/Alma/AlmaStringCalculator.py b/others/Alma/AlmaStringCalculator.py new file mode 100644 index 0000000..bfaa661 --- /dev/null +++ b/others/Alma/AlmaStringCalculator.py @@ -0,0 +1,98 @@ +from abc import ABC, abstractmethod +import unittest +from src.stringcalculator import StringCalculator #Auskommentieren, falls andere Implementierung genutzt wird +''' +class IStringCalculator(ABC): + @abstractmethod + def add(self, numbers: str) -> int: + pass + +class StringCalculator(IStringCalculator): + def add(self, numbers: str) -> int: + if not numbers: + return 0 + + # Überprüfe, ob ein benutzerdefiniertes Trennzeichen angegeben ist + if numbers.startswith("//"): + delimiter_line_end = numbers.find("\n") + delimiter = numbers[2:delimiter_line_end] # Extrahiere das Trennzeichen + numbers = numbers[delimiter_line_end + 1:] # Entferne die erste Zeile mit dem Trennzeichen + + else: + delimiter = ',' # Standard-Trennzeichen ist Komma, wenn keine Zeile mit dem Trennzeichen vorhanden ist + + # Ersetze alle Vorkommen des Trennzeichens und teile die Eingabe + numbers = numbers.replace("\n", delimiter) + nums = numbers.split(delimiter) + + # Filtere alle Zahlen, die größer als 1000 sind + nums = [int(num) for num in nums if int(num) <= 1000] + + # Prüfe auf negative Zahlen + negatives = [num for num in nums if num < 0] + + if negatives: + # Wenn negative Zahlen vorhanden sind, werfe eine Ausnahme + raise ValueError(f"Negatives not allowed: {', '.join(map(str, negatives))}") + + # Berechne die Summe der Zahlen, die <= 1000 sind + return sum(nums) +''' + +class TestStringCalculator(unittest.TestCase): + def setUp(self): + self.calculator = StringCalculator() + + def test_empty_string(self): + self.assertEqual(self.calculator.add(""), 0) + + def test_single_number(self): + self.assertEqual(self.calculator.add("1"), 1) + + def test_two_numbers(self): + self.assertEqual(self.calculator.add("1,2"), 3) + + def test_multiple_numbers(self): + self.assertEqual(self.calculator.add("1,2,3,4,5"), 15) + + def test_numbers_with_newline(self): + self.assertEqual(self.calculator.add("1\n2,3"), 6) + + def test_numbers_with_multiple_newlines(self): + self.assertEqual(self.calculator.add("1\n2\n3\n4\n5"), 15) + + def test_negative_number(self): + with self.assertRaises(ValueError) as context: + self.calculator.add("1,-2,3") + self.assertEqual(str(context.exception), "Negatives not allowed: -2") + + def test_multiple_negative_numbers(self): + with self.assertRaises(ValueError) as context: + self.calculator.add("1,-2,-3,4") + self.assertEqual(str(context.exception), "Negatives not allowed: -2, -3") + + def test_custom_delimiter(self): + self.assertEqual(self.calculator.add("//;\n1;2"), 3) + + def test_custom_delimiter_with_newline(self): + self.assertEqual(self.calculator.add("//;\n1;2\n3"), 6) + + def test_custom_delimiter_with_multiple_numbers(self): + self.assertEqual(self.calculator.add("//|\n1|2|3|4"), 10) + + def test_numbers_greater_than_1000(self): + self.assertEqual(self.calculator.add("2,1001"), 2) + + def test_numbers_greater_than_1000_with_custom_delimiter(self): + self.assertEqual(self.calculator.add("//;\n2;1001"), 2) + + def test_long_delimiter(self): + self.assertEqual(self.calculator.add("//[***]\n1***2***3"), 6) + + def test_long_delimiter_with_multiple_numbers(self): + self.assertEqual(self.calculator.add("//[---]\n1---2---3---4"), 10) + +if __name__ == "__main__": + unittest.main() + +# python -m unittest others.Alma.AlmaStringCalculator -v \ No newline at end of file diff --git a/others/Alma/reportAlmaImp.md b/others/Alma/reportAlmaImp.md new file mode 100644 index 0000000..286003a --- /dev/null +++ b/others/Alma/reportAlmaImp.md @@ -0,0 +1,5 @@ +| Name | Interface break | Failed Testcases | Comment | +|------|-----------------|------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------| +| Alma | no | test_add_multiple_negative_numbers (tests.testStringcalculator.TestStringCalculator) ... Negatives not allowed: -10, -20, -30 FAIL | | +| Alma | no | test_add_single_negative_number (tests.testStringcalculator.TestStringCalculator) ... Negatives not allowed: -2 FAIL | | +| Alma | no | test_add_with_custom_delimiter_multiple_characters (tests.testStringcalculator.TestStringCalculator) ... ERROR | Dein Code verarbeitet nur ein Zeichen als Delimiter, aber nicht mehrere Zeichen | \ No newline at end of file diff --git a/others/Alma/reportAlmaTests.md b/others/Alma/reportAlmaTests.md new file mode 100644 index 0000000..559e164 --- /dev/null +++ b/others/Alma/reportAlmaTests.md @@ -0,0 +1,4 @@ +| Name | Interface break | Failed Testcases | +|------|-----------------|-------------------------------------------------------------------------------------------------| +| Alma | no | test_multiple_negative_numbers (others.Alma.AlmaStringCalculator.TestStringCalculator) ... FAIL | +| Alma | no | test_negative_number (others.Alma.AlmaStringCalculator.TestStringCalculator) ... FAIL | \ No newline at end of file diff --git a/tests/testStringcalculator.py b/tests/testStringcalculator.py index 28448a3..a21f60d 100644 --- a/tests/testStringcalculator.py +++ b/tests/testStringcalculator.py @@ -39,9 +39,12 @@ from others.Dani.DaniStringCalculator import IStringCalculator, StringCalculator import unittest from others.Wasili.WasiliStringCalculator import IStringCalculator, StringCalculator -''' + import unittest from others.Momo.MomoStringCalculator import StringCalculator +''' +import unittest +from others.Alma.AlmaStringCalculator import IStringCalculator, StringCalculator class TestStringCalculator(unittest.TestCase): def setUp(self): -- GitLab From 954b813c132e85059029c8f4f77420d1fac1388c Mon Sep 17 00:00:00 2001 From: linopino <lasse.pikkemaat@web.de> Date: Wed, 2 Apr 2025 00:48:16 +0200 Subject: [PATCH 6/9] Integration von Marvins Code + Tests --- others/Marvin/reportMarvinImp.md | 4 ++++ others/Marvin/reportMarvinTests.md | 4 ++++ tests/testStringcalculator.py | 5 ++++- 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 others/Marvin/reportMarvinImp.md create mode 100644 others/Marvin/reportMarvinTests.md diff --git a/others/Marvin/reportMarvinImp.md b/others/Marvin/reportMarvinImp.md new file mode 100644 index 0000000..5374294 --- /dev/null +++ b/others/Marvin/reportMarvinImp.md @@ -0,0 +1,4 @@ +| Name | Interface break | Failed Testcases | +|--------|-----------------|-----------------------------------------------------------------------------------------------------------------------------------------------| +| Marvin | no | test_add_multiple_negative_numbers (tests.testStringcalculator.TestStringCalculator) ... Negative numbers are not allowed: -10, -20, -30 FAIL | +| Marvin | no | test_add_single_negative_number (tests.testStringcalculator.TestStringCalculator) ... Negative numbers are not allowed: -2 FAIL | \ No newline at end of file diff --git a/others/Marvin/reportMarvinTests.md b/others/Marvin/reportMarvinTests.md new file mode 100644 index 0000000..68709e7 --- /dev/null +++ b/others/Marvin/reportMarvinTests.md @@ -0,0 +1,4 @@ +| Name | Interface break | Failed Testcases | +|--------|-----------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Marvin | no | test_add_negative_numbers (others.Marvin.MarvinStringCalculator.TestStringCalculator) Feature 4: Negative Zahlen sollen Fehler werfen ... FAIL | +| Marvin | no | test_custom_long_delimiter_with_negative_numbers (others.Marvin.MarvinStringCalculator.TestStringCalculator) Feature 4 und 7: Benutzerdefinierter Delimiter beliebiger Länge + negative Zahlen ... FAIL | \ No newline at end of file diff --git a/tests/testStringcalculator.py b/tests/testStringcalculator.py index a21f60d..a94a7ed 100644 --- a/tests/testStringcalculator.py +++ b/tests/testStringcalculator.py @@ -42,9 +42,12 @@ from others.Wasili.WasiliStringCalculator import IStringCalculator, StringCalcul import unittest from others.Momo.MomoStringCalculator import StringCalculator -''' + import unittest from others.Alma.AlmaStringCalculator import IStringCalculator, StringCalculator +''' +import unittest +from others.Marvin.MarvinStringCalculator import StringCalculator class TestStringCalculator(unittest.TestCase): def setUp(self): -- GitLab From 38156dc159ef05090543197dbb60c52421999bea Mon Sep 17 00:00:00 2001 From: linopino <lasse.pikkemaat@web.de> Date: Wed, 2 Apr 2025 00:50:11 +0200 Subject: [PATCH 7/9] Integration von Marvins Code + Tests --- others/Marvin/MarvinStringCalculator.py | 131 ++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 others/Marvin/MarvinStringCalculator.py diff --git a/others/Marvin/MarvinStringCalculator.py b/others/Marvin/MarvinStringCalculator.py new file mode 100644 index 0000000..6a90218 --- /dev/null +++ b/others/Marvin/MarvinStringCalculator.py @@ -0,0 +1,131 @@ +import re +import unittest +from src.stringcalculator import StringCalculator #Auskommentieren, falls andere Implementierung genutzt wird + +''' +class StringCalculator: + def add(self, numbers: str) -> int: + # Feature 1: Leerer String ergibt 0 + if not numbers: + return 0 + + + + # Vorbereitung für weiter features + delimiters = [",", "\n"] + if numbers.startswith("//"): + delimiter_end_index = numbers.index("\n") + delimiter_section = numbers[2:delimiter_end_index] + numbers = numbers[delimiter_end_index + 1:] + + # Feature 7: Delimiter beliebiger Länge im Format //[***] + if delimiter_section.startswith("[") and delimiter_section.endswith("]"): + delimiter = re.escape(delimiter_section[1:-1]) + else: + delimiter = re.escape(delimiter_section) + + delimiters.append(delimiter) + + # Feature 3: Erlaube Zeilenumbrüche als Trenner + split_pattern = "|".join(delimiters) + number_list = re.split(split_pattern, numbers) + + + + + # Feature 4: Negativzahlen abfangen + negatives = [] + for num in number_list: + if num.strip() != "": + value = int(num) + if value < 0: + negatives.append(value) + + # Exception bei negativen Zahlen + if negatives: + raise ValueError(f"Negative numbers are not allowed: {', '.join(map(str, negatives))}") + + # Feature 2: Beliebig viele Zahlen summieren + return sum(int(n) for n in number_list if n.strip() != "" and int(n) <= 1000) + +''' + +class TestStringCalculator(unittest.TestCase): + """Test suite for the StringCalculator class.""" + + def setUp(self): + """neue Instanz des StringCalculators vor jedem Test""" + self.calculator = StringCalculator() + + def test_empty_string_returns_zero(self): + """Feature 1: Leerer String soll 0 ergeben""" + self.assertEqual(self.calculator.add(""), 0) + + def test_single_number_returns_value(self): + """Ein einzelner Wert soll zurückgegeben werden""" + self.assertEqual(self.calculator.add("1"), 1) + + def test_two_numbers_return_sum(self): + """Zwei Zahlen sollen summiert werden""" + self.assertEqual(self.calculator.add("1,2"), 3) + + def test_add_multiple_numbers(self): + """Feature 2: Mehrere Zahlen summieren""" + self.assertEqual(self.calculator.add("1,2,3,4,5"), 15) + + def test_add_numbers_with_newlines(self): + """Feature 3: Zeilenumbrüche als Trennzeichen""" + self.assertEqual(self.calculator.add("1\n2\n3"), 6) + + def test_add_negative_numbers(self): + """Feature 4: Negative Zahlen sollen Fehler werfen""" + with self.assertRaises(ValueError) as e: + self.calculator.add("-1,2,-3") + self.assertEqual(str(e.exception), "Negative numbers are not allowed: -1, -3") + + def test_add_numbers_with_custom_delimiter(self): + """Feature 5: Benutzerdefiniertes Trennzeichen""" + self.assertEqual(self.calculator.add("//;\n1;2;3"), 6) + + def test_add_numbers_with_custom_delimiter_different_symbol(self): + """Feature 5: Benutzerdefiniertes Trennzeichen mit anderem Symbol""" + self.assertEqual(self.calculator.add("//#\n4#5#6"), 15) + + def test_custom_delimiter_with_multiple_numbers(self): + """ + Kombinierter Test für: + feature 5 und feature 2 + Erwartet wird die korrekte Addition von sechs durch ein benutzerdefiniertes Zeichen getrennten Zahlen. + """ + self.assertEqual(self.calculator.add("//:\n1:2:3:4:5:6"), 21) + + def test_add_numbers_greater_than_1000(self): + """Feature6 test""" + self.assertEqual(self.calculator.add("1,1001,2,3"), 6) + + def test_add_numbers_with_newlines_and_ignore_above_1000(self): + """Feature 3 und 6 test Zeilenumbruch als trenner, Zahlen>1000 ignorieren""" + self.assertEqual(self.calculator.add("1\n2\n1000\n1001"), 1003) + + def test_add_numbers_with_custom_delimiter_long_length(self): + """Benutzerdefinierte Trennzeichen beliebig lang """ + self.assertEqual(self.calculator.add("//[***]\n1***2***3"), 6) + + def test_custom_long_delimiter_with_large_number_ignored(self): + """FEature 6 und 7 test Benutzerdefinierte Delimiter Länge und zahl über 1000 wird ignoriert""" + self.assertEqual(self.calculator.add("//[***]\n1***1001***2"), 3) + + def test_custom_long_delimiter_with_negative_numbers(self): + """Feature 4 und 7: Benutzerdefinierter Delimiter beliebiger Länge + negative Zahlen""" + with self.assertRaises(ValueError) as e: + self.calculator.add("//[***]\n1***-2***3***-4") + self.assertEqual(str(e.exception), "Negative numbers are not allowed: -2, -4") + + + + + +if __name__ == '__main__': + unittest.main() + +# python -m unittest others.Marvin.MarvinStringCalculator -v -- GitLab From 22bee8479f9095fa5480e580fe1b21372879d42b Mon Sep 17 00:00:00 2001 From: linopino <lasse.pikkemaat@web.de> Date: Wed, 2 Apr 2025 00:57:41 +0200 Subject: [PATCH 8/9] Integration von Hatices Code + Tests --- others/Hatice/HaticeStringCalculator.py | 98 +++++++++++++++++++++++++ others/Hatice/reportHaticeImp.md | 5 ++ others/Hatice/reportHaticeTests.md | 4 + tests/testStringcalculator.py | 5 +- 4 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 others/Hatice/HaticeStringCalculator.py create mode 100644 others/Hatice/reportHaticeImp.md create mode 100644 others/Hatice/reportHaticeTests.md diff --git a/others/Hatice/HaticeStringCalculator.py b/others/Hatice/HaticeStringCalculator.py new file mode 100644 index 0000000..e83a202 --- /dev/null +++ b/others/Hatice/HaticeStringCalculator.py @@ -0,0 +1,98 @@ +from abc import ABC, abstractmethod +import unittest +from src.stringcalculator import StringCalculator #Auskommentieren, falls andere Implementierung genutzt wird +''' +class IStringCalculator(ABC): + @abstractmethod + def add(self, numbers: str) -> int: + pass + +class StringCalculator(IStringCalculator): + def add(self, numbers: str) -> int: + if not numbers: + return 0 + + # Überprüfe, ob ein benutzerdefiniertes Trennzeichen angegeben ist + if numbers.startswith("//"): + delimiter_line_end = numbers.find("\n") + delimiter = numbers[2:delimiter_line_end] # Extrahiere das Trennzeichen + numbers = numbers[delimiter_line_end + 1:] # Entferne die erste Zeile mit dem Trennzeichen + + else: + delimiter = ',' # Standard-Trennzeichen ist Komma, wenn keine Zeile mit dem Trennzeichen vorhanden ist + + # Ersetze alle Vorkommen des Trennzeichens und teile die Eingabe + numbers = numbers.replace("\n", delimiter) + nums = numbers.split(delimiter) + + # Filtere alle Zahlen, die größer als 1000 sind + nums = [int(num) for num in nums if int(num) <= 1000] + + # Prüfe auf negative Zahlen + negatives = [num for num in nums if num < 0] + + if negatives: + # Wenn negative Zahlen vorhanden sind, werfe eine Ausnahme + raise ValueError(f"Negatives not allowed: {', '.join(map(str, negatives))}") + + # Berechne die Summe der Zahlen, die <= 1000 sind + return sum(nums) +''' + +class TestStringCalculator(unittest.TestCase): + def setUp(self): + self.calculator = StringCalculator() + + def test_empty_string(self): + self.assertEqual(self.calculator.add(""), 0) + + def test_single_number(self): + self.assertEqual(self.calculator.add("1"), 1) + + def test_two_numbers(self): + self.assertEqual(self.calculator.add("1,2"), 3) + + def test_multiple_numbers(self): + self.assertEqual(self.calculator.add("1,2,3,4,5"), 15) + + def test_numbers_with_newline(self): + self.assertEqual(self.calculator.add("1\n2,3"), 6) + + def test_numbers_with_multiple_newlines(self): + self.assertEqual(self.calculator.add("1\n2\n3\n4\n5"), 15) + + def test_negative_number(self): + with self.assertRaises(ValueError) as context: + self.calculator.add("1,-2,3") + self.assertEqual(str(context.exception), "Negatives not allowed: -2") + + def test_multiple_negative_numbers(self): + with self.assertRaises(ValueError) as context: + self.calculator.add("1,-2,-3,4") + self.assertEqual(str(context.exception), "Negatives not allowed: -2, -3") + + def test_custom_delimiter(self): + self.assertEqual(self.calculator.add("//;\n1;2"), 3) + + def test_custom_delimiter_with_newline(self): + self.assertEqual(self.calculator.add("//;\n1;2\n3"), 6) + + def test_custom_delimiter_with_multiple_numbers(self): + self.assertEqual(self.calculator.add("//|\n1|2|3|4"), 10) + + def test_numbers_greater_than_1000(self): + self.assertEqual(self.calculator.add("2,1001"), 2) + + def test_numbers_greater_than_1000_with_custom_delimiter(self): + self.assertEqual(self.calculator.add("//;\n2;1001"), 2) + + def test_long_delimiter(self): + self.assertEqual(self.calculator.add("//[***]\n1***2***3"), 6) + + def test_long_delimiter_with_multiple_numbers(self): + self.assertEqual(self.calculator.add("//[---]\n1---2---3---4"), 10) + +if __name__ == "__main__": + unittest.main() + +# python -m unittest others.Hatice.HaticeStringCalculator -v \ No newline at end of file diff --git a/others/Hatice/reportHaticeImp.md b/others/Hatice/reportHaticeImp.md new file mode 100644 index 0000000..47df290 --- /dev/null +++ b/others/Hatice/reportHaticeImp.md @@ -0,0 +1,5 @@ +| Name | Interface break | Failed Testcases | Comment | +|--------|-----------------|------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------| +| Hatice | no | test_add_multiple_negative_numbers (tests.testStringcalculator.TestStringCalculator) ... Negatives not allowed: -10, -20, -30 FAIL | | +| Hatice | no | test_add_single_negative_number (tests.testStringcalculator.TestStringCalculator) ... Negatives not allowed: -2 FAIL | | +| Hatice | no | test_add_with_custom_delimiter_multiple_characters (tests.testStringcalculator.TestStringCalculator) ... ERROR | Dein Code verarbeitet nur ein Zeichen als Delimiter, aber nicht mehrere Zeichen | \ No newline at end of file diff --git a/others/Hatice/reportHaticeTests.md b/others/Hatice/reportHaticeTests.md new file mode 100644 index 0000000..b3c5ff7 --- /dev/null +++ b/others/Hatice/reportHaticeTests.md @@ -0,0 +1,4 @@ +| Name | Interface break | Failed Testcases | +|--------|-----------------|-------------------------------------------------------------------------------------------------| +| Hatice | no | test_multiple_negative_numbers (others.Alma.AlmaStringCalculator.TestStringCalculator) ... FAIL | +| Hatice | no | test_negative_number (others.Alma.AlmaStringCalculator.TestStringCalculator) ... FAIL | \ No newline at end of file diff --git a/tests/testStringcalculator.py b/tests/testStringcalculator.py index a94a7ed..7c74a51 100644 --- a/tests/testStringcalculator.py +++ b/tests/testStringcalculator.py @@ -45,9 +45,12 @@ from others.Momo.MomoStringCalculator import StringCalculator import unittest from others.Alma.AlmaStringCalculator import IStringCalculator, StringCalculator -''' + import unittest from others.Marvin.MarvinStringCalculator import StringCalculator +''' +import unittest +from others.Hatice.HaticeStringCalculator import IStringCalculator, StringCalculator class TestStringCalculator(unittest.TestCase): def setUp(self): -- GitLab From bf16e398a6189f19a325e5c95e66d65bcf73f1bd Mon Sep 17 00:00:00 2001 From: linopino <lasse.pikkemaat@web.de> Date: Wed, 2 Apr 2025 01:32:07 +0200 Subject: [PATCH 9/9] =?UTF-8?q?Kommentar=20mit=20=C3=84nderung=20damit=20T?= =?UTF-8?q?ests=20mit=20negativen=20Zahlen=20nicht=20failen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/stringcalculator.py | 8 +++++++- tests/testStringcalculator.py | 20 ++++++++++++++------ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/stringcalculator.py b/src/stringcalculator.py index f48f2e8..6f4baac 100644 --- a/src/stringcalculator.py +++ b/src/stringcalculator.py @@ -1,5 +1,4 @@ from src.interfaces import IStringCalculator -import re class StringCalculator(IStringCalculator): def add(self, numbers: str) -> int: @@ -33,3 +32,10 @@ class StringCalculator(IStringCalculator): numbers_list = [num for num in numbers_list if num <= 1000] return sum(numbers_list) + +''' +Änderung damit die Tests mit den negativen Zahlen durchlaufen: + negative_numbers = [num for num in numbers_list if num < 0] + if negative_numbers: + raise ValueError(f"negatives not allowed: {','.join(map(str, negative_numbers))}") +''' \ No newline at end of file diff --git a/tests/testStringcalculator.py b/tests/testStringcalculator.py index 7c74a51..41e5f93 100644 --- a/tests/testStringcalculator.py +++ b/tests/testStringcalculator.py @@ -23,13 +23,12 @@ # Bei Eingabe von //[**]\n1**2**3 soll 6 ausgegeben werden # Bei Eingabe von //[###]\n10###20###30 soll 60 ausgegeben werden -''' -Eigener Code: + import unittest from src.interfaces import IStringCalculator from src.stringcalculator import StringCalculator -Orlandos Code: +''' import unittest from others.Orlando.OrlandoInterfaces import IStringCalculator from others.Orlando.OrlandoStringCalculator import StringCalculator @@ -48,10 +47,10 @@ from others.Alma.AlmaStringCalculator import IStringCalculator, StringCalculator import unittest from others.Marvin.MarvinStringCalculator import StringCalculator -''' + import unittest from others.Hatice.HaticeStringCalculator import IStringCalculator, StringCalculator - +''' class TestStringCalculator(unittest.TestCase): def setUp(self): self.calculator: IStringCalculator = StringCalculator() # Zugriff über das Interface @@ -106,4 +105,13 @@ if __name__ == "__main__": unittest.main() # python -m unittest tests.testStringcalculator -v -# python -m unittest discover -s tests -v \ No newline at end of file +# python -m unittest discover -s tests -v +''' +Keine strikte Typprüfung zur Laufzeit + +In der Methode setUp() hast du die Zuweisung: +self.calculator: IStringCalculator = StringCalculator() + +-Das : IStringCalculator ist nur ein Typ-Hinweis (Type Hint), aber Python überprüft das nicht zur Laufzeit. +-Python ignoriert den Typ-Hinweis und weist self.calculator einfach die Instanz von StringCalculator zu. +''' \ No newline at end of file -- GitLab