59 lines
1.2 KiB
Python
59 lines
1.2 KiB
Python
|
|
|
|
class FibonacciIterator(object):
|
|
def __init__(self, max_n):
|
|
self._precalculated = {0: 1, 1: 1, 2: 2, 3: 3, 4: 5}
|
|
self._biggest = 4
|
|
self._max_n = max_n
|
|
self._i = 0
|
|
|
|
def get_biggest_pair(self):
|
|
return ((self._biggest - 1, self._precalculated[self._biggest - 1])
|
|
, (self._biggest, self._precalculated[self._biggest]))
|
|
def fibonacci_element(self, n):
|
|
if(not isinstance(n, int)):
|
|
raise TypeError("n must be integer")
|
|
if(0 <= n <= self._biggest):
|
|
return self._precalculated[n]
|
|
|
|
(n_start_minus_one, b), (n_start, a) = self.get_biggest_pair()
|
|
|
|
for i in range(n_start, n):
|
|
swp = a
|
|
a += b
|
|
b = swp
|
|
self._precalculated[n] = a
|
|
|
|
self._biggest = n
|
|
return a
|
|
|
|
def __contains__(self, n):
|
|
if(n > self._max_n):
|
|
raise IndexError("{} > max_n({})".format(n, self._max_n))
|
|
return n <= self._biggest
|
|
|
|
def __getitem__(self, n):
|
|
if(n > self._max_n):
|
|
raise IndexError("{} > max_n({})".format(n, self._max_n))
|
|
return self.fibonacci_element(n)
|
|
|
|
def __iter__(self):
|
|
self._i = -1
|
|
return self
|
|
|
|
def __next__(self):
|
|
if(self._i > self._max_n):
|
|
raise StopIteration()
|
|
self._i += 1
|
|
return self.fibonacci_element(self._i)
|
|
|
|
if( __name__ == "__main__"):
|
|
i = FibonacciIterator(20)
|
|
|
|
for j in i:
|
|
print(j)
|
|
|
|
print(15 in i)
|
|
print(i[14])
|
|
|