[Tutor] generators and classes
Lloyd Kvam
pythontutor at venix.com
Tue Feb 24 09:25:52 EST 2004
Look at SimPy for some generator code with classes that would be hard to
do otherwise.
http://simpy.sourceforge.net/
Home
Marilyn Davis wrote:
> Thank you for this.
>
> On Tue, 24 Feb 2004, Lloyd Kvam wrote:
>
>
>>In the first example, you call list_unique which handles the
>>looping, calls the generator, and returns a list. The class example
>>puts the looping in the caller and never builds a list. Put unique
>>and list_unique methods into the class and I think it will work more
>>like the first example.
>
>
> I'm just thinking that maybe the generator facility doesn't make sense
> in a class structure --> because the initializing part of the
> generator function belongs in __init__ and then you want the yield to
> be in another function because __init__ isn't allowed to return
> anything. So, you already have two functions with shared scope so you
> might as well return, skip the next(), and keep things simple.
>
> I tried to do what you suggest and it gets clumsy (but it works!).
>
> Maybe you intended something different?
>
> #! /usr/bin/python2.2
> '''
> Demonstrates generators and the 'yield' keyword in the
> context of a class structure.'''
>
> from __future__ import generators
> import random
>
> class Scrambler:
> '''Generator to deliver randomly chosen values from bot
> to over_top - 1, delivering each value once only. To
> collect the numbers, you make an object and call:
> object.take.next()'''
> def __init__(self, bot, over_top):
> self.bot = bot
> self.over_top = over_top
> self.taken = [0] * (over_top - bot)
> self.take = self.dummy()
>
> def dummy(self):
> while 1:
> give = random.randrange(self.bot, self.over_top)
> if not self.taken[give - self.bot]:
> self.taken[give - self.bot] = 1
> yield give
>
> if __name__ == '__main__':
> scram = Scrambler(0,10)
> for i in range(10):
> print scram.take.next()
>
> #############################
> # OUTPUT:
> # bash-2.05a$ ./scrambler.py
> # 3
> # 4
> # 8
> # 2
> # 7
> # 1
> # 6
> # 0
> # 9
> # 5
> # bash-2.05a$
>
> ----
>
>>Marilyn Davis wrote:
>>
>>
>>>Hello again,
>>>
>>>I wrote this little program to demonstrate a generator:
>>>
>>>#! /usr/bin/python2.2
>>>'''Function to generate random numbers without repetition.
>>>Demonstrates generators and the 'yield' keyword.'''
>>>
>>>from __future__ import generators
>>>import random
>>>
>>>def unique(bot, over_top):
>>> '''Generator to deliver randomly chosen values from bot
>>> to over_top - 1, delivering each value once only.'''
>>> taken = [0] * (over_top - bot)
>>> while (1):
>>> give = random.randrange(bot, over_top)
>>> if not taken[give - bot]:
>>> taken[give - bot] = 1
>>> yield give
>>>
>>>def list_unique(bot, over_top):
>>> '''Returns a list of the generated numbers'''
>>> gen = unique(bot, over_top)
>>> return [gen.next() for i in range(bot, over_top)]
>>>
>>>if __name__ == '__main__':
>>> print '(0,5) = ', list_unique(0,5)
>>> print '(10,21) = ', list_unique(10,21)
>>>
>>>#############################
>>># OUTPUT:
>>># bash-2.05a$ ./unique.py
>>># (0,5) = [2, 3, 1, 0, 4]
>>># (10,21) = [17, 10, 18, 20, 19, 15, 11, 13, 12, 16, 14]
>>># bash-2.05a$
>>>
>>>-----
>>>
>>>But now that I'm preparing to teach OO, I want to do the class
>>>equivalent, which turns out like this:
>>>
>>>#! /usr/bin/env python2.2
>>>
>>>import random
>>>
>>>class NumberHat:
>>> '''Generator to deliver randomly chosen values from bot
>>>to over_top - 1, delivering each value once only.'''
>>> def __init__(self, bot, over_top):
>>> self.bot = bot
>>> self.over_top = over_top
>>> self.taken = [0] * (over_top - bot)
>>>
>>> def take(self):
>>> while 1:
>>> give = random.randrange(self.bot, self.over_top)
>>> if not self.taken[give - self.bot]:
>>> self.taken[give - self.bot] = 1
>>> return give
>>>
>>>if __name__ == '__main__':
>>> hat = NumberHat(0,10)
>>> for i in range(10):
>>> print hat.take()
>>>
>>>############################################################
>>># OUTPUT:
>>># bash-2.05a$ ./numberhat.py
>>># 1
>>># 5
>>># 6
>>># 9
>>># 3
>>># 7
>>># 0
>>># 8
>>># 2
>>># 4
>>># bash-2.05a$
>>>
>>>---
>>>
>>>But there's no generator in it. Is this natural? Or is there
>>>some other thought I should be thinking?
>>>
>>>Thank you again and again.
>>>
>>>Marilyn
>>>
>>>
>>>_______________________________________________
>>>Tutor maillist - Tutor at python.org
>>>http://mail.python.org/mailman/listinfo/tutor
>>>
>>
>>
>
--
Lloyd Kvam
Venix Corp.
1 Court Street, Suite 378
Lebanon, NH 03766-1358
voice: 603-653-8139
fax: 801-459-9582
More information about the Tutor
mailing list