Re: len() should always return something

2009-07-28 Thread Luis Zarrabeitia
On Friday 24 July 2009 11:58:36 am Phillip M. Feldman wrote:
 I've been converting Matlab codes to Python.  In Matlab, a scalar is just a
 one-by-one matrix and has a length of 1.  This convention seems no less
 arbitrary to me than Python's convention that the concept of length is not
 applicable to ints and floats.

Are you sure it isn't? (as opposed to being tainted by matlab?).

Almost everywhere, a scalar and a tuple are different things. How many 
elements are inside the number 7? If you assume that 7 is a matrix, why 
should it be a two-dimensional matrix? Why not a vector, or a three 
dimensional matrix instead? (I don't use matlab, but in octave, size(7) 
returns [1,1], not [1] or [1,1,1,1]).

That seems even more arbitrary to me. Of course, in a language like Matlab, 
that assumes that everything is a matrix, it makes sense for scalars to be 
mapped to a useful matrices. But that assumption is not natural.

Even pure math makes a difference between scalars and vectors. Matrix x Matrix 
multiplication is not always defined (even when the second matrix contains 
exactly one element), while Matrix x Scalar always is. (Octave, btw, will 
demote a two-dimensional 1x1 matrix to a scalar for Matrix multiplication, 
which may hide errors)

If you are converting from matlab, I'd say you have biggest things to worry 
about. As you said, you can just replace the len function (even safer may be 
to do [1]). Assignment, for instance, is /very/ different.

 If there is only a single measurement, it is reasonable to allow the calling 
 program to pass a scalar without wrapping it up into a list or array.

I try to avoid those automatic conversions, on the long run, I believe that 
most of them make the code more confusing for the caller. If you feel that 
you must allow that, my suggestion would be to create a method that will 
ensure that what you receive is a list (or whatever) and coerce its argument 
if not, and call that one at the beginning of your methods.

Regards,

[1] this will define len for any object, not only int and floats.
===
def size(x):
try:
return len(x)
except TypeError:
return 1,1
===

-- 
Luis Zarrabeitia (aka Kyrie)
Fac. de Matemática y Computación, UH.
http://profesores.matcom.uh.cu/~kyrie
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-27 Thread Joshua Kugler
Dr. Phillip M. Feldman wrote:

 
 As far as I know, there is no programming language which treats scalars
 like ints as if they were
 vectors of length 1
 
 Actually, Matlab does:
 
 length(5)
 ans =
  1
 

Oddly enough, so does Perl:

$ print length(44)
2

(that's in the Zoidberg shell)

j


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


Re: len() should always return something

2009-07-27 Thread Grant Edwards
On 2009-07-27, Joshua Kugler jos...@joshuakugler.com wrote:
 Dr. Phillip M. Feldman wrote:

 As far as I know, there is no programming language which
 treats scalars like ints as if they were vectors of length 1
 
 Actually, Matlab does:
 
 length(5)
 ans =
  1
 

 Oddly enough, so does Perl:

 $ print length(44)
 2

No, that's not really treating scalars as vectors of length 1.
Were it doing so, length(44) would be 1 rather than 2.  What
Perl does is treat everything as a string.

-- 
Grant Edwards   grante Yow! I was making donuts
  at   and now I'm on a bus!
   visi.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-27 Thread Joel Koltner
Dr. Phillip M. Feldman pfeld...@verizon.net wrote in message 
news:mailman.3699.1248490256.8015.python-l...@python.org...
 Here's a simple-minded example:
...
 This function works fine if xs is a list of floats, but not if it is single
 float.  It can be made to work as follows:

Wow, you could substitute Matlab for Python in your post and it'd still be 
just as good. :-)


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


Re: len() should always return something

2009-07-26 Thread Emmanuel Surleau
On Sunday 26 July 2009 00:42:26 Marcus Wanner wrote:
 On 7/25/2009 10:08 AM, Piet van Oostrum wrote:
  Steven D'Aprano st...@remove-this-cybersource.com.au (SD) wrote:
 
  SD Ambiguity essentially boils down to being unable to reasonably
  predict SD the expectation of the coder. I say reasonably, because if
  you allow SD unreasonable situations, everything is ambiguous:
 
  That's for me the reason that len(42) is ambiguous. The OP apparently
  had 1 as expectation, whereas my first thought was the minimal number of
  bits to represent the number and 7.5 million came later :=). The number
  of bits I certainly find reasonable, and I would find the number of
  decimal digits equally reasonable. More so than 1, actually. 1 as the
  length of an int doesn't give any information.

 Well, for my two cents, I will say that the number of binary bits or
 decimal digits is certainly the most sensible return value, and that the
 former is the most useful, because the latter can be got with
 len(str(42)). However, the former can also be (/slightly/ less)easily
 got with len(bin(42))-2...


For my two eurocents, I'd expect such an operator to be called sizeof and 
when applied to a collection, to also return the number of bits it uses. I 
don't think a 'len' function has meaning when applied to something else than a 
collection, really...

 I also think that Explicit is better than implicit. says that there
 should be no return value in this case, as any return value would be
 implicit.

Agreed.

Cheers,

Emm
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-26 Thread Steven D'Aprano
On Sat, 25 Jul 2009 16:21:39 -0700, Erik Max Francis wrote:

 Steven D'Aprano wrote:
 But it's not practically every function. It's hardly any function at
 all -- in my code, I don't think I've ever wanted this behavior. I
 would consider it an error for function(42) and function([42]) to
 behave the same way. One is a scalar, and the other is a vector --
 they're different things, it's poor programming practice to treat them
 identically.
 
 (If Matlab does this, so much the worse for Matlab, in my opinion.)
 
 There's actually good reason to do this in heavily matrix-oriented
 specialized languages; there are numerous applications where scalars and
 1x1 matrices are mathematically equivalent.


I'm curious what those applications are, because regular multiplication 
behaves differently depending on whether you have a 1x1 matrix or a 
scalar:

[[2]]*[[1, 2, 3], [2, 3, 4]] is not defined

2*[[1, 2, 3], [2, 3, 4]] = [[2, 4, 6], [2, 6, 8]]


I'm curious as to what these applications are, and what they're actually 
doing. Kronecker multiplication perhaps? Do you have some examples of 
those applications?



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-26 Thread Erik Max Francis

Steven D'Aprano wrote:
I'm curious what those applications are, because regular multiplication 
behaves differently depending on whether you have a 1x1 matrix or a 
scalar:


[[2]]*[[1, 2, 3], [2, 3, 4]] is not defined

2*[[1, 2, 3], [2, 3, 4]] = [[2, 4, 6], [2, 6, 8]]

I'm curious as to what these applications are, and what they're actually 
doing. Kronecker multiplication perhaps? Do you have some examples of 
those applications?


The most obvious example would be the matrix algebra equivalent of the 
calculation of the dot product, the equivalent of a dot product in 
normal vector algebra.  If you have two 3-vectors (say), u = (u_1, u_2, 
u_3) and v = (v_1, v_2, v_3), then the dot product is the sum of the 
pairwise products of these terms, u dot v = sum_i u_i v_i = u_1 v_1 + 
u_2 v_2 + u_3 v_3.


Nothing revolutionary there.  The matrix way of writing this wouldn't 
obviously work, since multiplying two nx1 or (1xn) matrixes by each 
other is invalid.  But you _can_ multiply a nx1 matrix by an 1xn matrix, 
and you get the equivalent of the dot product:


u v^T = ( u dot v ),

where the right hand side of the equation is formally a 1x1 matrix 
(intended to be indicated by the parentheses), but you can see how it is 
useful to think of it as just a scalar, because it's really just a 
matrix version of the same thing as a dot product.


This stretches out to other kinds of applications, where, say, in tensor 
calculus, you can think of a contravariant vector as being transformed 
into a covariant vector by the application of the matrix tensor, which 
is written as lowering an index.  The components of the contravariant 
vector can be thought of as a column vector, while the components of a 
covariant vector can be represented with a row vector.  The application 
 of the metric tensor to a contravariant vector turns it into a row 
