From 48b83fbfb8c422fa9254deb50a510518e6e0c2b1 Mon Sep 17 00:00:00 2001 From: Mithun Dutta Date: Mon, 16 Mar 2026 15:02:39 +0530 Subject: [PATCH 01/17] Add skeleton functions and test structure for complex numbers --- complex.py | 0 test_complex.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 complex.py create mode 100644 test_complex.py diff --git a/complex.py b/complex.py new file mode 100644 index 0000000..e69de29 diff --git a/test_complex.py b/test_complex.py new file mode 100644 index 0000000..e69de29 From 19b067d5053624e8d41c13d2bb7bde5c8e999586 Mon Sep 17 00:00:00 2001 From: Mithun Dutta Date: Mon, 16 Mar 2026 15:11:48 +0530 Subject: [PATCH 02/17] Add skeleton functions and test structure for complex numbers --- complex.py | 55 +++++++++++++++++++++++++++++++++++++++++++++++ test_complex.py | 57 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) diff --git a/complex.py b/complex.py index e69de29..7f5d58f 100644 --- a/complex.py +++ b/complex.py @@ -0,0 +1,55 @@ +# complex.py + +def parse_complex_string(expression): + """ + Member 1: Parses an input string like '(3 + 2j) * (5+ 3j)'[cite: 119]. + Extracts the two complex numbers and the mathematical operator. + Must support the standard a + bj representation[cite: 121]. + """ + pass + +def add_complex(c1, c2): + """ + Member 2: Handles the addition of two complex numbers[cite: 120]. + """ + pass + +def subtract_complex(c1, c2): + """ + Member 2: Handles the subtraction of c2 from c1[cite: 120]. + """ + pass + +def multiply_complex(c1, c2): + """ + Member 3: Handles the multiplication of two complex numbers[cite: 120]. + """ + pass + +def divide_complex(c1, c2): + """ + Member 3: Handles the division of c1 by c2[cite: 120]. + Must include error handling for division by zero. + """ + pass + +def compute_magnitude(c): + """ + Member 4: Calculates the magnitude of a single complex number[cite: 122]. + """ + pass + +def compute_phase(c): + """ + Member 4: Calculates the phase (angle) of a single complex number[cite: 122]. + """ + pass + +def evaluate_complex_expression(expression): + """ + Member 5 (Integrator): The main runner function. + Takes the raw string, passes it to parse_complex_string, + routes the parsed data to the correct math function above, + and returns the final string result. + """ + pass \ No newline at end of file diff --git a/test_complex.py b/test_complex.py index e69de29..ac71034 100644 --- a/test_complex.py +++ b/test_complex.py @@ -0,0 +1,57 @@ +# test_complex.py +import unittest +from complex import ( + parse_complex_string, add_complex, subtract_complex, + multiply_complex, divide_complex, compute_magnitude, + compute_phase, evaluate_complex_expression +) + +class TestComplexArithmetic(unittest.TestCase): + + # --- Member 1 Tests --- + def test_parse_complex_string_valid(self): + # Test normal valid strings here + pass + + def test_parse_complex_string_invalid(self): + # Test malformed strings or missing brackets here + pass + + # --- Member 2 Tests --- + def test_add_complex(self): + # Test normal addition and negative addition + pass + + def test_subtract_complex(self): + # Test normal subtraction + pass + + # --- Member 3 Tests --- + def test_multiply_complex(self): + # Lab manual example test case + self.assertEqual(multiply_complex('1+2j', '3+4j'), '-5+10j') + + def test_divide_complex(self): + # Test normal division + pass + + def test_divide_complex_by_zero(self): + # Test division by zero exception handling + pass + + # --- Member 4 Tests --- + def test_compute_magnitude(self): + # Test magnitude calculations + pass + + def test_compute_phase(self): + # Test phase calculations (check against known angles) + pass + + # --- Member 5 Tests (Integration) --- + def test_evaluate_complex_expression(self): + # Test the full pipeline from raw string to final output + pass + +if __name__ == "__main__": + unittest.main() \ No newline at end of file From f3b5eddb4ac763710a04e189750dfdfe79737431 Mon Sep 17 00:00:00 2001 From: Prashant Batchu Date: Mon, 16 Mar 2026 15:54:21 +0530 Subject: [PATCH 03/17] added test compute and magnitude --- complex.py | 9 ++++++--- test_complex.py | 20 ++++++++++++-------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/complex.py b/complex.py index 7f5d58f..1ce2a6f 100644 --- a/complex.py +++ b/complex.py @@ -1,5 +1,5 @@ # complex.py - +import cmath def parse_complex_string(expression): """ Member 1: Parses an input string like '(3 + 2j) * (5+ 3j)'[cite: 119]. @@ -12,6 +12,7 @@ def add_complex(c1, c2): """ Member 2: Handles the addition of two complex numbers[cite: 120]. """ + pass def subtract_complex(c1, c2): @@ -37,13 +38,15 @@ def compute_magnitude(c): """ Member 4: Calculates the magnitude of a single complex number[cite: 122]. """ - pass + z = complex(c.replace(" ", "")) + return abs(z) def compute_phase(c): """ Member 4: Calculates the phase (angle) of a single complex number[cite: 122]. """ - pass + z = complex(c.replace(" ", "")) + return cmath.phase(z) def evaluate_complex_expression(expression): """ diff --git a/test_complex.py b/test_complex.py index ac71034..853171d 100644 --- a/test_complex.py +++ b/test_complex.py @@ -5,7 +5,7 @@ multiply_complex, divide_complex, compute_magnitude, compute_phase, evaluate_complex_expression ) - +import math class TestComplexArithmetic(unittest.TestCase): # --- Member 1 Tests --- @@ -35,14 +35,18 @@ def test_divide_complex(self): # Test normal division pass - def test_divide_complex_by_zero(self): - # Test division by zero exception handling - pass - - # --- Member 4 Tests --- def test_compute_magnitude(self): - # Test magnitude calculations - pass + # Test magnitude calculations + self.assertAlmostEqual(compute_magnitude('3+4j'), 5.0) + self.assertAlmostEqual(compute_magnitude('1+0j'), 1.0) + self.assertAlmostEqual(compute_magnitude('0+2j'), 2.0) + + + def test_compute_phase(self): + # Test phase calculations (check against known angles) + self.assertAlmostEqual(compute_phase('1+0j'), 0.0) + self.assertAlmostEqual(compute_phase('0+1j'), math.pi/2) + self.assertAlmostEqual(compute_phase('-1+0j'), math.pi) def test_compute_phase(self): # Test phase calculations (check against known angles) From ca3b822e4c5f905c6fa11529bbf30c147b63baf0 Mon Sep 17 00:00:00 2001 From: Prashant Batchu Date: Mon, 16 Mar 2026 15:55:02 +0530 Subject: [PATCH 04/17] added test compute and magnitude. --- test_complex.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/test_complex.py b/test_complex.py index 853171d..7d276de 100644 --- a/test_complex.py +++ b/test_complex.py @@ -48,9 +48,6 @@ def test_compute_phase(self): self.assertAlmostEqual(compute_phase('0+1j'), math.pi/2) self.assertAlmostEqual(compute_phase('-1+0j'), math.pi) - def test_compute_phase(self): - # Test phase calculations (check against known angles) - pass # --- Member 5 Tests (Integration) --- def test_evaluate_complex_expression(self): From 3717a410b2783eae4f456f0522814b507aa94800 Mon Sep 17 00:00:00 2001 From: Billionaire25 Date: Mon, 16 Mar 2026 16:12:42 +0530 Subject: [PATCH 05/17] Added multiplication, division and test cases --- complex.py | 29 +++++++++++++++++++++++++--- test_complex.py | 50 ++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 71 insertions(+), 8 deletions(-) diff --git a/complex.py b/complex.py index 7f5d58f..63c52b4 100644 --- a/complex.py +++ b/complex.py @@ -1,4 +1,5 @@ # complex.py +from calculator import Calculator def parse_complex_string(expression): """ @@ -24,14 +25,36 @@ def multiply_complex(c1, c2): """ Member 3: Handles the multiplication of two complex numbers[cite: 120]. """ - pass + + # c1 and c2 are tuples: (real, imag) + calc = Calculator() + a, b = c1 + c, d = c2 + # (a+bi)*(c+di) = (ac - bd) + (ad + bc)i + real_part = calc.subtract(calc.multiply(a, c), calc.multiply(b, d)) + imag_part = calc.add(calc.multiply(a, d), calc.multiply(b, c)) + return (real_part, imag_part) def divide_complex(c1, c2): """ Member 3: Handles the division of c1 by c2[cite: 120]. Must include error handling for division by zero. """ - pass + # c1 and c2 are tuples: (real, imag) + calc = Calculator() + a, b = c1 + c, d = c2 + # denominator = c^2 + d^2 + denominator = calc.add(calc.multiply(c, c), calc.multiply(d, d)) + if denominator == 0: + raise ValueError("Division by zero in complex division") + # real part: (ac + bd) / (c^2 + d^2) + real_num = calc.add(calc.multiply(a, c), calc.multiply(b, d)) + real_part = calc.divide(real_num, denominator) + # imag part: (bc - ad) / (c^2 + d^2) + imag_num = calc.subtract(calc.multiply(b, c), calc.multiply(a, d)) + imag_part = calc.divide(imag_num, denominator) + return (real_part, imag_part) def compute_magnitude(c): """ @@ -52,4 +75,4 @@ def evaluate_complex_expression(expression): routes the parsed data to the correct math function above, and returns the final string result. """ - pass \ No newline at end of file + \ No newline at end of file diff --git a/test_complex.py b/test_complex.py index ac71034..aea19a0 100644 --- a/test_complex.py +++ b/test_complex.py @@ -27,17 +27,57 @@ def test_subtract_complex(self): pass # --- Member 3 Tests --- + def test_multiply_complex(self): - # Lab manual example test case - self.assertEqual(multiply_complex('1+2j', '3+4j'), '-5+10j') + # Normal cases + self.assertEqual(multiply_complex((3, 2), (5, 3)), (9, 19)) # (3+2j)*(5+3j) = (3*5-2*3, 3*3+2*5) = (15-6, 9+10) = (9, 19) + self.assertEqual(multiply_complex((0, 0), (5, 3)), (0, 0)) # Zero times anything + self.assertEqual(multiply_complex((1, 0), (0, 1)), (0, 1)) # (1+0j)*(0+1j) = (0, 1) + self.assertEqual(multiply_complex((2, -3), (-1, 4)), (10, 11)) # (2-3j)*(-1+4j) = (2*-1-(-3)*4, 2*4+(-3)*-1) = (-2+12, 8+3) = (10, 11) + + # Boundary cases + self.assertEqual(multiply_complex((0, 0), (0, 0)), (0, 0)) # Both zero + self.assertEqual(multiply_complex((999999, 0), (0, 999999)), (0, 999999*999999)) + self.assertEqual(multiply_complex((-1, -1), (-1, -1)), (0, 2)) + + # Invalid input handling + with self.assertRaises(TypeError): + multiply_complex((1,), (2, 3)) # Too few elements + with self.assertRaises(TypeError): + multiply_complex((1, 2, 3), (2, 3)) # Too many elements + with self.assertRaises(TypeError): + multiply_complex((1, 'a'), (2, 3)) # Non-numeric + with self.assertRaises(TypeError): + multiply_complex('not a tuple', (2, 3)) + def test_divide_complex(self): - # Test normal division - pass + # Normal cases + self.assertEqual(divide_complex((3, 2), (5, 3)), (0.6341463414634146, 0.04878048780487805)) + self.assertEqual(divide_complex((0, 0), (5, 3)), (0.0, 0.0)) + self.assertEqual(divide_complex((1, 0), (1, 0)), (1.0, 0.0)) + self.assertEqual(divide_complex((2, -3), (-1, 4)), (-0.6470588235294118, -0.5294117647058824)) + + # Boundary cases + self.assertEqual(divide_complex((0, 0), (0, 1)), (0.0, 0.0)) + self.assertEqual(divide_complex((999999, 0), (0, 999999)), (0.0, -1.0)) + self.assertEqual(divide_complex((-1, -1), (-1, -1)), (1.0, 0.0)) + + # Invalid input handling + with self.assertRaises(TypeError): + divide_complex((1,), (2, 3)) # Too few elements + with self.assertRaises(TypeError): + divide_complex((1, 2, 3), (2, 3)) # Too many elements + with self.assertRaises(TypeError): + divide_complex((1, 'a'), (2, 3)) # Non-numeric + with self.assertRaises(TypeError): + divide_complex('not a tuple', (2, 3)) + def test_divide_complex_by_zero(self): # Test division by zero exception handling - pass + with self.assertRaises(ValueError): + divide_complex((1, 2), (0, 0)) # --- Member 4 Tests --- def test_compute_magnitude(self): From b9d2a2873981370eeffb457851ccb5b04e9a655a Mon Sep 17 00:00:00 2001 From: Mithun Dutta Date: Thu, 19 Mar 2026 00:03:41 +0530 Subject: [PATCH 06/17] Implement parsar and unit test --- complex.py | 27 ++++++++++++++++++++++++--- test_complex.py | 13 ++++++++----- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/complex.py b/complex.py index 7f5d58f..94e0d23 100644 --- a/complex.py +++ b/complex.py @@ -1,12 +1,33 @@ # complex.py +import re +import cmath + +def _format_complex(c): + """ + Helper function to format a Python complex object back into a + clean 'a+bj' string without parentheses to match lab requirements. + """ + res = str(c).replace(' ', '') + if res.startswith('(') and res.endswith(')'): + res = res[1:-1] + return res def parse_complex_string(expression): """ - Member 1: Parses an input string like '(3 + 2j) * (5+ 3j)'[cite: 119]. + Parses an input string like '(3+2j) * (5+3j)'. Extracts the two complex numbers and the mathematical operator. - Must support the standard a + bj representation[cite: 121]. """ - pass + # Regex to capture everything inside the parentheses and the operator between them + pattern = r'\s*\(([^)]+)\)\s*([+\-*/])\s*\(([^)]+)\)\s*' + match = re.match(pattern, expression) + + if not match: + raise ValueError("Invalid complex expression format. Expected: '(a+bj) op (c+dj)'") + + c1_str, operator, c2_str = match.groups() + + # Remove any internal spaces (e.g., '3 + 2j' becomes '3+2j') + return c1_str.replace(' ', ''), operator, c2_str.replace(' ', '') def add_complex(c1, c2): """ diff --git a/test_complex.py b/test_complex.py index ac71034..7be77b4 100644 --- a/test_complex.py +++ b/test_complex.py @@ -8,14 +8,17 @@ class TestComplexArithmetic(unittest.TestCase): - # --- Member 1 Tests --- + # --- Parser Tests --- def test_parse_complex_string_valid(self): - # Test normal valid strings here - pass + c1, op, c2 = parse_complex_string('(3 + 2j) * (5+ 3j)') + self.assertEqual(c1, '3+2j') + self.assertEqual(op, '*') + self.assertEqual(c2, '5+3j') def test_parse_complex_string_invalid(self): - # Test malformed strings or missing brackets here - pass + # Boundary Condition: Missing brackets should raise a ValueError + with self.assertRaises(ValueError): + parse_complex_string('3+2j * 5+3j') # --- Member 2 Tests --- def test_add_complex(self): From 80767fba8034cf287f6b6eaec7d1ee9c2135b2d4 Mon Sep 17 00:00:00 2001 From: Feluda2005 <2023csb020.sabyasachi@students.iiests.ac.in> Date: Fri, 20 Mar 2026 19:06:07 +0530 Subject: [PATCH 07/17] Added multiplication, division and test cases --- __pycache__/calculator.cpython-313.pyc | Bin 0 -> 987 bytes __pycache__/complex.cpython-313.pyc | Bin 0 -> 3180 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 __pycache__/calculator.cpython-313.pyc create mode 100644 __pycache__/complex.cpython-313.pyc diff --git a/__pycache__/calculator.cpython-313.pyc b/__pycache__/calculator.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..969ff6b70db043f3cabb71e66bbff1409318ca8e GIT binary patch literal 987 zcmah|L2DC16n?Y2X|`!%VkA;Rg;j#EP-`#sP{fPPO#(6~1p~t**@T77Zk^p#(vv4q zym-lv$S?38crJL6!JDVvB#U_U&1}}TQpg;>nK$$1y>Gv7HmlVtfaCesFaCW3@KXiF zuvUv~8y9ofhI>Gv4U`-h`H6su;hMuDU(HxUk8BsGIrKpg3c{d7nAB*4u&9Yxq88!? zEg_cahOj4P*Ory1JQ$_{Pa<)y>I}`imPXZ5#hKzehvVi0oI9`}y#*{xX~kYJmV`?( zh*g^7II??m*r(ArdCP_8bi;`sdY}nS6Tm zqq%c-=i#^J{#kW@Wsg=&tKM@rrOjB#rygUn!q_w#rGZ*k8GD`bV0BVwZ0w6T3Gms3 z5o4l;Eksj6OF`xvk8`$9#9chq<&;IgOhU*Xqe5CsK+tvm0@lFNW&i*H literal 0 HcmV?d00001 diff --git a/__pycache__/complex.cpython-313.pyc b/__pycache__/complex.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6195042aea1ed1d351465dec6e57197d737518f6 GIT binary patch literal 3180 zcmcIm&2JM&6yJ3md;OJ|5WYz@RJ7O-tk_8^)g>i?1V|~gsuL6mqG-GxCmZZtcXk&- zBqVdHP!DYmh(tYvTay#eOLFAUa}{YXXw?H!)kCEo5a}P#_tv``Fu0ThBkh}+oi}fO z^FHRi?L;CfKs#-3D0)N?{=kXX0`6dY7zX!*f>01I3SWp^Btju@P~d?=8_>2w5NNQ_ z4z#@x0valWfrbkbP^l0B8kvozV}GHzv}i}q(u!t;3%3P}wIr|2L9FKkl zT+-X_BkTee{CE<{YtRt4b*J08@jw-PwPyM#!3b|#sfxo09JOS&x1DS#ln6fQWTP)fl3`%x{Gg_H}Krrlx zQl+!b5MMKJI=3}^FX>73&HDi`?T1e<1E~xD#D)0Y?@!f7pT-h*M(ZPP_bl0cKe3cp zF0EEqs%seIG^nC)idr z!rg`C;A&ze@qk+UPpnNmoL-;a%vvXht4CINI*WJ_#FP5qp=m6j) zl;~jl3iFNGs84*S$?fD<(J@VUsZkwEO9e_h4JNNwRJ|n1HPCFM7;-pDq(lvh8?Zi-HO`rA zz_G@he;%Pl?FNIrSX^>um|SfLC_@lcyaE=ALdck2*~CLldOE~zK+saKs#oOg6q39b zn9t(|d=>6A3Y5#~s2#;5*{HD_ZveifPPxUMY6kNj$MAC;#8JK@%c Date: Sat, 21 Mar 2026 12:19:36 +0530 Subject: [PATCH 08/17] Fix variable type errors in complex.py and correct the math in test_complex.py --- complex.py | 49 ++++++++++++++++++++++++------------------------- test_complex.py | 4 ++-- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/complex.py b/complex.py index ccb1593..9a22a3f 100644 --- a/complex.py +++ b/complex.py @@ -46,52 +46,51 @@ def multiply_complex(c1, c2): """ Member 3: Handles the multiplication of two complex numbers[cite: 120]. """ - + if not isinstance(c1, tuple) or not isinstance(c2, tuple): + raise TypeError("Inputs must be tuples") + if len(c1) != 2 or len(c2) != 2: + raise TypeError("Tuples must have exactly 2 elements") + if not (isinstance(c1[0], (int, float)) and isinstance(c1[1], (int, float)) and + isinstance(c2[0], (int, float)) and isinstance(c2[1], (int, float))): + raise TypeError("Tuple elements must be numeric") + calc = Calculator() + a, b = c1 + c, d = c2 - # 1. Convert the incoming strings to Python complex objects - c1 = complex(c1_str) - c2 = complex(c2_str) - - a, b = c1.real, c1.imag - c, d = c2.real, c2.imag - - # (a+bi)*(c+di) = (ac - bd) + (ad + bc)i real_part = calc.subtract(calc.multiply(a, c), calc.multiply(b, d)) imag_part = calc.add(calc.multiply(a, d), calc.multiply(b, c)) - # 4. Reconstruct into a complex object and format back to a string - result = complex(real_part, imag_part) - return _format_complex(result) + return (real_part, imag_part) def divide_complex(c1, c2): """ Member 3: Handles the division of c1 by c2[cite: 120]. Must include error handling for division by zero. """ - # c1 and c2 are tuples: (real, imag) + if not isinstance(c1, tuple) or not isinstance(c2, tuple): + raise TypeError("Inputs must be tuples") + if len(c1) != 2 or len(c2) != 2: + raise TypeError("Tuples must have exactly 2 elements") + if not (isinstance(c1[0], (int, float)) and isinstance(c1[1], (int, float)) and + isinstance(c2[0], (int, float)) and isinstance(c2[1], (int, float))): + raise TypeError("Tuple elements must be numeric") + calc = Calculator() + a, b = c1 + c, d = c2 - # 1. Convert the incoming strings to Python complex objects - c1 = complex(c1_str) - c2 = complex(c2_str) - - a, b = c1.real, c1.imag - c, d = c2.real, c2.imag - - # denominator = c^2 + d^2 denominator = calc.add(calc.multiply(c, c), calc.multiply(d, d)) if denominator == 0: raise ValueError("Division by zero in complex division") - # real part: (ac + bd) / (c^2 + d^2) + real_num = calc.add(calc.multiply(a, c), calc.multiply(b, d)) real_part = calc.divide(real_num, denominator) - # imag part: (bc - ad) / (c^2 + d^2) + imag_num = calc.subtract(calc.multiply(b, c), calc.multiply(a, d)) imag_part = calc.divide(imag_num, denominator) - result = complex(real_part, imag_part) - return _format_complex(result) + return (real_part, imag_part) def compute_magnitude(c): """ diff --git a/test_complex.py b/test_complex.py index e244b6a..37d0104 100644 --- a/test_complex.py +++ b/test_complex.py @@ -56,10 +56,10 @@ def test_multiply_complex(self): def test_divide_complex(self): # Normal cases - self.assertEqual(divide_complex((3, 2), (5, 3)), (0.6341463414634146, 0.04878048780487805)) + self.assertEqual(divide_complex((3, 2), (5, 3)), (0.6176470588235294, 0.029411764705882353)) self.assertEqual(divide_complex((0, 0), (5, 3)), (0.0, 0.0)) self.assertEqual(divide_complex((1, 0), (1, 0)), (1.0, 0.0)) - self.assertEqual(divide_complex((2, -3), (-1, 4)), (-0.6470588235294118, -0.5294117647058824)) + self.assertEqual(divide_complex((2, -3), (-1, 4)), (-0.8235294117647058, -0.29411764705882354)) # Boundary cases self.assertEqual(divide_complex((0, 0), (0, 1)), (0.0, 0.0)) From c9d327ef2f702aec72445840529135fe089a69e7 Mon Sep 17 00:00:00 2001 From: Ishika Gupta Date: Sun, 22 Mar 2026 18:00:23 +0530 Subject: [PATCH 09/17] Added complex evaluator --- complex.py | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/complex.py b/complex.py index 9a22a3f..b62adfe 100644 --- a/complex.py +++ b/complex.py @@ -106,9 +106,24 @@ def compute_phase(c): def evaluate_complex_expression(expression): """ - Member 5 (Integrator): The main runner function. - Takes the raw string, passes it to parse_complex_string, - routes the parsed data to the correct math function above, - and returns the final string result. + Evaluates a full complex expression string like: + '(1+2j) * (3+4j)' """ + + c1, op, c2 = parse_complex_string(expression) + + if op == '+': + return add_complex(c1, c2) + + elif op == '-': + return subtract_complex(c1, c2) + + elif op == '*': + return multiply_complex(c1, c2) + + elif op == '/': + return divide_complex(c1, c2) + + else: + raise ValueError("Unsupported operation") \ No newline at end of file From 24b5cf6adde3ef6fb0e2caa1f2f5561bdf8cf8aa Mon Sep 17 00:00:00 2001 From: subhamsaha7676 Date: Sun, 29 Mar 2026 01:38:34 +0530 Subject: [PATCH 10/17] Implemented complex addition and subtraction with unit tests --- complex_add.py | 27 +++++++++++++++++++++++++++ complex_sub.py | 27 +++++++++++++++++++++++++++ test_complex_add.py | 18 ++++++++++++++++++ test_complex_sub.py | 18 ++++++++++++++++++ 4 files changed, 90 insertions(+) create mode 100644 complex_add.py create mode 100644 complex_sub.py create mode 100644 test_complex_add.py create mode 100644 test_complex_sub.py diff --git a/complex_add.py b/complex_add.py new file mode 100644 index 0000000..5fadaf8 --- /dev/null +++ b/complex_add.py @@ -0,0 +1,27 @@ +# complex_add.py + +def format_complex(real, imag): + """ + Formats complex number into a+bi form string + """ + if imag >= 0: + return f"{real}+{imag}j" + else: + return f"{real}{imag}j" + + +def add_complex(c1, c2): + """ + Adds two complex numbers + c1, c2 -> tuples (real, imag) + """ + if not (isinstance(c1, tuple) and isinstance(c2, tuple)): + raise ValueError("Inputs must be tuples") + + r1, i1 = c1 + r2, i2 = c2 + + real = r1 + r2 + imag = i1 + i2 + + return format_complex(real, imag) \ No newline at end of file diff --git a/complex_sub.py b/complex_sub.py new file mode 100644 index 0000000..56cc8f2 --- /dev/null +++ b/complex_sub.py @@ -0,0 +1,27 @@ +# complex_sub.py + +def format_complex(real, imag): + """ + Formats complex number into a+bi form string + """ + if imag >= 0: + return f"{real}+{imag}j" + else: + return f"{real}{imag}j" + + +def subtract_complex(c1, c2): + """ + Subtracts two complex numbers (c1 - c2) + c1, c2 -> tuples (real, imag) + """ + if not (isinstance(c1, tuple) and isinstance(c2, tuple)): + raise ValueError("Inputs must be tuples") + + r1, i1 = c1 + r2, i2 = c2 + + real = r1 - r2 + imag = i1 - i2 + + return format_complex(real, imag) \ No newline at end of file diff --git a/test_complex_add.py b/test_complex_add.py new file mode 100644 index 0000000..4f3992e --- /dev/null +++ b/test_complex_add.py @@ -0,0 +1,18 @@ +import unittest +from complex_add import add_complex + + +class TestComplexAdd(unittest.TestCase): + + def test_add_positive(self): + self.assertEqual(add_complex((3, 2), (5, 3)), "8+5j") + + def test_add_negative(self): + self.assertEqual(add_complex((-1, -2), (3, 4)), "2+2j") + + def test_add_zero(self): + self.assertEqual(add_complex((0, 0), (0, 0)), "0+0j") + + +if __name__ == "__main__": + unittest.main() \ No newline at end of file diff --git a/test_complex_sub.py b/test_complex_sub.py new file mode 100644 index 0000000..a0785dc --- /dev/null +++ b/test_complex_sub.py @@ -0,0 +1,18 @@ +import unittest +from complex_sub import subtract_complex + + +class TestComplexSub(unittest.TestCase): + + def test_sub_positive(self): + self.assertEqual(subtract_complex((5, 3), (3, 2)), "2+1j") + + def test_sub_negative(self): + self.assertEqual(subtract_complex((3, 2), (5, 3)), "-2-1j") + + def test_sub_zero(self): + self.assertEqual(subtract_complex((0, 0), (0, 0)), "0+0j") + + +if __name__ == "__main__": + unittest.main() \ No newline at end of file From 020c970a04bd9da513ae16923ad7624e61c5bfeb Mon Sep 17 00:00:00 2001 From: subhamsaha7676 Date: Sun, 29 Mar 2026 01:46:31 +0530 Subject: [PATCH 11/17] Delete complex_add.py --- complex_add.py | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 complex_add.py diff --git a/complex_add.py b/complex_add.py deleted file mode 100644 index 5fadaf8..0000000 --- a/complex_add.py +++ /dev/null @@ -1,27 +0,0 @@ -# complex_add.py - -def format_complex(real, imag): - """ - Formats complex number into a+bi form string - """ - if imag >= 0: - return f"{real}+{imag}j" - else: - return f"{real}{imag}j" - - -def add_complex(c1, c2): - """ - Adds two complex numbers - c1, c2 -> tuples (real, imag) - """ - if not (isinstance(c1, tuple) and isinstance(c2, tuple)): - raise ValueError("Inputs must be tuples") - - r1, i1 = c1 - r2, i2 = c2 - - real = r1 + r2 - imag = i1 + i2 - - return format_complex(real, imag) \ No newline at end of file From d2744edc0f20058e5fa95d0041000c2e0f156898 Mon Sep 17 00:00:00 2001 From: subhamsaha7676 Date: Sun, 29 Mar 2026 01:52:39 +0530 Subject: [PATCH 12/17] Delete complex_sub.py --- complex_sub.py | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 complex_sub.py diff --git a/complex_sub.py b/complex_sub.py deleted file mode 100644 index 56cc8f2..0000000 --- a/complex_sub.py +++ /dev/null @@ -1,27 +0,0 @@ -# complex_sub.py - -def format_complex(real, imag): - """ - Formats complex number into a+bi form string - """ - if imag >= 0: - return f"{real}+{imag}j" - else: - return f"{real}{imag}j" - - -def subtract_complex(c1, c2): - """ - Subtracts two complex numbers (c1 - c2) - c1, c2 -> tuples (real, imag) - """ - if not (isinstance(c1, tuple) and isinstance(c2, tuple)): - raise ValueError("Inputs must be tuples") - - r1, i1 = c1 - r2, i2 = c2 - - real = r1 - r2 - imag = i1 - i2 - - return format_complex(real, imag) \ No newline at end of file From eac4b2d849427292264af275ab2af04d4c03e8fc Mon Sep 17 00:00:00 2001 From: subhamsaha7676 Date: Sun, 29 Mar 2026 01:53:19 +0530 Subject: [PATCH 13/17] Delete test_complex_add.py --- test_complex_add.py | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 test_complex_add.py diff --git a/test_complex_add.py b/test_complex_add.py deleted file mode 100644 index 4f3992e..0000000 --- a/test_complex_add.py +++ /dev/null @@ -1,18 +0,0 @@ -import unittest -from complex_add import add_complex - - -class TestComplexAdd(unittest.TestCase): - - def test_add_positive(self): - self.assertEqual(add_complex((3, 2), (5, 3)), "8+5j") - - def test_add_negative(self): - self.assertEqual(add_complex((-1, -2), (3, 4)), "2+2j") - - def test_add_zero(self): - self.assertEqual(add_complex((0, 0), (0, 0)), "0+0j") - - -if __name__ == "__main__": - unittest.main() \ No newline at end of file From 68d5bfb5c3bb5241282eb985f485b633a4f3c639 Mon Sep 17 00:00:00 2001 From: subhamsaha7676 Date: Sun, 29 Mar 2026 01:53:50 +0530 Subject: [PATCH 14/17] Delete test_complex_sub.py --- test_complex_sub.py | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 test_complex_sub.py diff --git a/test_complex_sub.py b/test_complex_sub.py deleted file mode 100644 index a0785dc..0000000 --- a/test_complex_sub.py +++ /dev/null @@ -1,18 +0,0 @@ -import unittest -from complex_sub import subtract_complex - - -class TestComplexSub(unittest.TestCase): - - def test_sub_positive(self): - self.assertEqual(subtract_complex((5, 3), (3, 2)), "2+1j") - - def test_sub_negative(self): - self.assertEqual(subtract_complex((3, 2), (5, 3)), "-2-1j") - - def test_sub_zero(self): - self.assertEqual(subtract_complex((0, 0), (0, 0)), "0+0j") - - -if __name__ == "__main__": - unittest.main() \ No newline at end of file From 4c6d57c3bbc10d1f20fe65866b658746059e317e Mon Sep 17 00:00:00 2001 From: Mithun Dutta Date: Sun, 29 Mar 2026 15:11:21 +0530 Subject: [PATCH 15/17] fixed the ttype mismach error --- complex.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/complex.py b/complex.py index b62adfe..9b961a2 100644 --- a/complex.py +++ b/complex.py @@ -3,6 +3,14 @@ import re import cmath + +def _complex_str_to_tuple(c_str): + try: + c = complex(c_str) + except ValueError as exc: + raise ValueError(f"Invalid complex number: {c_str}") from exc + return (float(c.real), float(c.imag)) + def _format_complex(c): """ Helper function to format a Python complex object back into a @@ -110,7 +118,9 @@ def evaluate_complex_expression(expression): '(1+2j) * (3+4j)' """ - c1, op, c2 = parse_complex_string(expression) + c1_str, op, c2_str = parse_complex_string(expression) + c1 = _complex_str_to_tuple(c1_str) + c2 = _complex_str_to_tuple(c2_str) if op == '+': return add_complex(c1, c2) From d154a1dd5589afaf15a53957157c49bd6c28ac3d Mon Sep 17 00:00:00 2001 From: Mithun Dutta Date: Sun, 29 Mar 2026 21:34:02 +0530 Subject: [PATCH 16/17] Removed redundant lines --- complex.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/complex.py b/complex.py index 6319925..1769318 100644 --- a/complex.py +++ b/complex.py @@ -2,7 +2,6 @@ import cmath from calculator import Calculator import re -import cmath def _complex_str_to_tuple(c_str): @@ -140,4 +139,4 @@ def evaluate_complex_expression(expression): else: raise ValueError("Unsupported operation") - \ No newline at end of file + From db3761f9084858fd3b058a9b97d188af8aad72ec Mon Sep 17 00:00:00 2001 From: subhamsaha7676 Date: Sun, 29 Mar 2026 22:37:45 +0530 Subject: [PATCH 17/17] Added addition and subtraction logic with unit tests. --- complex.py | 34 ++++++++++++++++++++++++++++++++-- test_complex.py | 41 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 71 insertions(+), 4 deletions(-) diff --git a/complex.py b/complex.py index 1769318..e02fa06 100644 --- a/complex.py +++ b/complex.py @@ -43,13 +43,43 @@ def add_complex(c1, c2): Member 2: Handles the addition of two complex numbers[cite: 120]. """ - pass + if not isinstance(c1, tuple) or not isinstance(c2, tuple): + raise TypeError("Inputs must be tuples") + if len(c1) != 2 or len(c2) != 2: + raise TypeError("Tuples must have exactly 2 elements") + if not (isinstance(c1[0], (int, float)) and isinstance(c1[1], (int, float)) and + isinstance(c2[0], (int, float)) and isinstance(c2[1], (int, float))): + raise TypeError("Tuple elements must be numeric") + + calc = Calculator() + a, b = c1 + c, d = c2 + + real_part = calc.add(a, c) + imag_part = calc.add(b, d) + + return (real_part, imag_part) def subtract_complex(c1, c2): """ Member 2: Handles the subtraction of c2 from c1[cite: 120]. """ - pass + if not isinstance(c1, tuple) or not isinstance(c2, tuple): + raise TypeError("Inputs must be tuples") + if len(c1) != 2 or len(c2) != 2: + raise TypeError("Tuples must have exactly 2 elements") + if not (isinstance(c1[0], (int, float)) and isinstance(c1[1], (int, float)) and + isinstance(c2[0], (int, float)) and isinstance(c2[1], (int, float))): + raise TypeError("Tuple elements must be numeric") + + calc = Calculator() + a, b = c1 + c, d = c2 + + real_part = calc.subtract(a, c) + imag_part = calc.subtract(b, d) + + return (real_part, imag_part) def multiply_complex(c1, c2): """ diff --git a/test_complex.py b/test_complex.py index 691e6d3..8a0199f 100644 --- a/test_complex.py +++ b/test_complex.py @@ -23,11 +23,48 @@ def test_parse_complex_string_invalid(self): # --- Member 2 Tests --- def test_add_complex(self): # Test normal addition and negative addition - pass + self.assertEqual(add_complex((3, 2), (5, 3)), (8, 5)) + self.assertEqual(add_complex((0, 0), (5, 3)), (5, 3)) + self.assertEqual(add_complex((1, 0), (0, 1)), (1, 1)) + self.assertEqual(add_complex((2, -3), (-1, 4)), (1, 1)) + + # Boundary cases + self.assertEqual(add_complex((0, 0), (0, 0)), (0, 0)) + self.assertEqual(add_complex((999999, 0), (0, 999999)), (999999, 999999)) + self.assertEqual(add_complex((-1, -1), (-1, -1)), (-2, -2)) + + # Invalid input handling + with self.assertRaises(TypeError): + add_complex((1,), (2, 3)) # Too few elements + with self.assertRaises(TypeError): + add_complex((1, 2, 3), (2, 3)) # Too many elements + with self.assertRaises(TypeError): + add_complex((1, 'a'), (2, 3)) # Non-numeric + with self.assertRaises(TypeError): + add_complex('not a tuple', (2, 3)) def test_subtract_complex(self): # Test normal subtraction - pass + self.assertEqual(subtract_complex((5, 3), (3, 2)), (2, 1)) + self.assertEqual(subtract_complex((0, 0), (5, 3)), (-5, -3)) + self.assertEqual(subtract_complex((1, 0), (0, 1)), (1, -1)) + self.assertEqual(subtract_complex((2, -3), (-1, 4)), (3, -7)) + + # Boundary cases + self.assertEqual(subtract_complex((0, 0), (0, 0)), (0, 0)) + self.assertEqual(subtract_complex((999999, 0), (0, 999999)), (999999, -999999)) + self.assertEqual(subtract_complex((-1, -1), (-1, -1)), (0, 0)) + + # Invalid input handling + with self.assertRaises(TypeError): + subtract_complex((1,), (2, 3)) # Too few elements + with self.assertRaises(TypeError): + subtract_complex((1, 2, 3), (2, 3)) # Too many elements + with self.assertRaises(TypeError): + subtract_complex((1, 'a'), (2, 3)) # Non-numeric + with self.assertRaises(TypeError): + subtract_complex('not a tuple', (2, 3)) + # --- Member 3 Tests ---