Presentation is loading. Please wait.

Presentation is loading. Please wait.

Computer Science 112 Fundamentals of Programming II Iterators.

Similar presentations


Presentation on theme: "Computer Science 112 Fundamentals of Programming II Iterators."— Presentation transcript:

1 Computer Science 112 Fundamentals of Programming II Iterators

2 The for Loop for value in : Allows the programmer to iterate through all of the values in a collection (or any other iterable object)

3 The for Loop for value in : list( ) # builds a list from the collection Users:

4 The for Loop for value in : list( ) # builds a list from the collection sum( ) Users:

5 The for Loop for value in : list( ) # builds a list from the collection sum( ) min( ) Users:

6 The for Loop for value in : list( ) # builds a list from the collection sum( ) min( ) map(, ) Users:

7 The for Loop for value in : list( ) # builds a list from the collection sum( ) min( ) map(, ) filter(, ) Users:

8 The for Loop for value in : list( ) # builds a list from the collection sum( ) min( ) map(, ) filter(, ) in Users:

9 The Benefits of a for Loop class ArrayBag(object): DEFAULT_CAPACITY = 10 def __init__(self, sourceCollection = None): self._items = Array(ArrayBag.DEFAULT_CAPACITY) self._size = 0 if sourceCollection: for item in sourceCollection: self.add(item) Here we assume that sourceCollection is iterable s = ArrayBag(range(1, 11))

10 The Benefits of a for Loop class LinkedBag(object): def __init__(self, sourceCollection = None): self._items = None self._size = 0 if sourceCollection: for item in sourceCollection: self.add(item) Here we assume that sourceCollection is iterable s = LinkedBag(range(1, 11))

11 The Benefits of a for Loop class ArrayBag(object): def __add__(self, other): """Returns a new bag containing the contents of self and other.""" result = ArrayBag(self) for item in other: result.add(item) return result Here we assume that self and other are iterable b3 = b1 + b2

12 The Benefits of a for Loop class ArrayBag(object): def __str__(self): """Returns the string representation of self.""" return "{" + ", ".join(map(str, self)) + "}" Here we assume that self is iterable

13 Loop Patterns and Iterators for i in range(someInteger): for value in someCollection: When the PVM sees a for loop, it evaluates the second operand of in and then calls the iter function on its value The code in the iter function repeatedly fetches the next value in the second operand and binds it to the first operand After each fetch operation, the code in the loop body is run

14 Two Loop Patterns Thus, the second operand of in must include an __iter__ method in its class If you want your collection to be iterable, you must define an __iter__ method for i in range(someInteger): for value in someCollection:

15 Implementing an Iterator class Array(object): def __init__(self, capacity, fillValue = None): self._items = list() for count in range(capacity): self._items.append(fillValue) def __iter__(self): return iter(self._items) The __iter__ method of the Array class simply returns the result of calling iter on its underlying list

16 ArrayBag Iterator: A Nice Try class ArrayBag(object): DEFAULT_CAPACITY = 10 def __init__(self, sourceCollection = None): self._items = Array(ArrayBag.DEFAULT_CAPACITY) self._size = 0 if sourceCollection: for item in sourceCollection: self.add(item) def __iter__(self): return iter(self._items) What’s wrong with this code?

17 Designing an Iterator The __iter__ method must initialize and maintain a cursor, which locates the current item __iter__ ’s loop quits when the cursor goes off the end of the collection The body of the loop yields the current item and advances the cursor

18 Implementing an Iterator class ArrayBag(object): DEFAULT_CAPACITY = 10 def __init__(self, sourceCollection = None): self._items = Array(ArrayBag.DEFAULT_CAPACITY) self._size = 0 if sourceCollection: for item in sourceCollection: self.add(item) def __iter__(self): cursor = 0 while cursor < len(self): yield self._items[cursor] cursor += 1

19 Running an Iterator DDD collection iterator def __iter__(self): cursor = 0 while cursor < len(self): yield self._items[cursor] cursor += 1

20 Running an Iterator DDD collection iterator def __iter__(self): cursor = 0 while cursor < len(self): yield self._items[cursor] cursor += 1

21 Running an Iterator DDD collection iterator def __iter__(self): cursor = 0 while cursor < len(self): yield self._items[cursor] cursor += 1

22 Running an Iterator DDD collection iterator def __iter__(self): cursor = 0 while cursor < len(self): yield self._items[cursor] cursor += 1

23 An Iterator for a Linked Structure The cursor would be initialized to the head pointer (like a probe) The loop quits when the cursor equals None The value yielded is in the cursor’s node The cursor is updated by setting it to the next node

24 Implementing an Iterator class LinkedBag(object): def __init__(self, sourceCollection = None): self._items = None self._size = 0 if sourceCollection: for item in sourceCollection: self.add(item) def __iter__(self): cursor = self._items while cursor != None: yield cursor.data cursor = cursor.next

25 Iterator Should Be Read-Only for item in bag: bag.remove(item) Mutations in the context of a for loop can cause the state of the underlying collection to become inconsistent with the state of the iterator

26 Iterator Should Be Read-Only for item in bag: bag.remove(item) # Will raise an exception We can arrange for the collection to track mutations so that the iterator can detect illicit ones and raise exceptions bag.clear() # Preferred method

27 For Monday Inheritance and Abstract Classes Chapter 6


Download ppt "Computer Science 112 Fundamentals of Programming II Iterators."

Similar presentations


Ads by Google