Skip to content

Commit

Permalink
complex-numbers: operator overloading
Browse files Browse the repository at this point in the history
Replace add, sub, mul, div, with __add__, __sub__, __mul__,
__truediv__ to showcase use of Pythons's magic methods on
operator overloading.
Add __eq__ in example.py to compare two
ComplexNumber objects.

Closes exercism#724
  • Loading branch information
susg committed Nov 9, 2017
1 parent ee8c719 commit 59f0310
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 38 deletions.
10 changes: 5 additions & 5 deletions exercises/complex-numbers/complex_numbers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ class ComplexNumber(object):
def __init__(self, real, imaginary):
pass

def add(self, other):
def __add__(self, other):
pass

def mul(self, other):
def __mul__(self, other):
pass

def sub(self, other):
def __sub__(self, other):
pass

def div(self, other):
def __truediv__(self, other):
pass

def abs(self):
Expand All @@ -21,4 +21,4 @@ def conjugate(self):
pass

def exp(self):
pass
pass
52 changes: 24 additions & 28 deletions exercises/complex-numbers/complex_numbers_test.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import division

import unittest

import math
Expand All @@ -13,80 +15,74 @@ class ComplexNumbersTest(unittest.TestCase):
def test_add_purely_real_numbers(self):
first_input = ComplexNumber(1, 0)
second_input = ComplexNumber(2, 0)
self.assertEqual(first_input.add(second_input).real, 3)
self.assertEqual(first_input.add(second_input).imaginary, 0)
expected = ComplexNumber(3, 0)
self.assertEqual(first_input + second_input, expected)

def test_add_purely_imaginary_numbers(self):
first_input = ComplexNumber(0, 1)
second_input = ComplexNumber(0, 2)
self.assertEqual(first_input.add(second_input).real, 0)
self.assertEqual(first_input.add(second_input).imaginary, 3)
expected = ComplexNumber(0, 3)
self.assertEqual(first_input + second_input, expected)

def test_add_numbers_with_real_and_imaginary_part(self):
first_input = ComplexNumber(1, 2)
second_input = ComplexNumber(3, 4)
self.assertEqual(first_input.add(second_input).real, 4)
self.assertEqual(first_input.add(second_input).imaginary, 6)
expected = ComplexNumber(4, 6)
self.assertEqual(first_input + second_input, expected)

def test_subtract_purely_real_numbers(self):
first_input = ComplexNumber(1, 0)
second_input = ComplexNumber(2, 0)
self.assertEqual(first_input.sub(second_input).real, -1)
self.assertEqual(first_input.sub(second_input).imaginary, 0)
expected = ComplexNumber(-1, 0)
self.assertEqual(first_input - second_input, expected)

def test_subtract_purely_imaginary_numbers(self):
first_input = ComplexNumber(0, 1)
second_input = ComplexNumber(0, 2)
self.assertEqual(first_input.sub(second_input).real, 0)
self.assertEqual(first_input.sub(second_input).imaginary, -1)
expected = ComplexNumber(0, -1)
self.assertEqual(first_input - second_input, expected)

def test_subtract_numbers_with_real_and_imaginary_part(self):
first_input = ComplexNumber(1, 2)
second_input = ComplexNumber(3, 4)
self.assertEqual(first_input.sub(second_input).real, -2)
self.assertEqual(first_input.sub(second_input).imaginary, -2)
expected = ComplexNumber(-2, -2)
self.assertEqual(first_input - second_input, expected)

def test_multiply_purely_real_numbers(self):
first_input = ComplexNumber(1, 0)
second_input = ComplexNumber(2, 0)
self.assertEqual(first_input.mul(second_input).real, 2)
self.assertEqual(first_input.mul(second_input).imaginary, 0)
expected = ComplexNumber(2, 0)
self.assertEqual(first_input * second_input, expected)

def test_multiply_purely_imaginary_numbers(self):
first_input = ComplexNumber(0, 1)
second_input = ComplexNumber(0, 2)
self.assertEqual(first_input.mul(second_input).real, -2)
self.assertEqual(first_input.mul(second_input).imaginary, 0)
expected = ComplexNumber(-2, 0)
self.assertEqual(first_input * second_input, expected)

def test_multiply_numbers_with_real_and_imaginary_part(self):
first_input = ComplexNumber(1, 2)
second_input = ComplexNumber(3, 4)
self.assertEqual(first_input.mul(second_input).real, -5)
self.assertEqual(first_input.mul(second_input).imaginary, 10)
expected = ComplexNumber(-5, 10)
self.assertEqual(first_input * second_input, expected)

def test_divide_purely_real_numbers(self):
input_number = ComplexNumber(1.0, 0.0)
expected = ComplexNumber(0.5, 0.0)
divider = ComplexNumber(2.0, 0.0)
self.assertEqual(input_number.div(divider).real, expected.real)
self.assertEqual(input_number.div(divider).imaginary,
expected.imaginary)
self.assertEqual(input_number / divider, expected)

def test_divide_purely_imaginary_numbers(self):
input_number = ComplexNumber(0, 1)
expected = ComplexNumber(0.5, 0)
divider = ComplexNumber(0, 2)
self.assertEqual(input_number.div(divider).real, expected.real)
self.assertEqual(input_number.div(divider).imaginary,
expected.imaginary)
self.assertEqual(input_number / divider, expected)

def test_divide_numbers_with_real_and_imaginary_part(self):
input_number = ComplexNumber(1, 2)
expected = ComplexNumber(0.44, 0.08)
divider = ComplexNumber(3, 4)
self.assertEqual(input_number.div(divider).real, expected.real)
self.assertEqual(input_number.div(divider).imaginary,
expected.imaginary)
self.assertEqual(input_number / divider, expected)

def test_absolute_value_of_a_positive_purely_real_number(self):
self.assertEqual(ComplexNumber(5, 0).abs(), 5)
Expand Down Expand Up @@ -168,4 +164,4 @@ def test_exponential_of_a_purely_real_number(self):


if __name__ == '__main__':
unittest.main()
unittest.main()
13 changes: 8 additions & 5 deletions exercises/complex-numbers/example.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,25 @@ def __init__(self, real, imaginary):
self.real = real
self.imaginary = imaginary

def add(self, other):
def __eq__(self, other):
return self.real == other.real and self.imaginary == other.imaginary

def __add__(self, other):
r = self.real + other.real
i = self.imaginary + other.imaginary
return ComplexNumber(r, i)

def mul(self, other):
def __mul__(self, other):
r = self.real * other.real - self.imaginary * other.imaginary
i = self.real * other.imaginary + self.imaginary * other.real
return ComplexNumber(r, i)

def sub(self, other):
def __sub__(self, other):
r = self.real - other.real
i = self.imaginary - other.imaginary
return ComplexNumber(r, i)

def div(self, other):
def __truediv__(self, other):
d = other.real * other.real + other.imaginary * other.imaginary
r = (self.real * other.real + self.imaginary *
other.imaginary) / float(d)
Expand All @@ -39,4 +42,4 @@ def conjugate(self):
def exp(self):
r = round(math.cos(self.imaginary), 8) * math.exp(self.real)
i = round(math.sin(self.imaginary), 8) * math.exp(self.real)
return ComplexNumber(r, i)
return ComplexNumber(r, i)

0 comments on commit 59f0310

Please sign in to comment.