From 9cb0a2d4c391ce688415487439e79234e9f04cf2 Mon Sep 17 00:00:00 2001
From: Almmaa <Alma.Berisha@student.reutlingen-university.de>
Date: Sun, 6 Apr 2025 00:28:36 +0200
Subject: [PATCH] =?UTF-8?q?Testf=C3=A4lle=20f=C3=BCr=20student1=20ausgef?=
 =?UTF-8?q?=C3=BChrt=20=20Fehler=20dokumentiert?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../my_string_calculator.cpython-313.pyc      | Bin 0 -> 6781 bytes
 ld                                            | 270 ++++++++++++++++++
 my_string_calculator.py                       |  88 ++++++
 other/student1/Calculator.py                  | 152 ++++++++++
 .../__pycache__/Calculator.cpython-313.pyc    | Bin 0 -> 8196 bytes
 other/student2/Calculator.py                  |  97 +++++++
 .../__pycache__/Calculator.cpython-313.pyc    | Bin 0 -> 6376 bytes
 other/student3/Calculator.py                  | 109 +++++++
 .../__pycache__/Calculator.cpython-313.pyc    | Bin 0 -> 9362 bytes
 other/student4/Calculator.py                  | 127 ++++++++
 .../__pycache__/Calculator.cpython-313.pyc    | Bin 0 -> 8756 bytes
 other/student5/Calculator_combined.py         |  96 +++++++
 .../Calculator_combined.cpython-313.pyc       | Bin 0 -> 7779 bytes
 other/student6/Calculator_combined.py         |  97 +++++++
 .../Calculator_combined.cpython-313.pyc       | Bin 0 -> 7719 bytes
 other/student7/Calculator.py                  |  88 ++++++
 .../__pycache__/Calculator.cpython-313.pyc    | Bin 0 -> 6786 bytes
 report.md                                     |   0
 test_me_on_student1.py                        |  50 ++++
 test_me_on_student2.py                        |  52 ++++
 test_me_on_student3.py                        |  49 ++++
 test_me_on_student4.py                        |  49 ++++
 test_me_on_student5.py                        |  30 ++
 test_me_on_student6.py                        |  53 ++++
 test_me_on_student7.py                        |  23 ++
 test_student1_on_me.py                        |  69 +++++
 test_student2_on_me.py                        |  47 +++
 test_student3_on_me.py                        |  49 ++++
 test_student4_on_me.py                        |  55 ++++
 test_student5_on_me.py                        |  57 ++++
 test_student6_on_me.py                        |  53 ++++
 test_student7_on_me.py                        |  35 +++
 32 files changed, 1795 insertions(+)
 create mode 100644 __pycache__/my_string_calculator.cpython-313.pyc
 create mode 100644 ld
 create mode 100644 my_string_calculator.py
 create mode 100644 other/student1/Calculator.py
 create mode 100644 other/student1/__pycache__/Calculator.cpython-313.pyc
 create mode 100644 other/student2/Calculator.py
 create mode 100644 other/student2/__pycache__/Calculator.cpython-313.pyc
 create mode 100644 other/student3/Calculator.py
 create mode 100644 other/student3/__pycache__/Calculator.cpython-313.pyc
 create mode 100644 other/student4/Calculator.py
 create mode 100644 other/student4/__pycache__/Calculator.cpython-313.pyc
 create mode 100644 other/student5/Calculator_combined.py
 create mode 100644 other/student5/__pycache__/Calculator_combined.cpython-313.pyc
 create mode 100644 other/student6/Calculator_combined.py
 create mode 100644 other/student6/__pycache__/Calculator_combined.cpython-313.pyc
 create mode 100644 other/student7/Calculator.py
 create mode 100644 other/student7/__pycache__/Calculator.cpython-313.pyc
 create mode 100644 report.md
 create mode 100644 test_me_on_student1.py
 create mode 100644 test_me_on_student2.py
 create mode 100644 test_me_on_student3.py
 create mode 100644 test_me_on_student4.py
 create mode 100644 test_me_on_student5.py
 create mode 100644 test_me_on_student6.py
 create mode 100644 test_me_on_student7.py
 create mode 100644 test_student1_on_me.py
 create mode 100644 test_student2_on_me.py
 create mode 100644 test_student3_on_me.py
 create mode 100644 test_student4_on_me.py
 create mode 100644 test_student5_on_me.py
 create mode 100644 test_student6_on_me.py
 create mode 100644 test_student7_on_me.py

diff --git a/__pycache__/my_string_calculator.cpython-313.pyc b/__pycache__/my_string_calculator.cpython-313.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..43497a3f65d0fe1ca3c2b54461add7f147d2419c
GIT binary patch
literal 6781
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
BVI}|o

literal 0
HcmV?d00001

