From 77ce677850cccdac33e93d34bed6a5aadc9ad584 Mon Sep 17 00:00:00 2001
From: Marvin Serchimo <marvin.serchimo@student.reutlingen-university.de>
Date: Sun, 6 Apr 2025 19:30:27 +0200
Subject: [PATCH] feature7

---
 .DS_Store                                     | Bin 0 -> 6148 bytes
 Feature1.py                                   |  32 +++++
 Feature2.py                                   |  41 +++++++
 Feature3.py                                   |  61 ++++++++++
 Feature4.py                                   |  80 +++++++++++++
 Feature5.py                                   |  88 ++++++++++++++
 Feature6.py                                   |  94 +++++++++++++++
 README.md                                     |   6 +-
 feature7                                      |   2 +-
 other/GotsisWasilios/TDD_StringCalculator.py  | 110 ++++++++++++++++++
 .../TDD_StringCalculator.cpython-313.pyc      | Bin 0 -> 6387 bytes
 report.md                                     |  11 ++
 stringCalculator.py                           |  29 +++++
 13 files changed, 550 insertions(+), 4 deletions(-)
 create mode 100644 .DS_Store
 create mode 100644 Feature1.py
 create mode 100644 Feature2.py
 create mode 100644 Feature3.py
 create mode 100644 Feature4.py
 create mode 100644 Feature5.py
 create mode 100644 Feature6.py
 create mode 100644 other/GotsisWasilios/TDD_StringCalculator.py
 create mode 100644 other/GotsisWasilios/__pycache__/TDD_StringCalculator.cpython-313.pyc
 create mode 100644 report.md
 create mode 100644 stringCalculator.py

diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..77b724c4358591816346c24827ee84261dcb97c3
GIT binary patch
literal 6148
zcmeH~O^O0R426?XL2%>JWo<lwHz=e%ffo>ez=hD@%<SvvzWgBAx)zZaNM2PcQTkhS
zbwoth|HqZcTtudDQ(0OVm|{PXUjF1PC%GPf50`!4U%cukYpn*3-*`OFV+sk7011!)
z36Q`C5wLq3Hl2ksk^l*iz@31-9}3*GrnXRjbs+c%039RkhPBTU&|(Q_O>Lpbz%*K+
z(W*X%Sl-*ACF^Qx3ypTs96mJvS#64eX|#(LY+zbl7)XEw1_Va2pWFSvfxnvn2QA!^
z0112<0UdYSZjFb^yY=buEWgXFts5Nb<p>WS0od48ynwsmyx0O-Q(Gu9Fn$O)1_ly%
GD}ftGN)wm>

literal 0
HcmV?d00001

diff --git a/Feature1.py b/Feature1.py
new file mode 100644
index 0000000..c2a76ec
--- /dev/null
+++ b/Feature1.py
@@ -0,0 +1,32 @@
+from abc import ABC, abstractmethod
+import unittest
+
+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
+        return sum(map(int, numbers.split(',')))
+
+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)
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/Feature2.py b/Feature2.py
new file mode 100644
index 0000000..313c838
--- /dev/null
+++ b/Feature2.py
@@ -0,0 +1,41 @@
+from abc import ABC, abstractmethod
+import unittest
+
+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
+        # Ersetze Zeilenumbrüche durch Kommas und teile die Eingabe nach Kommas
+        numbers = numbers.replace("\n", ",")
+        return sum(map(int, numbers.split(',')))
+
+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)
+
+if __name__ == "__main__":
+    unittest.main()
+
diff --git a/Feature3.py b/Feature3.py
new file mode 100644
index 0000000..e97fdae
--- /dev/null
+++ b/Feature3.py
@@ -0,0 +1,61 @@
+from abc import ABC, abstractmethod
+import unittest
+
+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
+        
+        # Ersetze Zeilenumbrüche durch Kommas und teile die Eingabe nach Kommas
+        numbers = numbers.replace("\n", ",")
+        
+        # Splitte die Zahlen und prüfe auf negative Zahlen
+        nums = numbers.split(',')
+        negatives = [num for num in nums if int(num) < 0]
+        
+        if negatives:
+            # Wenn negative Zahlen vorhanden sind, werfe eine Ausnahme
+            raise ValueError(f"Negatives not allowed: {', '.join(negatives)}")
+        
+        # Berechne die Summe der positiven Zahlen
+        return sum(map(int, 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")
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/Feature4.py b/Feature4.py
new file mode 100644
index 0000000..0a5f753
--- /dev/null
+++ b/Feature4.py
@@ -0,0 +1,80 @@
+from abc import ABC, abstractmethod
+import unittest
+
+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)
+        
+        # Prüfe auf negative Zahlen
+        negatives = [num for num in nums if int(num) < 0]
+        
+        if negatives:
+            # Wenn negative Zahlen vorhanden sind, werfe eine Ausnahme
+            raise ValueError(f"Negatives not allowed: {', '.join(negatives)}")
+        
+        # Berechne die Summe der positiven Zahlen
+        return sum(map(int, 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)
+
+if __name__ == "__main__":
+    unittest.main()
+
diff --git a/Feature5.py b/Feature5.py
new file mode 100644
index 0000000..4bb39d4
--- /dev/null
+++ b/Feature5.py
@@ -0,0 +1,88 @@
+from abc import ABC, abstractmethod
+import unittest
+
+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)
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/Feature6.py b/Feature6.py
new file mode 100644
index 0000000..0f35297
--- /dev/null
+++ b/Feature6.py
@@ -0,0 +1,94 @@
+from abc import ABC, abstractmethod
+import unittest
+
+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()
\ No newline at end of file
diff --git a/README.md b/README.md
index 13edffa..3898420 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Assignment 2
+# Assignement_02
 
 
 
@@ -15,14 +15,14 @@ Already a pro? Just edit this README.md and make it your own. Want to make it ea
 
 ```
 cd existing_repo
-git remote add origin https://gitlab.reutlingen-university.de/Marvin.Serchimo/assignment-2.git
+git remote add origin https://gitlab.reutlingen-university.de/Alma.Berisha/assignement_02.git
 git branch -M main
 git push -uf origin main
 ```
 
 ## Integrate with your tools
 
-- [ ] [Set up project integrations](https://gitlab.reutlingen-university.de/Marvin.Serchimo/assignment-2/-/settings/integrations)
+- [ ] [Set up project integrations](https://gitlab.reutlingen-university.de/Alma.Berisha/assignement_02/-/settings/integrations)
 
 ## Collaborate with your team
 
diff --git a/feature7 b/feature7
index 92de925..8e5342a 100644
--- a/feature7
+++ b/feature7
@@ -1,6 +1,6 @@
 import re 
 import unittest
-
+from other.GotsisWasilios.TDD_StringCalculator import TestStringCalculator as Wasili
 class StringCalculator:
     def add(self, numbers: str) -> int:
         # Feature 1: Leerer String ergibt 0
diff --git a/other/GotsisWasilios/TDD_StringCalculator.py b/other/GotsisWasilios/TDD_StringCalculator.py
new file mode 100644
index 0000000..ab815fa
--- /dev/null
+++ b/other/GotsisWasilios/TDD_StringCalculator.py
@@ -0,0 +1,110 @@
+#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
+
+#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()
diff --git a/other/GotsisWasilios/__pycache__/TDD_StringCalculator.cpython-313.pyc b/other/GotsisWasilios/__pycache__/TDD_StringCalculator.cpython-313.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..0560b12c2d952c1f11c1e0cbf8071d3f060cdc72
GIT binary patch
literal 6387
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
B1Q!4R

literal 0
HcmV?d00001

diff --git a/report.md b/report.md
new file mode 100644
index 0000000..27cbe3e
--- /dev/null
+++ b/report.md
@@ -0,0 +1,11 @@
+## Eigene Tests gegen andere Implementierungen
+
+| Name              | Interface break | Failed Testcases |
+|-------------------|------------------|-------------------|
+| AliciMuhamed      | –                | –                 |
+| BerishaAlma       | –                | –                 |
+| GotsisWasilios    | no               | 0                 |
+| PikkemaatLasse    | –                | –                 |
+| RafehDaniel       | –                | –                 |
+| WeishauptOrlando  | –                | –                 |
+| YildirimHatice    | –                | –                 |
diff --git a/stringCalculator.py b/stringCalculator.py
new file mode 100644
index 0000000..f9a7682
--- /dev/null
+++ b/stringCalculator.py
@@ -0,0 +1,29 @@
+from abc import ABC, abstractmethod
+import unittest
+
+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
+        return sum(map(int, numbers.split(',')))
+
+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)
+
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file
-- 
GitLab