ASPN ActiveState Programmer Network
ActiveState
/ Home / Perl / PHP / Python / Tcl / XSLT /
/ Safari / My ASPN /
Cookbooks | Documentation | Mailing Lists | Modules | News Feeds | Products | User Groups


Recent Messages
List Archives
About the List
List Leaders
Subscription Options

View Subscriptions
Help

View by Topic
ActiveState
.NET Framework
Open Source
Perl
PHP
Python
Tcl
Web Services
XML & XSLT

View by Category
Database
General
SOAP
System Administration
Tools
User Interfaces
Web Programming
XML Programming


MyASPN >> Mail Archive >> python-tutor
python-tutor
[Tutor] PolyRange -- iterator
by Spir other posts by this author
Nov 4 2009 8:44AM messages near this date
[Tutor] probando el email / mail test | Re: [Tutor] PolyRange -- iterator
Hello,

as I was crawling in endless complications with unadequate ranges, I decided to create a "Po
lyRange" type able to hold arbitrary many "sub-range"; which means finally a big range with 
wholes in it. This whole stuff again to cope with unicode -- a poly-range would be able to h
old a range for a char class (eg 'letter') which spans over several ordinal ranges. (Viva un
icode consortium!)

So, it works as needed. It is even able to "stretch" over addictional sub-ranges or to "unit
e" with a poly-range brother (sister, too). See code below.

Now, I need it to be properly iterable if needed -- the main use beeing indeed the 'in' oper
ator -- but who knows. So, I tried to implement __iter__ and next (by the way, why isin't it
 called __next__ instead, looks strange for a python builtin?). Seems to work, but the resul
t looks veeery heavy to my eyes. As I had never written an iterator before, would be nice an
d criticize the code?

Thank you,
Denis
-------
la vita e estrany



==========================================================
class PolyRange(object):
    def __init__(self, *bounds):
        ''' Build list of ranges from bounds.
            * bounds must sequence of (n1,n2) pairs. '''
        self.bounds = list(bounds)
        self.ranges = [xrange(n1,n2) for (n1,n2) in bounds]
        # iteration
    def __contains__(self, item):
        ''' x in self '''
        for range in self.ranges:
            if item in range:
                return True
    def __or__(self, other):
        ''' PolyRange union '''
        bounds = self.bounds + other.bounds
        return PolyRange(*bounds)
    def __add__(self, range):
        ''' PolyRange with new range added '''
        n1 = range[0] ; n2 = n1+len(range)
        bounds = self.bounds + [(n1,n2)]
        return PolyRange(*bounds)
    def __iter__(self):
        self.isEmpty = False
        (self.range_index, self.item_index) = (0,0)
        self.iter = self.ranges[0].__iter__()
        return self
    def next(self):
        # case already emptied
        if self.isEmpty:
            raise StopIteration
        # throw next item
        try:
            item = self.iter.next()
        except StopIteration:
            self.range_index += 1
            self.item_index = 0
        else:
            self.item_index += 1
            return item
        # next range
        if len(self.ranges) >  self.range_index:
            self.iter = self.ranges[self.range_index].__iter__()
        else:
            self.empty = True
            raise StopIteration
        # throw item
        try:
            item = self.iter.next()
        except StopIteration:
            self.empty = True
            raise StopIteration
        else:
            self.item_index += 1
            return item
    def __str__(self):
        return "(%s)" %'U'.join("[%s,%s)" %(n1,n2) for (n1,n2) in self.bounds)
    def __repr__(self):
        return "PolyRange(%s)" %', '.join(str(b) for b in self.bounds)
        return False

def testPolyRange():
    print "=== base case -- test in/contains"
    pr = PolyRange((1,3),(5,7),(9,11))
    print "%s\t%s" %(pr,repr(pr))
    print 2 in pr, 4 in pr

    print "=== union"
    pr = PolyRange((1,3),(5,7)) | PolyRange((9,11))
    print pr

    print "=== addition, iteration"
    r = xrange(3,9)
    pr0 = PolyRange((1,3),(5,7))
    pr1 = pr0 + r
    print pr1
    for i in pr1: print i,
testPolyRange()


_______________________________________________
Tutor maillist  -  Tutor@[...].org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Thread:
Spir
Hugo Arts
Spir
Hugo Arts
Stefan Lesicnik

Privacy Policy | Email Opt-out | Feedback | Syndication
© ActiveState Software Inc. All rights reserved