Re: find all multiplicands and multipliers for a number

2015-04-11 Thread Marko Rauhamaa
Paul Rubin :

> This takes about 4 seconds on a Intel(R) Core(TM) i5-3230M CPU @ 2.60GHz
> laptop (64 bit linux):

Converted to Python3:

#!/usr/bin/env python3

import itertools, time

def candidates():
yield 2
yield 3
for i in itertools.count(5,6):
yield i
yield i+2

def fac(n):
for c in candidates():
if c*c > n:
yield n
break
while n%c == 0:
yield c
n //= c

t0 = time.time()
print(list(fac(2**111+1)))
print(time.time() - t0)


This is slightly faster:


#!/usr/bin/env python3

import time

def fac(n):
for c in range(n):
if c*c > n:
yield n
break
while n%c == 0:
yield c
n //= c

t0 = time.time()
print(list(fac(2**111+1)))
print(time.time() - t0)



Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: try..except with empty exceptions

2015-04-11 Thread Steven D'Aprano
On Sat, 11 Apr 2015 12:23 pm, Dave Angel wrote:

> On 04/10/2015 09:42 PM, Steven D'Aprano wrote:
>> On Sat, 11 Apr 2015 05:31 am, sohcahto...@gmail.com wrote:
>>
>>> It isn't document because it is expected.  Why would the exception get
>>> caught if you're not writing code to catch it?  If you write a function
>>> and pass it a tuple of exceptions to catch, I'm not sure why you would
>>> expect it to catch an exception not in the tuple.  Just because the
>>> tuple
>>> is empty doesn't mean that it should catch *everything* instead.  That
>>> would be counter-intuitive.
>>
>> Really? I have to say, I expected it.
>>
>>
> 
> I'm astounded at your expectation.  That's like saying a for loop on an
> empty list ought to loop on all possible objects in the universe.

Not really.

If we wrote:

for x in:
# Missing sequence leads to an infinite loop

*then* your analogy would be excellent, but it isn't. With for loops, we
iterate over each item in the sequence, hence an empty sequence means we
don't iterate at all.

But with try...except, an empty exception list means to catch *everything*,
not nothing:

try: ...
except a,b,c: # catches a, b, c

try: ...
except a,b: # catches a, b

try: ...
except a: # catches a

try: ...
except: # catches EVERYTHING, not nothing


Putting (a, b, c) into a tuple shouldn't make a difference, and it doesn't,
unless the tuple is empty. That surprised me.

t = a, b, c
try:
except t:  # same as except a,b,c

t = a, b
try:
except t:  # same as except a,b

t = a,
try:
except t:  # same as except a

t = ()
try: 
except t:  # NOT THE SAME as bare except.


I can see the logic behind the current behaviour. If you implement except
clauses like this pseudo-code:


for exc in exceptions:
if raised_exception matches exc: catch it


then an empty tuple will naturally lead to nothing being caught. That
doesn't mean it isn't surprising from the perspective that an empty
exception list (i.e. a bare except) should be analogous to an empty tuple.


> The tuple lists those exceptions you're interested in, and they are
> tried, presumably in order, from that collection.  If none of those
> match, then the logic will advance to the next except clause.  If the
> tuple is empty, then clearly none will match.

Yes, that makes sense, and I agree that it is reasonable behaviour from one
perspective. But its also reasonable to treat "except ():" as analogous to
a bare except.

[...]
>> try:
>>  spam()
>> except:
>>  # Implicitly an empty tuple.
> 
> No, an omitted item is not the same as an empty tuple.

You are correct about Python as it actually is, but it could have been
designed so that except (): was equivalent to a bare except.


> If it were, then 
> we wouldn't have the problem of bare excepts, which are so tempting to
> novices.  There's plenty of precedent in many languages for a missing
> item being distinct from anything one could actually supply.

Let us put aside the fact that some people misuse bare excepts, and allow
that there are some uses for it. Now, in Python 2.6 and later, you can
catch everything by catching BaseException. But in older versions, you
could raise strings as well, and the only way to catch everything is with a
bare except.

If you want to write a function that takes a list of things to catch,
defaulting to "everything", in Python 2.6+ we can write:

def spam(things_to_catch=BaseException):
try:
do_stuff()
except things_to_catch:
handle_exception()


but in older versions you have to write this:

def spam(things_to_catch=None):
if things_to_catch is None:
try:
do_stuff()
except:
handle_exception()
else:
try:
do_stuff()
except things_to_catch:
handle_exception()


This violates Don't Repeat Yourself. Any time you have "a missing item being
distinct from anything one could actually supply", you have a poor design.

Anyway, in modern Python (2.6 onwards), now that string exceptions are gone,
you can supply something to catch everything. Or nothing, for that matter:

BaseException  # catch everything
Exception  # catch errors
(A, B, C)  # Just A, B or C or their subclasses
A  # Just A (or its subclasses)
()  # Catch nothing.

so I suppose that having an empty tuple mean "catch nothing" is better than
having it catch everything.



-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: find all multiplicands and multipliers for a number

2015-04-11 Thread Steven D'Aprano
On Sat, 11 Apr 2015 04:08 pm, Paul Rubin wrote:

> Steven D'Aprano  writes:
>> It may be a bit slow for very large numbers. On my computer, this takes
>> 20 seconds:
>> py> pyprimes.factors.factorise(2**111+1)
>> [3, 3, 1777, 3331, 17539, 25781083, 107775231312019L]
> 
> This takes about 4 seconds on a Intel(R) Core(TM) i5-3230M CPU @ 2.60GHz
> laptop (64 bit linux):

Nice for some who have fast machines, but on my old jalopy, your code takes
110 seconds, more than five times slower than mine. It also returns the
wrong result:

[3, 3, 3, 3, 7, 19, 73, 87211, 262657, 1.4411518807585587e+17]

Oops, you have a float in there, how did that happen?

We can tell your code gives the wrong result. It claims that 7 is a factor
of 2**111+1:

py> n = 2**111 + 1
py> itertools.islice(fac(n), 0, 5)

py> list(itertools.islice(fac(n), 0, 5))
[3, 3, 3, 3, 7]


but that can't be right:

py> n % 7
2L

Seven in not a factor of 2**111 + 1.

The reason your code gives wrong results is that you perform true division /
rather than integer division // which means that you with n a float, which
loses precision:

py> (n/9) % 3  # nine is a factor
0.0
py> (n//9) % 3  # exact, without rounding
1L



-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: try..except with empty exceptions

2015-04-11 Thread Serhiy Storchaka

On 11.04.15 10:11, Steven D'Aprano wrote:

Anyway, in modern Python (2.6 onwards), now that string exceptions are gone,
you can supply something to catch everything. Or nothing, for that matter:

BaseException  # catch everything


Not everything.

>>> class A: pass
...
>>> try: raise A
... except BaseException: pass
...
Traceback (most recent call last):
  File "", line 1, in 
__main__.A: <__main__.A instance at 0xb707982c>


--
https://mail.python.org/mailman/listinfo/python-list


Re: find all multiplicands and multipliers for a number

2015-04-11 Thread jonas . thornvall
Den lördag 11 april 2015 kl. 09:35:22 UTC+2 skrev Steven D'Aprano:
> On Sat, 11 Apr 2015 04:08 pm, Paul Rubin wrote:
> 
> > Steven D'Aprano  writes:
> >> It may be a bit slow for very large numbers. On my computer, this takes
> >> 20 seconds:
> >> py> pyprimes.factors.factorise(2**111+1)
> >> [3, 3, 1777, 3331, 17539, 25781083, 107775231312019L]
> > 
> > This takes about 4 seconds on a Intel(R) Core(TM) i5-3230M CPU @ 2.60GHz
> > laptop (64 bit linux):
> 
> Nice for some who have fast machines, but on my old jalopy, your code takes
> 110 seconds, more than five times slower than mine. It also returns the
> wrong result:
> 
> [3, 3, 3, 3, 7, 19, 73, 87211, 262657, 1.4411518807585587e+17]
> 
> Oops, you have a float in there, how did that happen?
> 
> We can tell your code gives the wrong result. It claims that 7 is a factor
> of 2**111+1:
> 
> py> n = 2**111 + 1
> py> itertools.islice(fac(n), 0, 5)
> 
> py> list(itertools.islice(fac(n), 0, 5))
> [3, 3, 3, 3, 7]
> 
> 
> but that can't be right:
> 
> py> n % 7
> 2L
> 
> Seven in not a factor of 2**111 + 1.
> 
> The reason your code gives wrong results is that you perform true division /
> rather than integer division // which means that you with n a float, which
> loses precision:
> 
> py> (n/9) % 3  # nine is a factor
> 0.0
> py> (n//9) % 3  # exact, without rounding
> 1L
> 
> 
> 
> -- 
> Steven

Love it.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: try..except with empty exceptions

2015-04-11 Thread Terry Reedy

On 4/10/2015 9:42 PM, Steven D'Aprano wrote:


try:
 spam()
except:
 # Implicitly an empty tuple.
 pass


No, specified as equivalent to 'except BaseException:' (or 'except 
(BaseException,):', either of which are different from 'except ():'.
"An expression-less except clause, if present, must be last; it matches 
any exception."


--
Terry Jan Reedy

--
https://mail.python.org/mailman/listinfo/python-list


Re: find all multiplicands and multipliers for a number

2015-04-11 Thread Dave Farrance
$ python2
Python 2.7.8 (default, Oct 20 2014, 15:05:19) 
[GCC 4.9.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> a = 256
>>> b = 256
>>> a is b
True
>>> a = 257
>>> b = 257
>>> a is b
False
>>> 

It's not safe to use 'is' to compare integers.

Use ==
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: try..except with empty exceptions

2015-04-11 Thread Cameron Simpson

On 10Apr2015 19:38, Rustom Mody  wrote:

On Saturday, April 11, 2015 at 7:53:31 AM UTC+5:30, Dave Angel wrote:

On 04/10/2015 09:42 PM, Steven D'Aprano wrote:
> On Sat, 11 Apr 2015 05:31 am, sohcahtoa82 wrote:
>> It isn't document because it is expected.  Why would the exception get
>> caught if you're not writing code to catch it?  If you write a function
>> and pass it a tuple of exceptions to catch, I'm not sure why you would
>> expect it to catch an exception not in the tuple.  Just because the tuple
>> is empty doesn't mean that it should catch *everything* instead.  That
>> would be counter-intuitive.
>
> Really? I have to say, I expected it.

I'm astounded at your expectation.  That's like saying a for loop on an
empty list ought to loop on all possible objects in the universe.


To work, this analogy should also have two python syntaxes like this:

"Normal" for-loop:
for var in iterable:
 suite

"Empty" for-loop:
for:
 suite


Well, to throw an anaolgy in the mix, the shell has a bare for syntax.

 list='a b c'
 for x in $list
 do  echo $x
 done

echoes a, b and c as you might expect.

This:

 for x
 do  echo $x
 done

echoes the command line arguments. (Which is extremely useful.)

But as with Python, the missing iteration means a _default_ source of 
iteration, not _no_ iteration.


To continue the analogy, this:

 list=
 for x in $list
 do  echo $x
 done

echoes nothing. As I would hope Steven would expect.

Importantly, in both Python and the shell you have a way to specify "nothing".  

If the empty tuple were to mean "catch everything" then there would not be a 
way to express "catch nothing". Bad bad bad!


Consider this a proof that Python's current meanings for bare except and 
"except ()" are sensible, using a proof by contradiction.


Cheers,
Cameron Simpson 
--
https://mail.python.org/mailman/listinfo/python-list


Re: try..except with empty exceptions

2015-04-11 Thread Dave Angel

On 04/11/2015 03:11 AM, Steven D'Aprano wrote:

On Sat, 11 Apr 2015 12:23 pm, Dave Angel wrote:


On 04/10/2015 09:42 PM, Steven D'Aprano wrote:

On Sat, 11 Apr 2015 05:31 am, sohcahto...@gmail.com wrote:


It isn't document because it is expected.  Why would the exception get
caught if you're not writing code to catch it?  If you write a function
and pass it a tuple of exceptions to catch, I'm not sure why you would
expect it to catch an exception not in the tuple.  Just because the
tuple
is empty doesn't mean that it should catch *everything* instead.  That
would be counter-intuitive.


Really? I have to say, I expected it.




I'm astounded at your expectation.  That's like saying a for loop on an
empty list ought to loop on all possible objects in the universe.


Not really.

If we wrote:

 for x in:
 # Missing sequence leads to an infinite loop

*then* your analogy would be excellent, but it isn't. With for loops, we
iterate over each item in the sequence, hence an empty sequence means we
don't iterate at all.

But with try...except, an empty exception list means to catch *everything*,
not nothing:


No an empty exception list means to catch nothing.  A *missing* 
exception list means catch everything, but that's a different syntax


try: ...
except a,b,c: # catches a, b, c

try: ...
except a,b: # catches a, b

try: ...
except a: # catches a


try: ...
except (a,)   #catches a

try: ...
except ()  #catches nothing, as expected



try: ...
except: # catches EVERYTHING, not nothing



Different syntax.  No reason for it to pretend that it's being given an 
empty tuple or list.




Putting (a, b, c) into a tuple shouldn't make a difference, and it doesn't,
unless the tuple is empty. That surprised me.

t = a, b, c
try:
except t:  # same as except a,b,c

t = a, b
try:
except t:  # same as except a,b

t = a,
try:
except t:  # same as except a

t = ()
try:
except t:  # NOT THE SAME as bare except.


Of course not.  It's empty, so it catches nothing. Just like 'for'




I can see the logic behind the current behaviour. If you implement except
clauses like this pseudo-code:


for exc in exceptions:
 if raised_exception matches exc: catch it


then an empty tuple will naturally lead to nothing being caught. That
doesn't mean it isn't surprising from the perspective that an empty
exception list (i.e. a bare except) should be analogous to an empty tuple.


Why should it??  It's a different syntax, with different rules.  Perhaps 
it should have been consistent, but then it's this statement that's 
surprising, not the behavior with an empty tuple.






The tuple lists those exceptions you're interested in, and they are
tried, presumably in order, from that collection.  If none of those
match, then the logic will advance to the next except clause.  If the
tuple is empty, then clearly none will match.


Yes, that makes sense, and I agree that it is reasonable behaviour from one
perspective. But its also reasonable to treat "except ():" as analogous to
a bare except.

[...]

try:
  spam()
except:
  # Implicitly an empty tuple.


No, an omitted item is not the same as an empty tuple.


You are correct about Python as it actually is, but it could have been
designed so that except (): was equivalent to a bare except.


Only by changing the bare except behavior.





If it were, then
we wouldn't have the problem of bare excepts, which are so tempting to
novices.  There's plenty of precedent in many languages for a missing
item being distinct from anything one could actually supply.


Let us put aside the fact that some people misuse bare excepts, and allow
that there are some uses for it. Now, in Python 2.6 and later, you can
catch everything by catching BaseException. But in older versions, you
could raise strings as well, and the only way to catch everything is with a
bare except.

If you want to write a function that takes a list of things to catch,
defaulting to "everything", in Python 2.6+ we can write:

def spam(things_to_catch=BaseException):
 try:
 do_stuff()
 except things_to_catch:
 handle_exception()


but in older versions you have to write this:

def spam(things_to_catch=None):
 if things_to_catch is None:
 try:
 do_stuff()
 except:
 handle_exception()
 else:
 try:
 do_stuff()
 except things_to_catch:
 handle_exception()


This violates Don't Repeat Yourself. Any time you have "a missing item being
distinct from anything one could actually supply", you have a poor design.


Yep, and it happens all the time.  For example, mylist[a,b,-1]What 
value can I use for b to mean the whole list?


There are others more grotesque, but I can't think of any at this moment.



Anyway, in modern Python (2.6 onwards), now that string exceptions are gone,
you can supply something to catch everything. Or nothing, for that matter:

BaseException  # catch everything
Exception  # catch err

Re: try..except with empty exceptions

2015-04-11 Thread Dave Angel

On 04/11/2015 06:14 AM, Dave Angel wrote:

On 04/11/2015 03:11 AM, Steven D'Aprano wrote:

On Sat, 11 Apr 2015 12:23 pm, Dave Angel wrote:


On 04/10/2015 09:42 PM, Steven D'Aprano wrote:

On Sat, 11 Apr 2015 05:31 am, sohcahto...@gmail.com wrote:


It isn't document because it is expected.  Why would the exception get
caught if you're not writing code to catch it?  If you write a
function
and pass it a tuple of exceptions to catch, I'm not sure why you would
expect it to catch an exception not in the tuple.  Just because the
tuple
is empty doesn't mean that it should catch *everything* instead.  That
would be counter-intuitive.


Really? I have to say, I expected it.




I'm astounded at your expectation.  That's like saying a for loop on an
empty list ought to loop on all possible objects in the universe.


Not really.

If we wrote:

 for x in:
 # Missing sequence leads to an infinite loop

*then* your analogy would be excellent, but it isn't. With for loops, we
iterate over each item in the sequence, hence an empty sequence means we
don't iterate at all.

But with try...except, an empty exception list means to catch
*everything*,
not nothing:


No an empty exception list means to catch nothing.  A *missing*
exception list means catch everything, but that's a different syntax


try: ...
except a,b,c: # catches a, b, c

try: ...
except a,b: # catches a, b

try: ...
except a: # catches a


try: ...
except (a,)   #catches a

try: ...
except ()  #catches nothing, as expected



try: ...
except: # catches EVERYTHING, not nothing



Different syntax.  No reason for it to pretend that it's being given an
empty tuple or list.



Putting (a, b, c) into a tuple shouldn't make a difference, and it
doesn't,
unless the tuple is empty. That surprised me.

t = a, b, c
try:
except t:  # same as except a,b,c

t = a, b
try:
except t:  # same as except a,b

t = a,
try:
except t:  # same as except a

t = ()
try:
except t:  # NOT THE SAME as bare except.


Of course not.  It's empty, so it catches nothing. Just like 'for'




I can see the logic behind the current behaviour. If you implement except
clauses like this pseudo-code:


for exc in exceptions:
 if raised_exception matches exc: catch it


then an empty tuple will naturally lead to nothing being caught. That
doesn't mean it isn't surprising from the perspective that an empty
exception list (i.e. a bare except) should be analogous to an empty
tuple.


Why should it??  It's a different syntax, with different rules.  Perhaps
it should have been consistent, but then it's this statement that's
surprising, not the behavior with an empty tuple.





The tuple lists those exceptions you're interested in, and they are
tried, presumably in order, from that collection.  If none of those
match, then the logic will advance to the next except clause.  If the
tuple is empty, then clearly none will match.


Yes, that makes sense, and I agree that it is reasonable behaviour
from one
perspective. But its also reasonable to treat "except ():" as
analogous to
a bare except.

[...]

try:
  spam()
except:
  # Implicitly an empty tuple.


No, an omitted item is not the same as an empty tuple.


You are correct about Python as it actually is, but it could have been
designed so that except (): was equivalent to a bare except.


Only by changing the bare except behavior.





If it were, then
we wouldn't have the problem of bare excepts, which are so tempting to
novices.  There's plenty of precedent in many languages for a missing
item being distinct from anything one could actually supply.


Let us put aside the fact that some people misuse bare excepts, and allow
that there are some uses for it. Now, in Python 2.6 and later, you can
catch everything by catching BaseException. But in older versions, you
could raise strings as well, and the only way to catch everything is
with a
bare except.

If you want to write a function that takes a list of things to catch,
defaulting to "everything", in Python 2.6+ we can write:

def spam(things_to_catch=BaseException):
 try:
 do_stuff()
 except things_to_catch:
 handle_exception()


but in older versions you have to write this:

def spam(things_to_catch=None):
 if things_to_catch is None:
 try:
 do_stuff()
 except:
 handle_exception()
 else:
 try:
 do_stuff()
 except things_to_catch:
 handle_exception()


This violates Don't Repeat Yourself. Any time you have "a missing item
being
distinct from anything one could actually supply", you have a poor
design.


Yep, and it happens all the time.  For example, mylist[a,b,-1]What
value can I use for b to mean the whole list?

There are others more grotesque, but I can't think of any at this moment.



Anyway, in modern Python (2.6 onwards), now that string exceptions are
gone,
you can supply something to catch everything. Or nothing, for that
matter:

BaseException  # catc

Re: Dependency Injection

2015-04-11 Thread Steven D'Aprano
On Sat, 11 Apr 2015 04:50 pm, Palpandi wrote:

> Hi all,
> 
> Can anyone explain about the dependency injection concept in python?
> 
> I have a class A. A is used in all other classes(B, C, D, ..). Is it good
> to use dependency injection concept in this situation or else any other
> suggestions?

The best description of Dependency Injection is this one from James Shore:

"Dependency Injection" is a 25-dollar term for a 5-cent 
concept. ... Dependency injection means giving an object 
its instance variables.

http://www.jamesshore.com/Blog/Dependency-Injection-Demystified.html


Suppose we have a class like this:

class Car:
def __init__(self):
self.engine = Engine('4L', 'automatic')
def accelerate(self):
...
def brake(self):
...


Our Car class depends on the Engine class. Now, suppose we want a car with
an electric engine. We could subclass:

class ElectricCar(Car):
def __init__(self):
self.engine = ElectricMotor()


and for some problems that's fine. But *dependency injection* is another
solution. We change the Car class to take the engine as an argument:


# With dependency injection.
class Car:
def __init__(self, engine):
self.engine = engine


Now preparing the engine is the responsibility of the caller, not the Car
class. But that gives us lots more flexibility that we otherwise didn't
have:

grandmothers_car = Car(Engine('6L', 'manual')
dads_car = Car(ElectricMotor())
my_car = Car(LawnmowerEngine())
funnycar = Car(NitroBurningSupercharger())


This can make (for example) testing easier and less fragile:

# Without dependency injection, we have to monkey-patch on the fly.
save_engine = Engine  # Save.
Engine = MockEngine  # Replace.
test = Car()
Engine = save_engine  # Restore.


# With dependency injection, things are easy.
test = Car(MockEngine())



but the cost is that the caller now is responsible for the Car's internals.
We can have the best of both worlds by using a default value:

class Car:
def __init__(self, engine=None):
if engine is None:
engine = Engine('4L', 'automatic')
self.engine = engine

# I don't care what sort of engine I get
car = Car()

# Now I want to test.
test = Car(MockEngine())


Another related strategy is to pass the engine type, not the engine itself:

class Car:
def __init__(self, engine_type):
self.engine = engine_type('4L', 'automatic')



-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: try..except with empty exceptions

2015-04-11 Thread Steven D'Aprano
On Sat, 11 Apr 2015 06:22 pm, Serhiy Storchaka wrote:

> On 11.04.15 10:11, Steven D'Aprano wrote:
>> Anyway, in modern Python (2.6 onwards), now that string exceptions are
>> gone, you can supply something to catch everything. Or nothing, for that
>> matter:
>>
>> BaseException  # catch everything
> 
> Not everything.
> 
>  >>> class A: pass
> ...
>  >>> try: raise A
> ... except BaseException: pass
> ...
> Traceback (most recent call last):
>File "", line 1, in 
> __main__.A: <__main__.A instance at 0xb707982c>

Hmmm, I thought that starting from 2.6 exceptions had to inherit from
BaseException. Thanks for the correction.


[steve@ando ~]$ python2.7 -c "class A: pass
raise A()"
Traceback (most recent call last):
  File "", line 2, in 
__main__.A: <__main__.A instance at 0xb7ebb1ac>


[steve@ando ~]$ python3.3 -c "class A: pass
raise A()"
Traceback (most recent call last):
  File "", line 2, in 
TypeError: exceptions must derive from BaseException


Ahah! So it's 3.x only that catching BaseException should catch everything.

In 2.6, Python stopped supporting string exceptions:

[steve@ando ~]$ python2.6 -c "raise 'spam'"
Traceback (most recent call last):
  File "", line 1, in 
TypeError: exceptions must be old-style classes or derived from
BaseException, not str

(glad that at least I remembered that part correctly!)




-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: try..except with empty exceptions

2015-04-11 Thread Steven D'Aprano
On Sat, 11 Apr 2015 07:27 pm, Cameron Simpson wrote:

> If the empty tuple were to mean "catch everything" then there would not be
> a way to express "catch nothing". Bad bad bad!

# Catch everything:
try:
spam()
except:
pass


# Catch nothing:
spam()


:-)


> Consider this a proof that Python's current meanings for bare except and
> "except ()" are sensible, using a proof by contradiction.


Given that Python 3 does not allow you to raise things which don't inherit
from BaseException, I wish that bare except clauses were dropped
altogether. In Python 3, the equivalent to "catch everything" is
spelled "except BaseException", which I think would be a lot less
attractive to beginners than bare "except:".

But I digress.

Yes, I agree that Python's behaviour here is better than the alternative.
Having "except ()" catch nothing is consistent with the behaviour with
other tuples, so I'm okay with that. But it still surprised me :-)



-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: try..except with empty exceptions

2015-04-11 Thread Chris Angelico
On Sat, Apr 11, 2015 at 9:00 PM, Steven D'Aprano
 wrote:
> Yes, I agree that Python's behaviour here is better than the alternative.
> Having "except ()" catch nothing is consistent with the behaviour with
> other tuples, so I'm okay with that. But it still surprised me :-)

It's worth noting that there's another false parallel here. Grouping
nothing creates something.

x = 1   # x is an integer
x = (1)  # ditto
x = (1)  # LITHP

Okay, so adding parentheses does nothing, right? Right.

x =  # syntax error
x = ()  # empty tuple

"Parentheses around nothing" is NOT the same as "nothing". So if you
compare against this, then it makes perfect sense for "except :" and
"except ():" to be distinctly different.

But I agree, it would be very nice if Python 3 could have abolished
the truly confusing part of this, where "except:" catches everything.
Forcing people to spell it "except BaseException:" would fix all of
this. How hard is it to deprecate and then remove that, same as string
exceptions were removed?

You know what, I'm moving that to -ideas.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: try..except with empty exceptions

2015-04-11 Thread Ian Foote
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On 11/04/15 08:11, Steven D'Aprano wrote:
> But with try...except, an empty exception list means to catch
> *everything*, not nothing:
> 
> try: ... except a,b,c: # catches a, b, c
> 
> try: ... except a,b: # catches a, b

This example is incorrect. In python3 it is a SyntaxError:

Python 3.4.0 (default, Apr 11 2014, 13:05:11)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more
information.
>>> try:
...  1/0
... except ValueError, ZeroDivisionError:
  File "", line 3
except ValueError, ZeroDivisionError:
 ^
SyntaxError: invalid syntax

In python2 it aliases ValueError as ZeroDivisionError:

Python 2.7.6 (default, Mar 22 2014, 22:59:56)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more
information.
>>> try:
...  1/0
... except ValueError, ZeroDivisionError:
...  pass
...
Traceback (most recent call last):
  File "", line 2, in 
ZeroDivisionError: integer division or modulo by zero

To get the behaviour you expect, you must use parentheses:

>>> try:
...  1/0
... except (ValueError, ZeroDivisionError):
...  pass
...

Regards,
Ian F
-BEGIN PGP SIGNATURE-
Version: GnuPG v1

iQEcBAEBAgAGBQJVKS2dAAoJEODsV4MF7PWznkAH/jidWhoJ//gsvBr0ByOOOEgc
A+k8HqrkALfzrh3aEjJB3sq19oLfLcepQeFVUh77mJKOMCQdEeyJtqIz6tLc4RUa
L/nXytHygXVTb5HIARGVkPD26gqAleSb9eZUfPeSEvRHy9UbFS7SMmOdkApheDX3
Vq8TOa8EchaYd+S89y9eepZAhGC7n2TNwrNgp36sbHoz/hYUxFNnugP0ow9FM0Wk
MGKGh04c3Lao+6w7a0scz4YKKb8wTdYkyYwlJhEdg3q74+PwYJpkjcGucna745AZ
XlAKlDCJ9LhPgMufuGdRNskJa4TF709ec5hG9itHu1lFKrjH1iJCEU9ntX6hInU=
=zi4K
-END PGP SIGNATURE-
-- 
https://mail.python.org/mailman/listinfo/python-list


Generarl programming question.

2015-04-11 Thread jonas . thornvall
If two functions crossreference eachother back and forth what happen with the 
local variables.

Will there be a new instance of function holding the variables or do they get 
messed up?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Generarl programming question.

2015-04-11 Thread Chris Angelico
On Sun, Apr 12, 2015 at 1:00 AM,   wrote:
> If two functions crossreference eachother back and forth what happen with the 
> local variables.
>
> Will there be a new instance of function holding the variables or do they get 
> messed up?

You mean if one function calls another, and that function calls the
first? That's called "mutual recursion":

def func1(x):
if x % 2: return x + 1
return func2(x - 2)

def func2(x):
if x % 3: return x + 2
return func1(x - 3)

The 'x' inside each function is completely separate, no matter how
many times they get called. They're usually stored on something called
a "call stack" - you put another sheet of paper on top of the stack
every time you call a function, local variables are all written on
that paper, and when you return from a function, you discard the top
sheet and see what's underneath.

For more information, search the web for the key terms in the above
description, particularly the ones I put in quotes.

If this isn't what you're talking about, the best way to clarify your
question is probably to post a simple (even stupidly trivial, like the
one above) example, and ask a question about that code. Someone'll
doubtless help out!

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Generarl programming question.

2015-04-11 Thread jonas . thornvall
Den lördag 11 april 2015 kl. 17:16:09 UTC+2 skrev Chris Angelico:
> On Sun, Apr 12, 2015 at 1:00 AM,   wrote:
> > If two functions crossreference eachother back and forth what happen with 
> > the local variables.
> >
> > Will there be a new instance of function holding the variables or do they 
> > get messed up?
> 
> You mean if one function calls another, and that function calls the
> first? That's called "mutual recursion":
> 
> def func1(x):
> if x % 2: return x + 1
> return func2(x - 2)
> 
> def func2(x):
> if x % 3: return x + 2
> return func1(x - 3)
> 
> The 'x' inside each function is completely separate, no matter how
> many times they get called. They're usually stored on something called
> a "call stack" - you put another sheet of paper on top of the stack
> every time you call a function, local variables are all written on
> that paper, and when you return from a function, you discard the top
> sheet and see what's underneath.
> 
> For more information, search the web for the key terms in the above
> description, particularly the ones I put in quotes.
> 
> If this isn't what you're talking about, the best way to clarify your
> question is probably to post a simple (even stupidly trivial, like the
> one above) example, and ask a question about that code. Someone'll
> doubtless help out!
> 
> ChrisA

Thanks i was worried, i try to make a generic base choice algorithm that should 
work for anybase, and i just realised that the bignumb add would need to call 
the bignumb subtraction and viceversa. I thought there may be instances but i 
was not sure. 

But I have a feeling the code will be hard to debug.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Generarl programming question.

2015-04-11 Thread Chris Angelico
On Sun, Apr 12, 2015 at 1:22 AM,   wrote:
> Thanks i was worried, i try to make a generic base choice algorithm that 
> should work for anybase, and i just realised that the bignumb add would need 
> to call the bignumb subtraction and viceversa. I thought there may be 
> instances but i was not sure.
>
> But I have a feeling the code will be hard to debug.

The thing to watch out for is unbounded recursion, where they might
call each other forever. But you could easily define your two
functions to fall back to the other like this:

def add(x, y):
if is_negative(y): return subtract(x, -y)
# implement addition with known-positive y

def subtract(x, y):
if is_negative(y): return add(x, -y)
# implement subtraction with known-positive y

There's no problem here, and no possible conflict. (I don't know how
it'd actually help, implementing it like this, but it's certainly
legal.)

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Generarl programming question.

2015-04-11 Thread Steven D'Aprano
On Sun, 12 Apr 2015 01:00 am, jonas.thornv...@gmail.com wrote:

> If two functions crossreference eachother back and forth what happen with
> the local variables.

Nothing. They are local to the function that creates them.


> Will there be a new instance of function holding the variables or do they
> get messed up?

No to both of those. You have two functions, each with it's own locals.


def spam():
colour = "red"
print("Inside spam: colour is:", colour)
eggs()
print("Inside spam after calling eggs: colour is:", colour)
eggs()


def eggs():
colour = "yellow"
print("Inside eggs: colour is:", colour)


Calling spam() gives you this output:

py> spam()
Inside spam: colour is: red
Inside eggs: colour is: yellow
Inside spam after calling eggs: colour is: red
Inside eggs: colour is: yellow


Even if the functions call each other (mutual recursion) each function's
local variables remain local.



-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Generarl programming question.

2015-04-11 Thread jonas . thornvall
Den lördag 11 april 2015 kl. 17:26:03 UTC+2 skrev Steven D'Aprano:
> On Sun, 12 Apr 2015 01:00 am, jonas.thornv...@gmail.com wrote:
> 
> > If two functions crossreference eachother back and forth what happen with
> > the local variables.
> 
> Nothing. They are local to the function that creates them.
> 
> 
> > Will there be a new instance of function holding the variables or do they
> > get messed up?
> 
> No to both of those. You have two functions, each with it's own locals.
> 
> 
> def spam():
> colour = "red"
> print("Inside spam: colour is:", colour)
> eggs()
> print("Inside spam after calling eggs: colour is:", colour)
> eggs()
> 
> 
> def eggs():
> colour = "yellow"
> print("Inside eggs: colour is:", colour)
> 
> 
> Calling spam() gives you this output:
> 
> py> spam()
> Inside spam: colour is: red
> Inside eggs: colour is: yellow
> Inside spam after calling eggs: colour is: red
> Inside eggs: colour is: yellow
> 
> 
> Even if the functions call each other (mutual recursion) each function's
> local variables remain local.
> 
> 
> 
> -- 
> Steven

I don't think it matter butt eggs also calls spam, once more.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Generarl programming question.

2015-04-11 Thread Thomas 'PointedEars' Lahn
Chris Angelico wrote:

> The 'x' inside each function is completely separate, no matter how
> many times they get called. They're usually stored on something called
> a "call stack" - you put another sheet of paper on top of the stack
> every time you call a function, local variables are all written on
> that paper, and when you return from a function, you discard the top
> sheet and see what's underneath.

Thank you for that description; I shall use it from now on when teaching 
laymen about the call stack.

-- 
PointedEars

Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: find all multiplicands and multipliers for a number

2015-04-11 Thread Paul Rubin
Steven D'Aprano  writes:
> [3, 3, 3, 3, 7, 19, 73, 87211, 262657, 1.4411518807585587e+17]
> Oops, you have a float in there, how did that happen?

Looks like you are using a broken version of Python.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: find all multiplicands and multipliers for a number

2015-04-11 Thread Paul Rubin
Marko Rauhamaa  writes:
> This is slightly faster:...
> def fac(n):
> for c in range(n):
> if c*c > n: ...

That's interesting and says something bad about generators in Python 3.
It's doing 3 times as many trial divisions as the version I posted, and
it's still faster?

xrange in Python 2 doesn't work with bignums, but using 
itertools.count(3,2) I get about 5.5 seconds and with itertools.count(3)
I get 11 seconds.

I wrote the same algorithm in Haskell and it's about 0.85 seconds,
probably due to native compilation and faster bignums.  A naive
implementation of Pollard's rho algorithm in Haskell is basically
instantaneous on that number.  I might try coding Pollard's method or
Brent's improvement in Python.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: find all multiplicands and multipliers for a number

2015-04-11 Thread Paul Rubin
Dennis Lee Bieber  writes:
>>Oops, you have a float in there, how did that happen?
>   Off the top of my head -- I'd suspect an older version of Python that
> promoted 2**111 to a double, rather than to a Long-Int.

No he's being a wise guy.  The /= returned a float result in Python 3
after the first factor was found.  I noticed the /= after posting, but I
figured the print statement would trigger a syntax error in Python 3.
Looks like he did a partial conversion.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: find all multiplicands and multipliers for a number

2015-04-11 Thread ravas
Thank you all. I learned a lot.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: find all multiplicands and multipliers for a number

2015-04-11 Thread Marko Rauhamaa
Paul Rubin :

> Marko Rauhamaa  writes:
>> This is slightly faster:...
>> def fac(n):
>> for c in range(n):
>> if c*c > n: ...
>
> That's interesting and says something bad about generators in Python
> 3. It's doing 3 times as many trial divisions as the version I posted,
> and it's still faster?

I think it mostly says divisions are not so evil as you think they might
be. Also, I wouldn't bother optimizing Python's performance too much.
Python is very wasteful wrt space and speed -- and for good reasons.
Either Python does it for you or it doesn't. If it doesn't, write that
part in C.

Myself, I write in bash what I can. What I can't, I write in Python.
What I can't write in Python, I write in C.


Marko

PS Note that you're being "wasteful" by multiplying c*c over and over
again instead of calculating the square root of n a handful of times.
But since multiplication isn't all that expensive, the square root
optimization doesn't affect execution time measurably.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: find all multiplicands and multipliers for a number

2015-04-11 Thread Paul Rubin
Marko Rauhamaa  writes:
> I think it mostly says divisions are not so evil as you think they might
> be.

They are bignum divisions which are much more expensive than machine
divisions.  And it's not just the divisions, it's also the number of
iterations through the whole loop.  And the Python 2 vs Python 3
difference is still unexplained.

> PS Note that you're being "wasteful" by multiplying c*c over and over

Yeah this is a reasonable point, though most of the c's should fit in a
machine word, at least in my 64-bit system.  I think Python still
separates ints and longs in the implementation.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Generarl programming question.

2015-04-11 Thread Terry Reedy

On 4/11/2015 12:23 PM, Thomas 'PointedEars' Lahn wrote:

Chris Angelico wrote:


The 'x' inside each function is completely separate, no matter how
many times they get called. They're usually stored on something called
a "call stack" - you put another sheet of paper on top of the stack
every time you call a function, local variables are all written on
that paper, and when you return from a function, you discard the top
sheet and see what's underneath.


Thank you for that description; I shall use it from now on when teaching
laymen about the call stack.


What Chris is describing is one local namespace (sheet of paper) per 
function *call*.  In early Fortran (at least the first version I used), 
there was one local namespace (sheet) per *function*.  The call stack 
was a stack of (pointers to) functions.  While a function object was in 
use (after a call, before the return), it could not be called again.  In 
other words, recursion, direct or indirect, was not allowed.  I believe 
the same was (is?) true of some versions of BASIC.


It has been proposed that Python use a hybrid model.  Function objects 
would have space for local variables for the first call, but there would 
also be a mechanism to allocate additional 'sheets' for recursive calls. 
 The idea is that most functions are not called recursively, so the 
overhead of allocating and freeing the per-call space is usually not 
needed.  I do not believe that anyone has implemented the idea to test 
feasibility and the actual speedup in relation to the additional complexity.


--
Terry Jan Reedy

--
https://mail.python.org/mailman/listinfo/python-list


Re: try..except with empty exceptions

2015-04-11 Thread Ian Kelly
On Apr 11, 2015 5:06 AM, "Steven D'Aprano" <
steve+comp.lang.pyt...@pearwood.info> wrote:
>
> Yes, I agree that Python's behaviour here is better than the alternative.
> Having "except ()" catch nothing is consistent with the behaviour with
> other tuples, so I'm okay with that. But it still surprised me :-)

There's another alternative that I haven't seen suggested yet. An empty
tuple could be considered an indication of a programming error and raise a
chained ValueError.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Generarl programming question.

2015-04-11 Thread Thomas 'PointedEars' Lahn
Terry Reedy wrote:

> On 4/11/2015 12:23 PM, Thomas 'PointedEars' Lahn wrote:
>> Chris Angelico wrote:
>>> The 'x' inside each function is completely separate, no matter how
>>> many times they get called. They're usually stored on something called
>>> a "call stack" - you put another sheet of paper on top of the stack
>>> every time you call a function, local variables are all written on
>>> that paper, and when you return from a function, you discard the top
>>> sheet and see what's underneath.
>>
>> Thank you for that description; I shall use it from now on when teaching
>> laymen about the call stack.
> 
> What Chris is describing is one local namespace (sheet of paper) per
> function *call*.

I *know* what he is describing: the *call* stack.

> In early Fortran (at least the first version I used),
> there was one local namespace (sheet) per *function*.

The names in such namespaces are now called static variables.  AFAIK, Python 
does not have them, but PHP, for example, has:

  function foo ()
  {
static $bar = 1;
$bar *= 2;
return $bar;
  }

The variable $bar then keeps its last value for subsequent calls of foo().

> The call stack was a stack of (pointers to) functions.

It would appear that the commonly used definition of “call stack” has 
considerably changed since then, since I have been programming computers for 
more than two decades now (not including FORTRAN, though) and never heard of
your definition before.

> It has been proposed that Python use a hybrid model.  Function objects 

Interesting.  I did not know that functions are objects in Python, too.

> would have space for local variables for the first call, but there would 
> also be a mechanism to allocate additional 'sheets' for recursive calls. 
>   The idea is that most functions are not called recursively, so the 
> overhead of allocating and freeing the per-call space is usually not 
> needed.  I do not believe that anyone has implemented the idea to test 
> feasibility and the actual speedup in relation to the additional 
> complexity.

ISTM that such static variables are the remains of non-object-oriented 
programming.  In a language where functions are first-class objects, you 
would use a closure instead.  And in OOP you would solve the problem with an 
object holding the value in a property that survives exiting the execution 
context of the function/method.  It is not a good idea to reintroduce 
obsolete concepts into Python.
 
-- 
PointedEars

Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: try..except with empty exceptions

2015-04-11 Thread Chris Angelico
On Sun, Apr 12, 2015 at 4:49 AM, Ian Kelly  wrote:
> On Apr 11, 2015 5:06 AM, "Steven D'Aprano"
>  wrote:
>>
>> Yes, I agree that Python's behaviour here is better than the alternative.
>> Having "except ()" catch nothing is consistent with the behaviour with
>> other tuples, so I'm okay with that. But it still surprised me :-)
>
> There's another alternative that I haven't seen suggested yet. An empty
> tuple could be considered an indication of a programming error and raise a
> chained ValueError.

Not really a lot of point. Just as with isinstance, an empty tuple
simply matches nothing. Why go to the effort of rejecting it?

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: try..except with empty exceptions

2015-04-11 Thread Chris Angelico
On Sun, Apr 12, 2015 at 6:04 AM, Chris Angelico  wrote:
> On Sun, Apr 12, 2015 at 4:49 AM, Ian Kelly  wrote:
>> On Apr 11, 2015 5:06 AM, "Steven D'Aprano"
>>  wrote:
>>>
>>> Yes, I agree that Python's behaviour here is better than the alternative.
>>> Having "except ()" catch nothing is consistent with the behaviour with
>>> other tuples, so I'm okay with that. But it still surprised me :-)
>>
>> There's another alternative that I haven't seen suggested yet. An empty
>> tuple could be considered an indication of a programming error and raise a
>> chained ValueError.
>
> Not really a lot of point. Just as with isinstance, an empty tuple
> simply matches nothing. Why go to the effort of rejecting it?

(At least, I assume you're not putting a literal empty tuple in. This
would be useful only in cases where the tuple is provided
dynamically.)

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: find all multiplicands and multipliers for a number

2015-04-11 Thread Chris Angelico
On Sun, Apr 12, 2015 at 3:52 AM, Paul Rubin  wrote:
>> PS Note that you're being "wasteful" by multiplying c*c over and over
>
> Yeah this is a reasonable point, though most of the c's should fit in a
> machine word, at least in my 64-bit system.  I think Python still
> separates ints and longs in the implementation.

I don't think it does. Performance doesn't seem to change in Py3 as
the numbers get bigger:

rosuav@sikorsky:~$ cat perftest.py
def naive_sum(top,base=0):
i=0
while ihttps://mail.python.org/mailman/listinfo/python-list


Re: Generarl programming question.

2015-04-11 Thread Terry Reedy

On 4/11/2015 3:19 PM, Thomas 'PointedEars' Lahn wrote:

Terry Reedy wrote:


On 4/11/2015 12:23 PM, Thomas 'PointedEars' Lahn wrote:

Chris Angelico wrote:

The 'x' inside each function is completely separate, no matter how
many times they get called. They're usually stored on something called
a "call stack" - you put another sheet of paper on top of the stack
every time you call a function, local variables are all written on
that paper, and when you return from a function, you discard the top
sheet and see what's underneath.


Thank you for that description; I shall use it from now on when teaching
laymen about the call stack.


What Chris is describing is one local namespace (sheet of paper) per
function *call*.



I *know* what he is describing: the *call* stack.


My comment above was directed not at you specifically but at the OP, 
Jonas, who appears to have had a mental model (like the following) in 
which recursion is not possible.  I think this mental model is fairly 
common among programming newbies.  And it is not crazy, just obsolete 
and superceded.  And, we constantly talk about a function's local names, 
which is correct, without constantly adding the caveat that in Python 
(and most modern languages) they are instanced per call.


I think of functions as being something like a class, in that each call 
gives a new instance with a new set of named values.



In early Fortran (at least the first version I used),
there was one local namespace (sheet) per *function*.


The names in such namespaces are now called static variables.  AFAIK, Python
does not have them, but PHP, for example, has:

   function foo ()
   {
 static $bar = 1;
 $bar *= 2;
 return $bar;
   }

The variable $bar then keeps its last value for subsequent calls of foo().


In Python, one can do something similar with attributes, except that 
attributes are easily accessible from outside the function.  Mutable 
defaults probably come closer.


def doubler(_val=[1])"
  _val[0] *= 2
  return _val[0]

print(doubler(), doubler(), doubler())
# 2 4 8


The call stack was a stack of (pointers to) functions.


It would appear that the commonly used definition of “call stack” has
considerably changed since then, since I have been programming computers for
more than two decades now (not including FORTRAN, though) and never heard of
your definition before.


I don't know what the stack required for returns was called in Fortran 
or how it was implemented in any particular compiler.



It has been proposed that Python use a hybrid model.  Function objects


Interesting.  I did not know that functions are objects in Python, too.


In Python, everything you can bind a name to is an object, and in 3.x, 
an instance of the base class 'object'.


--
Terry Jan Reedy


--
https://mail.python.org/mailman/listinfo/python-list


Re: try..except with empty exceptions

2015-04-11 Thread Cameron Simpson

On 11Apr2015 21:21, Chris Angelico  wrote:

But I agree, it would be very nice if Python 3 could have abolished
the truly confusing part of this, where "except:" catches everything.
Forcing people to spell it "except BaseException:" would fix all of
this. How hard is it to deprecate and then remove that, same as string
exceptions were removed?


I guess I'll go over there to oppose it then.

Why? It makes it harder to write portable python 2/3 code and does not add any 
semantic advantage.


Unless there's a common root exception class in Python 2, which I believe there 
isn't, you can't catch all exceptions in python 2 without the "except:" syntax.  
Which means the _only_ way to have some code in both 2 and 3 that does it 
requires 2 codebases.


As one who tries to have his code run in both 2 (usually recent 2, like 
2.6/2.7) and 3, this change would cause a signification breakage for me without 
bringing any semantic benefits.


Without vigorous use of the time machine I don't see a fix here.

For the record, I would be ok (but not "for") never having had bare "except" if 
all exceptions had always had a common root.


Hmm. Can I catch "object"? Sounds awful, but might work.

Cheers,
Cameron Simpson 

EMACS: Escape Meta Alt Control Shift
--
https://mail.python.org/mailman/listinfo/python-list


Re: try..except with empty exceptions

2015-04-11 Thread Chris Angelico
On Sun, Apr 12, 2015 at 7:37 AM, Cameron Simpson  wrote:
> On 11Apr2015 21:21, Chris Angelico  wrote:
>>
>> But I agree, it would be very nice if Python 3 could have abolished
>> the truly confusing part of this, where "except:" catches everything.
>> Forcing people to spell it "except BaseException:" would fix all of
>> this. How hard is it to deprecate and then remove that, same as string
>> exceptions were removed?
>
>
> I guess I'll go over there to oppose it then.
>
> Why? It makes it harder to write portable python 2/3 code and does not add
> any semantic advantage.
>
> Unless there's a common root exception class in Python 2, which I believe
> there isn't, you can't catch all exceptions in python 2 without the
> "except:" syntax.  Which means the _only_ way to have some code in both 2
> and 3 that does it requires 2 codebases.
>
> As one who tries to have his code run in both 2 (usually recent 2, like
> 2.6/2.7) and 3, this change would cause a signification breakage for me
> without bringing any semantic benefits.

Can you give an example of a place where in Py2 you absolutely have to
catch everything, and don't have control over the code, *and* are
trying to do a one-codebase routine with Py3 compatibility? If you're
trying for 2/3 compatibility, you'll need to have all your exceptions
derive from BaseException anyway.

At very worst, it could be turned into a compat-only syntax feature,
like the u"spam" noise prefix on Unicode strings - serving absolutely
no purpose in Py3 code, and ideally, able to be removed at some point
post-2020.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Generarl programming question.

2015-04-11 Thread Thomas 'PointedEars' Lahn
Terry Reedy wrote:

> On 4/11/2015 3:19 PM, Thomas 'PointedEars' Lahn wrote:
>> Terry Reedy wrote:
>>> What Chris is describing is one local namespace (sheet of paper) per
>>> function *call*.
>> I *know* what he is describing: the *call* stack.
> 
> My comment above was directed not at you specifically but at the OP,
> Jonas, […]

ACK

>> The variable $bar then keeps its last value for subsequent calls of
>> foo().
> 
> In Python, one can do something similar with attributes, except that
> attributes are easily accessible from outside the function.

AISB.  Python’s “attributes” are named “properties” elsewhere.

> Mutable defaults probably come closer.
> 
> def doubler(_val=[1])"
>_val[0] *= 2
>return _val[0]
> 
> print(doubler(), doubler(), doubler())
> # 2 4 8

Fascinating.  Thanks.

-- 
PointedEars

Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: try..except with empty exceptions

2015-04-11 Thread Cameron Simpson

On 12Apr2015 07:52, Chris Angelico  wrote:

On Sun, Apr 12, 2015 at 7:37 AM, Cameron Simpson  wrote:

On 11Apr2015 21:21, Chris Angelico  wrote:

But I agree, it would be very nice if Python 3 could have abolished
the truly confusing part of this, where "except:" catches everything.
Forcing people to spell it "except BaseException:" would fix all of
this. How hard is it to deprecate and then remove that, same as string
exceptions were removed?


I guess I'll go over there to oppose it then.

Why? It makes it harder to write portable python 2/3 code and does not add
any semantic advantage.

Unless there's a common root exception class in Python 2, which I believe
there isn't, you can't catch all exceptions in python 2 without the
"except:" syntax.  Which means the _only_ way to have some code in both 2
and 3 that does it requires 2 codebases.

As one who tries to have his code run in both 2 (usually recent 2, like
2.6/2.7) and 3, this change would cause a signification breakage for me
without bringing any semantic benefits.


Can you give an example of a place where in Py2 you absolutely have to
catch everything, and don't have control over the code, *and* are
trying to do a one-codebase routine with Py3 compatibility? If you're
trying for 2/3 compatibility, you'll need to have all your exceptions
derive from BaseException anyway.


I don't make many personal exception classes, tending to reuse stdlib ones. I'm 
sure I have a few.


But regarding codebase:

   [hg/css]fleet*> g except: **/*.py
   lib/python/cs/app/pilfer.py:664:  except:
   lib/python/cs/asynchron.py:145:except:
   lib/python/cs/db.py:184:  except:
   lib/python/cs/excutils.py:34:  except:
   lib/python/cs/fileutils.py:69:  except:
   lib/python/cs/idset.py:46:  except:
   lib/python/cs/later.py:156:except:
   lib/python/cs/mailutils.py:274:  except:
   lib/python/cs/nodedb/tokcab.py:57:except:
   lib/python/cs/queues.py:441:  except:
   lib/python/cs/queues.py:458:  except:
   lib/python/cs/threads.py:131:  except:

Catching all exceptions isn't terribly common, _except_ in service routines 
that wrap "unknown" operations. Classic example from my Asynchron class:


   def call(self, func, *a, **kw):
 ''' Have the Asynchron call `func(*a,**kw)` and store its values as
 self.result.
 If `func` raises an exception, store it as self.exc_info.
 '''
 try:
   r = func(*a, **kw)
 except:
   self.exc_info = sys.exc_info
 else:
   self.result = r

All sorts of things like thread pools and other "worker" functions, and 
run-forever daemons like mail filers that can have arbitrary exceptions occur 
in (partly) third party code eg from config files; you need to catch any 
unknown exception and fail the specific action, but continue the main daemon 
operation.


And since I use this code in Python 2, and since not all exceptions are 
BaseException subclasses, I need the bare syntax.


Also, IMO, a bare "except:" syntax is _far_ more pleasing to the eye than 
"except magic_exception_name_that+gets_everything:". Also, I wish 
"BaseException" were just spelled "Exception", if it has to be used.



At very worst, it could be turned into a compat-only syntax feature,
like the u"spam" noise prefix on Unicode strings - serving absolutely
no purpose in Py3 code, and ideally, able to be removed at some point
post-2020.


I'm -0.1 on the idea myself. I consider "except:" succinct and evocative, and 
prefer it to "except BaseException:".


Cheers,
Cameron Simpson 

On a videophone, the whole world can see you fart.  - Charlie Stross
--
https://mail.python.org/mailman/listinfo/python-list


Re: find all multiplicands and multipliers for a number

2015-04-11 Thread wolfram . hinderer
Am Samstag, 11. April 2015 09:14:50 UTC+2 schrieb Marko Rauhamaa:
> Paul Rubin :
> 
> > This takes about 4 seconds on a Intel(R) Core(TM) i5-3230M CPU @ 2.60GHz
> > laptop (64 bit linux):
> 
> Converted to Python3:
> 
> #!/usr/bin/env python3
> 
> import itertools, time
> 
> def candidates():
> yield 2
> yield 3
> for i in itertools.count(5,6):
> yield i
> yield i+2
> 
> def fac(n):
> for c in candidates():
> if c*c > n:
> yield n
> break
> while n%c == 0:
> yield c
> n //= c
> 
> t0 = time.time()
> print(list(fac(2**111+1)))
> print(time.time() - t0)
> 
> 
> This is slightly faster:
> 
> 
> #!/usr/bin/env python3
> 
> import time
> 
> def fac(n):
> for c in range(n):
> if c*c > n:
> yield n
> break
> while n%c == 0:
> yield c
> n //= c
> 
> t0 = time.time()
> print(list(fac(2**111+1)))
> print(time.time() - t0)
> 
> 

I get other results on 3.2.3:

n % 0 raises ZeroDivisionError.
After fixing that by using range(2, n) it takes about three times as long as 
the original version, which is what I'd expect.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: try..except with empty exceptions

2015-04-11 Thread Chris Angelico
On Sun, Apr 12, 2015 at 9:08 AM, Cameron Simpson  wrote:
> Catching all exceptions isn't terribly common, _except_ in service routines
> that wrap "unknown" operations. Classic example from my Asynchron class:
>
>def call(self, func, *a, **kw):
>  ''' Have the Asynchron call `func(*a,**kw)` and store its values as
>  self.result.
>  If `func` raises an exception, store it as self.exc_info.
>  '''
>  try:
>r = func(*a, **kw)
>  except:
>self.exc_info = sys.exc_info
>  else:
>self.result = r
>
> All sorts of things like thread pools and other "worker" functions, and
> run-forever daemons like mail filers that can have arbitrary exceptions
> occur in (partly) third party code eg from config files; you need to catch
> any unknown exception and fail the specific action, but continue the main
> daemon operation.
>
> And since I use this code in Python 2, and since not all exceptions are
> BaseException subclasses, I need the bare syntax.

Fair enough. Do you know how often you actually catch stuff that
wouldn't be caught by "except BaseException:"? I would guess it's
pretty rare. In fact, you can find out.

 try:
   r = func(*a, **kw)
 except BaseException:
   self.exc_info = sys.exc_info
 except:
   self.exc_info = sys.exc_info
   emit_warning()
else:
   self.result = r

You could simply mandate that, from version X.Y of your Asynchron
module onward, old-style classes must not be thrown.

> Also, IMO, a bare "except:" syntax is _far_ more pleasing to the eye than
> "except magic_exception_name_that+gets_everything:". Also, I wish
> "BaseException" were just spelled "Exception", if it has to be used.

> I'm -0.1 on the idea myself. I consider "except:" succinct and evocative,
> and prefer it to "except BaseException:".

What you're looking at here is exactly why it's not spelled that way.
The normal thing to do is NOT to catch absolutely everything, but to
allow KeyboardInterrupt and SystemExit to continue to bubble up.
That's spelled "except Exception". My whole point here is that the
bare except catches too much for normal use, and therefore should
_not_ be pleasing to the eye. The thing you should most often be doing
is "except ValueError" or equivalent; forcing you to put at least
_some_ name into the exception clause emphasizes that being specific
is not the unusual case.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: find all multiplicands and multipliers for a number

2015-04-11 Thread Terry Reedy

On 4/11/2015 5:10 PM, Chris Angelico wrote:

On Sun, Apr 12, 2015 at 3:52 AM, Paul Rubin  wrote:

PS Note that you're being "wasteful" by multiplying c*c over and over


Yeah this is a reasonable point, though most of the c's should fit in a
machine word, at least in my 64-bit system.  I think Python still
separates ints and longs in the implementation.


I don't think it does.


In 3.0, the 2.x int class and intobject.c were removed and the long 
class was renamed int, while longobject.c remained, with code relevant 
to the int class removed. I believe longobject effectively represents 
ints in base 2**15 or 2**30 (or 31?) for 32 and 64 bit machines, so that 
products of 'digits' fit in a single machine word.  (I am not sure if 
the increased size for 64 bit machines was implemented or not.)


> Performance doesn't seem to change in Py3 as
> the numbers get bigger:

I suspect the effect is more dramatic with multiplication.

--
Terry Jan Reedy

--
https://mail.python.org/mailman/listinfo/python-list


Re: find all multiplicands and multipliers for a number

2015-04-11 Thread Chris Angelico
On Sun, Apr 12, 2015 at 9:58 AM, Terry Reedy  wrote:
> I believe longobject effectively represents ints in base 2**15 or 2**30 (or
> 31?) for 32 and 64 bit machines, so that products of 'digits' fit in a
> single machine word.  (I am not sure if the increased size for 64 bit
> machines was implemented or not.)
>
>> Performance doesn't seem to change in Py3 as
>> the numbers get bigger:
>
> I suspect the effect is more dramatic with multiplication.

Sorry, sloppy language. Of course larger numbers will be a bit slower,
but there's no stark change at the edge of the machine word. The
performance loss from going from one limb to two will be comparable to
the loss from going from five to six, where it's already well past
machine integer. In Py2, there's a significant difference between
"int" performance and "long" performance (regardless of the actual
size of integer involved), but Py3 is more consistent.

It's a missed optimization at worst, but the upshot is that a Python
programmer doesn't need to think about integer sizes at all.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


has anyone used collusion API for creating graphs?

2015-04-11 Thread Pippo
I want to create graphs with using collusion API from annotated text

has anyone used the api? do you have any better suggestion too?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: find all multiplicands and multipliers for a number

2015-04-11 Thread Steven D'Aprano
On Sun, 12 Apr 2015 02:31 am, Paul Rubin wrote:

> Steven D'Aprano  writes:
>> [3, 3, 3, 3, 7, 19, 73, 87211, 262657, 1.4411518807585587e+17]
>> Oops, you have a float in there, how did that happen?
> 
> Looks like you are using a broken version of Python.

Well, we know about people who blame their tools ... *wink*

I'm really not using a broken version of Python. You're the one using /=
instead of integer division.

Ah, the penny drops! Are you using Python 2.7 with old-style division? That
would explain it.

Okay, let me do the experiment again, this time with old-division enabled,
using 2.7.


py> n = 2**111 + 1
py> with Stopwatch():
... pyprimes.factors.factorise(n)
...
[3, 3, 1777, 3331, 17539, 25781083, 107775231312019L]
time taken: 24.011609 seconds
py> with Stopwatch():
... list(fac(n))
...
[3, 3, 1777, 3331, 17539, 25781083, 107775231312019L]
time taken: 11.743913 seconds

That's certainly an improvement over what I got before, both in time and
correctness. I didn't expect that float arithmetic would be so much slower
than int arithmetic! Go figure.


Here's another demonstration:

py> m = 2**117 - 1
py> with Stopwatch():
... pyprimes.factors.factorise(m)
...
[7, 73, 79, 937, 6553, 8191, 86113, 121369, 7830118297L]
time taken: 0.089402 seconds
py> with Stopwatch():
... list(fac(m))
...
[7, 73, 79, 937, 6553, 8191, 86113, 121369, 7830118297L]
time taken: 0.047645 seconds


Nice! Except that your fac() function has a bug: it includes 1 as a prime
factor for some values, which is strictly incorrect.

py> list(fac(4))
[2, 2, 1]

That probably won't make much difference for the speed, but it will
certainly make a difference with the correctness.

Oh:

py> pyprimes.factors.factorise(-1234567)
[-1, 127, 9721]
py> list(fac(-1234567))
[-1234567]


-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: try..except with empty exceptions

2015-04-11 Thread Steven D'Aprano
On Sun, 12 Apr 2015 07:37 am, Cameron Simpson wrote:

> On 11Apr2015 21:21, Chris Angelico  wrote:
>>But I agree, it would be very nice if Python 3 could have abolished
>>the truly confusing part of this, where "except:" catches everything.
>>Forcing people to spell it "except BaseException:" would fix all of
>>this. How hard is it to deprecate and then remove that, same as string
>>exceptions were removed?
> 
> I guess I'll go over there to oppose it then.
> 
> Why? It makes it harder to write portable python 2/3 code and does not add
> any semantic advantage.

I don't think it does make it harder to write hybrid 2+3 applications.

The thing is, in 3, you *must* inherit from BaseException. String exceptions
are gone (they were removed in 2.6, so if you're still using them, you code
won't even run in 2.6 or 2.7). Old-style classes are gone, so your classic
exceptions will automatically be promoted to new-style classes.

class MyException:
pass

In 2.x code, that can be raised and caught. But not in 3.x, so if you are
writing hybrid code you have to change that anyway! It's surely a trivial
change:

class MyException(Exception):
pass


Now you can raise it in both 2.x and 3.x, and you can catch it with "except
Exception", as recommended.

Now, *technically* there are things that are possible with classic classes
in 2.x which are hard or impossible once you inherit from Exception, but
(1) I don't imagine that exceptions will use them, and (2) you still have
to deal with that when migrating anyway, so you are no worse off.

[To be precise, I'm referring to things like the ability to override dunder
methods on a per-instance basis. Want to give this specific instance, and
no other, the ability to support + addition? You can with classic classes,
but not easily with new-style classes. But who is going to want to do that
for an exception?]



> Unless there's a common root exception class in Python 2, which I believe
> there isn't, you can't catch all exceptions in python 2 without the
> "except:" syntax. 

Correct.


> Which means the _only_ way to have some code in both 2 
> and 3 that does it requires 2 codebases.

You would think so, but not really. The thing is, if you want to use a
single codebase, you cannot *raise* strings, or classic classes that don't
inherit from BaseException, not even in your 2.x code. Since you aren't
raising them, there's no need to catch them!

In hybrid code running under 2.x, a non-BaseException exception (NBEE) is a
bug to be fixed. The fact that you are no longer catching it in 2.x is a
good thing, because that forces you to find the offending code which raises
the NBEE and fix it.


 
> As one who tries to have his code run in both 2 (usually recent 2, like
> 2.6/2.7) and 3, this change would cause a signification breakage for me
> without bringing any semantic benefits.

I think that the only way that would be true is if you are referring to a
*library*, rather than an application. In other words, you have:

- a single code base with hybrid 2+3 code;

- your users are integrating it with other people's code (perhaps their own)
  which you do not control, i.e. it is a library, not an application;

- that 3rd party code raises string exceptions (up to 2.5) or classic NBEE;

- you have to catch those exceptions, and cannot just say to your users "we
  don't support non-BaseException exceptions any more".

Life is tough for library authors who want to support old code :-(


The solution, as I see it, would be to extract only the bits of your code
that does the exception handling, and split it into two separate files:

# catcher2.py
from common import dostuff
try: 
...
except BaseException:
dostuff()
except:
warnings.warn("fix your code, you neanderthal!")
dostuff()

# catcher3.py
from common import dostuff
try:
...
except BaseException:
dostuff()


and then conditionally import one or the other. Alternatively, you can use
exec, and a single file.

I wouldn't say that either solution thrills me. If I were in that position,
I would simply document that string exceptions and classic-class exceptions
are no longer supported, and make my users responsible for fixing or
replacing the third-party code that raises such things.



> Without vigorous use of the time machine I don't see a fix here.
> 
> For the record, I would be ok (but not "for") never having had bare
> "except" if all exceptions had always had a common root.
> 
> Hmm. Can I catch "object"? Sounds awful, but might work.

No.

http://bugs.python.org/issue2291

See also PEP 352, which explains some of the motivation of the post 2.4
changes to exceptions, and the expected timeline for changes leading up to
3.x. (Some of the PEP is a bit obsolete, it still refers to Python 2.9
being the last of the 2.x series.)

http://www.python.org/dev/peps/pep-0352/



-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: try..except with empty exceptions

2015-04-11 Thread Steven D'Aprano
On Sun, 12 Apr 2015 09:08 am, Cameron Simpson wrote:

> Also, IMO, a bare "except:" syntax is far more pleasing to the eye than
> "except magic_exception_name_that+gets_everything:".


And that is exactly what makes bare excepts an attractive nuisance!

I'm going to channel a newbie, cowboy or just plain lazy coder:


"I have a block of code with a bug. Bugs are bad. I know, I'll wrap it in

try:
block
except:
pass

and the bug will go away!"

It looks nice and requires relatively little typing. It seems like something
you should do, but it doesn't fix the problem, chances are it just makes it
worse. I've spotted many real-world examples where bare excepts mask the
presence of actual bugs, where the intention is clearly to catch a single
exception:

try:
return mylist[0]
except:
# empty list
return None


Forcing people to type an exception will discourage such cowboy coding. If
the choice is between

except BaseException:

instead of the lazy "except:" version, and

except IndexError:

which do you think people will write?



> Also, I wish
> "BaseException" were just spelled "Exception", if it has to be used.

Most of the time, "catch everything" should mean catching Exception, not
BaseException. Broadly speaking, built-in exceptions which are
considered "errors" inherit from Exception, and the small number that don't
are used for some variation of control-flow:

StopIteration
GeneratorExit
KeyboardInterrupt
SysExit


Most of the time when people say "catch everything" they mean catch all
errors, i.e. Exception, rather than "don't let the user interrupt the code
using KeyboardInterrupt".

See also PEP 352:

http://www.python.org/dev/peps/pep-0352/

-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: find all multiplicands and multipliers for a number

2015-04-11 Thread Paul Rubin
Steven D'Aprano  writes:
> Ah, the penny drops! Are you using Python 2.7 with old-style division? That
> would explain it.

Yes, see also the use of the print statement in that post.  I'm
surprised the code compiled at all in Python 3.

> Nice! Except that your fac() function has a bug: it includes 1 as a prime
> factor for some values, which is strictly incorrect.

Good catch, I noticed that too after posting.  

This might be of interest:

http://wrap.warwick.ac.uk/54707/1/WRAP_Hart_S1446788712000146a.pdf

I haven't tried figuring it out or coding it yet.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: find all multiplicands and multipliers for a number

2015-04-11 Thread Steven D'Aprano
On Sun, 12 Apr 2015 02:24 pm, Paul Rubin wrote:

> Steven D'Aprano  writes:
>> Ah, the penny drops! Are you using Python 2.7 with old-style division?
>> That would explain it.
> 
> Yes, see also the use of the print statement in that post.  I'm
> surprised the code compiled at all in Python 3.

I wasn't using Python 3. I was using 2.7 with "from __future__ import
division", as the BDFL intended :-)


>> Nice! Except that your fac() function has a bug: it includes 1 as a prime
>> factor for some values, which is strictly incorrect.
> 
> Good catch, I noticed that too after posting.
> 
> This might be of interest:
> 
> http://wrap.warwick.ac.uk/54707/1/WRAP_Hart_S1446788712000146a.pdf
> 
> I haven't tried figuring it out or coding it yet.

Thanks!


-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Generarl programming question.

2015-04-11 Thread Steven D'Aprano
Thomas, before I reply to your comment, I have a meta-comment to make.

Your signature says "Please do not cc me. / Bitte keine Kopien per E-Mail."
which suggests that you do not want to be emailed. But your post included
an explicit "Mail-Copies-To: use...@pointedears.de" header which compliant
news readers should interpret as "reply by email as well as news".

So which is lying? Your sig, that says not to email you, or the
Mail-Copies-To header, which says to email you?

Back to Python...


On Sun, 12 Apr 2015 08:05 am, Thomas 'PointedEars' Lahn wrote:

>> In Python, one can do something similar with attributes, except that
>> attributes are easily accessible from outside the function.
> 
> AISB.  Python’s “attributes” are named “properties” elsewhere.

Other common names include “members” (mostly in C++ I believe)
and “variables” (mostly Java, I believe). I think using “variable” to
describe an attribute/property/member of an object is a terrible idea.



-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: try..except with empty exceptions

2015-04-11 Thread Cameron Simpson

On 12Apr2015 09:21, Chris Angelico  wrote:

On Sun, Apr 12, 2015 at 9:08 AM, Cameron Simpson  wrote:

Catching all exceptions isn't terribly common, _except_ in service routines
that wrap "unknown" operations. Classic example from my Asynchron class: [...]

 try:
   r = func(*a, **kw)
 except:
   self.exc_info = sys.exc_info
 else:
   self.result = r

All sorts of things like thread pools and other "worker" functions, and
run-forever daemons like mail filers that can have arbitrary exceptions
occur in (partly) third party code eg from config files; you need to catch
any unknown exception and fail the specific action, but continue the main
daemon operation.

And since I use this code in Python 2, and since not all exceptions are
BaseException subclasses, I need the bare syntax.


Fair enough. Do you know how often you actually catch stuff that
wouldn't be caught by "except BaseException:"?


I don't know and I'm not sure I care (but discussion below). I would need to 
examine carefully what they were. Looking at the 2.7.9 doco for Exception it 
almost looks like that is what I should often want. (Though I think I have some 
circumstances where I might prefer BaseException.)



I would guess it's
pretty rare. In fact, you can find out.

try:
  r = func(*a, **kw)
except BaseException:
  self.exc_info = sys.exc_info
except:
  self.exc_info = sys.exc_info
  emit_warning()
   else:
  self.result = r

You could simply mandate that, from version X.Y of your Asynchron
module onward, old-style classes must not be thrown.


Except that Asynchron, like several of the other circumstances, is expected to 
be used with arbitrary callables from outside sources.



Also, IMO, a bare "except:" syntax is _far_ more pleasing to the eye than
"except magic_exception_name_that+gets_everything:". Also, I wish
"BaseException" were just spelled "Exception", if it has to be used.



I'm -0.1 on the idea myself. I consider "except:" succinct and evocative,
and prefer it to "except BaseException:".


What you're looking at here is exactly why it's not spelled that way.
The normal thing to do is NOT to catch absolutely everything, but to
allow KeyboardInterrupt and SystemExit to continue to bubble up.
That's spelled "except Exception".


Yes. But can I guarrentee that those are the only two? The 2.7.9 doco says:

  exception Exception
  All built-in, non-system-exiting exceptions are derived from this class.

I suppose I could consider that clear, but certainly in case of 
KeyboardInterrupt I might want to involve cleanup actions. I'll ignore 
interactive situations; messy.


My whole point here is that the bare except catches too much for normal use, 
and therefore should _not_ be pleasing to the eye. The thing you should most 
often be doing is "except ValueError" or equivalent; forcing you to put at 
least _some_ name into the exception clause emphasizes that being specific

is not the unusual case.


Yes. But it seems to me that "normal use" generally means the situation where 
one catches a quite narrow set of exceptions for which particular recoveries 
are well defined.


However, when I want "all exceptions", that really is what I mean. I need to 
think quite carefully about KeyboardInterrupt and SystemExit. The former is 
guarrenteed to be delivered to the main thread IIRC and I'd want to catch that 
specificly in my main() function, if at all. And I suspect that SystemExit 
really shouldn't be stopped; if something untoward is calling it, should it not 
succeed? Or be exposed and then hunted down and killed!


So your argument for "except Exception:" is quite compelling for many 
situations where I do currently use "except:". I will review them and have a 
proper think.


However, my Asynchron class really is a little special. I use Asynchron to 
underpin a bunch of classes whose instances get fulfilled later, especially 
callables that get queued and run at a suitable time (or which get run in 
response to some external long awaited event). So, example sketch:


 L = Later()
 ...
 # LF is a "LateFunction", a subclass of Asynchron
 LF = L.defer(function, *a, **kw)
 ...
 try:
   result = LF()
 except Whatever as e:
   ...

My Later class serves a purpose much like the futures module and I suppose a 
LateFunction is somewhat like a future.


Anyway, at some point in the above example "function" gets called (by the 
infrastructure of "Later") with the supplied arguments as the Later processes 
its queue.


The user can collect the result by calling "LF()" whenever they like, as though 
they were calling "function()" directly.  If the function has already run, the 
value is returned or whatever exception _it_ raised is raised now. Otherwise it 
blocks until the function is run; same behaviour for the caller except for a 
delay.


So in this situation: should I catch and defer KeyboardInterrupt or SystemExit?  
Maybe not, but the clean/naive implementation says to catch a

Re: try..except with empty exceptions

2015-04-11 Thread Cameron Simpson

On 12Apr2015 16:33, Cameron Simpson  wrote:
Finally, if we were to expunge support for "except:", one would also need a 
cast iron guarrentee that no exception could possibly occur which was not a 
subclass of BaseException. I'd expect that to mean that "raise" of a 
non-instance of BaseException to itself raise a TypeError.


And I see that Steven D'Aprano has already pointed out PEP 352:

 http://www.python.org/dev/peps/pep-0352/

which is marked "Status: Final". It says:

 The raise statement will be changed to require that any object passed to it 
 must inherit from BaseException. This will make sure that all exceptions fall 
 within a single hierarchy that is anchored at BaseException [2] . This also 
 guarantees a basic interface that is inherited from BaseException. The change 
 to raise will be enforced starting in Python 3.0 (see the Transition Plan 
 below).


Hmm. Not in 2.7? I can see the breakage it could cause, but where does that 
leave me? I think I could probably move to catching Exception almost across the 
board even in 2.5+ and feel pretty good.


Cheers,
Cameron Simpson 

If your new theorem can be stated with great simplicity, then there
will exist a pathological exception.- Adrian Mathesis
--
https://mail.python.org/mailman/listinfo/python-list


Re: try..except with empty exceptions

2015-04-11 Thread Cameron Simpson

On 12Apr2015 14:18, Steven D'Aprano  
wrote:

On Sun, 12 Apr 2015 09:08 am, Cameron Simpson wrote:

Also, IMO, a bare "except:" syntax is far more pleasing to the eye than
"except magic_exception_name_that+gets_everything:".


And that is exactly what makes bare excepts an attractive nuisance!

I'm going to channel a newbie, cowboy or just plain lazy coder:
"I have a block of code with a bug. Bugs are bad. I know, I'll wrap it in

try:
   block
except:
   pass

and the bug will go away!"


And haven't we all seen that _many_ times on this list:-)


It looks nice and requires relatively little typing. It seems like something
you should do, but it doesn't fix the problem, chances are it just makes it
worse.


And do not get me started on Makefiles which finish every compile command in 
"2>/dev/null" :-(



I've spotted many real-world examples where bare excepts mask the
presence of actual bugs, where the intention is clearly to catch a single
exception: [...]
Forcing people to type an exception will discourage such cowboy coding. If
the choice is between

   except BaseException:

instead of the lazy "except:" version, and

   except IndexError:

which do you think people will write?


I fear that the just-beyond-beginner might write "Exception", but your point is 
well taken.



Also, I wish
"BaseException" were just spelled "Exception", if it has to be used.


Most of the time, "catch everything" should mean catching Exception, not
BaseException. Broadly speaking, built-in exceptions which are
considered "errors" inherit from Exception, and the small number that don't
are used for some variation of control-flow:

StopIteration
GeneratorExit
KeyboardInterrupt
SysExit

Most of the time when people say "catch everything" they mean catch all
errors, i.e. Exception, rather than "don't let the user interrupt the code
using KeyboardInterrupt".


Yes, I see that this is true.

And I have special pain in some of my code which then causes me to specificly 
catch NameError ahead of my bare (or mostly bare) excepts because that usually 
indicates some stupid typo on my part, causing silent breakage and debugging 
hell. Ghastly.



See also PEP 352:
http://www.python.org/dev/peps/pep-0352/


Thank you for this.

Cheers,
Cameron Simpson 

To be or not to be?Not to be.
   - John Slater (Arnold Schwartzenegger),
 _Macbeth_ (_The_Last_Action_Hero_)
--
https://mail.python.org/mailman/listinfo/python-list