classification
Title: Vocabulary: Using "integral" in library/stdtypes.html
Type: enhancement Stage: resolved
Components: Documentation Versions: Python 3.6, Python 3.5, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: belopolsky, docs@python, georg.brandl, jyasskin, mark.dickinson, martin.panter, mdk, python-dev, rhettinger, serhiy.storchaka, vstinner
Priority: normal Keywords: patch

Created on 2016-03-08 21:24 by mdk, last changed 2016-05-08 22:45 by martin.panter. This issue is now closed.

Files
File name Uploaded Description Edit
stdtypes.patch mdk, 2016-03-12 11:08 review
stdtypes-integral.patch mdk, 2016-03-14 06:27 review
stdtypes-integral.v3.py3.patch martin.panter, 2016-04-26 07:39 review
stdtypes-integral.v3.py2.patch martin.panter, 2016-04-26 08:21 review
Messages (17)
msg261380 - (view) Author: Julien Palard (mdk) * (Python committer) Date: 2016-03-08 21:24
o/

TL;DR: I think the various usages of "Integral" in https://docs.python.org/3.5/library/stdtypes.html#numeric-types-int-float-complex are either wrong or too hard to understand and should be rewriten as "int".


While translating the documentation I found the sentence "x truncated to Integral" in https://docs.python.org/3.5/library/stdtypes.html#numeric-types-int-float-complex for the `math.floor(x)` method.

By "Integral" I assume you're speaking about the ABC `numbers.Integral`, whish is already not clear, but the capital I helps.

According to pydoc and PEP3141, the `numbers.Integral` ABC inherits from Rational, which inherits from Real which inherits from Complex which inherits from Number. So number is the broader ABC and integral the opposite, the representation of an integer.

I do _NOT_ assume that someone reading the stdtypes.html section is aware of those ABCs, so I don't think it's nice for them to use them without linking to them.

So I infer than "x truncated to integral" means "x truncated to the nearest integer". Which is far more readable.

Two lines after, I found "The greatest integral float <= x" for `math.floor(x)` which is less readable, no capital I to `integral` and what is an `integral float` ?

Also the documentation of `math.floor` states an `int` is returned (as the doc for math.trunc states an Integral is returned).

So there's two possibilities here:

 - The doc uses vocabulary and phrase structures I don't understand and "integral float" actually mean something.
 - The doc is not clear

In both cases, I suggest to either transform "integral" usages to a link to :class:`numbers.Integral` or simply speaking of "int" here.

