Why Python 3?

C

Chris Angelico

I would use Python 3 in a flash if only wxPython would support it.

There seems to be a "Project Phoenix" (found it at the other end of a
Google search) with that goal. I've no idea what its status is, but
you could help that project along by expressing interest and maybe
helping with their bug tracker, or hosting a buildbot (they seem to
use the same buildbot software that Python uses), or something like
that. If you're really serious about wanting Python 3 support, go the
whole way and actually help to port it!

ChrisA
 
T

Terry Reedy

The name 'floor division' and the float result are intentional, not
accidents.
In general that's true, but I'm talking about a context
in which you have some expectations as to the types of the
operands.

Most of the time, there are two possible scenarios:

1) The algorithm operates on integers, and the contract is
that you only get passed ints. In that case, you use //
and know that the result will be an int.

2) The algorithm operates on non-integers, and the contract
is that you get passed either ints or floats, with ints being
understood as standing in for floats. In that case, you
use / and know that it will perform float division and
return a float.

If someone passes you a float in case (1) it's true that
// won't return an int, but then they've violated the
contract.

Not necessarily if the float has an integer value. The intention of the
change was to make the value of number operations less dependent on the
type of the operands. Where the result type does matter is if the result
is used, for example, in indexing
 
I

Ian Kelly

numbers, it works for numpy types, and in Python 3 it works for ints.
That depends on what you mean by "works". I would actually
find it rather disturbing if an average() function implicitly
used floor division when given all ints.

The code above never uses floor division in Python 3. Therefore it "works".
 
S

Steven D'Aprano

Hmmm. Taking the average of a set of complex numbers has a reasonable
physical meaning. But, once you start down that path, I'm not sure how
far you can go before things no long make sense. What's the standard
deviation of a set of complex numbers? Does that even have any meaning?

Yes it does. Stdev is a measure of scale of the distribution, and is
always real and non-negative. For complex values, you can calculate it
using:

(abs(x - mean))**2

which is how numpy does it, or from the complex conjugate:

x1 = x-mean
x1.conj()*x1


which is how Matlab does it.

http://docs.scipy.org/doc/numpy/reference/generated/numpy.std.html
http://www.mathworks.com.au/matlabcentral/newsreader/view_thread/57323


Hence the variance is always non-negative, and the standard deviation is
always real. See also:

https://en.wikipedia.org/wiki/Variance#Generalizations
 
S

Steven D'Aprano

And that's what I mean about the common non-trivial case. It's easy
enough to come up with contrived or trivial cases that use any types,
but in most cases, it'd be fine to explicitly call float() on one of the
operands to explicitly request floating-point division. Choosing between
two division operators is not the same thing as choosing a data type.

Nobody says that they are. Choosing between / and // means to choose
between two different operator. / performs true division, the sort that
you learn about in school (modulo the usual floating point issues --
floats are not mathematical reals). // performs division which floors
towards negative infinity. (For positive values, that's equivalent to
truncation.)

Hence the two special methods: __truediv__ and __floordiv__ (plus the
reversed __r*__ versions).

I think you need to stop thinking about "integer division", because (1)
"integer division" is not well-defined, and (2) in the general case, //
doesn't return an int, although it should return a value that is integer
valued.

Why is integer division not well-defined? Because division of integers
doesn't necessarily return an integer: the integers are not closed with
the division operator. Cases like 10/5 are easy, that's just 2. What
about 11/5 or -7/3? I can think of at least six things that "integer
division" might do in those cases:

- round to nearest, ties round to even ("banker's rounding");
- round to nearest, ties round to odd;
- round towards positive infinity (ceiling);
- round towards negative infinity (floor);
- round towards zero (truncate);
- raise an exception;

so before talking about "integer division" we have to decide which of
those apply. Python doesn't talk about integer division, well not
officially, but talks about *floor division*. The nice thing about this
is that there's no requirement that it return an actual int:

py> 11.0//2
5.0

just an integer-valued value. It's up to the class to decide how it works.

Explicitly choosing float division:

x / float(y)

But here you're not choosing an *operator*, you're choosing a *type*.
With this model, how do I distinguish between floor division and true
division using, say, Fractions?

py> from fractions import Fraction as F
py> F(1799, 27)/F(3) # True division.
Fraction(1799, 81)
py> F(1799, 27)//F(3) # Floor division.
22

Converting to floats is not an option, since (1) it returns a float, not
a Fraction, and (2) it introduces rounding errors:

py> F(1799, 27)/F(3) == F(1799, 27)/3.0
False

[...]
Both explicit forms can be done cleanly without empowering the language
with the magic of int/int->float.

It's hardly magic, and I really am having difficult in working out
exactly what your objection to it is. Is it really as simple as
"operations on ints should only return ints, like in C"?
 
C

Chris Angelico

But here you're not choosing an *operator*, you're choosing a *type*.
With this model, how do I distinguish between floor division and true
division using, say, Fractions?

