By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,333 Members | 1,850 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,333 IT Pros & Developers. It's quick & easy.

Feedback on Until recipe

P: n/a
Occasionally someone posts to this group complaining about the lack of
"repeat ... until" in python. I too have occasionally wished for such
a construct, and after some thinking, I came up with the class below.
I'm hoping to get some feedback here, and if people besides me think
they might use it someday, I can put it on the python cookbook. I'm
pretty happy with it, the only ugly thing is you have to use a
lambda. Ideally i'd like to just see
while Until(i<3)
but that doesn't work.
Please tell me what you think, and thanks for your time.

Tom

class Until:
"""
>>i = 0
while Until(lambda: i<3):
... print "hello"
... i += 1
hello
hello
hello
>>while Until(lambda: i<2): #note i still equals 3 here
... print "hello"
hello
"""
yet = True
def __init__(self, mybool):
if self.__class__.yet or mybool():
self.__class__.yet = False
self.ans = True
else:
self.__class__.yet = True
self.ans = False

def __nonzero__(self):
return self.ans

Apr 24 '07 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Thomas Nelson wrote:
Occasionally someone posts to this group complaining about the lack of
"repeat ... until" in python. I too have occasionally wished for such
a construct, and after some thinking, I came up with the class below.
I'm hoping to get some feedback here, and if people besides me think
they might use it someday, I can put it on the python cookbook. I'm
pretty happy with it, the only ugly thing is you have to use a
lambda. Ideally i'd like to just see
while Until(i<3)
but that doesn't work.
Please tell me what you think, and thanks for your time.

Tom

class Until:
"""
>>i = 0
>>while Until(lambda: i<3):
... print "hello"
... i += 1
hello
hello
hello
>>while Until(lambda: i<2): #note i still equals 3 here
... print "hello"
hello
"""
yet = True
def __init__(self, mybool):
if self.__class__.yet or mybool():
self.__class__.yet = False
self.ans = True
else:
self.__class__.yet = True
self.ans = False

def __nonzero__(self):
return self.ans
First of all, I have to say it reads horribly. "while Until(...)" is
supposed to remind us of a *repeat* loop?

Secondly it isn't really what you want because the condition is still
being evaluated before the loop body is executed, when the idea of a
repeat loop is to terminate the loop after at least one iteration once
the condition is true. This is not strictly equivalent to your
conditions. Temporal logic is tricky.

By the way, isn't it always true that self.ans == not self.__class__.yet
(and why use a class variable, by the way, doesn't this stop you from
using nested loops)?

That's about all I can think of offhand. Sorry if it seems a bit
negative. I'm hoping it will spur you on to a better solution.

regards
Steve
regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://del.icio.us/steve.holden
Recent Ramblings http://holdenweb.blogspot.com

Apr 24 '07 #2

P: n/a
On Apr 24, 11:08 am, Thomas Nelson <t...@mail.utexas.eduwrote:
Occasionally someone posts to this group complaining about the lack of
"repeat ... until" in python. I too have occasionally wished for such
a construct, and after some thinking, I came up with the class below.
I'm hoping to get some feedback here, and if people besides me think
they might use it someday, I can put it on the python cookbook. I'm
pretty happy with it, the only ugly thing is you have to use a
lambda. Ideally i'd like to just see
while Until(i<3)
but that doesn't work.
Please tell me what you think, and thanks for your time.

Tom

class Until:
"""
>>i = 0
>>while Until(lambda: i<3):
... print "hello"
... i += 1
hello
hello
hello
>>while Until(lambda: i<2): #note i still equals 3 here
... print "hello"
hello
"""
yet = True
def __init__(self, mybool):
if self.__class__.yet or mybool():
self.__class__.yet = False
self.ans = True
else:
self.__class__.yet = True
self.ans = False

def __nonzero__(self):
return self.ans
Class-level "yet" variable not a good idea. Loops can be nested:

i = 0
# this should loop once, since test is logically at the end of the
loop
while Until(lambda : i < 0 ):
print "hello"
i += 1
j = 0
while Until(lambda : j < 0 ):
print "byebye"
j += 1

This loops forever.

After tinkering with this a bit, I can see why you need a class
variable. In your outer loop, "Until(lambda : i < 0)" is evaluated
every time around the loop, creating a new Until object, so you can't
preserve looping state in the object, you have to do it in the class.

I used your idea to create an instance-level Until that survives
looping, but the requirements for construction are still onerous. In
essence, the instance-level util defers the break-on-condition by one
loop iteration.

class Until:
"""
>>i = 0
while Until(lambda: i<3):
... print "hello"
... i += 1
hello
hello
hello
>>while Until(lambda: i<2):
... print "hello"
hello
"""
def __init__(self, mybool):
self.lastTest = True
self.mybool = mybool

def __nonzero__(self):
ret,self.lastTest = self.lastTest,self.mybool()
return ret

i = 0
uCond1 = Until(lambda : i < 0 )
uCond2 = Until(lambda : j < 0 )
while uCond1:
print "hello"
i += 1
j = 0
while uCond2:
print "byebye"
j += 1

-- Paul

Apr 26 '07 #3

