Need help with functor object in python

I do not understand my mistake in the code. Can someone correct me and also suggest good reading material?

TypeError: ‘NonLinearFunction’ object is not callable

import math

class NonLinearFunction :

    # The constructor method is given the 'slope' and 'bias' parameters
    # a and b which are stored as attributes of the object
    def __init__(self, a_ = 1.0, b_ = 1.0) :
        # Checks the validity of the slope and bias parameters:
        if type(a_) != type(1.0) :
            raise Exception("'a' must be a 'float'!")
        if type(b_) != type(1.0) :
            raise Exception("'b' must be a 'float'!")
        if a_ <= 0.0 :
            raise Exception("Invalid value for 'a'!")
        if b_ <= 0.0 :
            raise Exception("Invalid value for 'b'!")
        self.a = a_ # Set the attribute [self].a
        self.b = b_ # Set the attribute [self].b

def __call__(self, x_) :
        return 1. / math.sqrt(self.a * x_**2 + self.b)


if __name__ == "__main__" :

    a = 2.0
    b = 1.0
    dx = 0.2

    # Using the functor (function object):
    nonLinFunc = NonLinearFunction(a, b)
    fdata2 = open("test2.data", "w")
    for i in range(200) :
        xi = -10.0 + (i + 0.5) * dx
        fi = nonLinFunc(xi)
        print("{} {}".format(xi, fi), file=fdata2)
    fdata2.close()

    # Using several functors with distinct sets of parameters :
    dx = 0.04
    a1 = 2.4
    b1 = 1.3
    nonLinFunc1 = NonLinearFunction(a1, b1)
    a2 = 2.1
    b2 = 0.9
    nonLinFunc2 = NonLinearFunction(a2, b2)
    a3 = 1.7
    b3 = 0.8
    nonLinFunc3 = NonLinearFunction(a3, b3)
    fdata3 = open("test2bis.data", "w")
    for i in range(1000) :
        xi = -10.0 + (i + 0.5) * dx
        fi1 = nonLinFunc1(xi)
        fi2 = nonLinFunc2(xi)
        fi3 = nonLinFunc3(xi)
        print("{} {} {} {}".format(xi, fi1, fi2, fi3), file=fdata3)
    fdata3.close()
    
    exit(0)

It’s not callable because the line def __call__(self, x_) : is not indented correctly. It should be indented the same amount as def __init__(self, a_ = 1.0, b_ = 1.0) :.

In Python, correct indentation is essential.

1 Like