vector, and then contracting over the two vectors gives you the inner 
product as above.  The applications and contractions can all be 
visualized as matrix multiplications.  (Contrary to a popularization, 
tensors _aren't_ generalizations of matrices, but their components can be.)


It's a bunch of other examples like that where you end up with a 1x1 
matrix that really represents a scalar, and since that was intended 
there really isn't a lot of efficacy to treat it as a separate entity. 
Especially if you're dealing with a special-purpose language where 
everything is really a form of an generalized array representation of 
something _anyway_.


--
Erik Max Francis  m...@alcyone.com  http://www.alcyone.com/max/
 San Jose, CA, USA  37 18 N 121 57 W  AIM/Y!M/Skype erikmaxfrancis
  Scars are like memories. We do not have them removed.
   -- Chmeee
--
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-26 Thread drednot57
To the best of my recollection, the len() function only applies to
container objects; i. e. tuples, lists, strings, etc.  an integer
object is not a container, thus one receives an error when sending an
int as an argument for len().
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-25 Thread Andre Engels
On Sat, Jul 25, 2009 at 4:50 AM, Dr. Phillip M.
Feldmanpfeld...@verizon.net wrote:

 Here's a simple-minded example:

 def dumbfunc(xs):
   for x in xs:
      print x

 This function works fine if xs is a list of floats, but not if it is single
 float.  It can be made to work as follows:

 def dumbfunc(xs):
   if isinstance(xs,(int,float,complex)): xs= [xs]
   for x in xs:
      print x

 Having to put such extra logic into practically every function is one of the
 annoying things about Python.

I don't have this problem - when I have a list of one element, that's
what I use - a list with one element. I think things would get much
simpler if you do such a conversion right at the Matlab-Python
interface, rather than changing all kind of things in Python so that
its types are more matlab-like. Just like you shouldn't program Python
by simply translating Java or C into Python idiom, you also shouldn't
program Python by trying to mimic Matlab. Each language has its own
strengths and weaknesses, and moving things over too much in a
simplistic fashion will usually mean that you get the weaknesses of
both and the strengths of neither.

-- 
André Engels, andreeng...@gmail.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-25 Thread Steven D'Aprano
On Fri, 24 Jul 2009 19:50:54 -0700, Dr. Phillip M. Feldman wrote:

 Here's a simple-minded example:
 
 def dumbfunc(xs):
for x in xs:
   print x
 
 This function works fine if xs is a list of floats, but not if it is
 single float.  It can be made to work as follows:
 
 def dumbfunc(xs):
if isinstance(xs,(int,float,complex)):
   xs= [xs]
for x in xs:
   print x
 
 Having to put such extra logic into practically every function is one of
 the annoying things about Python.


But it's not practically every function. It's hardly any function at 
all -- in my code, I don't think I've ever wanted this behavior. I would 
consider it an error for function(42) and function([42]) to behave the 
same way. One is a scalar, and the other is a vector -- they're different 
things, it's poor programming practice to treat them identically.

(If Matlab does this, so much the worse for Matlab, in my opinion.)

However, if you want this behaviour, it's easy enough to get it with a 
decorator:

from functools import wraps
def matlab(func):
Decorate func so that it behaves like Matlab, that is, 
it considers a single scalar argument to be the same as a 
vector of length one.
@wraps(func)
def inner(arg, **kwargs):
# If arg is already a vector, don't touch it.
try:
# If this succeeds, it's a vector of some type.
iter(arg)
except TypeError:
# It's a scalar.
arg = [arg]
# Now call the decorated function (the original).
return func(arg, **kwargs)
return inner

With this decorator in hand, you can now easily get the behaviour you 
want with a single extra line per function:

 @matlab
... def mean(numbers):
... return sum(numbers)/len(numbers)
...
 mean([4.5])
4.5
 mean(4.5)
4.5
 mean([4.5, 3.6])
4.0498


Decorators are extremely powerful constructs, and well worth learning. As 
an example, here's a similar decorator that will accept multiple 
arguments, like the built-in functions min() and max():

def one_or_many(func):
Decorate func so that it behaves like the built-ins
min() and max().
@wraps(func)
def inner(*args, **kwargs):
# If we're given a single argument, and it's a vector, 
# use it as args.
if len(args) == 1:
try:
iter(args[0])
except TypeError:
pass
else:
# No exception was raised, so it's a vector.
args = args[0]
# Now call the decorated function (the original).
return func(args, **kwargs)
return inner


And then use it:

 @one_or_many
... def minmax(numbers):
... Return the minimum and maximum element of numbers, 
... making a single pass.
... # the following will fail if given no arguments
... smallest = biggest = numbers[0]  
... for x in numbers[1:]:
... if x  smallest:
... smallest = x
... elif x  biggest:
... biggest = x
... return (smallest, biggest)
...

 minmax([2, 4, 6, 8, 1, 3, 5, 7])
(1, 8)
 minmax(2, 4, 6, 8, 1, 3, 5, 7)
(1, 8)




-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-25 Thread Hendrik van Rooyen

On Friday 24 July 2009 16:45:40 Mark Dickinson wrote:

 On Jul 24, 3:11 pm, Rhodri James rho...@wildebst.demon.co.uk

 wrote:
  Which doesn't make your point less valid.  In fact I'd go so
  far as to argue that what len() gives you is the number of
  items in a container, so len(7) should return 0.

 Nah.  7 contains three bits, so len(7) should *clearly* return 3.

Almost right - however the first seven that you typed was a string
seven and not an int - so the hex is 37 and that takes at least
six bits...

:-)

Now if only someone can figure out a reason why it should
return seven, then it would be perfect!

- Hendrik
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-25 Thread Carl Banks
On Jul 23, 11:35 pm, Dr. Phillip M. Feldman pfeld...@verizon.net
wrote:
 Some aspects of the Python design are remarkably clever, while others leave
 me perplexed. Here's an example of the latter: Why does len() give an error
 when applied to an int or float? len() should always return something; in
 particular, when applied to a scalar, it should return a value of 1. Of
 course, I can define my own function like this:

 def mylen(x):
    if isinstance(x,int) or isinstance(x,float): return 1
    return len(x)

 But, this shouldn't be necessary.

I knew that you were coming from Matlab as soon as I saw the subject
line.

I use both Matlab and Python very often, and I understand the design
decisions behind both (insofar as Matlab can be considered a
design).

The thing to keep in mind about Python is that it's a general purpose
language, not just for mathematical computation, and there are some
things in Python that are a bit suboptimal for math calculations.
This is one of them: when the types of objects you are dealing with
most often are numbers, then there's not much chance for ambiguity
when treating a scalar as a 1x1 matrix.

However, when doing general purpose programming, you often use lots of
types besides numbers, some of which are containers themselves.  This
creates the possibility of ambiguity and inconsistent behavior.  Let's
consider your example function.

def dumbfunc(xs):
   for x in xs:
  print x

You can use it on an list, like this, and there is no ambiguity:

dumbfunc([1,2,3])

Now suppose Python allowed numbers to be treated as degenerate
sequences of length 1.  Then you could pass a number, and it would
work as you expect:

dumbfunc(1)

However, because Python is general purpose, you might also want to
pass other types around, such as strings.  Say you wanted to print a
list of string, you would do this, and it would work as expected:

dumbfunc([abc,def,ghi])

Now, the problem.  In the numbers example, you were able to treat a
single number as a degenerate list, and by our supposition, it
worked.  By analogy, you would expect to be able to do the same with a
list of strings, like this:

dumbfunc(abc)

Whoops: doesn't work.  Instead of printing one string abc it prints
three strings, a, b, and c.

By allowing scalar numbers to act as degenerate lists, you've
introduced a very bad inconsistency into the language, you've made it
difficult to learn the language by analogy.

For a general purpose language there is really no second-guessing this
design decision.  It would be unequivocally bad to have atomic types
act like sequences.  The reason it isn't so bad in Matlab is that you
can rely on the elements of an array to be scalar.

Matlab, for its part, does contain some types (cell arrays and
structures) that can contain non-scalars for cases when you want to do
that.  However, you will notice that no scalar will ever be treated as
a degenerate cell array or structure.  Even a poorly designed, ad hoc
language like Matlab won't try to treat scalar numbers as cell arrays,
because ambiguity like I described above will appear.  Nope, it takes
an abomination like Perl to do that.