Context: I'm translating the documentation in French, I achieved `tutorial.html` and `functions.html` and it's until here the hardest sentence to understand (others were simply wrong like in http://bugs.python.org/issue26029) or understandable, so even if those structures are semantically and gramatically correct, they're clearly one of the hardest to understand, which is sad as we're only speaking of rounding numbers. I mean, if there's a goal to sand away spikes in doc readability, this one is a big one.

So, can an english native speaker can enlighten me about this ?

Bests,
msg261383 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2016-03-08 21:37
In the contexts that you mentioned, "integral" is a synonym of "integer."
msg261406 - (view) Author: Julien Palard (mdk) * (Python committer) Date: 2016-03-09 08:45
> In the contexts that you mentioned, "integral" is a synonym of "integer."

Can you provide a source ? There's no mention of "integral" in the Wikipedia page of "integer" (but there's mentions of "integral element" and "integral domain" which are not synonyms for "integer".

Even if "integral" is a synonym for "integer", I think we should use "integer" or "int" in the documentation because "integral" is harder to understand as readers are searching why "integral" is used in this particular context instead of "integer".

It looks like the documentation describes the mathematical, theoretical, point of view of those functions, as supported by the PEP3141, but those functions are not theoretical, they're actual implementations returning actual integers.

I can understand the need to abstract the implementations to make the documentation more readable, we're already not manipulating bits or even bytes, there's nice abstractions of those implementations so we can manipulate `int`, `float` etc, which are also implementation we may want to abstract again and say we're not manipulating "the implementation" (like "an int") but a mathematical domain (like "a natural number"), but going all the way down to vocabulary I can't even find on Wikipedia is probably going the wrong way: The documentation is less readable this way.
msg261436 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2016-03-09 15:29
There's two different uses here:

The one use in "truncated to Integral" means that you get an integer type out.  It is not specified to be `int` because `__trunc__` may return other types.  It could be made into a link like the other use of Integral.

The other uses are "integral float", which is *not* the same as an integer.  It is a float whose value is a whole number, and AFAIK "integral" is the correct adjective for that.
msg261439 - (view) Author: Julien Palard (mdk) * (Python committer) Date: 2016-03-09 16:20
> It could be made into a link like the other use of Integral.

I'll propose a patch.

> The other uses are "integral float", which is *not* the same as an integer.  It is a float whose value is a whole number, and AFAIK "integral" is the correct adjective for that.

Can you please give me some links to definitions / usages of the "integral" adjective ? As "integral float" is not verbose on google SERPs, so I can document myself on it and eventually translate it correctly in french ?

I'm still thinking that those sentences are way too hard to understand for a youg user (Think of all the childs learning Python ^^), and they're contrasting a lot with the other parts of the documentations which are far more readable. (Also remember that I'm not native english, maybe "integral" is a wisely used word for this context and I completly missed it).
msg261463 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2016-03-09 18:55
> Can you provide a source ?

How about a dictionary?  For example, Oxford English Dictionary has

"""
integral, adj. and n.

4. Math.

 a. That is, or is denoted by, an integer, or involves only integers; consisting of a whole number or undivided quantity; not fractional, or not involving a fraction.
"""

http://www.oed.com/view/Entry/97344?redirectedFrom=integral#eid
msg261619 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2016-03-11 23:52
I have looked at PEP 3141, the history of the documentation in question, and the documentation of the functions in the “math” module. It seems that trunc(), floor() and ceil() were all intended to return a numbers.Integral type, but then PEP 3141’s floor() and ceil() were reverted from Python 2 due to compatibility concerns, where they only accept and return float objects. So it would be correct to clarify that Integral means numbers.Integral.

The term “integral float” was added by revision 94eeaeeb3ce9, to mean a Python float() object that represents an integer. This is correct (but hard to understand) for Python 2, but the change is not appropriate for Python 3, where floor() and ceil() follow PEP 3141 instead and do return integers (numbers.Integral).

I propose to just point to the proper math.trunc(), round() etc documentation and remove the table (originally added in revision 4f9723d9ca32). Julien: do you think the definitions in <https://docs.python.org/3.5/library/math.html#number-theoretic-and-representation-functions> are understandable?

Also I noticed Python 3’s floor() and ceil() doc strings say int not numbers.Integral. That should probably also be fixed.

Julien, if you agree with my suggestion, do you still want to do a patch for this? Otherwise, I could have a go when I get a chance.
msg261644 - (view) Author: Julien Palard (mdk) * (Python committer) Date: 2016-03-12 11:08
Hi Martin, awesome work you've done here. I was meditating those past days about the subject and came to a similar yet not that good conclusion that the table should have the same definitions than those from [library/math.html](https://docs.python.org/3.5/library/math.html#number-theoretic-and-representation-functions). But your solution is better, copy-paste is wrong, let's just link to the right documentation, in which case, a simple list is enough, there is no need for a table.

The definitions in the *library/math.html* and *library/functions.html* (for round) are perfectly clear and understandable, and properly link to number.Integral each time it's used. For the record:

    math.trunc(x)
    Return the Real value x truncated to an Integral (usually an integer). Delegates to x.__trunc__().

    math.ceil(x)
    Return the ceiling of x, the smallest integer greater than or equal to x. If x is not a float, delegates to x.__ceil__(), which should return an Integral value.

    math.floor(x)
    Return the floor of x, the largest integer less than or equal to x. If x is not a float, delegates to x.__floor__(), which should return an Integral value.

    round(number[, ndigits])
    Return the floating point value number rounded to ndigits digits after the decimal point. If ndigits is omitted, it returns the nearest integer to its input. Delegates to number.__round__(ndigits).

    For the built-in types supporting round(), values are rounded to the closest multiple of 10 to the power minus ndigits; if two multiples are equally close, rounding is done toward the even choice (so, for example, both round(0.5) and round(-0.5) are 0, and round(1.5) is 2). The return value is an integer if called with one argument, otherwise of the same type as number.

    Note The behavior of round() for floats can be surprising: for example, round(2.675, 2) gives 2.67 instead of the expected 2.68. This is not a bug: it’s a result of the fact that most decimal fractions can’t be represented exactly as a float. See Floating Point Arithmetic: Issues and Limitations for more information.

About the docstrings not being the same as the documentation, is there a "best practice" on how it should be ? Should'nt them always be the same ?

Here's a first patch to replace the table with a simple list.
msg261677 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2016-03-13 07:09
I don't think taking the table out makes the docs better.  It just removes a source of information just because the OP stumbled on the word "integral" which has both a standard (albeit erudite) meaning in Engligh and a precise meaning in the context of PEP-3141.   I recommend leaving the table as-is and linking to the PEP or to the numbers module so that an interested person can delved deeper if needed.  The table communicates a central concept that there are differences in the several ways to convert a float to an integer.
msg261687 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2016-03-13 08:58
Julien: I tend to keep doc strings rather concise. Just mention the main points, not all the obscure corner cases or examples. In this case I would probably just change “int” to “integer” (lowercase) or “numbers.Integral” if you want to be specific. You might also want to change “integral value” → “integer”.

Raymond: If you want to keep the table, please also fix the “integral float” references in Python 3 as well. Also see footnote (3) for the previous table, which also covers rounding.

I would still suggest to remove the empty “Notes” column. If there are any details worthy of footnotes, they should be added to the main documentation, not this table.
msg261702 - (view) Author: Julien Palard (mdk) * (Python committer) Date: 2016-03-13 18:23
Daily meditations:

 - This table is nice to show that there's various operations common to int and float (and does it well), not to list rounding methods (it happen to have only rounding methods, but that's a coincidence).

 - A coma separated list like ":func:`math.trunc`, :func:`round`, :func:`math.floor`, and :func:`math.ceil`." are enough to list them and to show they contain various rounding methods which is clear about the fact they are a bit different.

 - Yet we have to be both readable for everybody and ultra precise about implementation for those implementing their own __floor__, and the math module does it really nicely.

But we can keep the table without the empty "Notes" column, leaving place to explain them with more words, so they  can be more readable, approaching this way the readability of the math module ?

Finally, the problem is the conciseness of the result column (which make me think a link is better than a too-concise explanation).
msg261725 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2016-03-14 06:23
Julian, I don't see a bug here and think you've ventured too far into stylistic micro-rewordings.   If there is something unintelligible, we'll fix it, but this tracker item has lost focus and isn't using people's time efficiently (i.e. this isn't a forum for "daily meditations").
msg261727 - (view) Author: Julien Palard (mdk) * (Python committer) Date: 2016-03-14 06:27
I completely agree we're consuming too much time for what it is, sry for that. Let's just link to numbers.Integral and close it.

