0

Let's say I'm trying to make an imaginary number class in python (just as an exercise, I know there already is one built in). You should be able to add imaginary numbers to other imaginary numbers as well as imaginary numbers to ints and vice versa.

I got a hang of adding imaginaries to other imaginaries using __add__() and it seems like I might be able to add imaginaries to ints using duck typing (though I don't quite understand how), but I have no idea how to add an int to an imaginary. Please send help.

2
  • I'm not quite sure what help you're asking for here; seems more like a mathematical question (how to add an integer to an imaginary number). Maybe ask on math.se? Commented Dec 20, 2015 at 17:23
  • @DanielRoseman I know how to do it mathematically. I just want to know what a function in python would look like if I have an imaginary class and an int class and I want to do an imaginary + an int. Commented Dec 20, 2015 at 18:04

2 Answers 2

2

Implement __add__ to add anything to your class and implement __radd__ to implement adding an instance of your class to something else. Using isinstance on built-in types is not a terrible idea. Using it on your own classes is usually a sign of a rushed or a bad design. But if your are certain that the list of classes won't grow too much, don't worry about it. If it will grow, consider redesigning using the visitor pattern.

From the Python data model documentation:

For objects x and y, first x.__op__(y) is tried. If this is not implemented or returns NotImplemented, y.__rop__(x) is tried. If this is also not implemented or returns NotImplemented, a TypeError exception is raised.

Sign up to request clarification or add additional context in comments.

1 Comment

This is all starting to make sense to me now. I've been digging through the documentation and it's been helping, but do you know of any tutorials for this kind of stuff? If not, thank you anyway for the link. It helped me a lot.
0

For the addition you define the add method.

def __add__(self, other):

and within you try to recognise the type of the other argument:

if isinstance(other, imaginary):

You perform the calculation based on the outcome of these tests.

More is explained here: https://docs.python.org/2/library/numbers.html#implementing-the-arithmetic-operations

You can also get the idea from the test_complex.py test case:

class ComplexTest(unittest.TestCase):

    def assertAlmostEqual(self, a, b):
        if isinstance(a, complex):
            if isinstance(b, complex):
                unittest.TestCase.assertAlmostEqual(self, a.real, b.real)
                unittest.TestCase.assertAlmostEqual(self, a.imag, b.imag)
            else:
                unittest.TestCase.assertAlmostEqual(self, a.real, b)
                unittest.TestCase.assertAlmostEqual(self, a.imag, 0.)
        else:
            if isinstance(b, complex):
                unittest.TestCase.assertAlmostEqual(self, a, b.real)
                unittest.TestCase.assertAlmostEqual(self, 0., b.imag)
            else:
                unittest.TestCase.assertAlmostEqual(self, a, b)

1 Comment

This was my first thought on how to do this, but everywhere I have read it said that using isinstance() function is poor style so I thought there might be another way. I guess not.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.