As for how I would recommend you translate the Matlab function that
rely on this: you need to decide whether that scalar number you are
passing in is REALLY a scalar, or a degenerate vector.  If it's the
latter, just get over it and pass in a single-item list.  I have done
these kinds of conversions myself before, and that's the way to do
it.  Trying to be cute and writing functions that can work with both
types will lead to trouble and inconsistency, especially if you are a
Python newbie.  Just pass in a list if your function expects a list.


Carl Banks
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-25 Thread Diez B. Roggisch

Dr. Phillip M. Feldman schrieb:

Here's a simple-minded example:

def dumbfunc(xs):
   for x in xs:
  print x

This function works fine if xs is a list of floats, but not if it is single
float.  It can be made to work as follows:

def dumbfunc(xs):
   if isinstance(xs,(int,float,complex)): xs= [xs]
   for x in xs:
  print x

Having to put such extra logic into practically every function is one of the
annoying things about Python.


And where comes len(xs) into play here? What you want is iteration 
over scalars.


I do think that if you frequently have to write code like that, you are 
writing errorneous code.


But might that as it is, a simple


def iterable(i):
if isinstance(i, (int, float, complex)):
   return [i]
return i


is all you need. So you can write


for x in iterable(xs):


wherever you expect values to be either scalar or iterable.

Diez
--
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-25 Thread Piet van Oostrum
 Steven D'Aprano st...@remove-this-cybersource.com.au (S) wrote:

S Chris, I'm curious why you think that these Zen are relevant to the OP's 
S complaint.

S Re explicit vs implicit, len(42) is just as explicit as len([42, 23]).

S Arguably (I wouldn't argue this, but some people might) ints aren't 
S special enough to break the rule that len(obj) should always return 
S something.

S (I don't actually agree, but some people might be able to produce a 
S coherent argument why len() should apply equally to all objects.)

S Re errors passing silently, the OP doesn't believe that len(42) should be 
S an error, so that's not relevant.

S And there's nothing ambiguous about len(42).

len(42) should be 7.5 million.
-- 
Piet van Oostrum p...@cs.uu.nl
URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4]
Private email: p...@vanoostrum.org
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-25 Thread Hendrik van Rooyen
On Friday 24 July 2009 21:04:55 Roy Smith wrote:


 Compressing strings to a single bit is easy.  It's the uncompressing that's
 tricky.

Not really - all you have to do is to apply the EXACT same sequence
of operations that compressed it, in reverse.

The unfortunate part is that this information is in almost all cases
larger than the original, uncompressed string, so that it kind of defeats
the object of compression.

So yes - tricky!

:-)

- Hendrik


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


Re: len() should always return something

2009-07-25 Thread Hendrik van Rooyen
On Friday 24 July 2009 22:09:15 Marcus Wanner wrote:

 First one to correctly decompress the value 0 into an ASCII character
 wins the title of the world's most capable hacker :p

that is easy.

the xor of 0 and 1 is 1, which is ASCII soh, if I remember right.

soh is start of header.

Burroughs poll select, anyone?

- Hendrik

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


Re: len() should always return something

2009-07-25 Thread Marcus Wanner

On 7/25/2009 5:34 AM, Hendrik van Rooyen wrote:

On Friday 24 July 2009 22:09:15 Marcus Wanner wrote:


First one to correctly decompress the value 0 into an ASCII character
wins the title of the world's most capable hacker :p


that is easy.

the xor of 0 and 1 is 1, which is ASCII soh, if I remember right.

soh is start of header.

Burroughs poll select, anyone?

- Hendrik


nope, not soh.

Marcus
--
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-25 Thread Steven D'Aprano
On Sat, 25 Jul 2009 10:03:58 +0200, Piet van Oostrum wrote:

S And there's nothing ambiguous about len(42).
 
 len(42) should be 7.5 million.

And I don't understand your reasoning.upper() should be Millennium 
Hand and Shrimp!.

Every function would be ambiguous if we treat it as returning an 
arbitrary result. But we don't -- semantics do matter. We expect that 
string.upper() should return the string converted to uppercase, and 
that's not ambiguous because we already know what uppercase means. Even 
if somebody didn't know what uppercase meant, they would expect that it 
had a meaning, and it was just a matter of learning what it meant: for 
example, one might take string.upper() as any of:

* convert every letter a..z to A..Z

* convert the first letter of each word to A..Z

* throw away the argument and return the literal upper

* count how many characters are in A..Z

and so forth.

These are some of the infinite number of *possible* meanings to 
string.upper(), but only one of them is the *actual* meaning. The method 
isn't ambiguous, because the language designers have chosen one meaning, 
and having learned what that meaning is, it's the *only* meaning you can 
legitimately use. If you (generic you) are uncertain what that meaning 
is, that's uncertainty, not ambiguity.

Similarly, we might be uncertain about the meaning of len(42) -- 
reasonable values it might return are 0, 1, 2, the number of bits in 42, 
and possibly even 7.5 million as you suggest. But that's our ignorance, 
due to the fact that we haven't yet agreed on a meaning to len(42), and 
not ambiguity: having made up our mind what len(42) should mean, it could 
only mean one thing.

However, mixed string/integer addition is a good example of ambiguity. We 
can add strings:

1 + 2 = 12

and we can add integers:

1 + 2 = 3

but it is ambiguous as to what 1 + 2 should return. Guido might have 
made Python behave like Perl, and define addition of a string and an int, 
but there would still be ambiguity in the expression, because we can't 
tell if the coder intended 1+2 and forgot to quote the two, or 
intended 1+2 and forgot to convert the string 1 to an int.

Ambiguity essentially boils down to being unable to reasonably predict 
the expectation of the coder. I say reasonably, because if you allow 
unreasonable situations, everything is ambiguous:

I typed:

x = 42 + y

but maybe I intended to import the math module, therefore the + operator 
is ambiguous. Reasonable? No, because we're allowed to assume the coder 
is rational, and mistakes are small.


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-25 Thread Piet van Oostrum
 Steven D'Aprano st...@remove-this-cybersource.com.au (SD) wrote:

SD Ambiguity essentially boils down to being unable to reasonably predict 
SD the expectation of the coder. I say reasonably, because if you allow 
SD unreasonable situations, everything is ambiguous:

That's for me the reason that len(42) is ambiguous. The OP apparently
had 1 as expectation, whereas my first thought was the minimal number of
bits to represent the number and 7.5 million came later :=). The number
of bits I certainly find reasonable, and I would find the number of
decimal digits equally reasonable. More so than 1, actually. 1 as the
length of an int doesn't give any information.
-- 
Piet van Oostrum p...@cs.uu.nl
URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4]
Private email: p...@vanoostrum.org
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-25 Thread Hendrik van Rooyen
On Saturday 25 July 2009 14:59:43 Steven D'Aprano wrote:
 On Sat, 25 Jul 2009 10:03:58 +0200, Piet van Oostrum wrote:
 S And there's nothing ambiguous about len(42).
 
  len(42) should be 7.5 million.

 And I don't understand your reasoning.upper() should be Millennium
 Hand and Shrimp!.

That does it.
I will be kinder to you in future.
Anybody who quotes foul old Ron cannot be all bad.

- Hendrik

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


Re: len() should always return something

2009-07-25 Thread Rhodri James
On Sat, 25 Jul 2009 03:50:54 +0100, Dr. Phillip M. Feldman  
pfeld...@verizon.net wrote:




Here's a simple-minded example:

def dumbfunc(xs):
   for x in xs:
  print x

This function works fine if xs is a list of floats, but not if it is  
single

float.  It can be made to work as follows:

def dumbfunc(xs):
   if isinstance(xs,(int,float,complex)): xs= [xs]
   for x in xs:
  print x

Having to put such extra logic into practically every function is one of  
the

annoying things about Python.


If you persist in treating language 1 as if it was language 2, then
your code will always be ugly, and often buggy.  Unless we're talking
natural languages, in which case Yoda-like you will sound.

Fundamentally, your problem is your assertion that it is reasonable to
allow users to treat a single object as if it were wrapped in a list.
In Python, it is not reasonable, for the reasons that you are spending
so much time complaining about.

--
Rhodri James *-* Wildebeest Herder to the Masses
--
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-25 Thread Robert Kern

