I wrote out a test for a Complex class on python but I'm getting an error. Here's what I have:

class Complex:
    def __init__(self, real=0, imaginary=0):
        self._r=real
        self._i=imaginary

    def __add__ (self, other):
        return Complex((self._r + other._r), (self._i + other._i))

    def __sub__ (self, other):
        return Complex((self._r - other._r), (self._i - other._i))
    def __mul__ (self, other):
        return Complex((self._r * other._r - self._i * other._i), (self._r * other._i + self._i * other._r))
    def __truediv__ (self, other):
        return Complex(((self._r * other._r + self._i * other._i)) / (self._i**2 + other._i**2), ((self._r * other._i - other._r * self._i)) / (self._i**2 + other._i**2))
    def __str__ (self):
        if self._i < 0:

            return (str(self._r)+ "-" + str(-self._i) + "i")
        else:
            return (str(self._r) + "+" + str(self._i) + "i")

def test():
    try:
        while True:
            R1 = float(input("Enter first real number: "))
            I1 = float(input ("Enter first imaginary number: "))
            f1 = (R1, I1)
            print ("The first set of numbers are ", f1)
            R2 = float(input("Enter second real number: "))
            I2 = float(input("Enter second imaginary: "))
            f2 = (R2,I2)
            print ("The second set of numbers are ", f2)


            print (f1, "+", f2, "=", f1.__add__ (f2))
            print (f1, "-", f2, "=", f1.__sub__(f2))
            print (f1, "*", f2, "=", f1.__mul__ (f2))
            print (f1, "/", f2, "=", f1.__truediv__ (f2))



    except ValueError:
        pass


test()

I get error: AttributeError: 'tuple' object has no attribute 'sub'
Why is this happening?

You are not actualy using the class anywhere, also you should say f1 + f2, not f1.__add__(f2), it is same but less readable.

f1 = Complex(R1, I1)
print (f1, "+", f2, "=", f1 + f2)

The print statement needs a __repr__ method for the print statement in Python 2, you can define

__repr__ = __str__

If you define in beginning of the program

from __future__ import print_function
try:
    input = raw_input
except:
    pass

Your program runs also in Python 2

would it be the same if I was using python 3?

Yes only you do not need those 5 lines in beginning, which makes Python2 print and input behave same as Python3. It would be better though to inherit from object base class:

class Complex(object):
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.