Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #70366 > unrolled thread
| Started by | Anthony Papillion <papillion@gmail.com> |
|---|---|
| First post | 2014-04-18 22:28 -0500 |
| Last post | 2014-05-06 09:28 -0700 |
| Articles | 20 on this page of 72 — 23 participants |
Back to article view | Back to comp.lang.python
Why Python 3? Anthony Papillion <papillion@gmail.com> - 2014-04-18 22:28 -0500
Re: Why Python 3? Paul Rubin <no.email@nospam.invalid> - 2014-04-18 23:40 -0700
Re: Why Python 3? Chris Angelico <rosuav@gmail.com> - 2014-04-19 17:34 +1000
Re: Why Python 3? Roy Smith <roy@panix.com> - 2014-04-19 09:26 -0400
Re: Why Python 3? Chris Angelico <rosuav@gmail.com> - 2014-04-19 23:42 +1000
Re: Why Python 3? Albert-Jan Roskam <fomcl@yahoo.com> - 2014-04-19 10:57 -0700
Re: Why Python 3? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-04-20 10:07 +0000
Re: Why Python 3? Ian Kelly <ian.g.kelly@gmail.com> - 2014-04-19 03:25 -0600
Re: Why Python 3? Marko Rauhamaa <marko@pacujo.net> - 2014-04-19 12:59 +0300
Re: Why Python 3? Chris Angelico <rosuav@gmail.com> - 2014-04-19 19:37 +1000
Integer and float division [was Re: Why Python 3?] Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-04-20 11:02 +0000
Re: Integer and float division [was Re: Why Python 3?] Jussi Piitulainen <jpiitula@ling.helsinki.fi> - 2014-04-20 15:38 +0300
Re: Integer and float division [was Re: Why Python 3?] Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-04-20 15:09 +0000
Re: Integer and float division [was Re: Why Python 3?] Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2014-04-21 11:44 +1200
Re: Why Python 3? Terry Reedy <tjreedy@udel.edu> - 2014-04-19 13:23 -0400
Re: Why Python 3? Paul Rubin <no.email@nospam.invalid> - 2014-04-19 20:25 -0700
Re: Why Python 3? Ben Finney <ben+python@benfinney.id.au> - 2014-04-20 19:15 +1000
Re: Why Python 3? Walter Hurry <walterhurry@lavabit.com> - 2014-04-20 23:50 +0000
Re: Why Python 3? Chris Angelico <rosuav@gmail.com> - 2014-04-21 10:00 +1000
Re: Why Python 3? HoneyMonster <nobody@someplace.invalid> - 2014-04-21 04:08 +0000
Re: Why Python 3? Mark Lawrence <breamoreboy@yahoo.co.uk> - 2014-04-21 01:11 +0100
Re: Why Python 3? Mark Lawrence <breamoreboy@yahoo.co.uk> - 2014-04-19 18:31 +0100
Re: Why Python 3? Chris Angelico <rosuav@gmail.com> - 2014-04-20 03:53 +1000
Re: Why Python 3? Ian Kelly <ian.g.kelly@gmail.com> - 2014-04-19 13:58 -0600
Re: Why Python 3? Chris Angelico <rosuav@gmail.com> - 2014-04-20 06:31 +1000
Re: Why Python 3? Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2014-04-20 13:06 +1200
Re: Why Python 3? Chris Angelico <rosuav@gmail.com> - 2014-04-20 11:28 +1000
Re: Why Python 3? Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2014-04-21 10:52 +1200
Re: Why Python 3? Chris Angelico <rosuav@gmail.com> - 2014-04-21 09:24 +1000
Re: Why Python 3? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-04-21 03:43 +0000
Re: Why Python 3? Chris Angelico <rosuav@gmail.com> - 2014-04-21 14:43 +1000
Re: Why Python 3? Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2014-04-22 09:58 +1200
Re: Why Python 3? Chris Angelico <rosuav@gmail.com> - 2014-04-21 14:48 +1000
Re: Why Python 3? wxjmfauth@gmail.com - 2014-04-21 02:42 -0700
Re: Why Python 3? Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2014-04-22 10:28 +1200
Re: Why Python 3? Chris Angelico <rosuav@gmail.com> - 2014-04-22 08:43 +1000
Re: Why Python 3? Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2014-04-22 18:03 +1200
Re: Why Python 3? Terry Reedy <tjreedy@udel.edu> - 2014-04-20 00:17 -0400
Re: Why Python 3? Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2014-04-21 11:13 +1200
Re: Why Python 3? Terry Reedy <tjreedy@udel.edu> - 2014-04-20 20:09 -0400
Re: Why Python 3? Ian Kelly <ian.g.kelly@gmail.com> - 2014-04-19 14:38 -0600
Re: Why Python 3? Chris Angelico <rosuav@gmail.com> - 2014-04-20 06:53 +1000
Re: Why Python 3? Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2014-04-20 13:35 +1200
Re: Why Python 3? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-04-20 09:59 +0000
Unicode in Python Rustom Mody <rustompmody@gmail.com> - 2014-04-21 20:57 -0700
Re: Unicode in Python Terry Reedy <tjreedy@udel.edu> - 2014-04-22 01:44 -0400
Re: Unicode in Python Rustom Mody <rustompmody@gmail.com> - 2014-04-21 23:18 -0700
Re: Unicode in Python Chris Angelico <rosuav@gmail.com> - 2014-04-22 16:32 +1000
Re: Unicode in Python Steven D'Aprano <steve@pearwood.info> - 2014-04-22 06:11 +0000
Re: Unicode in Python Rustom Mody <rustompmody@gmail.com> - 2014-04-21 23:30 -0700
Re: Unicode in Python Chris Angelico <rosuav@gmail.com> - 2014-04-22 16:44 +1000
Re: Unicode in Python wxjmfauth@gmail.com - 2014-04-22 02:07 -0700
Re: Unicode in Python Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-04-22 12:21 +0000
Re: Unicode in Python wxjmfauth@gmail.com - 2014-04-22 08:28 -0700
Re: Unicode in Python Ian Kelly <ian.g.kelly@gmail.com> - 2014-04-22 00:31 -0600
Re: Unicode in Python Rustom Mody <rustompmody@gmail.com> - 2014-04-22 02:23 -0700
Re: Unicode in Python Rustom Mody <rustompmody@gmail.com> - 2014-04-22 11:09 -0700
Re: Why Python 3? Ian Kelly <ian.g.kelly@gmail.com> - 2014-04-20 10:22 -0600
Re: Why Python 3? Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2014-04-21 11:56 +1200
Re: Why Python 3? Ian Kelly <ian.g.kelly@gmail.com> - 2014-04-20 18:29 -0600
Re: Why Python 3? MRAB <python@mrabarnett.plus.com> - 2014-04-20 17:41 +0100
Re: Why Python 3? Chris Angelico <rosuav@gmail.com> - 2014-04-21 02:46 +1000
Re: Why Python 3? Roy Smith <roy@panix.com> - 2014-04-20 14:40 -0700
Re: Why Python 3? Terry Reedy <tjreedy@udel.edu> - 2014-04-20 17:58 -0400
Re: Why Python 3? Richard Damon <Richard@Damon-Family.org> - 2014-04-20 18:02 -0400
Re: Why Python 3? Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2014-04-21 12:22 +1200
Re: Why Python 3? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-04-21 02:13 +0000
Re: Why Python 3? Steve Hayes <hayesstw@telkomsa.net> - 2014-04-19 13:53 +0200
Re: Why Python 3? Chris Angelico <rosuav@gmail.com> - 2014-04-19 22:46 +1000
Re: Why Python 3? Rustom Mody <rustompmody@gmail.com> - 2014-04-19 08:59 -0700
Re: Why Python 3? Rick Johnson <rantingrickjohnson@gmail.com> - 2014-04-19 07:41 -0700
Re: Why Python 3? Thomas Lehmann <thomas.lehmann.private@googlemail.com> - 2014-05-06 09:28 -0700
Page 2 of 4 — ← Prev page 1 [2] 3 4 Next page →
| From | Mark Lawrence <breamoreboy@yahoo.co.uk> |
|---|---|
| Date | 2014-04-21 01:11 +0100 |
| Message-ID | <mailman.9394.1398039126.18130.python-list@python.org> |
| In reply to | #70442 |
On 21/04/2014 00:50, Walter Hurry wrote: > On Sat, 19 Apr 2014 20:25:32 -0700, Paul Rubin wrote: > >> Terry Reedy <tjreedy@udel.edu> writes: >>> LibreOffice bundles 3.3. So anyone who does Python scripting in >>> LibreOffice is using Python 3. Actually, I believe LO uses Python >>> internally for some of its scripting. If so, everyone using LO is >>> indirectly using 3.3. >> >> I didn't even know LO supported Python scripting, but I wouldn't count >> such indirect use anyway. I meant I don't know any Python programmers >> (at least in person) who use Python 3 for their daily coding. I think >> this is mostly because they (and I) use whatever is in the OS distro, >> and that is generally still 2.6 or 2.7. > > I would use Python 3 in a flash if only wxPython would support it. > It's getting there with the Phoenix project. Snapshots available here http://wxpython.org/Phoenix/snapshot-builds/ -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence --- This email is free from viruses and malware because avast! Antivirus protection is active. http://www.avast.com
[toc] | [prev] | [next] | [standalone]
| From | Mark Lawrence <breamoreboy@yahoo.co.uk> |
|---|---|
| Date | 2014-04-19 18:31 +0100 |
| Message-ID | <mailman.9366.1397928707.18130.python-list@python.org> |
| In reply to | #70371 |
On 19/04/2014 07:40, Paul Rubin wrote: > > That said, I don't know anyone who actually uses Python 3. > You do now :) -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence --- This email is free from viruses and malware because avast! Antivirus protection is active. http://www.avast.com
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-04-20 03:53 +1000 |
| Message-ID | <mailman.9367.1397930005.18130.python-list@python.org> |
| In reply to | #70371 |
On Sun, Apr 20, 2014 at 3:23 AM, Terry Reedy <tjreedy@udel.edu> wrote: > LibreOffice bundles 3.3. So anyone who does Python scripting in LibreOffice > is using Python 3. This much I agree with... > Actually, I believe LO uses Python internally for some of > its scripting. If so, everyone using LO is indirectly using 3.3. ... but this is kinda pushing it, I think. You're not *using* it any more than you're using Python whenever you post to Savoynet [1] - after all, Savoynet is a Mailman list, and Mailman runs on Python. But all those theatre people don't become Python users because of that. I'd have to say that "using Python 3" means writing code that runs in Python 3. So the LO people would, by your statement, be using Py3.3, as would anyone who actually writes LO scripts; but someone who just fires up LO, edits a document in the WYSIWYG editor, and goes about his business, isn't really using Python. Though the broader definition does have its uses. It's fun to explain to someone how that little device that shows him a map and where he is on it is depending on both special and general relativity. (GPS signals are strongly based on time, and the satellites are moving relative to the observer, and gravity is weaker up there.) But you're not really making use of the science yourself, you're depending on someone else having made use of it - same as you can hop on an airliner without understanding the physics of flight, much less the effects of birdstrike on jet engines. You're just glad that someone, somewhere, has worked all that out :) ChrisA [1] http://savoynet.oakapplepress.com/
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2014-04-19 13:58 -0600 |
| Message-ID | <mailman.9369.1397937555.18130.python-list@python.org> |
| In reply to | #70371 |
On Sat, Apr 19, 2014 at 3:37 AM, Chris Angelico <rosuav@gmail.com> wrote:
> On Sat, Apr 19, 2014 at 7:25 PM, Ian Kelly <ian.g.kelly@gmail.com> wrote:
>> The change from / denoting "classic
>> division" to "true division" really only affects the case where both
>> operands are integers, so far as I'm aware. If you want to divide two
>> integers and get a decimal result, then convert one or both of them to
>> decimals first; you would have needed to do the same with classic
>> division.
>
> If float were a perfect superset of int, and the only logical superset
> when you want non-integers, then it'd be fine.
Decimal is also not a perfect superset of int (although I believe it
is a superset of the intersection of int and float). Even if it were,
I'm not sure it would be appropriate to bless Decimal in this way
either, because they have no place in Python's number type hierarchy:
>>> from decimal import Decimal
>>> from numbers import Real
>>> isinstance(Decimal('1.23'), Real)
False
> But if you're mixing
> int and Decimal, you have to explicitly convert, whereas if you're
> mixing int and float, you don't. Why is it required to be explicit
> with Decimal but not float? Of all the possible alternate types, why
> float? Only because...
>
>> As for "why float" specifically, the division __future__ import has
>> been around since 2.2, longer than either decimals or fractions.
>
> ... it already existed. There's no particular reason to up-cast to
> float, specifically, and it can cause problems with large integers -
> either by losing accuracy, or by outright overflowing.
The authors of PEP 238 expressed their hope that when a rational type
(i.e. Fraction) was implemented, it would become the result type for
true division on two integers. I don't know why that never came to
pass; perhaps performance considerations won out.
> In Python 3, you have to say "Oh but I want my integer division to
> result in an integer":
>
> x * 10 // 5 == x * 2
Technically this says "I want the result of floor division", not "I
want the result as an integer". If you apply the floor division
operator to a non-int type, you'll get a non-int result. It just so
happens that the result of floor division of two integers can be given
as an integer, whereas the result of true division cannot.
Considering that Fraction and Decimal did not exist yet, what type do
you think the PEP 238 implementers should have chosen for the result
of dividing two ints? If float is not acceptable, and int is not
acceptable (which was the whole point of the PEP), then the only
alternative I can see would have been to raise a TypeError and force
the user to upcast explicitly. In that case, dividing arbitrary ints
using floating-point math would not be possible for those ints that
are outside the range of floats; you would get OverflowError on the
upcast operation, regardless of whether the result of division would
be within the range of a float.
> Yes, I can see that it's nice for simple interactive use.
More importantly, it's useful for implementers of generic mathematical
routines. If you're passed arbitrary inputs, you don't have to check
the types of the values you were given and then branch if both of the
values you were about to divide happened to be ints just because the
division operator arbitrarily does something different on ints.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-04-20 06:31 +1000 |
| Message-ID | <mailman.9370.1397939472.18130.python-list@python.org> |
| In reply to | #70371 |
On Sun, Apr 20, 2014 at 5:58 AM, Ian Kelly <ian.g.kelly@gmail.com> wrote:
> Considering that Fraction and Decimal did not exist yet, what type do
> you think the PEP 238 implementers should have chosen for the result
> of dividing two ints? If float is not acceptable, and int is not
> acceptable (which was the whole point of the PEP), then the only
> alternative I can see would have been to raise a TypeError and force
> the user to upcast explicitly. In that case, dividing arbitrary ints
> using floating-point math would not be possible for those ints that
> are outside the range of floats; you would get OverflowError on the
> upcast operation, regardless of whether the result of division would
> be within the range of a float.
>
>> Yes, I can see that it's nice for simple interactive use.
>
> More importantly, it's useful for implementers of generic mathematical
> routines. If you're passed arbitrary inputs, you don't have to check
> the types of the values you were given and then branch if both of the
> values you were about to divide happened to be ints just because the
> division operator arbitrarily does something different on ints.
Or you just cast one of them to float. That way you're sure you're
working with floats.
The main trouble is that float is not a perfect superset of int. If it
were, then it really would be upcasting, same as turning a float into
a complex is; there's no downside, other than performance.
If I'd been in charge, I would have simply let int/int continue to
return an int, as that's the one thing that is guaranteed not to
behave differently on different input values. Python 3 fixed Unicode
handling by ensuring that mixing text and bytes would cause problems
straight away, rather than waiting until you get a character with a
codepoint higher than U+00FF; 3.3 went further and made sure you
wouldn't get problems by going past U+FFFF even on Windows. I think we
all agree (well, all bar the trolls) that that was a good thing. So
why do we have this sort of thing go weird?
def always_true(x):
assert type(x) is int
return x*10/2 == x*5
In Python 2, I believe that will indeed be always true, for any
integer x. (Yeah, there's a naughty type check in there. I'm talking
about integers, mmkay?) In Python 3, it might not be.
>>> always_true(2**53)
True
>>> always_true(2**53+1)
False
(32-bit Windows, because I'm on the laptop. Other Pythons, other CPUs,
etc, may have different points where that happens, but the same will
happen.)
So either you keep a very close eye on everything to make sure you
don't have floats infecting your calculations, or you ignore the
problem and then start seeing odd stuff happen with specific numbers.
I'd rather have to explicitly request floating-point division; that
way, you get issues a lot sooner and more simply. "Why is 34/10 equal
to 3?" is a lot easier to explain than "Why does my program not work
when I give it numbers with lots of data encoded in them, when it
works fine with sequential numbers from zero?". (Imagine if you work
with invoice numbers, for instance, and your code is fine; but if you
encode the date into the first eight digits, then put the store number
in the next three, register number in the next three, and then the
last three are sequential. Should work the same, right?)
Anyway, way too late to change now. That ship sailed in 2.2 or thereabouts.
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Gregory Ewing <greg.ewing@canterbury.ac.nz> |
|---|---|
| Date | 2014-04-20 13:06 +1200 |
| Message-ID | <brgktaF7o67U1@mid.individual.net> |
| In reply to | #70397 |
Chris Angelico wrote: > I'd rather have to explicitly request floating-point division; When you write / in Python 3, you *are* explicitly requesting floating-point division. Similarly, when you write // you're explicitly requesting integer division. I don't see the problem. You write whatever you mean and it does what you tell it to do. > So either you keep a very close eye on everything to make sure you > don't have floats infecting your calculations, If you have something that works exclusively on ints and someone passes you a float, and you don't check for that, you'll have problems anyway even if no division is involved at all. There's no way that Python 3 division can *introduce* a float into an integer calculation unless you write / somewhere where you really meant //. But that's the same kind of mistake as calling foo() when you meant to call bar(). You can't blame the language for that. > but if you > encode the date into the first eight digits, then put the store number > in the next three, register number in the next three, and then the > last three are sequential. Should work the same, right?) It'll work fine as long as you use // when extracting the parts. If you use / then you're *explicitly* saying to do the calculation in floating point, which would not be a sane thing to do. -- Greg
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-04-20 11:28 +1000 |
| Message-ID | <mailman.9373.1397957316.18130.python-list@python.org> |
| In reply to | #70400 |
On Sun, Apr 20, 2014 at 11:06 AM, Gregory Ewing <greg.ewing@canterbury.ac.nz> wrote: > Chris Angelico wrote: >> >> I'd rather have to explicitly request floating-point division; > > > When you write / in Python 3, you *are* explicitly requesting > floating-point division. > > Similarly, when you write // you're explicitly requesting > integer division. > > I don't see the problem. You write whatever you mean and it > does what you tell it to do. Truncating vs true is not the same as int vs float. If you mean to explicitly request float division, you call float() on one or both arguments. You're being explicit about something different. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Gregory Ewing <greg.ewing@canterbury.ac.nz> |
|---|---|
| Date | 2014-04-21 10:52 +1200 |
| Message-ID | <brj1cuFmq1tU1@mid.individual.net> |
| In reply to | #70401 |
Chris Angelico wrote: > Truncating vs true is not the same as int vs float. If you mean to > explicitly request float division, you call float() on one or both > arguments. You're being explicit about something different. If you know you're dealing with either ints or floats, which is true in the vast majority of cases, then you know that / will always perform float division. As for why int/int should yield float and not some other type, float is alreay special -- it's built-in and has syntactic support in the form of literals. It's the most obvious choice. If a version of Python were ever to exist in which floating-point literals produced Decimals instead of floats, then int/int would produce a Decimal. -- Greg
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-04-21 09:24 +1000 |
| Message-ID | <mailman.9390.1398036251.18130.python-list@python.org> |
| In reply to | #70437 |
On Mon, Apr 21, 2014 at 8:52 AM, Gregory Ewing <greg.ewing@canterbury.ac.nz> wrote: > Chris Angelico wrote: > >> Truncating vs true is not the same as int vs float. If you mean to >> explicitly request float division, you call float() on one or both >> arguments. You're being explicit about something different. > > > If you know you're dealing with either ints or floats, > which is true in the vast majority of cases, then you > know that / will always perform float division. 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. Explicitly choosing float division: x / float(y) Explicitly choosing to truncate: math.trunc(x / y) Both explicit forms can be done cleanly without empowering the language with the magic of int/int->float. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2014-04-21 03:43 +0000 |
| Message-ID | <535493d4$0$29993$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #70439 |
On Mon, 21 Apr 2014 09:24:09 +1000, Chris Angelico wrote:
> On Mon, Apr 21, 2014 at 8:52 AM, Gregory Ewing
> <greg.ewing@canterbury.ac.nz> wrote:
>> Chris Angelico wrote:
>>
>>> Truncating vs true is not the same as int vs float. If you mean to
>>> explicitly request float division, you call float() on one or both
>>> arguments. You're being explicit about something different.
>>
>>
>> If you know you're dealing with either ints or floats, which is true in
>> the vast majority of cases, then you know that / will always perform
>> float division.
>
> 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"?
--
Steven D'Aprano
http://import-that.dreamwidth.org/
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-04-21 14:43 +1000 |
| Message-ID | <mailman.9396.1398055442.18130.python-list@python.org> |
| In reply to | #70450 |
On Mon, Apr 21, 2014 at 1:43 PM, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote: >> 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? 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
[toc] | [prev] | [next] | [standalone]
| From | Gregory Ewing <greg.ewing@canterbury.ac.nz> |
|---|---|
| Date | 2014-04-22 09:58 +1200 |
| Message-ID | <brlijmF8ffeU1@mid.individual.net> |
| In reply to | #70452 |
Chris Angelico wrote: > 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. -- Greg
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-04-21 14:48 +1000 |
| Message-ID | <mailman.9397.1398055717.18130.python-list@python.org> |
| In reply to | #70450 |
On Mon, Apr 21, 2014 at 1:43 PM, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote: >> 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"? 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
[toc] | [prev] | [next] | [standalone]
| From | wxjmfauth@gmail.com |
|---|---|
| Date | 2014-04-21 02:42 -0700 |
| Message-ID | <b2c04a85-f5a5-4bf9-9c85-d50263a0a0e1@googlegroups.com> |
| In reply to | #70453 |
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".
[toc] | [prev] | [next] | [standalone]
| From | Gregory Ewing <greg.ewing@canterbury.ac.nz> |
|---|---|
| Date | 2014-04-22 10:28 +1200 |
| Message-ID | <brlkdbF8r9iU1@mid.individual.net> |
| In reply to | #70453 |
Chris Angelico wrote: > 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. -- Greg
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-04-22 08:43 +1000 |
| Message-ID | <mailman.9421.1398120198.18130.python-list@python.org> |
| In reply to | #70479 |
On Tue, Apr 22, 2014 at 8:28 AM, Gregory Ewing <greg.ewing@canterbury.ac.nz> wrote: > 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. I do see that there are two sides to this. The question of "Is 1.0 equal to 1?" has a very obvious answer... whichever answer you go with, it's absolutely obvious! (Yes! They're the same number, of course they're equal! vs No! They're completely different representations, like 1 and "1" and "\1" are all different!) Separating the types makes very good sense, and unifying them makes very good sense, and for different reasons. Unifying them in as many ways as possible means you don't need the syntactic salt of ".0" on every number; you should be able to add 2.5+1 and get 3.5, just as if you'd added 2.5+1.0. And that's fine. Separating them also makes sense, though; it means that an operation on Type X and Type Y will behave equally sanely regardless of the values of those objects. 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. This is, in my opinion, analogous to a UTF-16 string type; if you work with strings of nothing but BMP characters, everything works perfectly, but put in an astral character and things may or may not work. A lot of operations will work fine, but just a few will break. Python 3 has fixed that by giving us the pain of transition *right at the beginning*; you look at Text and at Bytes as completely separate things. People who like their ASCII like the idea that the letter "A" is equivalent to the byte 0x41. It's convenient, it's easy. But it leads to problems later. Now, the analogy does break down a bit in that it's probably more likely that a program will have to deal with non-ASCII characters than with integers that can't be represented in IEEE double precision. 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? ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Gregory Ewing <greg.ewing@canterbury.ac.nz> |
|---|---|
| Date | 2014-04-22 18:03 +1200 |
| Message-ID | <brmf1mFdlg9U1@mid.individual.net> |
| In reply to | #70480 |
Chris Angelico wrote: > 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. -- Greg
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2014-04-20 00:17 -0400 |
| Message-ID | <mailman.9375.1397967483.18130.python-list@python.org> |
| In reply to | #70400 |
On 4/19/2014 9:06 PM, Gregory Ewing wrote: > Chris Angelico wrote: >> I'd rather have to explicitly request floating-point division; > > When you write / in Python 3, you *are* explicitly requesting > floating-point division. > > Similarly, when you write // you're explicitly requesting > integer division. One is requesting 'floor division' >>> 3.0//2.0 1.0 To me, calling that integer division is a bit misleading in that one might expect the result, at least, to be an int rather than a float. (Yes, it is an integer-valued float.) -- Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
| From | Gregory Ewing <greg.ewing@canterbury.ac.nz> |
|---|---|
| Date | 2014-04-21 11:13 +1200 |
| Message-ID | <brj2klFn1c0U1@mid.individual.net> |
| In reply to | #70405 |
Terry Reedy wrote: > On 4/19/2014 9:06 PM, Gregory Ewing wrote: > >> Similarly, when you write // you're explicitly requesting >> integer division. > > One is requesting 'floor division' > > >>> 3.0//2.0 > 1.0 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. -- Greg
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2014-04-20 20:09 -0400 |
| Message-ID | <mailman.9393.1398039008.18130.python-list@python.org> |
| In reply to | #70438 |
On 4/20/2014 7:13 PM, Gregory Ewing wrote: > Terry Reedy wrote: >> On 4/19/2014 9:06 PM, Gregory Ewing wrote: >> >>> Similarly, when you write // you're explicitly requesting >>> integer division. >> >> One is requesting 'floor division' >> >> >>> 3.0//2.0 >> 1.0 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 -- Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
Page 2 of 4 — ← Prev page 1 [2] 3 4 Next page →
Back to top | Article view | comp.lang.python
csiph-web