On 2009-07-24 21:50, Dr. Phillip M. Feldman wrote:

Here's a simple-minded example:

def dumbfunc(xs):
for x in xs:
   print x

This function works fine if xs is a list of floats, but not if it is single
float.  It can be made to work as follows:

def dumbfunc(xs):
if isinstance(xs,(int,float,complex)): xs= [xs]
for x in xs:
   print x

Having to put such extra logic into practically every function is one of the
annoying things about Python.


I have spent the last ten years writing scientific code in Python (i.e. that 
which otherwise might be written in Matlab), and I can guarantee you that you do 
not need to put such extra logic in practically every function. Even when 
naively translating code from Matlab, it's not often necessary.


By the way, are you familiar with numpy? If you are converting code from Matlab, 
you will almost certainly need it. We have a number of functions that make these 
kinds of operations easy when they are in fact necessary. For example, we have 
isscalar() and atleast_1d().


  def dumbfunc(xs):
xs = numpy.atleast_1d(xs)
for x in xs:
  print x

http://numpy.scipy.org/

--
Robert Kern

I have come to believe that the whole world is an enigma, a harmless enigma
 that is made terrible by our own mad attempt to interpret it as though it had
 an underlying truth.
  -- Umberto Eco

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


Re: len() should always return something

2009-07-25 Thread Robert Kern

On 2009-07-25 02:55, Diez B. Roggisch wrote:

Dr. Phillip M. Feldman schrieb:

Here's a simple-minded example:

def dumbfunc(xs):
for x in xs:
print x

This function works fine if xs is a list of floats, but not if it is
single
float. It can be made to work as follows:

def dumbfunc(xs):
if isinstance(xs,(int,float,complex)): xs= [xs]
for x in xs:
print x

Having to put such extra logic into practically every function is one
of the
annoying things about Python.


And where comes len(xs) into play here? What you want is iteration
over scalars.


He explained in another post that iteration is another feature along the same 
lines that he would want for scalars.


--
Robert Kern

I have come to believe that the whole world is an enigma, a harmless enigma
 that is made terrible by our own mad attempt to interpret it as though it had
 an underlying truth.
  -- Umberto Eco

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


Re: len() should always return something

2009-07-25 Thread Marcus Wanner

On 7/25/2009 10:08 AM, Piet van Oostrum wrote:

Steven D'Aprano st...@remove-this-cybersource.com.au (SD) wrote:


SD Ambiguity essentially boils down to being unable to reasonably predict 
SD the expectation of the coder. I say reasonably, because if you allow 
SD unreasonable situations, everything is ambiguous:


That's for me the reason that len(42) is ambiguous. The OP apparently
had 1 as expectation, whereas my first thought was the minimal number of
bits to represent the number and 7.5 million came later :=). The number
of bits I certainly find reasonable, and I would find the number of
decimal digits equally reasonable. More so than 1, actually. 1 as the
length of an int doesn't give any information.
Well, for my two cents, I will say that the number of binary bits or 
decimal digits is certainly the most sensible return value, and that the 
former is the most useful, because the latter can be got with 
len(str(42)). However, the former can also be (/slightly/ less)easily 
got with len(bin(42))-2...


I also think that Explicit is better than implicit. says that there 
should be no return value in this case, as any return value would be 
implicit.


Marcus
--
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-25 Thread Erik Max Francis

Steven D'Aprano wrote:
But it's not practically every function. It's hardly any function at 
all -- in my code, I don't think I've ever wanted this behavior. I would 
consider it an error for function(42) and function([42]) to behave the 
same way. One is a scalar, and the other is a vector -- they're different 
things, it's poor programming practice to treat them identically.


(If Matlab does this, so much the worse for Matlab, in my opinion.)


There's actually good reason to do this in heavily matrix-oriented 
specialized languages; there are numerous applications where scalars and 
1x1 matrices are mathematically equivalent.


--
Erik Max Francis  m...@alcyone.com  http://www.alcyone.com/max/
 San Jose, CA, USA  37 18 N 121 57 W  AIM/Y!M/Skype erikmaxfrancis
  Gods are born and die, but the atom endures.
   -- Alexander Chase
--
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-25 Thread Chris Rebert
On Sat, Jul 25, 2009 at 4:21 PM, Erik Max Francism...@alcyone.com wrote:
 Steven D'Aprano wrote:

 But it's not practically every function. It's hardly any function at all
 -- in my code, I don't think I've ever wanted this behavior. I would
 consider it an error for function(42) and function([42]) to behave the same
 way. One is a scalar, and the other is a vector -- they're different things,
 it's poor programming practice to treat them identically.

 (If Matlab does this, so much the worse for Matlab, in my opinion.)

 There's actually good reason to do this in heavily matrix-oriented
 specialized languages; there are numerous applications where scalars and 1x1
 matrices are mathematically equivalent.

The pertinent issue here being that Python, as a language, is neither
matrix-oriented nor special-purpose. :)

Cheers,
Chris
-- 
http://blog.rebertia.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-25 Thread Erik Max Francis

Chris Rebert wrote:

On Sat, Jul 25, 2009 at 4:21 PM, Erik Max Francism...@alcyone.com wrote:

Steven D'Aprano wrote:

But it's not practically every function. It's hardly any function at all
-- in my code, I don't think I've ever wanted this behavior. I would
consider it an error for function(42) and function([42]) to behave the same
way. One is a scalar, and the other is a vector -- they're different things,
it's poor programming practice to treat them identically.

(If Matlab does this, so much the worse for Matlab, in my opinion.)

There's actually good reason to do this in heavily matrix-oriented
specialized languages; there are numerous applications where scalars and 1x1
matrices are mathematically equivalent.


The pertinent issue here being that Python, as a language, is neither
matrix-oriented nor special-purpose. :)


Yes.  And I was responding to the comment that such a feature of a 
language would a priori be poor design.  It _isn't_ poor design for 
special purpose languages.  Python isn't one of them, but Matlab _is_.


--
Erik Max Francis  m...@alcyone.com  http://www.alcyone.com/max/
 San Jose, CA, USA  37 18 N 121 57 W  AIM/Y!M/Skype erikmaxfrancis
  More fodder for the new lost generation
   -- Nik Kershaw
--
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-25 Thread Chris Rebert
On Sat, Jul 25, 2009 at 6:47 PM, Erik Max Francism...@alcyone.com wrote:
 Chris Rebert wrote:

 On Sat, Jul 25, 2009 at 4:21 PM, Erik Max Francism...@alcyone.com wrote:

 Steven D'Aprano wrote:

 But it's not practically every function. It's hardly any function at
 all
 -- in my code, I don't think I've ever wanted this behavior. I would
 consider it an error for function(42) and function([42]) to behave the
 same
 way. One is a scalar, and the other is a vector -- they're different
 things,
 it's poor programming practice to treat them identically.

 (If Matlab does this, so much the worse for Matlab, in my opinion.)

 There's actually good reason to do this in heavily matrix-oriented
 specialized languages; there are numerous applications where scalars and
 1x1
 matrices are mathematically equivalent.

 The pertinent issue here being that Python, as a language, is neither
 matrix-oriented nor special-purpose. :)

 Yes.  And I was responding to the comment that such a feature of a language
 would a priori be poor design.  It _isn't_ poor design for special purpose
 languages.  Python isn't one of them, but Matlab _is_.

I was agreeing with your point actually. That was what I was trying to
convey in my post. Apparently I wasn't as successful in that regard as
I'd hoped.

- Chris
-- 
http://blog.rebertia.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-24 Thread Grant Edwards
On 2009-07-24, Dr. Phillip M. Feldman pfeld...@verizon.net wrote:

 Some aspects of the Python design are remarkably clever, while
 others leave me perplexed. Here's an example of the latter:
 Why does len() give an error when applied to an int or float?
 len() should always return something; in particular, when
 applied to a scalar, it should return a value of 1.

If len(7) returned a value of 1, then wouldn't one expect 7[0]
to be valid?  It isn't, so you'd then have to redefine all
types so that they are sequences that can be indexed.  Sounds
like a big mess to me...

[Are there types for which len() returns a value that can't be
indexed?]

-- 
Grant Edwards   grante Yow! It's the RINSE CYCLE!!
  at   They've ALL IGNORED the
   visi.comRINSE CYCLE!!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-24 Thread Rhodri James