Earlier it was said that having both / and // lets you explicitly
choose whether you want a float result or an int by picking an
operator. I'm saying that's not so; the operator and the type aren't
quite orthogonal, but close to.

ChrisA
 
C

Chris Angelico

It's hardly magic, and I really am having difficult in working out
exactly what your objection to it is. Is it really as simple as
"operations on ints should only return ints, like in C"?

All other basic arithmetic operations on two numbers of the same type
results in another number of that type. You wouldn't expect the
product of two Fractions to be a Decimal, nor the sum of two complex
numbers be a float (even if it results in an imaginary part of zero,
it'll still be a complex: (1+2j) + (2-2j) --> (3+0j) not 3.0). There's
just one special case: dividing an integer by an integer yields a
float, if and only if you use truediv. It sticks out as an exception.

ChrisA
 
W

wxjmfauth

wxPhoenix.
The funny side of wxPhoenix is, that it *also* has its
own understanding of unicode and it finally only
succeeds to produce mojibakes.

I've tried to explained...

(I was an early wxPython user from wxPython 2.0 (!).
I used, tested, reported about, all wxPython versions up to
the shift to the wxPython 2.9 "unicode only" versions, then
I gave up).

--------------

Something else.

I'm ready to bet, the unicode related bugs I found in Python 3
(core Python) are still here in five years from now.

--------------

Something else, part 2.

IDLE. Ten seconds to make it crashing, just by using unicode.

--------------

Working with Python 2.7 + third party libs (even in iso-8859-1) *in*
a pure "cp1252 mode", including source code is a very, very solid
experience.

--------------

The "Microsoft", "Adobe", foundries... , and in the "open software",
the golang, ruby2, TeX unicode engines, all are working very correctly
and smoothly with unicode.


jmf

PS Yes, I'm aware such comments are not really "fair play".
 
G

Gregory Ewing

Chris said:
Earlier it was said that having both / and // lets you explicitly
choose whether you want a float result or an int by picking an
operator. I'm saying that's not so; the operator and the type aren't
quite orthogonal, but close to.

I don't think I said that, or if I did I was using sloppy
language.

As someone pointed out a couple of posts ago, it's not
really about types, it's about selecting which *operation*
you want to perform. Ordinary division and floor division
are very different operations, and you want to be sure
you get the right one.
 
G

Gregory Ewing

Chris said:
All other basic arithmetic operations on two numbers of the same type
results in another number of that type. ... There's
just one special case: dividing an integer by an integer yields a
float, if and only if you use truediv. It sticks out as an exception.

I take your point, but I think this is a case where
practicality beats purity by a large margin. The idea
that arithmetic should always give a result of the same
type is all very nice in theory, but it just isn't
practical where division is concerned.

The reason it doesn't work well is because of the
automatic promotion of ints to floats when they meet
other floats. This leads to a style where people often
use ints to stand for int-valued floats and expect
them to be promoted where necessary.

Things would be different if ints and floats were
completely separate types, like str and bytes, but
that would be extremely inconvenient. I used a language
like that once, and it wasn't a pleasant experience.
 
R

Rustom Mody

Spoken like a true ASCII user :)
Heh!


The "killer feature" of Python 3 is improved handling of Unicode, which
now brings Python 3 firmly into the (very small) group of programming
languages with first-class support for more than 128 different characters
by default.

As a unicode user (ok wannabe unicode user :D ) Ive
written up some unicode ideas that have been discussed here in the
last couple of weeks:

http://blog.languager.org/2014/04/unicoded-python.html

If Ive non or misattributed some ideas please excuse and let me know!
 
T

Terry Reedy

As a unicode user (ok wannabe unicode user :D ) Ive
written up some unicode ideas that have been discussed here in the
last couple of weeks:

http://blog.languager.org/2014/04/unicoded-python.html

"With python 3 we are at a stage where python programs can support
unicode well however python program- source is still completely ASCII."

In Python 3, "Python reads program text as Unicode code points; the
encoding of a source file can be given by an encoding declaration and
defaults to UTF-8". Why start off with an erroneous statement, which you
even know and show is erroneous?
 
G

Gregory Ewing

Chris said:
As it
is, we have the case that most lowish integers have equivalent floats
(all integers within the range that most people use them), and beyond
that, you have problems.

No, I don't. I'm not talking about representing ints using
floats, I'm talking about representing floats using ints.
*Every* possible integer-valued float value can be written
exactly as a Python int.

It doesn't matter that there are some ints that can't be
represented as floats, because when I'm writing an int literal
as a shorthand for a float, I'm not going to be using any of
those values -- or if I do, I'm willing to accept the
resulting loss of precision, because in my mind they're
*not* ints, they're floats.
But
would you rather have to deal with the problem straight away, or when
your program is some day given a much bigger number to swallow, and it
quietly rounds it off to the nearest multiple of 8?

