"""
 types.py

 An example of a polymorphic function in python 
 ... and an object with an "overloaded" addition operator
 
   $ python types.py
   Vector(1,2) + Vector(5,6) is Vector(6,8).
   1 + 2 is 3.

"""


def plus(a, b):
    """ (a,b) are numbers, tuples, or Vector instances ... 
        add together to get a number, tuple, or Vector. """
    # This code might *not* be considered particularly "pythonic";
    # testing for specifric tends to be frowned on.
    if type(a) == tuple: return (i+j for (i,j) in zip(a,b))
    if type(a) in (int, float, Vector): return a + b
    raise Exception(f"unknown type in plus({a}, {b})")

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def xy(self): return (self.x, self.y)
    def __str__(self):             # implement str() for Vector
        return f"Vector({self.x},{self.y})"
    def __add__(self, other):      # implement self + other for Vector
        return Vector(*plus(self.xy(), other.xy()))

def main():
    
    v1 = Vector(1,2)
    v2 = Vector(5,6)
    result = plus(v1, v2)
    print(f" {v1} + {v2} is {result}.")

    v1 = 1
    v2 = 2
    result = plus(1, 2)
    print(f" {v1} + {v2} is {result}.")

main()