diff --git a/ld b/ld
new file mode 100644
index 0000000..5972578
--- /dev/null
+++ b/ld
@@ -0,0 +1,270 @@
+
+                   SSUUMMMMAARRYY OOFF LLEESSSS CCOOMMMMAANNDDSS
+
+      Commands marked with * may be preceded by a number, _N.
+      Notes in parentheses indicate the behavior if _N is given.
+      A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K.
+
+  h  H                 Display this help.
+  q  :q  Q  :Q  ZZ     Exit.
+ ---------------------------------------------------------------------------
+
+                           MMOOVVIINNGG
+
+  e  ^E  j  ^N  CR  *  Forward  one line   (or _N lines).
+  y  ^Y  k  ^K  ^P  *  Backward one line   (or _N lines).
+  f  ^F  ^V  SPACE  *  Forward  one window (or _N lines).
+  b  ^B  ESC-v      *  Backward one window (or _N lines).
+  z                 *  Forward  one window (and set window to _N).
+  w                 *  Backward one window (and set window to _N).
+  ESC-SPACE         *  Forward  one window, but don't stop at end-of-file.
+  d  ^D             *  Forward  one half-window (and set half-window to _N).
+  u  ^U             *  Backward one half-window (and set half-window to _N).
+  ESC-)  RightArrow *  Right one half screen width (or _N positions).
+  ESC-(  LeftArrow  *  Left  one half screen width (or _N positions).
+  ESC-}  ^RightArrow   Right to last column displayed.
+  ESC-{  ^LeftArrow    Left  to first column.
+  F                    Forward forever; like "tail -f".
+  ESC-F                Like F but stop when search pattern is found.
+  r  ^R  ^L            Repaint screen.
+  R                    Repaint screen, discarding buffered input.
+        ---------------------------------------------------
+        Default "window" is the screen height.
+        Default "half-window" is half of the screen height.
+ ---------------------------------------------------------------------------
+
+                          SSEEAARRCCHHIINNGG
+
+  /_p_a_t_t_e_r_n          *  Search forward for (_N-th) matching line.
+  ?_p_a_t_t_e_r_n          *  Search backward for (_N-th) matching line.
+  n                 *  Repeat previous search (for _N-th occurrence).
+  N                 *  Repeat previous search in reverse direction.
+  ESC-n             *  Repeat previous search, spanning files.
+  ESC-N             *  Repeat previous search, reverse dir. & spanning files.
+  ESC-u                Undo (toggle) search highlighting.
+  ESC-U                Clear search highlighting.
+  &_p_a_t_t_e_r_n          *  Display only matching lines.
+        ---------------------------------------------------
+        A search pattern may begin with one or more of:
+        ^N or !  Search for NON-matching lines.
+        ^E or *  Search multiple files (pass thru END OF FILE).
+        ^F or @  Start search at FIRST file (for /) or last file (for ?).
+        ^K       Highlight matches, but don't move (KEEP position).
+        ^R       Don't use REGULAR EXPRESSIONS.
+        ^W       WRAP search if no match found.
+ ---------------------------------------------------------------------------
+
+                           JJUUMMPPIINNGG
+
+  g  <  ESC-<       *  Go to first line in file (or line _N).
+  G  >  ESC->       *  Go to last line in file (or line _N).
+  p  %              *  Go to beginning of file (or _N percent into file).
+  t                 *  Go to the (_N-th) next tag.
+  T                 *  Go to the (_N-th) previous tag.
+  {  (  [           *  Find close bracket } ) ].
+  }  )  ]           *  Find open bracket { ( [.
+  ESC-^F _<_c_1_> _<_c_2_>  *  Find close bracket _<_c_2_>.
+  ESC-^B _<_c_1_> _<_c_2_>  *  Find open bracket _<_c_1_>.
+        ---------------------------------------------------
+        Each "find close bracket" command goes forward to the close bracket 
+          matching the (_N-th) open bracket in the top line.
+        Each "find open bracket" command goes backward to the open bracket 
+          matching the (_N-th) close bracket in the bottom line.
+
+  m_<_l_e_t_t_e_r_>            Mark the current top line with <letter>.
+  M_<_l_e_t_t_e_r_>            Mark the current bottom line with <letter>.
+  '_<_l_e_t_t_e_r_>            Go to a previously marked position.
+  ''                   Go to the previous position.
+  ^X^X                 Same as '.
+  ESC-m_<_l_e_t_t_e_r_>        Clear a mark.
+        ---------------------------------------------------
+        A mark is any upper-case or lower-case letter.
+        Certain marks are predefined:
+             ^  means  beginning of the file
+             $  means  end of the file
+ ---------------------------------------------------------------------------
+
+                        CCHHAANNGGIINNGG FFIILLEESS
+
+  :e [_f_i_l_e]            Examine a new file.
+  ^X^V                 Same as :e.
+  :n                *  Examine the (_N-th) next file from the command line.
+  :p                *  Examine the (_N-th) previous file from the command line.
+  :x                *  Examine the first (or _N-th) file from the command line.
+  :d                   Delete the current file from the command line list.
+  =  ^G  :f            Print current file name.
+ ---------------------------------------------------------------------------
+
+                    MMIISSCCEELLLLAANNEEOOUUSS CCOOMMMMAANNDDSS
+
+  -_<_f_l_a_g_>              Toggle a command line option [see OPTIONS below].
+  --_<_n_a_m_e_>             Toggle a command line option, by name.
+  __<_f_l_a_g_>              Display the setting of a command line option.
+  ___<_n_a_m_e_>             Display the setting of an option, by name.
+  +_c_m_d                 Execute the less cmd each time a new file is examined.
+
+  !_c_o_m_m_a_n_d             Execute the shell command with $SHELL.
+  |XX_c_o_m_m_a_n_d            Pipe file between current pos & mark XX to shell command.
+  s _f_i_l_e               Save input to a file.
+  v                    Edit the current file with $VISUAL or $EDITOR.
+  V                    Print version number of "less".
+ ---------------------------------------------------------------------------
+
+                           OOPPTTIIOONNSS
+
+        Most options may be changed either on the command line,
+        or from within less by using the - or -- command.
+        Options may be given in one of two forms: either a single
+        character preceded by a -, or a name preceded by --.
+
+  -?  ........  --help
+                  Display help (from command line).
+  -a  ........  --search-skip-screen
+                  Search skips current screen.
+  -A  ........  --SEARCH-SKIP-SCREEN
+                  Search starts just after target line.
+  -b [_N]  ....  --buffers=[_N]
+                  Number of buffers.
+  -B  ........  --auto-buffers
+                  Don't automatically allocate buffers for pipes.
+  -c  ........  --clear-screen
+                  Repaint by clearing rather than scrolling.
+  -d  ........  --dumb
+                  Dumb terminal.
+  -D xx_c_o_l_o_r  .  --color=xx_c_o_l_o_r
+                  Set screen colors.
+  -e  -E  ....  --quit-at-eof  --QUIT-AT-EOF
+                  Quit at end of file.
+  -f  ........  --force
+                  Force open non-regular files.
+  -F  ........  --quit-if-one-screen
+                  Quit if entire file fits on first screen.
+  -g  ........  --hilite-search
+                  Highlight only last match for searches.
+  -G  ........  --HILITE-SEARCH
+                  Don't highlight any matches for searches.
+  -h [_N]  ....  --max-back-scroll=[_N]
+                  Backward scroll limit.
+  -i  ........  --ignore-case
+                  Ignore case in searches that do not contain uppercase.
+  -I  ........  --IGNORE-CASE
+                  Ignore case in all searches.
+  -j [_N]  ....  --jump-target=[_N]
+                  Screen position of target lines.
+  -J  ........  --status-column
+                  Display a status column at left edge of screen.
+  -k [_f_i_l_e]  .  --lesskey-file=[_f_i_l_e]
+                  Use a lesskey file.
+  -K  ........  --quit-on-intr
+                  Exit less in response to ctrl-C.
+  -L  ........  --no-lessopen
+                  Ignore the LESSOPEN environment variable.
+  -m  -M  ....  --long-prompt  --LONG-PROMPT
+                  Set prompt style.
+  -n .........  --line-numbers
+                  Suppress line numbers in prompts and messages.
+  -N .........  --LINE-NUMBERS
+                  Display line number at start of each line.
+  -o [_f_i_l_e]  .  --log-file=[_f_i_l_e]
+                  Copy to log file (standard input only).
+  -O [_f_i_l_e]  .  --LOG-FILE=[_f_i_l_e]
+                  Copy to log file (unconditionally overwrite).
+  -p [_p_a_t_t_e_r_n]  --pattern=[_p_a_t_t_e_r_n]
+                  Start at pattern (from command line).
+  -P [_p_r_o_m_p_t]   --prompt=[_p_r_o_m_p_t]
+                  Define new prompt.
+  -q  -Q  ....  --quiet  --QUIET  --silent --SILENT
+                  Quiet the terminal bell.
+  -r  -R  ....  --raw-control-chars  --RAW-CONTROL-CHARS
+                  Output "raw" control characters.
+  -s  ........  --squeeze-blank-lines
+                  Squeeze multiple blank lines.
+  -S  ........  --chop-long-lines
+                  Chop (truncate) long lines rather than wrapping.
+  -t [_t_a_g]  ..  --tag=[_t_a_g]
+                  Find a tag.
+  -T [_t_a_g_s_f_i_l_e] --tag-file=[_t_a_g_s_f_i_l_e]
+                  Use an alternate tags file.
+  -u  -U  ....  --underline-special  --UNDERLINE-SPECIAL
+                  Change handling of backspaces.
+  -V  ........  --version
+                  Display the version number of "less".
+  -w  ........  --hilite-unread
+                  Highlight first new line after forward-screen.
+  -W  ........  --HILITE-UNREAD
+                  Highlight first new line after any forward movement.
+  -x [_N[,...]]  --tabs=[_N[,...]]
+                  Set tab stops.
+  -X  ........  --no-init
+                  Don't use termcap init/deinit strings.
+  -y [_N]  ....  --max-forw-scroll=[_N]
+                  Forward scroll limit.
+  -z [_N]  ....  --window=[_N]
+                  Set size of window.
+  -" [_c[_c]]  .  --quotes=[_c[_c]]
+                  Set shell quote characters.
+  -~  ........  --tilde
+                  Don't display tildes after end of file.
+  -# [_N]  ....  --shift=[_N]
+                  Set horizontal scroll amount (0 = one half screen width).
+                --file-size
+                  Automatically determine the size of the input file.
+                --follow-name
+                  The F command changes files if the input file is renamed.
+                --header=[_N[,_M]]
+                  Use N lines and M columns to display file headers.
+                --incsearch
+                  Search file as each pattern character is typed in.
+                --line-num-width=N
+                  Set the width of the -N line number field to N characters.
+                --mouse
+                  Enable mouse input.
+                --no-keypad
+                  Don't send termcap keypad init/deinit strings.
+                --no-histdups
+                  Remove duplicates from command history.
+                --no-number-headers
+                  Don't give line numbers to header lines.
+                --redraw-on-quit
+                  Redraw final screen when quitting.
+                --rscroll=C
+                  Set the character used to mark truncated lines.
+                --save-marks
+                  Retain marks across invocations of less.
+                --search-options=[EFKNRW-]
+                  Set default options for every search.
+                --status-col-width=N
+                  Set the width of the -J status column to N characters.
+                --status-line
+                  Highlight or color the entire line containing a mark.
+                --use-backslash
+                  Subsequent options use backslash as escape char.
+                --use-color
+                  Enables colored text.
+                --wheel-lines=N
+                  Each click of the mouse wheel moves N lines.
+
+
+ ---------------------------------------------------------------------------
+
+                          LLIINNEE EEDDIITTIINNGG
+
+        These keys can be used to edit text being entered 
+        on the "command line" at the bottom of the screen.
+
+ RightArrow ..................... ESC-l ... Move cursor right one character.
+ LeftArrow ...................... ESC-h ... Move cursor left one character.
+ ctrl-RightArrow  ESC-RightArrow  ESC-w ... Move cursor right one word.
+ ctrl-LeftArrow   ESC-LeftArrow   ESC-b ... Move cursor left one word.
+ HOME ........................... ESC-0 ... Move cursor to start of line.
+ END ............................ ESC-$ ... Move cursor to end of line.
+ BACKSPACE ................................ Delete char to left of cursor.
+ DELETE ......................... ESC-x ... Delete char under cursor.
+ ctrl-BACKSPACE   ESC-BACKSPACE ........... Delete word to left of cursor.
+ ctrl-DELETE .... ESC-DELETE .... ESC-X ... Delete word under cursor.
+ ctrl-U ......... ESC (MS-DOS only) ....... Delete entire line.
+ UpArrow ........................ ESC-k ... Retrieve previous command line.
+ DownArrow ...................... ESC-j ... Retrieve next command line.
+ TAB ...................................... Complete filename & cycle.
+ SHIFT-TAB ...................... ESC-TAB   Complete filename & reverse cycle.
+ ctrl-L ................................... Complete filename, list all.
diff --git a/my_string_calculator.py b/my_string_calculator.py
new file mode 100644
index 0000000..b525ef2
--- /dev/null
+++ b/my_string_calculator.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
+
+        # 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()
\ No newline at end of file
diff --git a/other/student1/Calculator.py b/other/student1/Calculator.py
new file mode 100644
index 0000000..ddc60c6
--- /dev/null
+++ b/other/student1/Calculator.py
@@ -0,0 +1,152 @@
+import unittest
+from abc import ABC, abstractmethod #Daniel Rafeh
+
+
+class IStringCalculator(ABC):
+    @abstractmethod
+    def add(self, numbers: str) -> int: 
+        pass
+
+class StringCalculator(IStringCalculator):
+    def add(self, numbers: str) -> int: 
+
+        '''Leere Eingabe soll 0 ausgeben'''
+        if numbers == "":
+            return 0
+        
+        '''Standard-Trennzeichen'''
+        delimiter = ";"
+        
+        '''Es wird geprüft ob ein benutzerdefiniertes Trennzeichen vorhanden ist.'''
+        if numbers.startswith("//"):
+            sep = numbers.split("\n", 1) 
+            delimiter_sep = sep[0][2:]
+
+            '''Für den Fall, dass das Trennzeichen in eckigen Klammern steht werden die Klammern entfernt und das Trennzeichen gespeichert'''
+            if delimiter_sep.startswith("[") and delimiter_sep.endswith("]"):
+                delimiter = delimiter_sep[1:-1]
+
+            else:
+                delimiter = delimiter_sep[0]
+
+            '''Entfernen der ersten Zeile, damit nur noch Zahlen übrig bleiben'''
+            numbers = sep[1]
+
+        '''Ersetzen von Zeilenumbrüchen mit Delimiter und ersetzen von Delimiter durch ",", um splitten zu können'''
+        numbers = numbers.replace("\n", delimiter).replace(delimiter, ",")
+
+        list = numbers.split(",")
+        result = 0
+        
+        negative_numbers = []
+
+        for num in list:
+            num = num.strip()
+            if num == "":
+                continue
+
+            '''Sicherstellen dass Floats nicht berücksichtigt werden'''
+            if "." in num:
+                return "only integers allowed"
+            
+            '''Sicherstellen, dass keine Buchstaben verwendet werden dürfen'''
+            try:
+                number = int(num)
+            except ValueError:
+                return "only integers allowed"
+
+            '''Konvertirung von Strings zu Integer'''
+            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()
\ No newline at end of file
diff --git a/other/student1/__pycache__/Calculator.cpython-313.pyc b/other/student1/__pycache__/Calculator.cpython-313.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e4e08953a9e4aefe974df4cc26c82e769f8ca559
GIT binary patch
literal 8196
zcmd5>Yit|G5#D={JiaATZ%gv&5!-Y~QIssFwUe~9;zu1@Ms;E0R!Z3ub)xA|M|SUI
z$12jgFGq<`I7VtjMgIu>Wdr@up9b0=0onrnDS{2eT!U6X{#5^zNJR^yMLTnRNPH<N
zP}Ew0-|g+r?(ELa&dd$B-EIegGIHdT#3>&kALC1@Sc;YHUqIzPk%+{+NGLwp7nzGJ
zWiN7+6G;c@Clc31Bz~G5;|gOaZ?;;X)jG|WTP<d*4O)e1GU+NY+I^NOZPS8eKXsK5
z8CC_ffYqg+j1`+il3)@{z_E$%69LxXzH(;V@W?ZoPUW~hujtp(v+=#-%Uc_U*89MK
zG7_Pz#87UUm)L2G#7$dI@DkreuJa`})FxS|kgx`9M)OxCohH@9xSWbFq+~r!H*reC
zrY_9SC{#17RM8ix8fW)#WuT7o+2#T6lLUFlOgtp8TwYUBb5wv<4e3SExDr1#9o1kW
z6Q^HLwAb`>W*YVbOhfT9*N}2UPA$lKGObRh^=k?Rl7(4C)g#lpOB>4EGB|m5)@ZF+
z^$;{$kuR?PHrWtd+fX4Ck7goZH-uPBmFJaM%y7hF^Xb`z6xLm_*tZwtRI$e!i_Ime
zrl*psqNZapirX_dSgXM$Rh@eAwKW#gbXaFRChM??nFU?ZfE4-AW&{rcF2w{~j@A!w
zhvY5(EtavkS4Ou8JXS}y@v+SjYs)sa7lz}=iW9~~VA(zbP<g^|zC4_-rF6d33g>Dw
z&$X%MSn+z8M?>vUt2j?wq<Nli!>QdTQAT1+jfHbgu)T06RKO@RiRWHbBz~;edaT$Z
zgRTQD&R10=i)0-u>XFJtIf+Hal1&nLqVm9jugk$+!=W2E@RK;Wsz{C+T99Xym#mT#
zc(7M2P&c`nJK`iOPNFjA?rc?)!K-A6vZWPI*6EM3lB?9OG7Wa^Dy>PiNUUlN6V(>A
z_{oJRa2BG%BpydqDP2_TFP;U+?eZZ);56J(;WW_8&;s_t(+h1=&e8-?q0G$=yRu6x
zT0<E$GisYe1+FU5vUEkH_MZA_Vdl$UBjjo_<c2j`FTX;F6L?Lbew!s~D{+ym<_J)F
zscFhz+aH3aLEv514$ziFbJRLW`p8t-ZrX?pYA%w)=8opbbKGGv#{_(fJ(m=PD&ko%
z7V?ZDYUxx;92VsTEuqXPssWY`<~Nwri)=V-Fpf=_oor&;guzT1%&VLKhGH;5gBg0<
znpRV{M7YRG0_>3}r&8&g%53tlpsA1BR3!nI`i7#3YFaP#iH}?Bwg()B1B?LGwVO%(
znqkp0sibZQiaJ|puu&zGlH&^WfQiV^c3h<6WiW8cSxVE?u*#VXP#auIQE40W1{@Sb
zUAUiyeO5^&=aaeuc1Ke(hP(V8!&g3))O57V+CoY<no28-l`J*~6~kJ5!&@(wOTjpq
zcC4k^K%fOhHPUW?5O0$$D{=YXnOS}=?{C=<2J$WKOZE*Rns@rvojqA+&&uq&b0F&+
z$oo3q3*8H?@~d*rcWh}q-+g$M`PsSE$m+<-#ih$zJaJ!P^WN@t@6oLH=mT!u8_arx
zzv@|!oX<wi|AAYNT*^i+<+}q9`W~EF>ki+u1LvOO5Bjp*!FTK%uE~5`=Sttbxux?P
z!VP2=z878{d|=P{M%I0&vc6M~zW9DT=exLM+wivCedDb+R-~M_Z;8)0`<AR5hkDk8
zj*tEAur6Qgdx3j_cb|r;*9RNB^<h)ThU)^p#FrO8Y#-WiUD;wecle{u?iK0h9q(AT
z1mZrK_qMJu%ZvFYalPqiw&~~t>mQrK8_>uvzhTbc%euPXKKDt8v~=tY6PI_*dpPG5
zS0g#+VBY`qFXL+?XL3X1S^xN&Yy8jdp1l7!j9zm8V`qT0^nwd;hmH23Ee@WKH4F}Z
z+vR-W1pB)aj<c-g_Y4DAbYcR<Zi<(Twji`3p!S#wX1XWZfv;80s0-T=P#H8Fb%$)R
z&so~g6TxG3^zZm6_#dRJ@IQE^ux#G}sP;cygn|bGv|xmR{s+(|SpfwJ!Xs*z1VD#m
z2XsmfK$qkMbW1KkkK_jQN*=%_$qU#lH39mhW<bB>18kA}fUQysV4KuR+Y@bpcBADb
zMboQQc=JVAV!X6qTr`>j)3fzM<vy7z_mwPcl%&dS30NYK1z1y91``i3=B?C_LNxCV
z+-OCQW{j?S?1#+0OF*pQ3EU<hHTUJ32bTDsSWVehtPI_{xw3CU1$-`<glBcB>qVK8
z?FElR>Ulx%-({}_9)bk83EBfwo5u1XN56!1(+D_a4PrC>ECxXjS#z@n2Zp5>y%o0X
zfCxvADf1cqmT|c5zIO?(z|`6Rz-^NE`0mcVHFx*=Th~{7%jy!B7hLN?M^@-q@vq1q
z2;!5LiNQpuh@u!rI15m*ZI8LDw5m*)k+3n)c<W^%2`8!DzJED=@V39mMS>%nsDcdy
z&}s?*yaG7imu{vDV$h7^jpa~H3vmP49t5b=hSr?t@IjQvaBz%bkk>#SJ$2>r3Pb?k
zP-xm1`7h*B95aQ?AkZp&IXpr0u*i)LjnSix_ugdg{hF-Krj&E3w5%IXHQw$XvKUOM
zJq7R?8nD(o_JMHnNn3<PJ`xlc_me~O9ywf6bPUmse3l>zbn*I<Xv=xTio0+?Bw>j-
zMuMZ8_%+(#I<%RhfGdwT;EWu9O-sqzwF%?t#`35kPM}a~4Ma!I(_bN!1K}?g+0ZBr
zG!}^86i6u?H=}*cIM!Gim6Wg5*N>K*r?)~B2Sh(?;qYlk<n#!gXe^L|2Q7cR?B_wt
zMCtk((UtQIR*2zXXoPJfC`N{dBebuv6bhyj5_bz4m`?~5_A{M($TXO;j`Qryc?J%k
zB$~tFspH3wzv_qpj=*n}PB)fG;i}BT_iM6z^7~ztO3It4BQ;KCtuvJK41FHaV15$g
zp6x|||9$8^RZbL1oWzIOQn-$(kW#Y949hJOi`LL+Pz;@*m>${u7vw57{|WGr-;L4f
z3(!^g%Bu-c_lPl8vL>G?#xmu1U}9|qpwc(j7~i$tlfUslnt8wf(bZq~WP8tjAe?{V
zj@l-k5XGQ4wu#BJ1`evrw8vTo5;3tEMZc*iYB@&|Zfut84)`9jxrTr_uqPR*ImM#Q
z!QJl@t@fL{H!n^Ga@~*)iea)Uw#UL4&oq|8z5{;<GN|LWdvczmpXdJZFx<R<|CdkS
zMIK$1`R&_4QM{(8%n#g{uDq@rgN@~~OZ8@bA++Z_eFsnoY$Ukf$8Mh~0&q^n8&c4f
z!e%jtsV0n*jfJw`xaIm{s)=h3hC{c6;C7Ae7v&u?B~`Mv1vzEXS`w4T#&Ba9)gN&e
zrBma|R%(=}QPg*UTv-!dvk-)Yr!gWr4Y4vhHHy(aokzgXt~Sl$GUYj+d>#H}RE)mH
z0xXie3$tjW02N+qtuvVOgevY`Bew-fJxqX21Ul;GQ@;#-^gIG46DcONsD$t`!q*XA
zMfes1e$>%9gzE?y1RddZ1az?Uy9nP$_z^<A{Oq&Xfq)z}obwL(6#fw${M5=?`aTtE
z;2CT)!R+0w?Gj&L>WnK;{|yFTU`$75a>f5f=jEgti^2aI!h)KF&sz9{fs<$A6wNe6
zdtLZP6O+S+fM+x=L*md}I3}eH9w(^EI~&5Yg+E%Kr)UH)iK@K>0J(04`4jQ}g$(Ri
zA@9Ay?GSkEIG$(P*4mHl5P0sKVJ|Yw1!m<7>xY8bL%|(lzHVJ*3GZ53%yFH0-u33?
QA6)+Nl`W3&UFL571LRhAdH?_b

literal 0
HcmV?d00001

diff --git a/other/student2/Calculator.py b/other/student2/Calculator.py
new file mode 100644
index 0000000..05449ba
--- /dev/null
+++ b/other/student2/Calculator.py
@@ -0,0 +1,97 @@
+import unittest
+from abc import ABC, abstractmethod #Wasili
+
+#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()
\ No newline at end of file
diff --git a/other/student2/__pycache__/Calculator.cpython-313.pyc b/other/student2/__pycache__/Calculator.cpython-313.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..b8ea3ae8c73d007501c8384c94b321840b9e2cad
GIT binary patch
literal 6376
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

literal 0
HcmV?d00001

diff --git a/other/student3/Calculator.py b/other/student3/Calculator.py
new file mode 100644
index 0000000..e91cd9e
--- /dev/null
+++ b/other/student3/Calculator.py
@@ -0,0 +1,109 @@
+import unittest
+import re  #Momo
+
+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()
\ No newline at end of file
diff --git a/other/student3/__pycache__/Calculator.cpython-313.pyc b/other/student3/__pycache__/Calculator.cpython-313.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1394af73c7b584d4b136e8c64570dba56c2e12b0
GIT binary patch
literal 9362
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
T`_b7SoPG1$eU@+)=5GHD%4-8r

literal 0
HcmV?d00001

diff --git a/other/student4/Calculator.py b/other/student4/Calculator.py
new file mode 100644
index 0000000..e38e25f
--- /dev/null
+++ b/other/student4/Calculator.py
@@ -0,0 +1,127 @@
+import re 
+import unittest #Marvin
+
+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()
diff --git a/other/student4/__pycache__/Calculator.cpython-313.pyc b/other/student4/__pycache__/Calculator.cpython-313.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..12e1f492b290095e043cc3c3bafdf28c08c709b5
GIT binary patch
literal 8756
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

literal 0
HcmV?d00001

diff --git a/other/student5/Calculator_combined.py b/other/student5/Calculator_combined.py
new file mode 100644
index 0000000..09214d2
--- /dev/null
+++ b/other/student5/Calculator_combined.py
@@ -0,0 +1,96 @@
+from abc import ABC, abstractmethod
+import unittest #Orlandos test kombiniert aus 2 dateien,da fehlerhafte meldung mit scr hat anders nicht geklappt 
+
+
+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
+
+        delimiter = ","
+
+        if numbers.startswith("//"):
+            header, numbers = numbers.split("\n", 1)
+
+            if header.startswith("//[") and header.endswith("]"):
+                delimiter = header[3:-1]
+            else:
+                delimiter = header[2:]
+
+        numbers = numbers.replace("\n", ",")
+        numbers = numbers.replace(delimiter, ",")
+
+        number_list = numbers.split(",")
+        cleaned_numbers = [
+            int(n.strip()) for n in number_list if n.strip() != ""
+        ]
+
+        negatives = [n for n in cleaned_numbers if n < 0]
+        if negatives:
+            raise ValueError(f"negatives not allowed: {', '.join(map(str, negatives))}")
+
+        cleaned_numbers = [n for n in cleaned_numbers if n <= 1000]
+
+        return sum(cleaned_numbers)
+
+# --- TESTS ---
+class TestStringCalculator(unittest.TestCase):
+    def setUp(self):
+        self.calc = StringCalculator()
+
+    def test_add_empty_string(self):
+        self.assertEqual(self.calc.add(""), 0)
+
+    def test_add_single_number(self):
+        self.assertEqual(self.calc.add("1"), 1)
+
+    def test_add_two_numbers(self):
+        self.assertEqual(self.calc.add("1,2"), 3)
+
+    def test_add_multiple_numbers(self):
+        self.assertEqual(self.calc.add("1,2,3,4,5"), 15)
+
+    def test_add_ignores_empty_entries(self):
+        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(self):
+        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_negative_number(self):
+        with self.assertRaises(ValueError) as context:
+            self.calc.add("1,-2")
+        self.assertIn("negatives not allowed: -2", str(context.exception))
+
+    def test_multiple_negative_numbers(self):
+        with self.assertRaises(ValueError) as context:
+            self.calc.add("-1,-2,3")
+        self.assertIn("negatives not allowed: -1, -2", str(context.exception))
+
+    def test_custom_delimiter(self):
+        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_ignores_large_numbers(self):
+        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_multi_char_delimiter(self):
+        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()
diff --git a/other/student5/__pycache__/Calculator_combined.cpython-313.pyc b/other/student5/__pycache__/Calculator_combined.cpython-313.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..58da210273e9ccdba83d4985845021ab109a6672
GIT binary patch
literal 7779
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

literal 0
HcmV?d00001

diff --git a/other/student6/Calculator_combined.py b/other/student6/Calculator_combined.py
new file mode 100644
index 0000000..35f4531
--- /dev/null
+++ b/other/student6/Calculator_combined.py
@@ -0,0 +1,97 @@
+from abc import ABC, abstractmethod
+import re
+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
+
+        if numbers.startswith("//"):
+            if "\n" not in numbers:
+                raise ValueError("Ungültiges Format: Nicht vollständig")
+            delimiter_end_index = numbers.index("\n")
+            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, ",")
+
+        numbers = numbers.replace("\n", ",")
+
+        # Split the string by commas, convert each value to an integer, and sum them up
+        try:
+            numbers_list = list(map(int, numbers.split(",")))
+        except ValueError:
+            raise ValueError("Ungültiges Zahlenformat: Enthält nicht-numerische Werte")
+
+        negative_numbers = [num for num in numbers_list if num < 0]
+        if negative_numbers:
+            raise ValueError(f"Negative nicht erlaubt: {negative_numbers}")
+
+        numbers_list = [num for num in numbers_list if num <= 1000]
+
+        return sum(numbers_list)
+
+
+class TestStringCalculator(unittest.TestCase):
+    def setUp(self):
+        self.calculator: IStringCalculator = StringCalculator()  # Zugriff über das Interface
+
+    def test_add_empty_string(self):
+        self.assertEqual(self.calculator.add(""), 0)
+
+    def test_add_single_number(self):
+        self.assertEqual(self.calculator.add("1"), 1)
+
+    def test_add_two_numbers(self):
+        self.assertEqual(self.calculator.add("10,20"), 30)
+
+    def test_add_multiple_numbers(self):
+        self.assertEqual(self.calculator.add("1,2,3"), 6)
+        self.assertEqual(self.calculator.add("10,20,30,40"), 100)
+
+    def test_add_with_newline_separator(self):
+        self.assertEqual(self.calculator.add("1\n2,3"), 6)
+        self.assertEqual(self.calculator.add("10\n20\n30"), 60)
+
+    def test_add_single_negative_number(self):
+        with self.assertRaises(ValueError) as context:
+            self.calculator.add("1,-2,3")
+        self.assertEqual(str(context.exception), "Negative nicht erlaubt: [-2]")
+
+    def test_add_multiple_negative_numbers(self):
+        with self.assertRaises(ValueError) as context:
+            self.calculator.add("-10\n-20,-30")
+        self.assertEqual(str(context.exception), "Negative nicht erlaubt: [-10, -20, -30]")
+
+    def test_add_with_custom_delimiter(self):
+        self.assertEqual(self.calculator.add("//;\n1;2"), 3)
+        self.assertEqual(self.calculator.add("//x\n7x8\n9"), 24)
+
+    def test_invalid_custom_delimiter_format(self):
+        with self.assertRaises(ValueError) as context:
+            self.calculator.add("//;1;2")
+        self.assertTrue("Ungültiges Format" in str(context.exception))
+
+    def test_ignore_numbers_greater_than_1000(self):
+        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()
diff --git a/other/student6/__pycache__/Calculator_combined.cpython-313.pyc b/other/student6/__pycache__/Calculator_combined.cpython-313.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..63f3b5d384042ba48f47a641fd4dd097ec8a0620
GIT binary patch
literal 7719
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
J=<BpC{R^mK9q9l7

literal 0
HcmV?d00001

diff --git a/other/student7/Calculator.py b/other/student7/Calculator.py
new file mode 100644
index 0000000..b525ef2
--- /dev/null
+++ b/other/student7/Calculator.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
+
+        # 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()
\ No newline at end of file
diff --git a/other/student7/__pycache__/Calculator.cpython-313.pyc b/other/student7/__pycache__/Calculator.cpython-313.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f61d4aee076afc81ec36544859b8b4244ff90ae4
GIT binary patch
literal 6786
zcmd^ET}&I<6~5z{vBy8efFZ#ofFZw548+(ZSqPgSvdtzbkTB~cySO`b%s{*~V|r)U
zY*1E;Dm5jls@<y1E|pelc3&FQKG3J~n$<q^(a1rd>8f3|RaGigVlh>;ed;-5j{#$o
z-IwK|H{zQ+$LIc>pL@=kn`}jegFw63`{n4rU4;A%U(CkmJK0a5^N5H<WUi3Q3}r4`
zsKtlxmMbh}>qrX`*?J;!QKpm4jiH=D<$-FAas?`HP;EdJqU<27SKJDmwx}T5yKWK^
zt0n|^0gGD;>CBUSWYjWh@jI6B-EYy^bLV^YU9nrLMq_bpOxA9vhWq0i#}`C94%9~^
zN+=@|Y7rUAMmf<E<wZ7X4Raz_Pu}9pWvET$sW58w+w`hSqDB+SXm2bTpGd~E6kX<E
zCf%k?jNOu{s#~e7O;9Cn*{~`Debi4DSs#&6GQ;%G;C?w(PL5Cks4DXNeELAVD;iN@
zA_JorWc3GHYCH-8!J@74!m6$E+p*+COiQGcXiB>+Q(&1GmKE(}bbV`W<9Bs7Hax7?
zZrODkkWm*Z!hQ0E;L1XWP&7@y->wUiq{PN#NzxsXG?p5kNMhe5Nk5#3CG)?yC21r<
zRV|rNWF;j@)X)SAd)3*5qER=@rPoT5s=+?vQcMFOZcS*i3aq#etwPv^U^M}!P+I^V
zkR{%;Vqy4->Cg&+$Ky~IA6b@IYqChs4abq2EQ~W?%N_#QY+<l32lnMn`%){|)n?eW
za*J8*Fx)T=#oi`+BEhid=U~}KB*Gj40=8jzA7vuUAX>briI&bh)#Q#f5*Ry(GZi(F
zHF*_Fgb}%jg(C`kvs&a^fm0;##tc|QtHQ!~)1^1eA+iy+Gw*>4?#H&_$9xw!^7~P^
z2<IW!dDYSme&`{uHW8xmLnx)uBD~2d+Pb<xN|?E?hLBPmS1o<bggA+hD4fC<%?n0P
zMMS0x&a^QHM4$){BftfW5mp#sEokQ$tl%{FAVO3atT5l!pF`+mMjNU$dl9QCySeXO
zBvjD8%nW%7oSeyV03`RppTdu9==mM}6xBFsX>ZpV$1?VpQENIANc<BFH@T-@9tH1y
zTULEaO7q2%$<!TrxXU+b3HbaD-2uK&HT6zHyRCC031wKfQF%NWi_1E%jwcfu-Gj3^
zuESxLU!gQbb?&WHLebf=*f`ydzp?7XnBPWGcEcU@>R~yV7)xj}mGI<AGR$f(&~y$W
zk*c$Rx?M3hr=kP+axHh_jKf(|?DZHHFfXY80=Q59?B2cPsadfSmuJ!0Fz;-b9$s|r
zpLgzGYCiIteIM_8GMs4+rCp6nbxn_%bW1p0*Ew}*X?MeHaK15|ZtP6&KJoD47j=85
zF2Nk0`VZTG-v0Q&6MLq*W6HMV-u>RY58s`BJ>xz+#eHcd2mKj$&nFkA#ozVLvcG+G
zj++mh{)O;M_Wj-ugpV&wacOr?j;kh&T(iwH7e5r?2Yb3E{10c%->dhfn@-GXf4KYm
zyPtVJ6aVPXoO>;EGLk-VJ>764Q++e-y18a0m7e#*KfRk4>b_d7C6zCKwQ41`ooXG3
z`}B~f_W<{_#|`*twY}HRecEIN%*RB5Vk)BOI~1Is&{_mEkzqq4+EJXRIJVUz4FM07
zilZKo70X`Ui-8Ruk3-M#kqc+Y7l*$>%b!t_y$z(|a8^$!1T;V%6BdRuK$~a<6hz3j
z)Gi8u4$%(i6diyr(Fs@~x&U{H6@YGW7ht962CNb*Y4vE8zgn+(O;)vH_gFp*n~0lR
z!ad@NzyOwQ0eD1)3cs1TGeVLD+9+%S*!&hl9lB#Zoy{<YgR98uGaMAohpa`$_4-o#
zXfuApNTFgPxlcZ?KbolzOmRPR8*1FNMU0Qe7T<slL~BwiIs+9&DQYESD`UnCi0Jt-
zP=^pd+pj|<0W-|7x-+Ii64zeAY)L~v%ehAwdK+b|f@G*k^4Pd`7qTR#c>PdGdAIOE
za3pFoz<shLxE6)Fd7*B)=GRTXYFhLL=DmR@gBkDf+2#cyyrT+Xf)tVop)Vm6OJ8kB
zrGnH@T;%E}{cw5lH!-%oNPaQn4bBD^gwCCmf07LbI+oG-N^79f(13O)l^0*t50;mI
z16%M#(nm7h(CoDZ;pC1=ZwKiEp+Gp$xs2(iv<_+w9gIyRwZwSA4^;hVc|{cS8h*9i
zSs2QAUz+P!5MJI<ZSX+{Xk*zZbxWQHuc3+jhlGSRgQUoJFvsg{<+V|Y|0HNTyPZaE
zX1pinm<6G0M>S#xjW|M%u%nZHr>uYM->Q{$2gs>M)lYp*{cIW8^`es`WxPFebU`@3
zRa0n5BeDDyI^`0}P$8|DX~P1=JER-)I|as?tyGyV7SfIJ;SI(AdeVVe3Prj($Ht=h
z1~Z81v8b8**qpwaNr0H8H-5&9SbU_3_~2iExQA^bBMc<CNoz3B3Qj!fEmQWkcFfpx
zS1$Pt#uBQm(u1)4h7^bj&lR?I`JK2tj$g1d79;!Xws=a><af0E$8fF=sL9zsU&)$z
z!oQ8dH?#J@f@(hiWXg)F#frxHipGy7pH&=vGP>ldd~e|4z@n>Z-qrM2c;@myXUVQ(
z@G+cAs2_QzZ!9*n%{R1VyzS}WcNc`d=R7bhR2=<p7Au(#_MP*wPkoMaZMID%$N!;c
zK&%JPXoYA$*-+Lw0>0J|9Yha^pjGf_`10jmqhaO^=QH<NRY;7X@&+$E=sYg+bxiMk
z<_c_U`l}1VwSwvC>oD&odw+W+=A^B?z1tD&?w}~#b{RE3p=zlyY5l`+n~Yk_dl414
zUH*6@<2^M8)#d4}QSn>Ug*~qeM~Gf7tBn@Jv5F<!oL*0scdl&*;;P%`+3#h%-E&Zf
zo!L=6IosRsIfC~(?uG7!m+|wywBH=tMpNr&EPu~=_M57#c!s_g`PiEo@9DW)3&Ob_
z)t$8?5IlZ7Na3!ojM{RM%Phl2sT{+r8SQpVkznL;eVfQtcF<K^4K=i*vODm6b#%W#
z{;=UTWkt!IwBlo=Un=iE-*74s)f6{%<!6jyqu=i-d0&Iq60{rP3_>pgMmu^1VF2L<
z!Vton2r+~agakqoq0}`G{)YlZz&jEn>pUQ<a8KR3YGwFNgcAs-5Y8ZUBlI$>R+jH)
zRvj!q2*~g~NInZ>hCgp$_kRq6;R(h9csV~7ODK{AH;ioTR-9rLn!9}$CX|GR2FYEi
z<8_iQpsIUga3Nvr5wEdy4kswOsnUhhxtso%sR}#{{HfOfR#=8%{zCTuiMZD|mZ_L#
z*9bh;9Qzn=de4zH0?)P6t;|_w`qbjy!2I688o{@f?=ysRO-*K4?-J+wN#Bq9emt<k
J60Y75<$t()V$J{n

literal 0
HcmV?d00001

diff --git a/report.md b/report.md
new file mode 100644
index 0000000..e69de29
diff --git a/test_me_on_student1.py b/test_me_on_student1.py
new file mode 100644
index 0000000..fd33f2f
--- /dev/null
+++ b/test_me_on_student1.py
@@ -0,0 +1,50 @@
+import unittest
+from other.student1.Calculator import StringCalculator  # dani
+
+class TestMyCalcOnStudent1(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):
+            self.calculator.add("1,-2,3")
+
+    def test_multiple_negative_numbers(self):
+        with self.assertRaises(ValueError):
+            self.calculator.add("1,-2,-3,4")
+
+    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/test_me_on_student2.py b/test_me_on_student2.py
new file mode 100644
index 0000000..62056a3
--- /dev/null
+++ b/test_me_on_student2.py
@@ -0,0 +1,52 @@
+import unittest
+from other.student2.Calculator import StringCalculator  #wasili
+
+class TestMeOnStudent2(unittest.TestCase):
+    def setUp(self):
+        self.calc = StringCalculator()
+
+    def test_empty_string(self):
+        self.assertEqual(self.calc.add(""), 0)
+    
+    def test_single_number(self):
+        self.assertEqual(self.calc.add("1"), 1)
+    
+    def test_two_numbers(self):
+        self.assertEqual(self.calc.add("1,2"), 3)
+    
+    def test_multiple_numbers(self):
+        self.assertEqual(self.calc.add("1,2,3,4,5"), 15)
+    
+    def test_numbers_with_newline(self):
+        self.assertEqual(self.calc.add("1\n2,3"), 6)
+    
+    def test_numbers_with_multiple_newlines(self):
+        self.assertEqual(self.calc.add("1\n2\n3\n4\n5"), 15)
+    
+    def test_negative_number(self):
+        with self.assertRaises(ValueError) as context:
+            self.calc.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.calc.add("1,-2,-3,4")
+        self.assertEqual(str(context.exception), "negatives not allowed: -2, -3")
+    
+    def test_custom_delimiter(self):
+        self.assertEqual(self.calc.add("//;\n1;2"), 3)
+    
+    def test_custom_delimiter_with_newline(self):
+        self.assertEqual(self.calc.add("//;\n1;2\n3"), 6)
+    
+    def test_custom_delimiter_with_multiple_numbers(self):
+        self.assertEqual(self.calc.add("//|\n1|2|3|4"), 10)
+    
+    def test_numbers_greater_than_1000(self):
+        self.assertEqual(self.calc.add("2,1001"), 2)
+    
+    def test_numbers_greater_than_1000_with_custom_delimiter(self):
+        self.assertEqual(self.calc.add("//;\n2;1001"), 2)
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/test_me_on_student3.py b/test_me_on_student3.py
new file mode 100644
index 0000000..1219fa4
--- /dev/null
+++ b/test_me_on_student3.py
@@ -0,0 +1,49 @@
+import unittest
+from other.student3.Calculator import StringCalculator #momo
+
+class TestMyCasesOnStudent3(unittest.TestCase):
+    def setUp(self):
+        self.calc = StringCalculator()
+
+    def test_empty_string(self):
+        self.assertEqual(self.calc.add(""), 0)
+
+    def test_single_number(self):
+        self.assertEqual(self.calc.add("1"), 1)
+
+    def test_two_numbers(self):
+        self.assertEqual(self.calc.add("1,2"), 3)
+
+    def test_multiple_numbers(self):
+        self.assertEqual(self.calc.add("1,2,3,4,5"), 15)
+
+    def test_numbers_with_newline(self):
+        self.assertEqual(self.calc.add("1\n2,3"), 6)
+
+    def test_multiple_newlines(self):
+        self.assertEqual(self.calc.add("1\n2\n3\n4\n5"), 15)
+
+    def test_negative_number(self):
+        with self.assertRaises(ValueError) as e:
+            self.calc.add("1,-2,3")
+        self.assertEqual(str(e.exception), "negatives not allowed: -2")
+
+    def test_multiple_negative_numbers(self):
+        with self.assertRaises(ValueError) as e:
+            self.calc.add("1,-2,-3,4")
+        self.assertEqual(str(e.exception), "negatives not allowed: -2,-3")
+
+    def test_custom_delimiter(self):
+        self.assertEqual(self.calc.add("//;\n1;2"), 3)
+
+    def test_custom_delimiter_with_newline(self):
+        self.assertEqual(self.calc.add("//;\n1;2\n3"), 6)
+
+    def test_ignore_numbers_over_1000(self):
+        self.assertEqual(self.calc.add("2,1001"), 2)
+
+    def test_custom_delimiter_any_length(self):
+        self.assertEqual(self.calc.add("//[***]\n1***2***3"), 6)
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/test_me_on_student4.py b/test_me_on_student4.py
new file mode 100644
index 0000000..751d20e
--- /dev/null
+++ b/test_me_on_student4.py
@@ -0,0 +1,49 @@
+import unittest
+from other.student4.Calculator import StringCalculator  # Marvin
+
+class TestMyCasesOnStudent4(unittest.TestCase):
+    def setUp(self):
+        self.calc = StringCalculator()
+
+    def test_empty_string(self):
+        self.assertEqual(self.calc.add(""), 0)
+
+    def test_single_number(self):
+        self.assertEqual(self.calc.add("1"), 1)
+
+    def test_two_numbers(self):
+        self.assertEqual(self.calc.add("1,2"), 3)
+
+    def test_multiple_numbers(self):
+        self.assertEqual(self.calc.add("1,2,3,4,5"), 15)
+
+    def test_numbers_with_newline(self):
+        self.assertEqual(self.calc.add("1\n2,3"), 6)
+
+    def test_multiple_newlines(self):
+        self.assertEqual(self.calc.add("1\n2\n3\n4\n5"), 15)
+
+    def test_negative_number(self):
+        with self.assertRaises(ValueError) as e:
+            self.calc.add("1,-2,3")
+        self.assertEqual(str(e.exception), "Negative numbers are not allowed: -2")
+
+    def test_multiple_negative_numbers(self):
+        with self.assertRaises(ValueError) as e:
+            self.calc.add("1,-2,-3,4")
+        self.assertEqual(str(e.exception), "Negative numbers are not allowed: -2, -3")
+
+    def test_custom_delimiter(self):
+        self.assertEqual(self.calc.add("//;\n1;2"), 3)
+
+    def test_custom_delimiter_with_newline(self):
+        self.assertEqual(self.calc.add("//;\n1;2\n3"), 6)
+
+    def test_ignore_numbers_over_1000(self):
+        self.assertEqual(self.calc.add("2,1001"), 2)
+
+    def test_custom_delimiter_any_length(self):
+        self.assertEqual(self.calc.add("//[***]\n1***2***3"), 6)
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/test_me_on_student5.py b/test_me_on_student5.py
new file mode 100644
index 0000000..c66995b
--- /dev/null
+++ b/test_me_on_student5.py
@@ -0,0 +1,30 @@
+import unittest
+from other.student5.Calculator_combined import StringCalculator #orlando
+
+class TestMeOnStudent5(unittest.TestCase):
+    def setUp(self):
+        self.calc = StringCalculator()
+
+    def test_ignores_empty_entries(self):
+        self.assertEqual(self.calc.add("1,,2"), 3)
+        self.assertEqual(self.calc.add(",,1,,2,,"), 3)
+
+    def test_add_multi_char_delimiter(self):
+        self.assertEqual(self.calc.add("//[abc]\n4abc5abc6"), 15)
+
+    def test_newlines_mixed_with_commas(self):
+        self.assertEqual(self.calc.add("1,2\n3"), 6)
+
+    def test_single_number(self):
+        self.assertEqual(self.calc.add("5"), 5)
+
+    def test_custom_delimiters_varied(self):
+        self.assertEqual(self.calc.add("//_\n7_8_9"), 24)
+
+    def test_multiple_negatives(self):
+        with self.assertRaises(ValueError) as context:
+            self.calc.add("-1,-2")
+        self.assertIn("negatives not allowed", str(context.exception))
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/test_me_on_student6.py b/test_me_on_student6.py
new file mode 100644
index 0000000..9e6e723
--- /dev/null
+++ b/test_me_on_student6.py
@@ -0,0 +1,53 @@
+import unittest
+from other.student6.Calculator_combined import StringCalculator  #lasse
+
+class TestStudent6OnMe(unittest.TestCase):
+    def setUp(self):
+        self.calc = StringCalculator()
+
+    def test_add_empty_string(self):
+        self.assertEqual(self.calc.add(""), 0)
+
+    def test_add_single_number(self):
+        self.assertEqual(self.calc.add("1"), 1)
+
+    def test_add_two_numbers(self):
+        self.assertEqual(self.calc.add("10,20"), 30)
+
+    def test_add_multiple_numbers(self):
+        self.assertEqual(self.calc.add("1,2,3"), 6)
+        self.assertEqual(self.calc.add("10,20,30,40"), 100)
+
+    def test_add_with_newline_separator(self):
+        self.assertEqual(self.calc.add("1\n2,3"), 6)
+        self.assertEqual(self.calc.add("10\n20\n30"), 60)
+
+    def test_add_single_negative_number(self):
+        with self.assertRaises(ValueError) as context:
+            self.calc.add("1,-2,3")
+        self.assertEqual(str(context.exception), "Negative nicht erlaubt: [-2]")
+
+    def test_add_multiple_negative_numbers(self):
+        with self.assertRaises(ValueError) as context:
+            self.calc.add("-10\n-20,-30")
+        self.assertEqual(str(context.exception), "Negative nicht erlaubt: [-10, -20, -30]")
+
+    def test_add_with_custom_delimiter(self):
+        self.assertEqual(self.calc.add("//;\n1;2"), 3)
+        self.assertEqual(self.calc.add("//x\n7x8\n9"), 24)
+
+    def test_invalid_custom_delimiter_format(self):
+        with self.assertRaises(ValueError):
+            self.calc.add("//;1;2")
+
+    def test_ignore_numbers_greater_than_1000(self):
+        self.assertEqual(self.calc.add("2,1001"), 2)
+        self.assertEqual(self.calc.add("1002,50200"), 0)
+
+    def test_add_with_custom_delimiter_multiple_characters(self):
+        self.assertEqual(self.calc.add("//[**]\n1**2**3"), 6)
+        self.assertEqual(self.calc.add("//[###]\n10###20###30"), 60)
+
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/test_me_on_student7.py b/test_me_on_student7.py
new file mode 100644
index 0000000..e320a61
--- /dev/null
+++ b/test_me_on_student7.py
@@ -0,0 +1,23 @@
+import unittest
+from other.student7.Calculator import StringCalculator  # Student 7s Code wird getestet
+
+class TestMeOnStudent7(unittest.TestCase):
+    def setUp(self):
+        self.calc = StringCalculator()
+
+    def test_empty_string(self):
+        self.assertEqual(self.calc.add(""), 0)
+
+    def test_custom_delimiter(self):
+        self.assertEqual(self.calc.add("//|\n1|2|3|4"), 10)
+
+    def test_newlines_and_large_numbers(self):
+        self.assertEqual(self.calc.add("1\n2,1001"), 3)
+
+    def test_negative_handling(self):
+        with self.assertRaises(ValueError) as context:
+            self.calc.add("1,-2,-3")
+        self.assertEqual(str(context.exception), "Negatives not allowed: -2, -3")
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/test_student1_on_me.py b/test_student1_on_me.py
new file mode 100644
index 0000000..41a50da
--- /dev/null
+++ b/test_student1_on_me.py
@@ -0,0 +1,69 @@
+import unittest
+from my_string_calculator import StringCalculator 
+
+class TestStudent1OnMyCalc(unittest.TestCase):
+    def setUp(self):
+        self.c = StringCalculator()
+
+    def test_empty(self):
+        self.assertEqual(self.c.add(""), 0)
+
+    def test_oneNumber(self):
+        self.assertEqual(self.c.add("1"), 1)
+    
+    def test_addingTwoNumbers(self):
+        self.assertEqual(self.c.add("1,2"), 3)
+
+    def test_addingTwoNumbersWithZero(self):
+        self.assertEqual(self.c.add("0,5"), 5)
+
+    def test_handleFloat(self):
+        with self.assertRaises(Exception):
+            self.c.add("3.5")
+
+    def test_handleLetter(self):
+        with self.assertRaises(Exception):
+            self.c.add("1, z")
+
+    def test_addWithBackslashN(self):
+        self.assertEqual(self.c.add("1\n2,3"), 6)
+
+    def test_negativeValues(self):
+        with self.assertRaises(ValueError):
+            self.c.add("-3")
+
+    def test_delimiter(self):
+        self.assertEqual(self.c.add("//;\n1;2"), 3)
+
+    def test_thousandone(self):
+        self.assertEqual(self.c.add("2, 1001"), 2)
+
+    def test_multidelimiter(self):
+        self.assertEqual(self.c.add("//[***]\n1***2***3"), 6)
+
+    def test_multi_negative(self):
+        with self.assertRaises(ValueError):
+            self.c.add("-3, -4")
+
+    def test_space_between_numbers(self):
+        self.assertEqual(self.c.add(" 4  , 5"), 9)
+
+    def test_multiple_num_with_thousandone(self):
+        self.assertEqual(self.c.add(" 2, 1001, 5"), 7)
+
+    def test_empty_text(self):
+        self.assertEqual(self.c.add("//;\n"), 0)
+
+    def test_one_number_with_empty_string(self):
+        self.assertEqual(self.c.add("1,"), 1)
+
+    def test_negative_with_positive(self):
+        with self.assertRaises(ValueError):
+            self.c.add("-2, 5")
+
+    def test_mixture(self):
+        with self.assertRaises(ValueError):
+            self.c.add("//;\n-1;2;1001;-3")
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/test_student2_on_me.py b/test_student2_on_me.py
new file mode 100644
index 0000000..ad6d014
--- /dev/null
+++ b/test_student2_on_me.py
@@ -0,0 +1,47 @@
+import unittest
+from my_string_calculator import StringCalculator  # Wasili
+
+class TestStudent2OnMe(unittest.TestCase):
+    def setUp(self):
+        self.calc = StringCalculator()
+
+    def test_add_empty(self):
+        self.assertEqual(self.calc.add(""), 0)
+
+    def test_add_one_string(self):
+        self.assertEqual(self.calc.add("1"), 1)
+
+    def test_add_two_string(self):
+        self.assertEqual(self.calc.add("1,2"), 3)
+
+    def test_add_multiple_string(self):
+        self.assertEqual(self.calc.add("1,2,3,4,5,6,7"), 28)
+
+    def test_add_new_lines(self):
+        self.assertEqual(self.calc.add("1\n2,3,4"), 10)
+
+    def test_add_exception(self):
+        with self.assertRaises(ValueError) as context:
+            self.calc.add("-5")
+        self.assertEqual(str(context.exception), "Negatives not allowed: -5")
+
+    def test_add_negative_numbers(self):
+        with self.assertRaises(ValueError) as context:
+            self.calc.add("-5,-2,-2")
+        self.assertEqual(str(context.exception), "Negatives not allowed: -5, -2, -2")
+
+    def test_add_different_delimiters(self):
+        self.assertEqual(self.calc.add("//;\n1;2"), 3)
+
+    def test_add_numbers_greater_than_1000(self):
+        self.assertEqual(self.calc.add("2,1001"), 2)
+        self.assertEqual(self.calc.add("2,10022\n6"), 8)
+
+    def test_delimiters_of_any_length(self):
+        self.assertEqual(self.calc.add("//[***]\n1***2***3"), 6)
+
+    def test_delimiters_of_any_length2(self):
+        self.assertEqual(self.calc.add("//[*+*+*]\n1*+*+*2*+*+*3*+*+*220"), 226)
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/test_student3_on_me.py b/test_student3_on_me.py
new file mode 100644
index 0000000..a498fc0
--- /dev/null
+++ b/test_student3_on_me.py
@@ -0,0 +1,49 @@
+import unittest
+from my_string_calculator import StringCalculator #Momo
+
+class TestStudent3CasesOnMe(unittest.TestCase):
+    def setUp(self):
+        self.calc = StringCalculator()
+
+    def test_empty_string(self):
+        self.assertEqual(self.calc.add(""), 0)
+
+    def test_single_number(self):
+        self.assertEqual(self.calc.add("5"), 5)
+
+    def test_multiple_numbers(self):
+        self.assertEqual(self.calc.add("5,5"), 10)
+
+    def test_unknown_amount_of_numbers(self):
+        self.assertEqual(self.calc.add("1,2,3"), 6)
+        self.assertEqual(self.calc.add("10,20,30,40"), 100)
+        self.assertEqual(self.calc.add("1,2,3,4,5,6"), 21)
+
+    def test_numbers_separated_by_newline(self):
+        self.assertEqual(self.calc.add("1\n2"), 3)
+        self.assertEqual(self.calc.add("1\n2\n3"), 6)
+        self.assertEqual(self.calc.add("10,20\n30"), 60)
+
+    def test_negative_number_exception(self):
+        with self.assertRaises(ValueError) as e:
+            self.calc.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.calc.add("-1,-2,3")
+        self.assertEqual(str(e.exception), "Negatives not allowed: -1, -2")
+
+    def test_add_numbers_with_custom_delimiter(self):
+        self.assertEqual(self.calc.add("//;\n1;2;3"), 6)
+
+    def test_ignore_numbers_over_1000(self):
+        self.assertEqual(self.calc.add("1,1001,2,3"), 6)
+
+    def test_custom_delimiter_with_long_pattern(self):
+        self.assertEqual(self.calc.add("//[***]\n1***2***3"), 6)
+        self.assertEqual(self.calc.add("//[+++]\n1+++2+++3"), 6)
+        self.assertEqual(self.calc.add("//[aa]\n1aa2aa3"), 6)
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/test_student4_on_me.py b/test_student4_on_me.py
new file mode 100644
index 0000000..70cde1e
--- /dev/null
+++ b/test_student4_on_me.py
@@ -0,0 +1,55 @@
+import unittest
+from my_string_calculator import StringCalculator 
+
+class TestStudent4CasesOnMe(unittest.TestCase):
+    def setUp(self):
+        self.calculator = StringCalculator()
+
+    def test_empty_string_returns_zero(self):
+        self.assertEqual(self.calculator.add(""), 0)
+
+    def test_single_number_returns_value(self):
+        self.assertEqual(self.calculator.add("1"), 1)
+
+    def test_two_numbers_return_sum(self):
+        self.assertEqual(self.calculator.add("1,2"), 3)
+
+    def test_add_multiple_numbers(self):
+        self.assertEqual(self.calculator.add("1,2,3,4,5"), 15)
+
+    def test_add_numbers_with_newlines(self):
+        self.assertEqual(self.calculator.add("1\n2\n3"), 6)
+
+    def test_add_negative_numbers(self):
+        with self.assertRaises(ValueError) as e:
+            self.calculator.add("-1,2,-3")
+        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)
+
+    def test_add_numbers_with_custom_delimiter_different_symbol(self):
+        self.assertEqual(self.calculator.add("//#\n4#5#6"), 15)
+
+    def test_custom_delimiter_with_multiple_numbers(self):
+        self.assertEqual(self.calculator.add("//:\n1:2:3:4:5:6"), 21)
+
+    def test_add_numbers_greater_than_1000(self):
+        self.assertEqual(self.calculator.add("1,1001,2,3"), 6)
+
+    def test_add_numbers_with_newlines_and_ignore_above_1000(self):
+        self.assertEqual(self.calculator.add("1\n2\n1000\n1001"), 1003)
+
+    def test_add_numbers_with_custom_delimiter_long_length(self):
+        self.assertEqual(self.calculator.add("//[***]\n1***2***3"), 6)
+
+    def test_custom_long_delimiter_with_large_number_ignored(self):
+        self.assertEqual(self.calculator.add("//[***]\n1***1001***2"), 3)
+
+    def test_custom_long_delimiter_with_negative_numbers(self):
+        with self.assertRaises(ValueError) as e:
+            self.calculator.add("//[***]\n1***-2***3***-4")
+        self.assertEqual(str(e.exception), "Negatives not allowed: -2, -4")
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/test_student5_on_me.py b/test_student5_on_me.py
new file mode 100644
index 0000000..f612723
--- /dev/null
+++ b/test_student5_on_me.py
@@ -0,0 +1,57 @@
+import unittest
+from my_string_calculator import StringCalculator  
+
+class TestStudent5OnMyCode(unittest.TestCase):
+    def setUp(self):
+        self.calc = StringCalculator()
+
+    def test_add_empty_string(self):
+        self.assertEqual(self.calc.add(""), 0)
+
+    def test_add_single_number(self):
+        self.assertEqual(self.calc.add("1"), 1)
+
+    def test_add_two_numbers(self):
+        self.assertEqual(self.calc.add("1,2"), 3)
+
+    def test_add_multiple_numbers(self):
+        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):
+        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):
+        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):
+        with self.assertRaises(ValueError) as context:
+            self.calc.add("1,-2")
+        self.assertIn("Negatives not allowed", str(context.exception))
+
+    def test_add_raises_exception_on_multiple_negatives(self):
+        with self.assertRaises(ValueError) as context:
+            self.calc.add("-1,-2,3")
+        self.assertIn("Negatives not allowed", str(context.exception))
+
+    def test_add_with_custom_delimiter(self):
+        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):
+        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):
+        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()
diff --git a/test_student6_on_me.py b/test_student6_on_me.py
new file mode 100644
index 0000000..f21ca8b
--- /dev/null
+++ b/test_student6_on_me.py
@@ -0,0 +1,53 @@
+import unittest
+from my_string_calculator import StringCalculator  # lasse
+
+class TestStudent6OnMe(unittest.TestCase):
+    def setUp(self):
+        self.calc = StringCalculator()
+
+    def test_add_empty_string(self):
+        self.assertEqual(self.calc.add(""), 0)
+
+    def test_add_single_number(self):
+        self.assertEqual(self.calc.add("1"), 1)
+
+    def test_add_two_numbers(self):
+        self.assertEqual(self.calc.add("10,20"), 30)
+
+    def test_add_multiple_numbers(self):
+        self.assertEqual(self.calc.add("1,2,3"), 6)
+        self.assertEqual(self.calc.add("10,20,30,40"), 100)
+
+    def test_add_with_newline_separator(self):
+        self.assertEqual(self.calc.add("1\n2,3"), 6)
+        self.assertEqual(self.calc.add("10\n20\n30"), 60)
+
+    def test_add_single_negative_number(self):
+        with self.assertRaises(ValueError) as context:
+            self.calc.add("1,-2,3")
+        self.assertEqual(str(context.exception), "Negative nicht erlaubt: [-2]")
+
+    def test_add_multiple_negative_numbers(self):
+        with self.assertRaises(ValueError) as context:
+            self.calc.add("-10\n-20,-30")
+        self.assertEqual(str(context.exception), "Negative nicht erlaubt: [-10, -20, -30]")
+
+    def test_add_with_custom_delimiter(self):
+        self.assertEqual(self.calc.add("//;\n1;2"), 3)
+        self.assertEqual(self.calc.add("//x\n7x8\n9"), 24)
+
+    def test_invalid_custom_delimiter_format(self):
+        with self.assertRaises(ValueError):
+            self.calc.add("//;1;2")
+
+    def test_ignore_numbers_greater_than_1000(self):
+        self.assertEqual(self.calc.add("2,1001"), 2)
+        self.assertEqual(self.calc.add("1002,50200"), 0)
+
+    def test_add_with_custom_delimiter_multiple_characters(self):
+        self.assertEqual(self.calc.add("//[**]\n1**2**3"), 6)
+        self.assertEqual(self.calc.add("//[###]\n10###20###30"), 60)
+
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/test_student7_on_me.py b/test_student7_on_me.py
new file mode 100644
index 0000000..626f263
--- /dev/null
+++ b/test_student7_on_me.py
@@ -0,0 +1,35 @@
+import unittest
+from my_string_calculator import StringCalculator  # Hatice und ich hatten den selben code
+
+class TestStudent7OnMe(unittest.TestCase):
+    def setUp(self):
+        self.calc = StringCalculator()
+
+    def test_empty_string(self):
+        self.assertEqual(self.calc.add(""), 0)
+
+    def test_single_number(self):
+        self.assertEqual(self.calc.add("1"), 1)
+
+    def test_two_numbers(self):
+        self.assertEqual(self.calc.add("1,2"), 3)
+
+    def test_multiple_numbers(self):
+        self.assertEqual(self.calc.add("1,2,3,4,5"), 15)
+
+    def test_numbers_with_newline(self):
+        self.assertEqual(self.calc.add("1\n2,3"), 6)
+
+    def test_negative_number(self):
+        with self.assertRaises(ValueError) as e:
+            self.calc.add("1,-2")
+        self.assertEqual(str(e.exception), "Negatives not allowed: -2")
+
+    def test_custom_delimiter(self):
+        self.assertEqual(self.calc.add("//;\n1;2"), 3)
+
+    def test_large_numbers_ignored(self):
+        self.assertEqual(self.calc.add("2,1001"), 2)
+
+if __name__ == "__main__":
+    unittest.main()
-- 
GitLab