I don't understand what problem you're imagining here.
Any program that needs to do exact calculations with integer
values should work with ints throughout and use // or
divmod() if it needs to do any division. Nothing will get
unexpectedly rounded off then.
 
S

Steven D'Aprano

As a unicode user (ok wannabe unicode user :D ) Ive written up some
unicode ideas that have been discussed here in the last couple of weeks:

http://blog.languager.org/2014/04/unicoded-python.html

What you are talking about is not handling Unicode with Python, but
extending the programming language to allow non-English *letters* to be
used as if they were *symbols*.

That's very problematic, since it assumes that nobody would ever want to
use non-English letters in an alphanumeric context. You write:

Now to move ahead!
We dont[sic] want
1

We want
3
[end quote]



(Speak for yourself.) But this is a problem. Suppose I want to use a
Greek word as a variable, as Python allows me to do:


λόγος = "a word"


Or perhaps as the parameter to a function. Take the random.expovariate
function, which currently takes an argument "lambd" (since lambda is a
reserved word). I might write instead:

def expovariate(self, λ): ...


After all, λ is an ordinary letter of the (Greek) alphabet, why shouldn't
it be used in variable names? But if "λx" is syntax for "lambda x", then
I'm going to get syntax errors:

λόγος = "a word"
=> like: lambda όγος = "a word"

def expovariate(self, λ):
=> like: def expovariate(self, lambda):


both of which are obviously syntax errors.

This is as hostile to Greek-using programmers as deciding that "f" should
be reserved for functions would be to English-using programmers:

# space between the f and the function name is not needed
fspam(x, y):
...

class Thingy:
f__init__(selF):
...
fmethod(selF, arg):
return arg + 1


Notice that I can't even write "self" any more, since that gives a syntax
error. Presumable "if" is okay, as it is a keyword.

Using Unicode *symbols* rather than non-English letters is less of a
problem, since they aren't valid in identifiers.


More comments to follow later.
 
R

Rustom Mody

On 4/21/2014 11:57 PM, Rustom Mody wrote:
"With python 3 we are at a stage where python programs can support
unicode well however python program- source is still completely ASCII."
In Python 3, "Python reads program text as Unicode code points; the
encoding of a source file can be given by an encoding declaration and
defaults to UTF-8". Why start off with an erroneous statement, which you
even know and show is erroneous?

Ok

Ive reworded it to make it clear that I am referring to the character-sets and
not encodings.
 
R

Rustom Mody

What you are talking about is not handling Unicode with Python, but
extending the programming language to allow non-English *letters* to be
used as if they were *symbols*.
That's very problematic, since it assumes that nobody would ever want to
use non-English letters in an alphanumeric context. You write:
Now to move ahead!
We dont[sic] want

We want 3
[end quote]

(Speak for yourself.) But this is a problem. Suppose I want to use a
Greek word as a variable, as Python allows me to do:
λόγος = "a word"
Or perhaps as the parameter to a function. Take the random.expovariate
function, which currently takes an argument "lambd" (since lambda is a
reserved word). I might write instead:
def expovariate(self, λ): ...
After all, λ is an ordinary letter of the (Greek) alphabet, why shouldn't
it be used in variable names? But if "λx" is syntax for "lambda x", then
I'm going to get syntax errors:
λόγος = "a word"
=> like: lambda όγος = "a word"
def expovariate(self, λ):
=> like: def expovariate(self, lambda):
both of which are obviously syntax errors.
This is as hostile to Greek-using programmers as deciding that "f" should
be reserved for functions would be to English-using programmers:
# space between the f and the function name is not needed
fspam(x, y):
...
class Thingy:
f__init__(selF):
...
fmethod(selF, arg):
return arg + 1
Notice that I can't even write "self" any more, since that gives a syntax
error. Presumable "if" is okay, as it is a keyword.
Using Unicode *symbols* rather than non-English letters is less of a
problem, since they aren't valid in identifiers.

Ok point taken.

So instead of using λ (0x3bb) we should use ð€ (0x1d740) or something thereabouts like ðœ†
 
C

Chris Angelico

Ive reworded it to make it clear that I am referring to the character-sets and
not encodings.

It's still false, and was in Python 2 as well. The only difference on
that front is that, in the absence of an encoding cookie, Python 2
defaults to ASCII while Python 3 defaults to UTF-8. PEP 263 explains
the feature as it was added to Py2; PEP 3120 makes the change to a
UTF-8 default.

Python source code is Unicode text, and has been since 2001 and Python 2.3.

ChrisA
 
C

Chris Angelico

So instead of using λ (0x3bb) we should use ð€ (0x1d740) or something thereabouts like ðœ†

You still have a major problem: How do you type that? It gives you
very little advantage over the word "lambda", it introduces
readability issues, it's impossible for most people to type (and
programming with a palette of arbitrary syntactic tokens isn't my idea
of fun), it's harder for a new programmer to get docs for (especially
if s/he reads the file in the wrong encoding), and all in all, it's a
pretty poor substitute for a word.

ChrisA
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top