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:
- for
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 theFibonacciIteratorclass, 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
-
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__()raisesStopIterationat the appropriate moment.
-
Error: Incorrect variable initialization
- Cause: Incorrect assignment of initial values for
currentandnext_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.
- Cause: Incorrect assignment of initial values for
-
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 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
- Python Iterators - Official Documentation - Official Python documentation on iterators and the iteration protocol.
- Python Iterator Protocol Explained - Detailed description of iterator types and
__iter__()and__next__()methods. - Fibonacci Sequence - Real Python - Comprehensive guide to different Fibonacci sequence implementations in Python.
- Python Generators vs Iterators - Comparison of generators and iterators with usage examples.
- StopIteration Exception - Python Docs - Documentation of the StopIteration exception used in iterators.