Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #27710 > unrolled thread
| Started by | Mark Carter <alt.mcarter@gmail.com> |
|---|---|
| First post | 2012-08-23 02:05 -0700 |
| Last post | 2012-08-24 07:48 +1000 |
| Articles | 18 — 8 participants |
Back to article view | Back to comp.lang.python
Guarding arithmetic Mark Carter <alt.mcarter@gmail.com> - 2012-08-23 02:05 -0700
Re: Guarding arithmetic Chris Angelico <rosuav@gmail.com> - 2012-08-23 19:16 +1000
Re: Guarding arithmetic Mark Carter <alt.mcarter@gmail.com> - 2012-08-23 02:22 -0700
Re: Guarding arithmetic Chris Angelico <rosuav@gmail.com> - 2012-08-23 19:29 +1000
Re: Guarding arithmetic Mark Carter <alt.mcarter@gmail.com> - 2012-08-23 02:22 -0700
Re: Guarding arithmetic Laszlo Nagy <gandalf@shopzeus.com> - 2012-08-23 11:23 +0200
Re: Guarding arithmetic Mark Carter <alt.mcarter@gmail.com> - 2012-08-23 02:47 -0700
Re: Guarding arithmetic Mark Carter <alt.mcarter@gmail.com> - 2012-08-23 02:47 -0700
Re: Guarding arithmetic Laszlo Nagy <gandalf@shopzeus.com> - 2012-08-23 11:28 +0200
Re: Guarding arithmetic Chris Angelico <rosuav@gmail.com> - 2012-08-23 19:30 +1000
Re: Guarding arithmetic Peter Otten <__peter__@web.de> - 2012-08-23 12:11 +0200
Re: Guarding arithmetic rusi <rustompmody@gmail.com> - 2012-08-23 10:15 -0700
Re: Guarding arithmetic Laszlo Nagy <gandalf@shopzeus.com> - 2012-08-23 13:01 +0200
Re: Guarding arithmetic MRAB <python@mrabarnett.plus.com> - 2012-08-23 12:21 +0100
Re: Guarding arithmetic Peter Otten <__peter__@web.de> - 2012-08-23 13:28 +0200
Re: Guarding arithmetic Mark Lawrence <breamoreboy@yahoo.co.uk> - 2012-08-23 15:11 +0100
Re: Guarding arithmetic Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2012-08-23 14:49 -0400
Re: Guarding arithmetic Chris Angelico <rosuav@gmail.com> - 2012-08-24 07:48 +1000
| From | Mark Carter <alt.mcarter@gmail.com> |
|---|---|
| Date | 2012-08-23 02:05 -0700 |
| Subject | Guarding arithmetic |
| Message-ID | <8b9a5844-66b0-4940-946a-5e626462cdce@googlegroups.com> |
Suppose I want to define a function "safe", which returns the argument passed if there is no error, and 42 if there is one. So the setup is something like: def safe(x): # WHAT WOULD DEFINE HERE? print safe(666) # prints 666 print safe(1/0) # prints 42 I don't see how such a function could be defined. Is it possible?
[toc] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2012-08-23 19:16 +1000 |
| Message-ID | <mailman.3700.1345713371.4697.python-list@python.org> |
| In reply to | #27710 |
On Thu, Aug 23, 2012 at 7:05 PM, Mark Carter <alt.mcarter@gmail.com> wrote:
> Suppose I want to define a function "safe", which returns the argument passed if there is no error, and 42 if there is one. So the setup is something like:
>
> def safe(x):
> # WHAT WOULD DEFINE HERE?
>
> print safe(666) # prints 666
> print safe(1/0) # prints 42
>
> I don't see how such a function could be defined. Is it possible?
That can work ONLY if the division of 1/0 doesn't raise an exception.
This is why the concept of NaN exists; I'm not sure if there's a way
to tell Python to return NaN instead of bombing, but it's most likely
only possible with floating point, not integer.
However, there's an easier way.
try:
print 1/0
except ZeroDivisionError:
print 42
Catch the exception and do with it what you will.
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Mark Carter <alt.mcarter@gmail.com> |
|---|---|
| Date | 2012-08-23 02:22 -0700 |
| Message-ID | <mailman.3701.1345713754.4697.python-list@python.org> |
| In reply to | #27711 |
On Thursday, 23 August 2012 10:16:08 UTC+1, Chris Angelico wrote: > On Thu, Aug 23, 2012 at 7:05 PM, Mark Carter <> wrote: > > Suppose I want to define a function "safe", which returns the argument passed if there is no error, and 42 if there is one. > only possible with floating point, not integer. > > try: > print 1/0 > except ZeroDivisionError: > print 42 OK, so it looks like a solution doesn't exist to the problem as specified. I guess it's something that only a language with macros could accommodate.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2012-08-23 19:29 +1000 |
| Message-ID | <mailman.3704.1345714163.4697.python-list@python.org> |
| In reply to | #27711 |
On Thu, Aug 23, 2012 at 7:22 PM, Mark Carter <alt.mcarter@gmail.com> wrote:
> OK, so it looks like a solution doesn't exist to the problem as specified. I guess it's something that only a language with macros could accommodate.
You're asking for a function to prevent the evaluation of its
arguments from throwing an error. That's fundamentally not possible
with a function call. Exception handling is a much more normal way of
handling it; though if you prefer, you could wrap it up in a function
like this:
def safe_div(num,denom):
try:
return num/denom
except ZeroDivisionError:
return 42
print safe_div(1,0) # still a poor name though
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Mark Carter <alt.mcarter@gmail.com> |
|---|---|
| Date | 2012-08-23 02:22 -0700 |
| Message-ID | <b1bd0444-e8ef-4f03-bd69-208e0c550147@googlegroups.com> |
| In reply to | #27711 |
On Thursday, 23 August 2012 10:16:08 UTC+1, Chris Angelico wrote: > On Thu, Aug 23, 2012 at 7:05 PM, Mark Carter <> wrote: > > Suppose I want to define a function "safe", which returns the argument passed if there is no error, and 42 if there is one. > only possible with floating point, not integer. > > try: > print 1/0 > except ZeroDivisionError: > print 42 OK, so it looks like a solution doesn't exist to the problem as specified. I guess it's something that only a language with macros could accommodate.
[toc] | [prev] | [next] | [standalone]
| From | Laszlo Nagy <gandalf@shopzeus.com> |
|---|---|
| Date | 2012-08-23 11:23 +0200 |
| Message-ID | <mailman.3702.1345713811.4697.python-list@python.org> |
| In reply to | #27710 |
On 2012-08-23 11:05, Mark Carter wrote:
> Suppose I want to define a function "safe", which returns the argument passed if there is no error, and 42 if there is one. So the setup is something like:
>
> def safe(x):
> # WHAT WOULD DEFINE HERE?
>
> print safe(666) # prints 666
> print safe(1/0) # prints 42
>
> I don't see how such a function could be defined. Is it possible?
You are very vague. "There is an error" - but what kind of error? To
catch all possible exceptions you could do:
def unsafe(x):
# put your code here...
def safe(x):
try:
return unsafe(x)
except:
return 42
Generally, it is a bad idea. Exception handlers were invented because
they give you a way to handle any error in the call chain. When an
exception occurs, the interpreter will start searching for an
appropriate exception handler traversing up in the call chain. By
converting exceptions into return values, you are bypassing this search.
Then you will have to write conditions instead of exception handlers
inside ALL methods in the call chain, creating a "manual" search for the
handler of the exception. In most cases, this will make your code
difficult, error prone and hard to read.
In some special cases, this can be a good idea to do.
Can you please let us know when and how would you like to use it?
[toc] | [prev] | [next] | [standalone]
| From | Mark Carter <alt.mcarter@gmail.com> |
|---|---|
| Date | 2012-08-23 02:47 -0700 |
| Message-ID | <73b19a13-5c2d-4ee8-b7e3-a9ee3c75ec37@googlegroups.com> |
| In reply to | #27714 |
On Thursday, 23 August 2012 10:23:20 UTC+1, Laszlo Nagy wrote: > On 2012-08-23 11:05, Mark Carter wrote: > You are very vague. "There is an error" - but what kind of error? Assume that it doesn't matter. > In some special cases, this can be a good idea to do. Those are the cases that I'm interested in.
[toc] | [prev] | [next] | [standalone]
| From | Mark Carter <alt.mcarter@gmail.com> |
|---|---|
| Date | 2012-08-23 02:47 -0700 |
| Message-ID | <mailman.3706.1345715262.4697.python-list@python.org> |
| In reply to | #27714 |
On Thursday, 23 August 2012 10:23:20 UTC+1, Laszlo Nagy wrote: > On 2012-08-23 11:05, Mark Carter wrote: > You are very vague. "There is an error" - but what kind of error? Assume that it doesn't matter. > In some special cases, this can be a good idea to do. Those are the cases that I'm interested in.
[toc] | [prev] | [next] | [standalone]
| From | Laszlo Nagy <gandalf@shopzeus.com> |
|---|---|
| Date | 2012-08-23 11:28 +0200 |
| Message-ID | <mailman.3703.1345714142.4697.python-list@python.org> |
| In reply to | #27710 |
> That can work ONLY if the division of 1/0 doesn't raise an exception. > This is why the concept of NaN exists; I'm not sure if there's a way > to tell Python to return NaN instead of bombing, but it's most likely > only possible with floating point, not integer. For integers, Python will always raise an exception when you try to divide by zero. And integers has nothing to do with NaN. Because NaN is meaningful for floating point numbers only. Python can be compiled to raise floating point exceptions. (On Python 2, this is a compile time option: FPECTL. On Python 3, this can be configured runtime: http://docs.python.org/library/fpectl.html )
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2012-08-23 19:30 +1000 |
| Message-ID | <mailman.3705.1345714240.4697.python-list@python.org> |
| In reply to | #27710 |
On Thu, Aug 23, 2012 at 7:28 PM, Laszlo Nagy <gandalf@shopzeus.com> wrote: >> That can work ONLY if the division of 1/0 doesn't raise an exception. >> This is why the concept of NaN exists; I'm not sure if there's a way >> to tell Python to return NaN instead of bombing, but it's most likely >> only possible with floating point, not integer. > > For integers, Python will always raise an exception when you try to divide > by zero. And integers has nothing to do with NaN. Because NaN is meaningful > for floating point numbers only. Python can be compiled to raise floating > point exceptions. (On Python 2, this is a compile time option: FPECTL. On > Python 3, this can be configured runtime: > http://docs.python.org/library/fpectl.html ) Thanks, that's the sort of thing I meant. I'm not familiar enough with Python's floating point handler to know those details. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2012-08-23 12:11 +0200 |
| Message-ID | <mailman.3707.1345716686.4697.python-list@python.org> |
| In reply to | #27710 |
Mark Carter wrote: > Suppose I want to define a function "safe", which returns the argument > passed if there is no error, and 42 if there is one. So the setup is > something like: > > def safe(x): > # WHAT WOULD DEFINE HERE? > > print safe(666) # prints 666 > print safe(1/0) # prints 42 > > I don't see how such a function could be defined. Is it possible? 1/0 is evaluated before safe() is called. Therefore safe() has no chance to catch the exception. You have to move the evaluation into the safe() function: >>> def safe(deferred, default=42, exception=Exception): ... try: ... return deferred() ... except exception: ... return default ... >>> print safe(lambda: 666) 666 >>> print safe(lambda: 1/0) 42
[toc] | [prev] | [next] | [standalone]
| From | rusi <rustompmody@gmail.com> |
|---|---|
| Date | 2012-08-23 10:15 -0700 |
| Message-ID | <e68c7216-5d08-444f-9424-e7f8561f9754@qa3g2000pbc.googlegroups.com> |
| In reply to | #27721 |
On Aug 23, 3:11 pm, Peter Otten <__pete...@web.de> wrote: > Mark Carter wrote: > > Suppose I want to define a function "safe", which returns the argument > > passed if there is no error, and 42 if there is one. So the setup is > > something like: > > > def safe(x): > > # WHAT WOULD DEFINE HERE? > > > print safe(666) # prints 666 > > print safe(1/0) # prints 42 > > > I don't see how such a function could be defined. Is it possible? > > 1/0 is evaluated before safe() is called. Therefore safe() has no chance to > catch the exception. You have to move the evaluation into the safe() > function: > > >>> def safe(deferred, default=42, exception=Exception): > > ... try: > ... return deferred() > ... except exception: > ... return default > ...>>> print safe(lambda: 666) > 666 > >>> print safe(lambda: 1/0) > > 42 Nice! Functional programmers know that once you have a lazy language, you can simulate all control constructs within that framework. eg in Haskell one could define an 'if-function' as iffunc (True, a, b) = a iffunc (False, a, b) = b In most other languages such a definition would not work. What Peter has demonstrated is that for an eager language like python, a bare-lambda is a lazy-fying construct
[toc] | [prev] | [next] | [standalone]
| From | Laszlo Nagy <gandalf@shopzeus.com> |
|---|---|
| Date | 2012-08-23 13:01 +0200 |
| Message-ID | <mailman.3708.1345719712.4697.python-list@python.org> |
| In reply to | #27710 |
>>>> def safe(deferred, default=42, exception=Exception):
> ... try:
> ... return deferred()
> ... except exception:
> ... return default
What a beautiful solution! I was wondering if the following would be
possible:
def test(thing, default, *exc_classes):
try:
thing()
except *exc_classes:
return default
But it is syntactically invalid.
Here is a workaround that is not so beautiful:
def test(thing, default, *exc_classes):
try:
thing()
except Exception, e:
for cls in exc_classes:
if isinstance(e,cls):
return default
raise
print test( (lambda: 1/0), -1, ValueError, ZeroDivisionError) # prints -1
[toc] | [prev] | [next] | [standalone]
| From | MRAB <python@mrabarnett.plus.com> |
|---|---|
| Date | 2012-08-23 12:21 +0100 |
| Message-ID | <mailman.3709.1345720887.4697.python-list@python.org> |
| In reply to | #27710 |
On 23/08/2012 12:01, Laszlo Nagy wrote:
>
>>>>> def safe(deferred, default=42, exception=Exception):
>> ... try:
>> ... return deferred()
>> ... except exception:
>> ... return default
>
> What a beautiful solution! I was wondering if the following would be
> possible:
>
>
> def test(thing, default, *exc_classes):
> try:
> thing()
> except *exc_classes:
> return default
>
>
> But it is syntactically invalid.
>
> Here is a workaround that is not so beautiful:
>
>
> def test(thing, default, *exc_classes):
> try:
> thing()
> except Exception, e:
> for cls in exc_classes:
> if isinstance(e,cls):
> return default
> raise
>
> print test( (lambda: 1/0), -1, ValueError, ZeroDivisionError) # prints -1
>
The 'except' clause accepts a tuple of exception classes, so this works:
def test(thing, default, *exc_classes):
try:
thing()
except exc_classes:
return default
[toc] | [prev] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2012-08-23 13:28 +0200 |
| Message-ID | <mailman.3710.1345721290.4697.python-list@python.org> |
| In reply to | #27710 |
Laszlo Nagy wrote: >>>>> def safe(deferred, default=42, exception=Exception): >> ... try: >> ... return deferred() >> ... except exception: >> ... return default > > What a beautiful solution! I was wondering if the following would be > possible: > > > def test(thing, default, *exc_classes): > try: > thing() > except *exc_classes: > return default > > > But it is syntactically invalid. The except clause allows a tuple of exceptions: >>> def safe(deferred, default, *exceptions): ... try: ... return deferred() ... except exceptions: ... return default ... >>> safe(lambda: 1/0, -1, ValueError, ZeroDivisionError) -1
[toc] | [prev] | [next] | [standalone]
| From | Mark Lawrence <breamoreboy@yahoo.co.uk> |
|---|---|
| Date | 2012-08-23 15:11 +0100 |
| Message-ID | <mailman.3714.1345730984.4697.python-list@python.org> |
| In reply to | #27710 |
On 23/08/2012 10:05, Mark Carter wrote: > Suppose I want to define a function "safe", which returns the argument passed if there is no error, and 42 if there is one. So the setup is something like: > > def safe(x): > # WHAT WOULD DEFINE HERE? > > print safe(666) # prints 666 > print safe(1/0) # prints 42 > > I don't see how such a function could be defined. Is it possible? > Well you've already got lots of answers but I'm not certain about what you're trying to achieve. If you could explicitly state your requirements I'm sure that the numerous MVPs (Most Valuable Pythonistas) here would come up with The Best Solution ™ to your problem. -- Cheers. Mark Lawrence.
[toc] | [prev] | [next] | [standalone]
| From | Dennis Lee Bieber <wlfraed@ix.netcom.com> |
|---|---|
| Date | 2012-08-23 14:49 -0400 |
| Message-ID | <mailman.3727.1345747783.4697.python-list@python.org> |
| In reply to | #27710 |
On Thu, 23 Aug 2012 02:05:50 -0700 (PDT), Mark Carter
<alt.mcarter@gmail.com> declaimed the following in
gmane.comp.python.general:
> print safe(1/0) # prints 42
>
1/0 is evaluated before safe() is called... and hence will raise an
exception before getting into the function.
Python does not defer operations that are arguments of a function
call. You can only defer them by wrapping them into a function...
>>> def safe(arg):
... try:
... return arg()
... except:
... return 42
...
>>> print safe(lambda : 1/0)
42
Unfortunately, that means you can't just take an arbitrary equation
and wrap it in a call to safe() as you have to make provision for local
names...
>>> def safe(fnc, *args):
... try:
... return fnc(*args)
... except:
... return 42
...
>>> print safe(lambda a, b : a / b, 1, 0)
42
>>> print safe(lambda a, b : a / b, 1, 1)
1
>>>
>>> a = 1
>>> b = 0
>>> print safe(lambda a, b : a / b, a, b)
42
>>> b = 2
>>> print safe(lambda a, b : a / b, a, b)
0
>>>
By the time you wrap the equation with a lambda all, named, terms,
AND supply the named terms after the lambda, you might as well just wrap
the equation in a plain try/except block.
--
Wulfraed Dennis Lee Bieber AF6VN
wlfraed@ix.netcom.com HTTP://wlfraed.home.netcom.com/
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2012-08-24 07:48 +1000 |
| Message-ID | <mailman.3732.1345758509.4697.python-list@python.org> |
| In reply to | #27710 |
On Fri, Aug 24, 2012 at 4:49 AM, Dennis Lee Bieber <wlfraed@ix.netcom.com> wrote: > By the time you wrap the equation with a lambda all, named, terms, > AND supply the named terms after the lambda, you might as well just wrap > the equation in a plain try/except block. But closures spare you that hassle. >>> a=1 >>> b=0 >>> print(safe(lambda: a/b)) 42 >>> b=2 >>> print(safe(lambda: a/b)) 0.5 (Example done in Python 3 so semantics are a little different) ChrisA
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web