Back
Python

Fibonacci sequence iterator

Task

Write an iterator class that generates Fibonacci numbers up to a specified maximum value.

✅ Code

🧠 How it works?

Theory and Context

Class: In Python, classes organize code by grouping variables (attributes) and functions (methods) related to an object.

Iterator: An iterator is a class that implements __iter__() and __next__() methods to create an iterable object that can be used in for loops and other iteration-based constructs.

Fibonacci Sequence: It's a sequence where each number is the sum of the two preceding ones, starting with 0 and 1. Mathematically we define:

  • F0=0F_0 = 0
  • F1=1F_1 = 1
  • Fn=Fn1+Fn2F_n = F_{n-1} + F_{n-2} for n2n \geq 2

StopIteration: It's an exception raised in the __next__() method to signal that there are no more elements to iterate over.

Implementation Analysis

  • class FibonacciIterator: — This is the declaration of the FibonacciIterator class, which will store the state of the Fibonacci iterator.
  • def __init__(self, max_value: int): — This is the constructor that initializes the maximum value, as well as variables for the current and next element of the sequence.
  • self.current = 0 — Sets the initial value of the sequence to 0.
  • self.next_value = 1 — Sets the next value of the sequence to 1.
  • def __iter__(self): return self: — Returns itself as an iterable object. This is a requirement for classes that want to be used as iterators.
  • def __next__(self) -> int: — Captures the logic for extracting the next value in the sequence. Checks if the current value is greater than the maximum. If so, it raises StopIteration.
  • current_value = self.current: — Stores the current state before its update.
  • self.current, self.next_value = self.next_value, self.current + self.next_value: — Updates values for the next iteration.
  • return current_value: — Returns the current value before its update.

In the if __name__ == "__main__": block, an iterator is initialized with a maximum value and sequence elements are printed.

⚠️ Common errors

  1. Error: Not raising StopIteration

    • Cause: Omitting the condition to end the iteration.
    • Consequences: Infinite loop, leading to program overload and crashes.
    • Avoidance: Ensure that __next__() raises StopIteration at the appropriate moment.
  2. Error: Incorrect variable initialization

    • Cause: Incorrect assignment of initial values for current and next_value.
    • Consequences: The loop body may not work as expected, leading to incorrect results.
    • Avoidance: Make sure you initialize variables in the constructor in the correct order.
  3. Error: Incorrect typing

    • Cause: Type mismatches between declared and actual variables.
    • Consequences: Introduction of errors during operation when unexpected types appear.
    • Avoidance: Use typing, but also test and validate input data.

🔁 Other approaches

  • Recursive implementation of the Fibonacci sequence: One can create a recursive function that returns the n-th Fibonacci number.

    • Advantages: Easier to understand in the context of the mathematical definition, pleasant for beginners to learn.
    • Usage context: Good for small values of n, but can be inefficient for large values due to O(2n)O(2^n) complexity.
  • Generators in Python: One can use a generator, which allows for a more elegant and memory-efficient implementation.

  • Advantages: Memory efficiency, reduced complexity, because we do not store class state.
  • Usage context: Ideal when we only need sequential processing of large data sets.

📚 Further Reading