sohil patel
sohil patel

Reputation: 27

python decorators(TypeError: 'NoneType' object is not an iterator)

Below is my python program for decorator and coroutines,

#coroutine decorator    
def coroutine_decorator(coroutine_func):
    def wrapper(*args,**kwargs):
    c=coroutine_func(*args,**kwargs)
    next(c)
    return c
return wrapper

# Define the coroutine function 'linear_equation' below
@coroutine_decorator
def linear_equation(a, b):
    while True:
        x=yield
        e=a*(x**2)+b
        print("Expression, {0}*x^2 + {1}, with x being {2} equals {3}".format(int(a),x,int(b),int(e)))

# Define the coroutine function 'numberParser' below
@coroutine_decorator
def numberParser():
    equation1 = linear_equation(3, 4)
    equation2 = linear_equation(2, -1)
# code to send the input number to both the linear equations
    equation1.send(6.0)
    equation2.send(6.0)


def main(x):
    n = numberParser()
    n.send(x)


if __name__ == "__main__":
    x = float(input())

Iam getting run time error,I can understand what is going wrong, not sure why iam getting TypeError: 'NoneType' object is not an iterator

Traceback (most recent call last):
File "solution.py", line 42, in <module>
res = main(x);
File "solution.py", line 34, in main
n = numberParser()
File "solution.py", line 10, in wrapper
next(c)
TypeError: 'NoneType' object is not an iterator 

Upvotes: 1

Views: 5772

Answers (5)

Max Dell-Thibodeau
Max Dell-Thibodeau

Reputation: 11

Try this. This worked for me before the main function:

# Define 'coroutine_decorator' below
def coroutine_decorator(coroutine_func):
    def wrapper(*args,**kwargs):
        c=coroutine_func(*args,**kwargs)
        next(c)
        return c
    return wrapper
    
# Define coroutine 'linear_equation' as specified in previous exercise
@coroutine_decorator
def linear_equation(a, b):
    while True:
        x=yield
        e=a*(x**2)+b
        print("Expression, {0}*x^2 + {2}, with x being {1} equals {3}".format(int(a),x,int(b),float(e)))
        
# Define the coroutine function 'numberParser' below
@coroutine_decorator
def numberParser():
    equation1 = linear_equation(3, 4)
    equation2 = linear_equation(2, -1)
    # code to send the input number to both the linear equations
    while True :
        x = yield
        equation1.send(x)
        equation2.send(x)
    
def main(x):
    n = numberParser()
    n.send(x)

Upvotes: 0

issuesolver in
issuesolver in

Reputation: 39

Below code working for me

# Define the function 'coroutine_decorator' below
def coroutine_decorator(coroutine_func):
    def wrapper(*args, **kwdargs):
        c = coroutine_func(*args, **kwdargs)
        next(c)
        return c
    return wrapper

# Define coroutine 'linear_equation' as specified in previous exercise
@coroutine_decorator
def linear_equation(a, b):
    while True:
        x = yield
        e = a*(x**2)+b
        print('Expression, '+str(a)+'*x^2 + '+str(b)+', with x being '+str(x)+' equals '+str(e))
  

# Define the coroutine function 'numberParser' below
@coroutine_decorator
def numberParser():
    equation1 = linear_equation(3, 4)
    equation2 = linear_equation(2, -1)
    # code to send the input number to both the linear equations
    while True:
        x = yield
        equation1.send(x)
        equation2.send(x)

You have written the below code wrongly for the wrapper Def. Defining the C variable and the below step is part of sub def wrapper.

    def coroutine_decorator(coroutine_func):
        def wrapper(*args, **kwdargs):
        c = coroutine_func(*args, **kwdargs)
        next(c)
        return c
    return wrapper

Then I have added the below block in numberParse Def

while True:
    x = yield
    equation1.send(x)
    equation2.send(x)

Upvotes: 2

user9585964
user9585964

Reputation:

The numberParser coroutine isn't yielding itself for routine

Modify

# code to send the input number to both the linear equations
    equation1.send(6.0)
    equation2.send(6.0)

to

# code to send the input number to both the linear equations
while True :
        x = yield
        equation1.send(x)
        equation2.send(x)

Upvotes: 2

shree
shree

Reputation: 1

You are very close to the answer. Remember the very basic of a coroutine :

execution of a coroutine stops when it reaches yield statement

So all you need to do is call yield on the equation1 and equation2 like this :

equation1.send(x)
equation2.send(x)
equation1 = yield
equation2 = yield

Upvotes: 0

Kevin
Kevin

Reputation: 76254

Since you're calling next on the decorated function, presumably you can only decorate a function if it's a generator or if it returns an iterator. numberParser does not contain a yield statement, and it doesn't return anything, so it doesn't meet those requirements.

You should modify numberParser so it yields something, or so it returns an iterator.

Upvotes: 2

Related Questions