0

I have been implementing function overloading using function to find the area of various figures(that includes square,circle and rectangle) but when I try to implement the concept here is the error that I get.

I made an instance of the class and then tried to call all the function with difference in the number of parameters. But still I am getting a lot of error.

from abc import abstractmethod
class Poly:
    def __init__(self,n=0):
        self._n = n

    def area(self,a):
        if isinstance(r,int):
            return a ** 2

    def area(self,b,pi):
        if isinstance(a,float):
            ar = pi * b * b
        return ar

    def area(self,l,r,ar):
        if isinstance(l,int) and isinstance(r,int):
            ar = l * r
            return l*r

if __name__ == '__main__':
    p = Poly()
    pi = 3.14
    ar = 0
    l = 3
    r = 4
    b = 10
    a = 2
    peroi1 = p.area(a)
    print(peroi1)
    peroi2 = p.area(b,pi)
    print(peroi2)
    peroi3 = p.area(l,r,ar)
    print(peroi3)

The expected output should give the area of square,circle and rectangle respectively but I get the following error.

Traceback (most recent call last):
  File "overloadpractice.py", line 28, in <module>
    peroi1 = p.area(a)
TypeError: area() missing 2 required positional arguments: 'r' and 'ar'
Arun Kumar
  • 201
  • 2
  • 4
  • 13
  • Python doesn't let you overload methods like this. If you did `x = p.area`, which object would `x` be equal to? – Patrick Haugh Jul 20 '19 at 06:49
  • I also found this post, which might help you: https://stackoverflow.com/questions/6434482/python-function-overloading?rq=1 – Dov Rine Jul 20 '19 at 08:58

1 Answers1

0

You can do something like this, but there are better ways. I'll come up with a better example in a little while:

class Poly:
    def __init__(self, n=0):
        self._n = n

    def area(self, *args):
        if len(args) == 1:
            if isinstance(a, int):
                return r ** 2

        elif len(args) == 2:
            if isinstance(a, float):
                return pi * b * b

        elif len(args) == 3:
            if isinstance(l, int) and isinstance(r, int):
                ar = l * r
                return l*r

        else:
            return 'invalid number of arguments'


if __name__ == '__main__':
    pi = 3.14
    ar = 0
    l = 3
    r = 4
    b = 10
    a = 2

    p = Poly()

    peroi1 = p.area(a)
    print(peroi1)
    peroi2 = p.area(b, pi)
    print(peroi2)
    peroi3 = p.area(l, r, ar)
    print(peroi3)

A better(easier to test and maintain) example:

from math import pi

SQUARE = 1
CIRCLE = 2
RECTANGLE = 3

get_area = {
    SQUARE: lambda side :  side * side,
    CIRCLE: lambda radius, _ : pi * radius * radius,
    RECTANGLE: lambda length, width, _ : length * width 
}

class Poly:
    def __init__(self, n=0):
        self._n = n

    def area(self, *args):
        return get_area.get(len(args), lambda: 'invalid number of arguments')(*args)

if __name__ == '__main__':
    ar = 0
    l = 3
    r = 4
    b = 10
    a = 2
    # moved pi to an import
    square = Poly()
    circle = Poly()
    rectangle = Poly()

    print(square.area(a))            # 4  
    print(circle.area(b, pi))        # 14.1592653589793
    print(rectangle.area(l, r, ar))  # 12
    print(square.area())             # invalid number of variables

Dov Rine
  • 810
  • 6
  • 12
  • 1
    In trying to make the better example, I'm getting confused by these 1 letter variables in the global scope. What do they represent? – Dov Rine Jul 20 '19 at 07:29
  • The are simply sides of the figure.. also I just wanted 3 different function calls on area() rather than just implementing it on a single function and checking the length of arguments. – Arun Kumar Jul 20 '19 at 07:33
  • This is 3 different calls. Are you saying that you want to be changing the values of the 1 letter vars? – Dov Rine Jul 20 '19 at 07:43
  • You could use keyword arguments (kwargs) to Poly.area() and check for their existence and then return results based on that, but it changes the calling code, too. – Dov Rine Jul 20 '19 at 07:46
  • 1
    The truth is that the area method doesn't use the instance var(s) at all and (should?) probably therefore be a @staticmethod anyway. – Dov Rine Jul 20 '19 at 07:50
  • @ArunKumar: Are you saying that the one letter variables represent different shapes, so l is a triangle, r is a rectangle, etc? In that case, a and ar are not polygons, right?. – Dov Rine Jul 20 '19 at 07:52
  • @ArunKumar: I guess you could be saying that the one letter vars are the lengths of the sides of a polygon? If that's the case, it's probably better to put them in a list in the instance like: ```Poly(sides=[0,3,4,10,2])``` and then save them to self.sides in ```__init__```. – Dov Rine Jul 20 '19 at 07:57
  • 1
    @ArunKumar: Never mind. I missed the last line of your post and get it now. I'll update the example again to reflect that. – Dov Rine Jul 20 '19 at 07:59