| 1 | import math |
| 2 | |
| 3 | |
| 1 | 4 | class ComplexNumber: |
| 2 | 5 | def __init__(self, real: float, imaginary: float): |
| 3 | | pass |
| 6 | self.real = real |
| 7 | self.imaginary = imaginary |
| 4 | 8 | |
| 5 | 9 | def __eq__(self, other: 'ComplexNumber') -> bool: |
| 6 | | pass |
| 10 | # Edge Case: Handle comparison with non-ComplexNumber objects |
| 11 | if not isinstance(other, ComplexNumber): |
| 12 | return False |
| 13 | return self.real == other.real and self.imaginary == other.imaginary |
| 7 | 14 | |
| 8 | 15 | def __add__(self, other: 'ComplexNumber') -> 'ComplexNumber': |
| 9 | | pass |
| 16 | # Edge Case: Handle addition with non-ComplexNumber objects |
| 17 | if not isinstance(other, ComplexNumber): |
| 18 | raise TypeError("Can only add ComplexNumber to another ComplexNumber") |
| 19 | real_part = self.real + other.real |
| 20 | imaginary_part = self.imaginary + other.imaginary |
| 21 | return ComplexNumber(real_part, imaginary_part) |
| 10 | 22 | |
| 11 | 23 | def __mul__(self, other: 'ComplexNumber') -> 'ComplexNumber': |
| 12 | | pass |
| 24 | # Edge Case: Handle multiplication with non-ComplexNumber objects |
| 25 | if not isinstance(other, ComplexNumber): |
| 26 | raise TypeError("Can only multiply ComplexNumber with another ComplexNumber") |
| 27 | real_part = self.real * other.real - self.imaginary * other.imaginary |
| 28 | imaginary_part = self.imaginary * other.real + self.real * other.imaginary |
| 29 | return ComplexNumber(real_part, imaginary_part) |
| 13 | 30 | |
| 14 | 31 | def __sub__(self, other: 'ComplexNumber') -> 'ComplexNumber': |
| 15 | | pass |
| 32 | # Edge Case: Handle subtraction with non-ComplexNumber objects |
| 33 | if not isinstance(other, ComplexNumber): |
| 34 | raise TypeError("Can only subtract ComplexNumber from another ComplexNumber") |
| 35 | real_part = self.real - other.real |
| 36 | imaginary_part = self.imaginary - other.imaginary |
| 37 | return ComplexNumber(real_part, imaginary_part) |
| 16 | 38 | |
| 17 | 39 | def __truediv__(self, other: 'ComplexNumber') -> 'ComplexNumber': |
| 18 | | pass |
| 40 | # Edge Case: Handle division with non-ComplexNumber objects |
| 41 | if not isinstance(other, ComplexNumber): |
| 42 | raise TypeError("Can only divide ComplexNumber by another ComplexNumber") |
| 43 | # Edge Case: Handle division by zero complex number |
| 44 | denominator = other.real**2 + other.imaginary**2 |
| 45 | if denominator == 0: |
| 46 | raise ZeroDivisionError("Cannot divide by zero complex number") |
| 47 | real_part = (self.real * other.real + self.imaginary * other.imaginary) / denominator |
| 48 | imaginary_part = (self.imaginary * other.real - self.real * other.imaginary) / denominator |
| 49 | return ComplexNumber(real_part, imaginary_part) |
| 19 | 50 | |
| 20 | 51 | def __abs__(self) -> float: |
| 21 | | pass |
| 52 | # Edge Case: Handle very large or very small real/imaginary parts that might cause overflow/underflow |
| 53 | return math.sqrt(self.real**2 + self.imaginary**2) |
| 22 | 54 | |
| 23 | 55 | def conjugate(self) -> 'ComplexNumber': |
| 24 | | pass |
| 56 | # Edge Case: Handle negative zero in imaginary part |
| 57 | return ComplexNumber(self.real, -self.imaginary) |
| 25 | 58 | |
| 26 | 59 | def exp(self) -> 'ComplexNumber': |
| 27 | | pass |
| 60 | # Edge Case: Handle very large real parts that might cause overflow |
| 61 | try: |
| 62 | exp_real = math.exp(self.real) |
| 63 | except OverflowError: |
| 64 | # If exp(self.real) overflows, return infinity with appropriate sign |
| 65 | exp_real = float('inf') if self.real > 0 else 0.0 |
| 66 | |
| 67 | real_part = exp_real * math.cos(self.imaginary) |
| 68 | imaginary_part = exp_real * math.sin(self.imaginary) |
| 69 | return ComplexNumber(real_part, imaginary_part) |
| 70 | |
| 71 | def __str__(self) -> str: |
| 72 | """Return string representation of complex number.""" |
| 73 | if self.imaginary == 0: |
| 74 | return f"{self.real}" |
| 75 | elif self.real == 0: |
| 76 | return f"{self.imaginary}i" |
| 77 | elif self.imaginary > 0: |
| 78 | return f"{self.real} + {self.imaginary}i" |
| 79 | else: |
| 80 | return f"{self.real} - {-self.imaginary}i" |
| 81 | |
| 82 | def __repr__(self) -> str: |
| 83 | """Return official string representation of complex number.""" |
| 84 | return f"ComplexNumber({self.real}, {self.imaginary})" |
| 85 | |
| 86 | def __repr__(self) -> str: |
| 87 | """Return official string representation of complex number.""" |
| 88 | return f"ComplexNumber({self.real}, {self.imaginary})" |
| 89 | |
| 90 | # Handled Edge Cases: comparison with non-ComplexNumber objects |
| 91 | # Handled Edge Cases: addition with non-ComplexNumber objects |
| 92 | # Handled Edge Cases: multiplication with non-ComplexNumber objects |
| 93 | # Handled Edge Cases: subtraction with non-ComplexNumber objects |
| 94 | # Handled Edge Cases: division with non-ComplexNumber objects, division by zero complex number |
| 95 | # Handled Edge Cases: very large or very small real/imaginary parts causing overflow/underflow |
| 96 | # Handled Edge Cases: negative zero in imaginary part |
| 97 | # Handled Edge Cases: very large real parts causing overflow in exp function |