Computational Modeling Fall 2005 For today: at least started on HomeworkTwenty Today: 1) iterators and generators 2) discrete event simulation 3) reductionism vs. what? Iterators --------- In order to be iterated over, an object has to define an __iter__ method that returns an iterator object. The iterator object has to have a next method that can be invoked repeatedly, each time returning the "next" value in the sequence, or raising the StopIteration exception. Try this: t = [1, 2, 3] i = t.__iter__() print i print type(i) i.next() # do this 4 times What happens if you have more than one iterator for the same list? What happens if you create an iterator, modify the list, and then iterate through the iterator? The __iter__ method can (and often does) return a reference to the object itself, so both __iter__ and next are implemented in the same class. In that case you can only have one iterator over the the object at a time. class Iterator: def __init__(self): self.data = [1, 2, 3] self.index = 0 def __iter__(self): return self def next(self): if self.index == len(self.data): raise StopIteration res = self.data[self.index] self.index += 1 return res iterator = Iterator() for i in iterator: print i So one way to iterate over a user-defined object is to implement the iterator protocol. Another way is to inherit from one of the built-in container classes, all of which implement the iterator protocol. A third way is to write a generator. Generator --------- Any function that contains a yield statement is a generator function. The return value from a generator function is an generator iterator, sometimes called generator. Try this: import string def id_genfun(): for c in string.uppercase: yield c idgenerator = id_genfun() print idgenerator print type(idgenerator) print idgenerator.next() for id in idgenerator: print id Combining these ideas, we can use generators to implement the iterator protocol: class Iterator: def __init__(self): self.data = [1, 2, 3] def __iter__(self): for i in self.data: yield i iterator = Iterator() for i in iterator: print i The __iter__ method is a generator function, so it returns a generator iterator, which is a perfectly legal iterator. Notice that this is much smaller than the previous version. Pirates ------- A framework you might want to use is at http://wb/cm/code/Pirate1.py Notice the generator function that hands out ids. An Event is a singleton list, which means I can put it in a Heap and the Heap knows how to compare Events. class Event(list): def __init__(self, time): self.append(time) One problem is that to access the time of an event, I would have to remember that e[0] is the time. One solution is to define accessor methods: and then define a property: def get_time(self): return self[0] def set_time(self, t): self[0] = t time = property(get_time, set_time) Now if you say e = Event(10) print e.time # python uses get_time e.time = 11 # python used set_time Probably a better solution would have been to make time an attribute and define a __cmp__ method for the Event class. Each event has a reference named handle to a method that will be used to handle the event. def make_fall(time, pirate): """return a new fall Event with the given time and pirate """ e = Event(time) e.pirate = pirate e.handle = e.handle_fall # SET THE HANDLER return e In the main loop, this make it easy to dispatch an event to the right handler: while heap: # get the next event e = heap.popmin() # update the global clock and handle the event gtime = e.time e.handle() Reductionism vs. what? ---------------------- So far we have focused on predictive models, which are judged primarily by their accuracy, and secondarily by the other criteria Kuhn mentioned. Explanatory models may (or may not) be a different thing, to be judged by different criteria. Explantory models are answers to "why" questions. But "why" questions are fundamentally ill-posed, so it is not easy to say what a satisfactory answer should look like. The most powerful tool we have for answering why questions is reductionism. Is it the _only_ tool? What are the alternatives?