P: n/a
I moved the state into the Until instance vs. the Until class, so that
it now supports nesting. But the calling syntax is even uglier - but
necessary to avoid creating a new Until instance each time around.
That is "while Until(blah):" evaluates and constructs a new Until
instance each time around the loop, so that is why the state had to be
kept in a class-level variable in your original design (which is why
nesting doesn't work).

class Until:
def __init__(self, mybool):
self.lastTest = True
self.mybool = mybool

def __nonzero__(self):
ret,self.lastTest = self.lastTest,self.mybool()
return ret

i = 0
u1 = Until(lambda : i < 0 )
while u1:
print "hello"
i += 1
j = 0
u2 = Until(lambda : j < 0 )
while u2:
print "byebye"
j += 1

Apr 26 '07 #4

P: n/a
On Wed, 2007-04-25 at 19:11 -0700, Paul McGuire wrote:
I moved the state into the Until instance vs. the Until class, so that
it now supports nesting. But the calling syntax is even uglier - but
necessary to avoid creating a new Until instance each time around.
That is "while Until(blah):" evaluates and constructs a new Until
instance each time around the loop, so that is why the state had to be
kept in a class-level variable in your original design (which is why
nesting doesn't work).

class Until:
def __init__(self, mybool):
self.lastTest = True
self.mybool = mybool

def __nonzero__(self):
ret,self.lastTest = self.lastTest,self.mybool()
return ret

i = 0
u1 = Until(lambda : i < 0 )
while u1:
print "hello"
i += 1
j = 0
u2 = Until(lambda : j < 0 )
while u2:
print "byebye"
j += 1
Using iterators is a way around the problem of making a new instance
every time around the loop, but the calling syntax is not much nicer
since it is shoehorned into a for-loop. Note that I've renamed the beast
in order to reflect what it actually does: The loop body is repeated as
long as the given condition is true.

class RepeatAsLongAs(object):
def __init__(self, cond):
self.cond = cond
self.previousTest = True
def __iter__(self):
return self
def next(self):
ret, self.previousTest = self.previousTest, self.cond()
if not ret: raise StopIteration
return ret

i = 0
for _ in RepeatAsLongAs(lambda: i<0):
print "hello"
i += 1
j = 0
for _ in RepeatAsLongAs(lambda: j<0):
print "byebye"
j += 1

Having said that, I don't see myself ever using such a beast. The
equivalent code

while True:
# do something
if until_condition: break

is much more concise, much easier to understand, and it shows explicitly
that the condition is checked after the loop body is executed.

-Carsten
Apr 26 '07 #5

P: n/a
On 2007-04-24, Thomas Nelson <th*@mail.utexas.eduwrote:
Occasionally someone posts to this group complaining about the lack of
"repeat ... until" in python. I too have occasionally wished for such
a construct, and after some thinking, I came up with the class below.
I'm hoping to get some feedback here, and if people besides me think
they might use it someday, I can put it on the python cookbook. I'm
pretty happy with it, the only ugly thing is you have to use a
lambda. Ideally i'd like to just see
while Until(i<3)
but that doesn't work.
Please tell me what you think, and thanks for your time.
Maybe we should try to get the developers revive PEP 315.

This PEP whould introduce a do-while statement that looks
like the folowing:

do
statements
while condition
statements
this would be equivallent to:

while 1:
statements
if not condition:
break
statements
Those wanting something like:

repeat
statements
until condition
Could then write something like:

do
statements
while not condition
pass
Still not the most elegant but a vast improvement IMO.

--
Antoon Pardon
Apr 26 '07 #6

P: n/a
On Apr 26, 11:58 am, Antoon Pardon <apar...@forel.vub.ac.bewrote:
On 2007-04-24, Thomas Nelson <t...@mail.utexas.eduwrote:
Occasionally someone posts to this group complaining about the lack of
"repeat ... until" in python. I too have occasionally wished for such
a construct, and after some thinking, I came up with the class below.
I'm hoping to get some feedback here, and if people besides me think
they might use it someday, I can put it on the python cookbook. I'm
pretty happy with it, the only ugly thing is you have to use a
lambda. Ideally i'd like to just see
while Until(i<3)
but that doesn't work.
Please tell me what you think, and thanks for your time.

Maybe we should try to get the developers revive PEP 315.

This PEP whould introduce a do-while statement that looks
like the folowing:

do
statements
while condition
statements

this would be equivallent to:

while 1:
statements
if not condition:
break
statements

Those wanting something like:

repeat
statements
until condition

Could then write something like:

do
statements
while not condition
pass

Still not the most elegant but a vast improvement IMO.
At http://mail.python.org/pipermail/pyt...ry/060718.html
Raymond Hettinger suggested removing the final colon after the 'while'
if there's no statement after it, which I agree with, although I would
prefer 'repeat' instead of 'do' (IMHO that doesn't suggest repetition
clearly enough):

repeat:
statements
while condition:
statements

and:

repeat:
statements
while condition

Apr 26 '07 #7

P: n/a
On 2007-04-26, MRAB <go****@mrabarnett.plus.comwrote:
At http://mail.python.org/pipermail/pyt...ry/060718.html
Raymond Hettinger suggested removing the final colon after the 'while'
if there's no statement after it, which I agree with, although I would
prefer 'repeat' instead of 'do' (IMHO that doesn't suggest repetition
clearly enough):

repeat:
statements
while condition:
statements

and:

repeat:
statements
while condition
I wouldn't object to this. But more important than how it will look like
IMO is that it gets implemented. Acoording to your URL there is little
chance that this will be implemented before Py3k. A pity.

--
Antoon Pardon
Apr 27 '07 #8

This discussion thread is closed

Replies have been disabled for this discussion.