On Fri, 24 Jul 2009 14:57:02 +0100, Grant Edwards inva...@invalid wrote:


On 2009-07-24, Dr. Phillip M. Feldman pfeld...@verizon.net wrote:


Some aspects of the Python design are remarkably clever, while
others leave me perplexed. Here's an example of the latter:
Why does len() give an error when applied to an int or float?
len() should always return something; in particular, when
applied to a scalar, it should return a value of 1.


If len(7) returned a value of 1, then wouldn't one expect 7[0]
to be valid?  It isn't, so you'd then have to redefine all
types so that they are sequences that can be indexed.  Sounds
like a big mess to me...

[Are there types for which len() returns a value that can't be
indexed?]



Dictionaries.

Which doesn't make your point less valid.  In fact I'd go so
far as to argue that what len() gives you is the number of
items in a container, so len(7) should return 0.

--
Rhodri James *-* Wildebeest Herder to the Masses
--
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-24 Thread Mark Dickinson
On Jul 24, 3:11 pm, Rhodri James rho...@wildebst.demon.co.uk
wrote:
 Which doesn't make your point less valid.  In fact I'd go so
 far as to argue that what len() gives you is the number of
 items in a container, so len(7) should return 0.

Nah.  7 contains three bits, so len(7) should *clearly* return 3.

Mark
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-24 Thread superpollo

Mark Dickinson wrote:

On Jul 24, 3:11 pm, Rhodri James rho...@wildebst.demon.co.uk
wrote:


Which doesn't make your point less valid.  In fact I'd go so
far as to argue that what len() gives you is the number of
items in a container, so len(7) should return 0.



Nah.  7 contains three bits, so len(7) should *clearly* return 3.


and len(7) must return 8, by the same token... but wait!

 len(7)
1


my python installation must me outdated ;-)

bye

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


Re: len() should always return something

2009-07-24 Thread Diez B. Roggisch

Mark Dickinson schrieb:

On Jul 24, 3:11 pm, Rhodri James rho...@wildebst.demon.co.uk
wrote:

Which doesn't make your point less valid.  In fact I'd go so
far as to argue that what len() gives you is the number of
items in a container, so len(7) should return 0.


Nah.  7 contains three bits, so len(7) should *clearly* return 3.


But it contains a minimum of 32 bits! And why are you treating ones as 
special over zeros? I thought the times of BitRacism were finally over...


Diez
--
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-24 Thread Piet van Oostrum
 Rhodri James rho...@wildebst.demon.co.uk (RJ) wrote:

RJ On Fri, 24 Jul 2009 14:57:02 +0100, Grant Edwards inva...@invalid wrote:
 On 2009-07-24, Dr. Phillip M. Feldman pfeld...@verizon.net wrote:
 
 Some aspects of the Python design are remarkably clever, while
 others leave me perplexed. Here's an example of the latter:
 Why does len() give an error when applied to an int or float?
 len() should always return something; in particular, when
 applied to a scalar, it should return a value of 1.
 
 If len(7) returned a value of 1, then wouldn't one expect 7[0]
 to be valid?  It isn't, so you'd then have to redefine all
 types so that they are sequences that can be indexed.  Sounds
 like a big mess to me...
 
 [Are there types for which len() returns a value that can't be
 indexed?]
 

RJ Dictionaries.

RJ Which doesn't make your point less valid.  In fact I'd go so
RJ far as to argue that what len() gives you is the number of
RJ items in a container, so len(7) should return 0.

But len(7) could as well be defined as 3, 1, 32, or 64 (depending on the
implementation). Therefore it doesn't make much sense.
-- 
Piet van Oostrum p...@cs.uu.nl
URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4]
Private email: p...@vanoostrum.org
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Re: len() should always return something

2009-07-24 Thread Phillip M. Feldman

I've read the "Zen of Python", but most of these aphorisms are vague and could be understood differently by different readers. In particular, I don't understand the statement that "explicit is better than implicit". Some examples of this would be helpful.I've been converting Matlab codes to Python. In Matlab, a scalar is just a one-by-one matrix and has a length of 1. This convention seems no less arbitrary to me than Python's convention that the concept of length is not applicable to ints and floats. My workaround was to write the following function:def is_scalar(x): """Return True if x is an instance of int, float, or complex. Otherwise, return False. Note: If x is a length-1 list or array containing an int, float, or complex value, False is returned.""" if isinstance(x,int) or isinstance(x,float) or isinstance(x,complex): return True return FalseThe application is the following: In various types of scientific applications, one operates on a list of measurements. If there is only a single measurement, it is reasonable to allow the calling program to pass a scalar without wrapping it up into a list or array.PhillipJul 24, 2009 07:02:29 AM, c...@rebertia.com wrote:On Thu, Jul 23, 2009 at 11:35 PM, Dr. Phillip M.Feldmanpfeld...@verizon.net wrote: Some aspects of the Python design are remarkably clever, while others leave me perplexed. Here's an example of the latter: Why does len() give an error when applied to an int or float? len() should always return something; in particular, when applied to a scalar, it should return a value of 1. Of course, I can define my own function like this: def mylen(x):  if isinstance(x,int) or isinstance(x,float): return 1  return len(x) But, this shouldn't be necessary.The problem is that redefining len()/length/size that way wouldviolate several principles of Python's design (The "Zen" of Python -http://www.python.org/dev/peps/pep-0020/).Specifically:- Explicit is better than implicit.- Special cases aren't special enough to break the rules.- Errors should never pass silently.- In the face of ambiguity, refuse the temptation to guess.If you'd explain the situation that prompts you to find thisredefinition necessary, I'm sure someone can suggest a betterapproach.Cheers,Chris-- http://blog.rebertia.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-24 Thread Rhodri James

On Fri, 24 Jul 2009 16:10:07 +0100, Piet van Oostrum p...@cs.uu.nl wrote:


Rhodri James rho...@wildebst.demon.co.uk (RJ) wrote:


RJ On Fri, 24 Jul 2009 14:57:02 +0100, Grant Edwards inva...@invalid  
wrote:

On 2009-07-24, Dr. Phillip M. Feldman pfeld...@verizon.net wrote:


Some aspects of the Python design are remarkably clever, while
others leave me perplexed. Here's an example of the latter:
Why does len() give an error when applied to an int or float?
len() should always return something; in particular, when
applied to a scalar, it should return a value of 1.


If len(7) returned a value of 1, then wouldn't one expect 7[0]
to be valid?  It isn't, so you'd then have to redefine all
types so that they are sequences that can be indexed.  Sounds
like a big mess to me...

[Are there types for which len() returns a value that can't be
indexed?]




RJ Dictionaries.



RJ Which doesn't make your point less valid.  In fact I'd go so
RJ far as to argue that what len() gives you is the number of
RJ items in a container, so len(7) should return 0.


But len(7) could as well be defined as 3, 1, 32, or 64 (depending on the
implementation). Therefore it doesn't make much sense.


Quite.

--
Rhodri James *-* Wildebeest Herder to the Masses
--
http://mail.python.org/mailman/listinfo/python-list


Re: Re: len() should always return something

2009-07-24 Thread Chris Rebert
 Jul 24, 2009 07:02:29 AM, c...@rebertia.com wrote:

 On Thu, Jul 23, 2009 at 11:35 PM, Dr. Phillip M.
 Feldmanpfeld...@verizon.net wrote:

 Some aspects of the Python design are remarkably clever, while others
 leave
 me perplexed. Here's an example of the latter: Why does len() give an
 error
 when applied to an int or float? len() should always return something; in
 particular, when applied to a scalar, it should return a value of 1. Of
 course, I can define my own function like this:

 def mylen(x):
   if isinstance(x,int) or isinstance(x,float): return 1
   return len(x)

 But, this shouldn't be necessary.

 The problem is that redefining len()/length/size that way would
 violate several principles of Python's design (The Zen of Python -
 http://www.python.org/dev/peps/pep-0020/).

 Specifically:
 - Explicit is better than implicit.
 - Special cases aren't special enough to break the rules.
 - Errors should never pass silently.
 - In the face of ambiguity, refuse the temptation to guess.

 If you'd explain the situation that prompts you to find this
 redefinition necessary, I'm sure someone can suggest a better
 approach.

