more fun with PEP 276

Nick Mathewson QnickQm at alum.mit.edu
Tue Dec 11 03:12:23 CET 2001


In article <mailman.1008029196.13243.python-list at python.org>, 
        James_Althoff at i2.com wrote:
 [...]
> / and // weren't my first choice (< and <= were -- I'm still working
> on that approach) but since they had the advantage of actually
> *working* in this scheme, I just went with it. 

Did you see my post under the subject heading of
  "An implementation of a variation on "for 1 <= i <= 10"  ?

I believe I managed to get "for i in 1 <= Integers() <= 10" nailed,
and I _think_ I got "for i in 1 <= ints <= 10" down pretty well too.

I'll repeat the information here:

============================================================

Here's some code that implements almost this behavior.  Now you can type:

for i in 1 <= ints <= 10:
   print i

I don't have "for i in ints <= 10" going yet, but that should be a fairly
easy extension.

This code requires that you have at least Python 2.2 for the iterator
logic to work.  Python2.2 is still in beta, but hey -- so is this
code. :)

#!/usr/bin/python

class Integers:
    def __init__(self, step=None, auto=0):
	self.lb = None   #Lower bound (inclusive)
	self.ub = None   #Upper bound (inclusive)
	self.up = None   #Flag: Are we counting up (a<i<c) or down (a>i>c)?
	self.step = step #Stepping increment
	self.auto = auto #Automatically return an iterator when we have 2
	                 # bounds?

    def __gt__(self, n):
	self.lb = n+1
	if self.ub == None: self.up = 1	
	if self.auto and self.ub != None and self.lb != None:
	    return iter(self)
	else:
	    return self

    def __lt__(self, n):
	self.ub = n-1
	if self.lb == None: self.up = 0
	if self.auto and self.ub != None and self.lb != None:
	    return iter(self)
	else:
	    return self

    def __ge__(self, n):
	self.lb=n
	if self.ub == None: self.up = 1
	if self.auto and self.ub != None and self.lb != None:
	    return iter(self)
	else:
	    return self

    def __le__(self, n):
	self.ub=n
	if self.lb == None: self.up = 0
	if self.auto and self.ub != None and self.lb != None:
	    return iter(self)
	else:
	    return self

    def __nonzero__(self):
	return 1

    def __iter__(self):
	if self.step == None:
	    self.step = (-1, 1)[self.up]
	else:
	    assert self.step != 0 and self.up == (self.step > 0)
    
	if self.up:
	    return iter(xrange(self.lb, self.ub+1, self.step))
	else:
	    return iter(xrange(self.ub, self.lb-1, self.step))

ints = Integers(step=1, auto=1)

if __name__=='__main__':

    assert [i for i in 1 <= Integers() <= 10] == range(1,11)
    assert [i for i in 10 >= Integers() >= 1] == range(10,0,-1)

    assert [i for i in 1 < Integers() < 10] == range(2,10)
    assert [i for i in 10 > Integers() > 1] == range(9,1,-1)

    assert [i for i in 1 < Integers() <= 10] == range(2,11)
    assert [i for i in 10 > Integers() >= 1] == range(9,0,-1)

    assert [i for i in 1 <= Integers() < 10] == range(1,10)
    assert [i for i in 10 >= Integers() > 1] == range(10,1,-1)
 
    assert [i for i in 2 <= Integers(step=2) < 99] == range(2,99,2)

    n = 0
    for i in 1 <= ints <= 10:
	for j in 1 <= ints <= 10:
	    n += 1
    assert n == 100 
    
    assert zip(1 <= ints <= 3, 1 <= ints <= 3) == zip((1,2,3), (1,2,3))
============================================================

Yrs,
-- 
 Nick Mathewson    <Q nick Q m at alum dot mit dot edu>
                      Remove Q's to respond.  No spam.



More information about the Python-list mailing list