I attached a simple patch for it.
msg261729 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2016-03-14 07:46
Georg, is it possible to make a link from formatted text ``math.trunc(x)`` to the math.trunc() function?
msg264225 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2016-04-26 07:38
Here is a v3 patch for Python 3, addressing everyone’s comments:

Fix the leftover table markup
Link math.trunc(x) etc syntax to the main documentation
Hide numbers module prefix from Integral class name
Change “integral float” → ~numbers.Integral
Add emphasis for *n* parameter
Change int → Integral in doc strings
msg264234 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2016-04-26 08:21
Here is the Python 2 version. The difference is that floor() and ceil() return an “integer as a float”, and I didn’t touch the doc strings.
msg265132 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2016-05-08 11:59
New changeset 9e29034a41fa by Martin Panter in branch '3.5':
Issue #26512: Clarify Integral; tidy up table of rounding functions
https://hg.python.org/cpython/rev/9e29034a41fa

New changeset a8883951b2ff by Martin Panter in branch 'default':
Issue #26512: Merge rounding doc from 3.5
https://hg.python.org/cpython/rev/a8883951b2ff

New changeset a69805edfadd by Martin Panter in branch '2.7':
Issue #26512: Clarify Integral; tidy up table of rounding functions
https://hg.python.org/cpython/rev/a69805edfadd
History
Date User Action Args
2019-09-25 07:07:32serhiy.storchakalinkissue38268 superseder
2016-05-08 22:45:51martin.pantersetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2016-05-08 11:59:32python-devsetnosy: + python-dev
messages: + msg265132
2016-04-26 09:29:53vstinnersetnosy: + vstinner
2016-04-26 08:21:59martin.pantersetfiles: + stdtypes-integral.v3.py2.patch

messages: + msg264234
2016-04-26 07:39:20martin.pantersetfiles: + stdtypes-integral.v3.py3.patch
2016-04-26 07:38:58martin.pantersetfiles: - stdtypes-integral.v3.py3.patch
2016-04-26 07:38:26martin.pantersetfiles: + stdtypes-integral.v3.py3.patch

messages: + msg264225
stage: needs patch -> patch review
2016-04-26 06:15:01rhettingersetassignee: rhettinger ->
2016-03-14 07:46:44serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg261729
2016-03-14 06:27:13mdksetfiles: + stdtypes-integral.patch

messages: + msg261727
2016-03-14 06:23:18rhettingersetmessages: + msg261725
2016-03-13 18:23:07mdksetmessages: + msg261702
2016-03-13 08:58:31martin.pantersetmessages: + msg261687
2016-03-13 07:09:02rhettingersetassignee: docs@python -> rhettinger

messages: + msg261677
nosy: + rhettinger
2016-03-12 11:33:21serhiy.storchakasetnosy: + jyasskin
2016-03-12 11:08:47mdksetfiles: + stdtypes.patch
keywords: + patch
messages: + msg261644
2016-03-11 23:52:00martin.pantersetstage: needs patch
messages: + msg261619
versions: + Python 2.7, Python 3.6
2016-03-10 13:59:29serhiy.storchakasetnosy: + martin.panter
2016-03-10 13:36:02vstinnersetnosy: + mark.dickinson
2016-03-09 18:55:04belopolskysetmessages: + msg261463
2016-03-09 16:20:11mdksetmessages: + msg261439
2016-03-09 15:29:16georg.brandlsetnosy: + georg.brandl
messages: + msg261436
2016-03-09 08:45:49mdksetmessages: + msg261406
2016-03-08 21:37:32belopolskysetnosy: + belopolsky
messages: + msg261383
2016-03-08 21:24:04mdkcreate