python / cpython

The Python programming language
https://www.python.org
Other
63.49k stars 30.41k forks source link

Python tutorial misleads users about floor division behavior #87200

Open 05661d66-873f-4b42-8577-c94bd66ee9a6 opened 3 years ago

05661d66-873f-4b42-8577-c94bd66ee9a6 commented 3 years ago
BPO 43034
Nosy @rhettinger, @terryjreedy, @akulakov

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields: ```python assignee = None closed_at = None created_at = labels = ['3.9', 'docs'] title = 'Python tutorial misleads users about floor division behavior' updated_at = user = 'https://bugs.python.org/jessevsilverman' ``` bugs.python.org fields: ```python activity = actor = 'andrei.avk' assignee = 'docs@python' closed = False closed_date = None closer = None components = ['Documentation'] creation = creator = 'jessevsilverman' dependencies = [] files = [] hgrepos = [] issue_num = 43034 keywords = [] message_count = 5.0 messages = ['385746', '385840', '385932', '385952', '397168'] nosy_count = 5.0 nosy_names = ['rhettinger', 'terry.reedy', 'docs@python', 'andrei.avk', 'jessevsilverman'] pr_nums = [] priority = 'normal' resolution = None stage = None status = 'open' superseder = None type = None url = 'https://bugs.python.org/issue43034' versions = ['Python 3.9'] ```

05661d66-873f-4b42-8577-c94bd66ee9a6 commented 3 years ago

I had never worked thru the Python tutorial, it's kind of awesome.

I noticed multiple independent presenters incorrectly describe the behavior of floor division when the signs of the operands don't match. Not just sloppy ones, some who are usually pretty careful -- people forget. I found it odd.

Today I read: https://docs.python.org/3.9/tutorial/introduction.html#using-python-as-a-calculator 'Division (/) always returns a float. To do floor division and get an integer result (discarding any fractional result) you can use the // operator; to calculate the remainder you can use %:'

I know what they mean (there will never be a non-zero fractional component in the result) however, stating that it "discards any fraction result" explicitly suggests that it will round towards zero for all results. The name of the operator tells us the true story, as does a test, it rounds towards negative infinity for all results.

Hopefully all the people using Python to treat cancer, fly to Mars and run power plants know what the behavior is. However, anecdotally, I have seen evidence that generally cautious, fairly-detail oriented programmers seem to forget the details of the behavior, this is one place in the docs from which many people first learn about the floor division operator and this page would lead me to believe it operates differently than it does in reality.

If the words right there don't get changed, or the example of -10/3 doesn't get added, would this be a good excuse for a third footnote? I would actually wish for both the wording to be changed and to show an example like -10 / 3, tho admittedly I came from an Engineering background so I am always worried someone's going to blow up somewhere...

Deepest regards for everyone who gets to regularly close the complaints about floor division working as designed and documented -- but not quite documented on this page which more people may read than others covering the operator.

rhettinger commented 3 years ago

The first section of the tutorial isn't the right place to go into these details. The point of the section is to have a basic introduction to the interactive prompt. It is intensionally gentle and lightweight.

It isn't the purpose of the tutorial to document complete semantics and corner cases. We leave that for the language reference or for coverage of specific types in the library reference. See footnote (1) in the operator table at https://docs.python.org/3/library/stdtypes.html#numeric-types-int-float-complex .

terryjreedy commented 3 years ago

-17/3 = -5.666666666666667 = -6.0 + .333333333333333. It is the latter fraction that gets discarded.

However, this is a frequent source of confusion. How about adding

>>> -17 // 3
-6
>>> -17 % 3
1
>>> -6 * 3 + 1
-17

to illustrate what we mean, without footnote or additional text.

05661d66-873f-4b42-8577-c94bd66ee9a6 commented 3 years ago

I understand and agree with both comments. I will confirm that a substantial number of people think -17 // 3 yields -5.0, so when I saw this I wondered if it reinforced that common misconception.

I was curious enough to not just confirm in the actual docs not only that -17 // 3 == -6.0 but learned why it does so.

I would be happy to see any of Terry's three suggestions added, with the first one adding the most bang for the buck (if someone is surprised to see -6.0 there, they can go look up why).

akulakov commented 3 years ago

Possibly:

5//2 # 2 -5//2 # -3

Would be easier to understand.

ethanfurman commented 2 years ago

I like @akulakov 's suggestion, with a comment to follow the footnote for details on the negative example.