On Fri, Jul 24, 2009 at 8:58 AM, Phillip M. Feldmanpfeld...@verizon.net wrote:
 I've read the Zen of Python, but most of these aphorisms are vague and
 could be understood differently by different readers.  In particular, I
 don't understand the statement that explicit is better than implicit.
 Some examples of this would be helpful.

 I've been converting Matlab codes to Python.  In Matlab, a scalar is just a
 one-by-one matrix and has a length of 1.  This convention seems no less
 arbitrary to me than Python's convention that the concept of length is not
 applicable to ints and floats.  My workaround was to write the following
 function:

 def is_scalar(x):
Return True if x is an instance of int, float, or complex.
Otherwise, return False.  Note: If x is a length-1 list or array
containing an int, float, or complex value, False is returned.
if isinstance(x,int) or isinstance(x,float) or isinstance(x,complex):
   return True
return False

 The application is the following: In various types of scientific
 applications, one operates on a list of measurements.  If there is only a
 single measurement, it is reasonable to allow the calling program to pass a
 scalar without wrapping it up into a list or array.

You could use Python's extended call syntax when defining your function:

def average(*args):
return sum(args) / len(args)

average(7) #== 7
average(2,3,4,5,6) #== 4
average(*[2,3,4,5,6]) #== 4
average([2,3,4,5,6]) #== error

Cheers,
Chris
-- 
http://blog.rebertia.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-24 Thread Terry Reedy

Phillip M. Feldman wrote:

I've been converting Matlab codes to Python.  In Matlab, a scalar is 
just a one-by-one matrix and has a length of 1.  This convention seems 
no less arbitrary to me than Python's convention that the concept of 
length is not applicable to ints and floats.


Multiplication of a vector/matrix by a scalar always defined and 
commutative. Multiplication of a vector/matrix by a 1x1 matrix is not 
always even defined. So not having scalars in a matrix package strikes 
me as a bit odd.


 My workaround was to write

the following function:

def is_scalar(x):
   Return True if x is an instance of int, float, or complex.
   Otherwise, return False.  Note: If x is a length-1 list or array
   containing an int, float, or complex value, False is returned.
   if isinstance(x,int) or isinstance(x,float) or isinstance(x,complex):


Better:if isinstance(x, (int, float, complex)):

but you forgot decimals and fractions and any other possible number modules.

In 3.1,
 from numbers import Number
 from decimal import Decimal
 from fractions import Fraction
 for x in 1, 1.0, (1+0j), Decimal(1), Fraction(1,1):
isinstance(x, Number)


True
True
True
True
True

and the same for any other module that registers a class as a Number


  return True
   return False

The application is the following: In various types of scientific 
applications, one operates on a list of measurements.  If there is only 
a single measurement, it is reasonable to allow the calling program to 
pass a scalar without wrapping it up into a list or array.


If you want to do that, start with

def f(x):
  try: len(x)
  except TypeError: x = x,

or in 3.1 use Number test above.

Terry Jan Reedy

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


Re: len() should always return something

2009-07-24 Thread Steven D'Aprano
On Fri, 24 Jul 2009 16:50:03 +0200, superpollo wrote:

 Nah.  7 contains three bits, so len(7) should *clearly* return 3.
 
 and len(7) must return 8, by the same token... but wait!
 
   len(7)
 1
  
  
 my python installation must me outdated ;-)

No no no, you're obviously using an awesome version of Python that can 
compress single-character strings to a single bit!



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


list vs. tuple [Re: len() should always return something]

2009-07-24 Thread Roy Smith
In article mailman.3674.1248461573.8015.python-l...@python.org,
 Terry Reedy tjre...@udel.edu wrote:

 Better:if isinstance(x, (int, float, complex)):

I never noticed this before, but it seems odd that the second argument to 
isinstance() should be a tuple.  Using the normal arguments made about 
tuples vs. lists, it seems like a list would be the right data structure 
here.  I suppose a set would be even more right, but (I'm pretty sure) 
isinstance() predates sets.

I'm curious why a tuple was chosen.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-24 Thread Roy Smith
In article 0279f596$0$5185$c3e8...@news.astraweb.com,
 Steven D'Aprano st...@remove-this-cybersource.com.au wrote:

 On Fri, 24 Jul 2009 16:50:03 +0200, superpollo wrote:
 
  Nah.  7 contains three bits, so len(7) should *clearly* return 3.
  
  and len(7) must return 8, by the same token... but wait!
  
len(7)
  1
   
   
  my python installation must me outdated ;-)
 
 No no no, you're obviously using an awesome version of Python that can 
 compress single-character strings to a single bit!

Compressing strings to a single bit is easy.  It's the uncompressing that's 
tricky.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-24 Thread Steven D'Aprano
On Fri, 24 Jul 2009 00:02:28 -0700, Chris Rebert wrote:

 On Thu, Jul 23, 2009 at 11:35 PM, Dr. Phillip M.
 Feldmanpfeld...@verizon.net wrote:

 Some aspects of the Python design are remarkably clever, while others
 leave me perplexed. Here's an example of the latter: Why does len()
 give an error when applied to an int or float? len() should always
 return something; in particular, when applied to a scalar, it should
 return a value of 1. Of course, I can define my own function like this:

 def mylen(x):
   if isinstance(x,int) or isinstance(x,float): return 1 return len(x)

 But, this shouldn't be necessary.
 
 The problem is that redefining len()/length/size that way would violate
 several principles of Python's design (The Zen of Python -
 http://www.python.org/dev/peps/pep-0020/).
 
 Specifically:
 - Explicit is better than implicit.
 - Special cases aren't special enough to break the rules. 
 - Errors should never pass silently.
 - In the face of ambiguity, refuse the temptation to guess.


Chris, I'm curious why you think that these Zen are relevant to the OP's 
complaint.

Re explicit vs implicit, len(42) is just as explicit as len([42, 23]).

Arguably (I wouldn't argue this, but some people might) ints aren't 
special enough to break the rule that len(obj) should always return 
something.

(I don't actually agree, but some people might be able to produce a 
coherent argument why len() should apply equally to all objects.)

Re errors passing silently, the OP doesn't believe that len(42) should be 
an error, so that's not relevant.

And there's nothing ambiguous about len(42).

I agree with the current Python behaviour, but I don't think there's 
anything in the Zen to support it. As far as I know, there is no 
programming language which treats scalars like ints as if they were 
vectors of length 1, which makes Python's choice to make ints unlengthed 
a no-brainer.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: list vs. tuple [Re: len() should always return something]

2009-07-24 Thread Steven D'Aprano
On Fri, 24 Jul 2009 15:03:29 -0400, Roy Smith wrote:

 In article mailman.3674.1248461573.8015.python-l...@python.org,
  Terry Reedy tjre...@udel.edu wrote:
 
 Better:if isinstance(x, (int, float, complex)):
 
 I never noticed this before, but it seems odd that the second argument
 to isinstance() should be a tuple.  Using the normal arguments made
 about tuples vs. lists, it seems like a list would be the right data
 structure here.

What would be the point of using a list? You're never going to sort it, 
or append items to it, or otherwise mutate it. You build it, pass it to a 
function which doesn't modify it in any fashion, then it gets garbage 
collected.


 I suppose a set would be even more right, but (I'm
 pretty sure) isinstance() predates sets.

Yes.

[st...@sylar ~]$ python1.5
Python 1.5.2 (#1, Apr  1 2009, 22:55:54)  [GCC 4.1.2 20070925 (Red Hat 
4.1.2-27)] on linux2
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
 isinstance
built-in function isinstance
 set
Traceback (innermost last):
  File stdin, line 1, in ?
NameError: set



 I'm curious why a tuple was chosen.

Tuples are smaller and faster to build than lists -- they're the most 
lightweight sequence type in Python. You don't need all the extra 
functionality of lists, so why go to the time and effort of building a 
list?




