madcrazydrumma
madcrazydrumma

Reputation: 1897

Why is my function throwing a 'StopIteration' exception?

I've got a function that calculates Pythagorean triples using a generator. However when i call next(myfunc()) it throws this error:

Traceback (most recent call last):
  File "path omitted", line 124, in <module>
    next(x)
StopIteration

Where x = myfunc()

Here is my function:

import math

def myfunc():
    i = 1
    for z in range(0, i):
        for y in range(0, z):
            for x in range(0, y):
                if (math.pow(x, 2) + math.pow(y, 2)) == math.pow(z, 2):
                    yield (x*y*z)
                    i += 1

Upvotes: 1

Views: 551

Answers (1)

Holt
Holt

Reputation: 37606

The problem is that your function does not yield anything because your range are probably messed up:

  1. z goes from 0 to i - 1 (0) - So you have only one loop z = 0
  2. y goes from 0 to z - 1 (-1) - See the problem?

So basically you're calling next on an "empty" generator, so you get a StopIteration exception.

Also note that range(0, i) is evaluated only once, just after i = 1, so incrementing i in your inner loop does not affect the bound of your outer loop, so it is a useless statement.

BTW, most of the time you do not have to call next manually, you should rather use a for loop:

for a in myfunc(): # The for loop handle the StopIteration exception for you
    print(a)

Edit: And you should not use math.pow to compute the square value of an integer because it is not accurate (floating point precision) and it is much more slower than doing x * x, so simply check x * x + y * y == z * z (or use python power notation **: x ** 2 + y ** 2 == z ** 2).

Upvotes: 7

Related Questions