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

More elegant way to try running a function X times?

P: n/a
Hello

As a newbie, it's pretty likely that there's a smarter way to do this,
so I'd like to check with the experts:

I need to try calling a function 5 times. If successful, move on; If
not, print an error message, and exit the program:

=====
success = None

for i in range(5):
#Try to fetch public IP
success = CheckIP()
if success:
break

if not success:
print "Exiting."
sys.exit()
=====

Thank you.
Nov 19 '08 #1
Share this Question
Share on Google+
9 Replies


P: n/a
I need to try calling a function 5 times. If successful, move on; If
not, print an error message, and exit the program:

success = None
for i in range(5):
#Try to fetch public IP
success = CheckIP()
if success:
break
if not success:
print "Exiting."
sys.exit()
Though a bit of an abuse, you can use

if not any(CheckIP() for _ in range(5)):
print "Exiting"
sys.exit()

(this assumes Python2.5, but the any() function is easily
recreated per the docs at [1]; and also assumes the generator
creation of 2.4, so this isn't as useful in 2.3 and below)

Alternatively, you can use the for/else structure:

for i in range(5):
if CheckIP():
break
else:
print "Exiting"
sys.exit()

-tkc

[1]
http://www.python.org/doc/2.5.2/lib/...cs.html#l2h-10

..
Nov 19 '08 #2

P: n/a
Gilles Ganault <no****@nospam.comwrote:
>As a newbie, it's pretty likely that there's a smarter way to do this,
so I'd like to check with the experts:

I need to try calling a function 5 times. If successful, move on; If
not, print an error message, and exit the program:

=====
success = None

for i in range(5):
#Try to fetch public IP
success = CheckIP()
if success:
break

if not success:
print "Exiting."
sys.exit()
=====
for i in range(5):
if CheckIP():
break
else:
print "Exiting."
sys.exit()

Note very carefully that the "else" goes with the "for" and not the "if".

--
\S -- si***@chiark.greenend.org.uk -- http://www.chaos.org.uk/~sion/
"Frankly I have no feelings towards penguins one way or the other"
-- Arthur C. Clarke
her nu becomež se bera eadward ofdun hlęddre heafdes bęce bump bump bump
Nov 19 '08 #3

P: n/a

On Nov 19, 2008, at 09:09, Gilles Ganault wrote:
Hello

As a newbie, it's pretty likely that there's a smarter way to do this,
so I'd like to check with the experts:

I need to try calling a function 5 times. If successful, move on; If
not, print an error message, and exit the program:

=====
success = None

for i in range(5):
#Try to fetch public IP
success = CheckIP()
if success:
break

if not success:
print "Exiting."
sys.exit()
=====
A little simpler:

for i in range(5):
if CheckIP():
break
else:
print "Exiting."
sys.exit()

The else part will only fire if the for finishes without breaking.
Hope this helps a bit...
Nick Fabry



Thank you.
--
http://mail.python.org/mailman/listinfo/python-list
Nov 19 '08 #4

P: n/a
On 19 Nov 2008 14:37:06 +0000 (GMT), Sion Arrowsmith
<si***@chiark.greenend.org.ukwrote:
>Note very carefully that the "else" goes with the "for" and not the "if".
Thanks guys.
Nov 19 '08 #5

P: n/a
On Nov 19, 10:21*am, Gilles Ganault <nos...@nospam.comwrote:
On 19 Nov 2008 14:37:06 +0000 (GMT), Sion Arrowsmith

<si...@chiark.greenend.org.ukwrote:
Note very carefully that the "else" goes with the "for" and not the "if"..

Thanks guys.
And if you end up doing this for several different functions, you can
factor it out with the following decorator:

class MaxRetriesExceededError(Exception):
pass

def retry(n):
def decorator(f):
def wrapper(*args, **kwds):
for i in xrange(n):
r = f(*args, **kwds)
if r: return r
raise MaxRetriesExceededError
return wrapper
return decorator

If the number of retries is fixed and known at "compile" time, you can
use the standard decorator syntax:

@retry(5)
def CheckIP():
...

If not, just decorate it explicitly at runtime:

def CheckIP():
...

n = int(raw_input('Give number of retries:'))
CheckIP = retry(n)(CheckIP)
HTH,
George
Nov 19 '08 #6

P: n/a
Tim Chase wrote:
>success = None
for i in range(5):
#Try to fetch public IP
success = CheckIP()
if success:
break
if not success:
print "Exiting."
sys.exit()

Though a bit of an abuse, you can use

if not any(CheckIP() for _ in range(5)):
print "Exiting"
sys.exit()
I don't see why you speak of abuse, bit of abuse would be, say if you replaced
range(5) by '12345' to win a char; but otoh I think you misspelled any() for all().

Cheers BB

Nov 20 '08 #7

P: n/a
>>success = None
>>for i in range(5):
#Try to fetch public IP
success = CheckIP()
if success:
break
if not success:
print "Exiting."
sys.exit()
Though a bit of an abuse, you can use

if not any(CheckIP() for _ in range(5)):
print "Exiting"
sys.exit()

I don't see why you speak of abuse, bit of abuse would be, say if you replaced
range(5) by '12345' to win a char; but otoh I think you misspelled any() for all().
The OP's code break'ed (broke?) upon the first success, rather
than checking all of them. Thus, it would be any() rather than
all(). Using all() would require 5 successful calls to
CheckIP(), rather than one-out-of-five successful calls.

As for abuse, the "for _ in iterable" always feels a little hokey
to me. It works, but feels warty.

-tkc

Nov 20 '08 #8

P: n/a
Gilles Ganault wrote:
Hello

As a newbie, it's pretty likely that there's a smarter way to do this,
so I'd like to check with the experts:

I need to try calling a function 5 times. If successful, move on; If
not, print an error message, and exit the program:

=====
success = None

for i in range(5):
#Try to fetch public IP
success = CheckIP()
if success:
break

if not success:
print "Exiting."
sys.exit()
Use the for statement's "else" clause: it's there to allow you to
specify code to be executed only when the loop terminates normally.

for i in range(5):
if CheckIP():
break
else:
sys.exit("Could not verify IP address")
.... remainder of program ...

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC http://www.holdenweb.com/

Nov 20 '08 #9

P: n/a
Tim Chase wrote:
>>>success = None
for i in range(5):
#Try to fetch public IP
success = CheckIP()
if success:
break
if not success:
print "Exiting."
sys.exit()
Though a bit of an abuse, you can use

if not any(CheckIP() for _ in range(5)):
print "Exiting"
sys.exit()

I don't see why you speak of abuse, bit of abuse would be, say if you
replaced range(5) by '12345' to win a char; but otoh I think you
misspelled any() for all().

The OP's code break'ed (broke?) upon the first success, rather than
checking all of them. Thus, it would be any() rather than all(). Using
all() would require 5 successful calls to CheckIP(), rather than
one-out-of-five successful calls.
Right. So it could also be written " if all(not CheckIP()... ". Perhaps more
closely re-telling the OP's ?
>
As for abuse, the "for _ in iterable" always feels a little hokey to
me. It works, but feels warty.
I guess this means you did not learn Prolog before Python ?

Cheers, BB

Nov 20 '08 #10

This discussion thread is closed

Replies have been disabled for this discussion.