-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-24 Thread Chris Rebert
On Fri, Jul 24, 2009 at 12:05 PM, Steven
D'Apranost...@remove-this-cybersource.com.au wrote:
 On Fri, 24 Jul 2009 00:02:28 -0700, Chris Rebert wrote:

 On Thu, Jul 23, 2009 at 11:35 PM, Dr. Phillip M.
 Feldmanpfeld...@verizon.net wrote:

 Some aspects of the Python design are remarkably clever, while others
 leave me perplexed. Here's an example of the latter: Why does len()
 give an error when applied to an int or float? len() should always
 return something; in particular, when applied to a scalar, it should
 return a value of 1. Of course, I can define my own function like this:

 def mylen(x):
   if isinstance(x,int) or isinstance(x,float): return 1 return len(x)

 But, this shouldn't be necessary.

 The problem is that redefining len()/length/size that way would violate
 several principles of Python's design (The Zen of Python -
 http://www.python.org/dev/peps/pep-0020/).

 Specifically:
 - Explicit is better than implicit.
 - Special cases aren't special enough to break the rules.
 - Errors should never pass silently.
 - In the face of ambiguity, refuse the temptation to guess.


 Chris, I'm curious why you think that these Zen are relevant to the OP's
 complaint.

To explain in more detail:

 Re explicit vs implicit, len(42) is just as explicit as len([42, 23]).

If you want a collection (something that has length), then one should
explicitly create one, not implicitly have a singleton value act like
it's a pseudo-collection.
I admit I'm somewhat conflating this principle with the anti-ambiguity
principle, but the two are related, imho.

 Arguably (I wouldn't argue this, but some people might) ints aren't
 special enough to break the rule that len(obj) should always return
 something.

Except that's not the current rule. The current rule is that it's
defined only for collections.
One would instead have to argue why ints are special enough to have
len() defined despite not being collections.
I think the point made by Grant Edwards is instructive. len(x) = 1
typically implies list(x)[0] and similar should be valid. Altering the
behavior would invalidate that theorem and cause quite a bit of code
upheaval, all just to save the OP from typing one pair of []s.

 (I don't actually agree, but some people might be able to produce a
 coherent argument why len() should apply equally to all objects.)

Well, yes, this /whole/ argument is entirely academic; the behavior
is extremely unlikely to change, we're just trying to give ex post
facto rationales for pedagogical purposes. :)

 Re errors passing silently, the OP doesn't believe that len(42) should be
 an error, so that's not relevant.

True, it would not directly silence an error, but defining len() on
scalars would tend towards obscuring errors in code that incorrectly
treats scalars as collections.

 And there's nothing ambiguous about len(42).

Really? What is its value then? I think arguments of varying quality
can be made for:
1 - as the OP and those from array programming languages would suggest
2 - the number of decimal digits in 42, if one was feeling Perlish
6 - the minimum number of bits necessary to represent 42 in binary
32 (or 64, depending on your CPU) - the number of bits necessary to
represent an int (obviously breaks down a bit with arbitrary-magnitude
ints)
undefined - i.e. it causes an error, the current behavior; asking for
the length of a non-collection is nonsensical or absurd

 I agree with the current Python behaviour, but I don't think there's
 anything in the Zen to support it. As far as I know, there is no

The problem and strength of the Zen is that it's all about how you
interpret it. :-)

Cheers,
Chris
-- 
http://blog.rebertia.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-24 Thread Marcus Wanner

On 7/24/2009 3:04 PM, Roy Smith wrote:

In article 0279f596$0$5185$c3e8...@news.astraweb.com,
 Steven D'Aprano st...@remove-this-cybersource.com.au wrote:


On Fri, 24 Jul 2009 16:50:03 +0200, superpollo wrote:


Nah.  7 contains three bits, so len(7) should *clearly* return 3.

and len(7) must return 8, by the same token... but wait!

  len(7)
1
 
 
my python installation must me outdated ;-)
No no no, you're obviously using an awesome version of Python that can 
compress single-character strings to a single bit!


Compressing strings to a single bit is easy.  It's the uncompressing that's 
tricky.

I assume you mean ord(7)%2?

First one to correctly decompress the value 0 into an ASCII character 
wins the title of the world's most capable hacker :p


Marcus
--
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-24 Thread Mark Lawrence

Marcus Wanner wrote:

On 7/24/2009 3:04 PM, Roy Smith wrote:

In article 0279f596$0$5185$c3e8...@news.astraweb.com,
 Steven D'Aprano st...@remove-this-cybersource.com.au wrote:


On Fri, 24 Jul 2009 16:50:03 +0200, superpollo wrote:


Nah.  7 contains three bits, so len(7) should *clearly* return 3.

and len(7) must return 8, by the same token... but wait!

  len(7)
1
 
 
my python installation must me outdated ;-)
No no no, you're obviously using an awesome version of Python that 
can compress single-character strings to a single bit!


Compressing strings to a single bit is easy.  It's the uncompressing 
that's tricky.

I assume you mean ord(7)%2?

First one to correctly decompress the value 0 into an ASCII character 
wins the title of the world's most capable hacker :p


Marcus

asciichar = chr(len(0)) if the OP's wishes come true?

--
Kindest regards.

Mark Lawrence.

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


Re: len() should always return something

2009-07-24 Thread Marcus Wanner

On 7/24/2009 4:18 PM, Mark Lawrence wrote:

Marcus Wanner wrote:

On 7/24/2009 3:04 PM, Roy Smith wrote:

In article 0279f596$0$5185$c3e8...@news.astraweb.com,
 Steven D'Aprano st...@remove-this-cybersource.com.au wrote:


On Fri, 24 Jul 2009 16:50:03 +0200, superpollo wrote:


Nah.  7 contains three bits, so len(7) should *clearly* return 3.

and len(7) must return 8, by the same token... but wait!

  len(7)
1
 
 
my python installation must me outdated ;-)
No no no, you're obviously using an awesome version of Python that 
can compress single-character strings to a single bit!


Compressing strings to a single bit is easy.  It's the uncompressing 
that's tricky.

I assume you mean ord(7)%2?

First one to correctly decompress the value 0 into an ASCII character 
wins the title of the world's most capable hacker :p


Marcus

asciichar = chr(len(0)) if the OP's wishes come true?


Nope, wasn't ?...

Marcus
--
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-24 Thread Tim Chase

Marcus Wanner wrote:

First one to correctly decompress the value 0 into an ASCII
character wins the title of the world's most capable hacker :p


Bah...uncompressing the value 0 into *an* ASCII character is 
easy.  Uncompressing it into the *original* ASCII character from 
which it was compressed (with the aforementioned compression 
method) becomes a bit trickier ;-)


-tkc



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


Re: len() should always return something

2009-07-24 Thread Chris Rebert
On Fri, Jul 24, 2009 at 1:30 PM, Tim Chasepython.l...@tim.thechases.com wrote:
 Marcus Wanner wrote:

 First one to correctly decompress the value 0 into an ASCII
 character wins the title of the world's most capable hacker :p

 Bah...uncompressing the value 0 into *an* ASCII character is easy.
  Uncompressing it into the *original* ASCII character from which it was
 compressed (with the aforementioned compression method) becomes a bit
 trickier ;-)

Deja vu: http://www.hackles.org/cgi-bin/archives.pl?request=310

- Chris
-- 
http://blog.rebertia.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: list vs. tuple [Re: len() should always return something]

2009-07-24 Thread Terry Reedy

Steven D'Aprano wrote:

On Fri, 24 Jul 2009 15:03:29 -0400, Roy Smith wrote:


In article mailman.3674.1248461573.8015.python-l...@python.org,
 Terry Reedy tjre...@udel.edu wrote:


Better:if isinstance(x, (int, float, complex)):

I never noticed this before, but it seems odd that the second argument
to isinstance() should be a tuple.  Using the normal arguments made
about tuples vs. lists, it seems like a list would be the right data
structure here.


I ignore the 'normal arguments' and it seems that Guido or the designer 
of isinstance did so here too.  Fortunately.  Practicality beats 
'purity', especially misguided purity.


What would be the point of using a list? You're never going to sort it, 
or append items to it, or otherwise mutate it. You build it, pass it to a 
function which doesn't modify it in any fashion, then it gets garbage 
collected.




I suppose a set would be even more right, but (I'm
pretty sure) isinstance() predates sets.


Yes.

[st...@sylar ~]$ python1.5
Python 1.5.2 (#1, Apr  1 2009, 22:55:54)  [GCC 4.1.2 20070925 (Red Hat 
4.1.2-27)] on linux2

Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam

isinstance

built-in function isinstance

set

Traceback (innermost last):
  File stdin, line 1, in ?
NameError: set




I'm curious why a tuple was chosen.


Tuples are smaller and faster to build than lists -- they're the most 
lightweight sequence type in Python. You don't need all the extra 
functionality of lists, so why go to the time and effort of building a 
list?


In fact, constant tuples can be and now are compiled as constants:

 dis(compile('(1,2,3)','','eval'))
  1   0 LOAD_CONST   3 ((1, 2, 3))
  3 RETURN_VALUE
 dis(compile('[1,2,3]','','eval'))
  1   0 LOAD_CONST   0 (1)
  3 LOAD_CONST   1 (2)
  6 LOAD_CONST   2 (3)
  9 BUILD_LIST   3
 12 RETURN_VALUE

Internally, even a frozenset is more complicated than a tuple since it 
still needs a hash table, which is overkill for something that will be 
linearly scanned exactly once.


tjr

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


Re: len() should always return something

2009-07-24 Thread Terry Reedy

Chris Rebert wrote:


I think the point made by Grant Edwards is instructive. len(x) = 1
typically implies list(x)[0] and similar should be valid. 


At least, one should be able to iterate with x and get len(x) items.
See below.


And there's nothing ambiguous about len(42).


Really? What is its value then? I think arguments of varying quality
can be made for:
1 - as the OP and those from array programming languages would suggest
2 - the number of decimal digits in 42, if one was feeling Perlish
6 - the minimum number of bits necessary to represent 42 in binary
32 (or 64, depending on your CPU) - the number of bits necessary to
represent an int (obviously breaks down a bit with arbitrary-magnitude
ints)
undefined - i.e. it causes an error, the current behavior; asking for
the length of a non-collection is nonsensical or absurd


In set theory, one can define counts recursively as follows
0 = {} (set, not dict)
n+1 = n | {n}
so len(n) = n, and in particular, len(42) = 42.

On the same basis, it has been proposed (and rejected) that iter(n) == 
range(n), do that we could write 'for i in 10' for instance. Guido 
thought this too esoteric.


Terry Jan Reedy

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


Re: list vs. tuple [Re: len() should always return something]

2009-07-24 Thread Duncan Booth
Roy Smith r...@panix.com wrote:

 In article mailman.3674.1248461573.8015.python-l...@python.org,
  Terry Reedy tjre...@udel.edu wrote:
 
 Better:if isinstance(x, (int, float, complex)):
 
 I never noticed this before, but it seems odd that the second argument
 to isinstance() should be a tuple.  Using the normal arguments made
 about tuples vs. lists, it seems like a list would be the right data
 structure here.  I suppose a set would be even more right, but (I'm
 pretty sure) isinstance() predates sets.
 
 I'm curious why a tuple was chosen.

There's a very good reason[*]. The second argument to isinstance() is a 
classinfo where a classinfo is a type or a tuple of classinfo.

That means you can have an arbitrarily complex set of nested tuples e.g. 
(int, (float, complex)), but the immutable nature of tuples means the 
implementation of isinstance can walk the tuple tree without ever having to 
worry about infinite loops.

If classinfo could be a list of types then someone somewhere would feed it 
a recursive list and then complain that the interpreter crashed.

Exception specifications are tuples for the same reason.

[*] For some definition of 'very good'. Would Python be significantly 
impaired if you couldn't combine classinfos into a tree structure? Probably 
not.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-24 Thread bartc
Dr. Phillip M. Feldman pfeld...@verizon.net wrote in message 
news:mailman.3644.1248417347.8015.python-l...@python.org...


Some aspects of the Python design are remarkably clever, while others 
leave
me perplexed. Here's an example of the latter: Why does len() give an 
error

when applied to an int or float? len() should always return something; in
particular, when applied to a scalar, it should return a value of 1.


So you want len() to treat 123 as though it could potentially be a list 
containing a single element?


In that case there could be an ambiguity here:

print len([10,20,30])

Should it print 3 (the elements in [10,20,30]), or 1 (treating [10,20,30] as 
a potential list containing the single element [10,20,30])?


--
bartc 


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


Re: list vs. tuple [Re: len() should always return something]

2009-07-24 Thread Dr. Phillip M. Feldman

isinstance(x, (int, float, complex))

is certainly very compact, and does what I want.  Thanks!
-- 
View this message in context: 
http://www.nabble.com/len%28%29-should-always-return-something-tp24639361p24654347.html
Sent from the Python - python-list mailing list archive at Nabble.com.

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


Re: len() should always return something

2009-07-24 Thread Dr. Phillip M. Feldman

As far as I know, there is no programming language which treats scalars like
ints as if they were 
vectors of length 1

Actually, Matlab does:

 length(5)
ans =
 1
 
-- 
View this message in context: 
http://www.nabble.com/len%28%29-should-always-return-something-tp24639361p24654358.html
Sent from the Python - python-list mailing list archive at Nabble.com.

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


Re: len() should always return something

2009-07-24 Thread Dr. Phillip M. Feldman

Here's a simple-minded example:

def dumbfunc(xs):
   for x in xs:
  print x

This function works fine if xs is a list of floats, but not if it is single
float.  It can be made to work as follows:

def dumbfunc(xs):
   if isinstance(xs,(int,float,complex)): xs= [xs]
   for x in xs:
  print x

Having to put such extra logic into practically every function is one of the
annoying things about Python.

Phillip


Diez B. Roggisch-2 wrote:
 
 Dr. Phillip M. Feldman schrieb:
 Some aspects of the Python design are remarkably clever, while others
 leave
 me perplexed. Here's an example of the latter: Why does len() give an
 error
 when applied to an int or float? len() should always return something; in
 particular, when applied to a scalar, it should return a value of 1. Of
 course, I can define my own function like this:
 
 def mylen(x):
if isinstance(x,int) or isinstance(x,float): return 1
return len(x)
 
 But, this shouldn't be necessary.
 
 Can you show some example of where that is actually making a piece of 
 code more elegant?
 
 Diez
 -- 
 http://mail.python.org/mailman/listinfo/python-list
 
 

-- 
View this message in context: 
http://www.nabble.com/len%28%29-should-always-return-something-tp24639361p24654439.html
Sent from the Python - python-list mailing list archive at Nabble.com.

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


Re: len() should always return something

2009-07-24 Thread Chris Rebert
On Fri, Jul 24, 2009 at 7:50 PM, Dr. Phillip M.
Feldmanpfeld...@verizon.net wrote:

 Here's a simple-minded example:

 def dumbfunc(xs):
   for x in xs:
      print x

 This function works fine if xs is a list of floats, but not if it is single
 float.  It can be made to work as follows:

 def dumbfunc(xs):
   if isinstance(xs,(int,float,complex)): xs= [xs]
   for x in xs:
      print x

 Having to put such extra logic into practically every function is one of the
 annoying things about Python.

You can easily fix that using decorators:

(disclaimer: untested, except mentally)

#bit of setup; pays off later
def list_or_single(func):
def wrapper(arg):
try: iter(arg)
except TypeError: arg = [arg]
return func(arg)
return wrapper

#now just prefix functions with @list_or_single

@list_or_single
def dumbfunc(xs):
for x in xs:
print x

Using the extended call syntax as I explained earlier is another option.

Cheers,
Chris
-- 
http://blog.rebertia.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: len() should always return something

2009-07-24 Thread Carl Banks
On Jul 24, 6:57 am, Grant Edwards inva...@invalid wrote:
 On 2009-07-24, Dr. Phillip M. Feldman pfeld...@verizon.net wrote:



  Some aspects of the Python design are remarkably clever, while
  others leave me perplexed. Here's an example of the latter:
  Why does len() give an error when applied to an int or float?
  len() should always return something; in particular, when
  applied to a scalar, it should return a value of 1.

 If len(7) returned a value of 1, then wouldn't one expect 7[0]
 to be valid?  It isn't, so you'd then have to redefine all
 types so that they are sequences that can be indexed.  Sounds
 like a big mess to me...

You can call the big mess Matlab.


Carl Banks
-- 
http://mail.python.org/mailman/listinfo/python-list