GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — bpo-37819: Add Fraction.as_integer_ratio() by rhettinger · Pull Request #15212 · python/cpython

Conversation

@rhettinger

@rhettinger rhettinger commented Aug 11, 2019 •
edited by bedevere-bot
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

https://bugs.python.org/issue37819

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@rhettinger
bpo-37819: Add Fraction.as_integer_ratio()
3ca5886
@rhettinger rhettinger added type-feature A feature request or enhancement needs backport to 3.8 labels Aug 11, 2019
@rhettinger
rhettinger requested review from gvanrossum and mdickinson August 11, 2019 17:38
@the-knights-who-say-ni the-knights-who-say-ni added the CLA signed label Aug 11, 2019
@bedevere-bot bedevere-bot added the awaiting core review label Aug 11, 2019
gvanrossum
gvanrossum reviewed Aug 11, 2019
View reviewed changes

@gvanrossum gvanrossum left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would change "exactly equal" to just "equal" -- there's nothing to be gained by adding "exactly".

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Doc/library/fractions.rst Outdated

.. method:: as_integer_ratio()

Return a tuple of integers, whose ratio is exactly equal

@gvanrossum gvanrossum Aug 11, 2019

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop "exactly"

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@aeros aeros Aug 11, 2019

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gvanrossum To some degree, I think that mentioning "exactly" might help readers to understand the advantage of using an integer ratio when they need more precision. However, there might be a better way to mention this.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@rhettinger rhettinger Aug 11, 2019

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I'll drop this "exactly". The wording was take from the docstring for float.as_integer_ratio() but in makes a lot more sense.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Lib/fractions.py Outdated
def as_integer_ratio(self):
"""Return integer ratio.

Return a pair of integers, whose ratio is exactly equal to the original

@gvanrossum gvanrossum Aug 11, 2019

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@rhettinger rhettinger Aug 11, 2019

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
aeros
aeros reviewed Aug 11, 2019
View reviewed changes

@aeros aeros left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR @rhettinger.

I had some minor suggestions:

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Misc/NEWS.d/next/Library/2019-08-11-10-34-19.bpo-37819.LVJls-.rst
@@ -0,0 +1,2 @@
Add Fraction.as_integer_ratio() to match the corresponding methods in bool,

@aeros aeros Aug 11, 2019

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be helpful to provide a link to the method using inline markup? This would allow readers to easily find the documentation for the new method.

Also regarding this line, as far as I'm aware, there's not a bool.as_integer_ratio() method. To confirm this, I used git grep to search the documentation:

image

As expected, it returned the methods for decimal, int, and float but nothing for bool.

Suggested change
Add Fraction.as_integer_ratio() to match the corresponding methods in bool,
Add :meth:`Fraction.as_integer_ratio` to match the corresponding methods in

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@rhettinger rhettinger Aug 11, 2019

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't have to provide cross-links from Misc/NEWS. It is okay for entries there to be plain text.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@aeros aeros Aug 11, 2019 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rhettinger Oh yeah it's okay either way, but since the Misc/NEWS entries support reST and Sphinx I think it's helpful to include links to functions, methods, or classes that were modified in functionality or documentation. Usually the news entries are very brief, so if a curious reader wants to get more information they can simply use the link.

To those of us who are familiar with the structuring of the documentation, it's usually easy to find the relevant sections. But, some less familiar or newer readers might have trouble doing so, especially if they use an external search engine (which frequently will lead them to the 2.7 docs or an incorrect page).

It's more a convenience/QoL addition for the readers than anything, and I don't think it hurts the readability or takes much effort from our end. I might start a thread over on python-dev to see what the others think. Not at all for this PR specifically, but just in general.

Edit: Just realized that I can't start threads on the Python-Dev list. I'll open a new topic on Discuss instead, let me know if you'd like a link to the thread. Never mind, I'm able to create a new thread on the ML. I'll do so later tonight, in the meantime here's the discuss post: https://discuss.python.org/t/should-news-entries-contain-documentation-links/2127

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@aeros aeros Aug 11, 2019 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, what was the conclusion on bool being in the news entry? From my understanding, there is not a bool.as_integer_ratio() method.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@methane methane Aug 19, 2019

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aeros167 Have you validated your understanding?

From my understanding, bool inherits from int. If int has as_integer_ratio(), bool should have it too.

$ ./python
Python 3.9.0a0 (heads/master:e95ac20103, Jul 24 2019, 21:48:01)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> i = 42
>>> i.as_integer_ratio()
(42, 1)
>>> True.as_integer_ratio()
(1, 1)

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

aeros reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

@aeros aeros Aug 19, 2019

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@methane Thanks for the explanation!

At first this didn't make sense to me, but then I remembered that:

>>> int(True)
1
>>> int(False)
0
>>> True == 1
True
>>> False == 0
True

So it makes sense that the boolean values would also have the int methods, since they are effectively specialized ints. I was just confused at first since I could not find an explicit mention of bool.is_integer_ratio() in the docs, but I suppose it doesn't need to be mentioned since as you said, bool inherits from int.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Lib/fractions.py Outdated
def as_integer_ratio(self):
"""Return integer ratio.

Return a pair of integers, whose ratio is exactly equal to the original

@aeros aeros Aug 11, 2019 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be potentially helpful to readers to specify in the doc-string that the integer pair is returned as a tuple? This is not uncommonly done, but I think it's worthwhile to specifically mention this:

Suggested change
Return a pair of integers, whose ratio is exactly equal to the original
Return a tuple containing two integers, whose ratio is exactly equal to the original

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@rhettinger rhettinger Aug 11, 2019

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

aeros reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
Comment thread Lib/test/test_fractions.py
ValueError, "cannot convert NaN to integer ratio",
F.from_decimal, Decimal("snan"))

def test_as_integer_ratio(self):

@aeros aeros Aug 11, 2019 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a comparison of these tests to the existing ones, and noticed that test_decimal.py contains coverage for attempting to convert inf (inf = 1e1000), -inf, nan (nan = inf - inf), and an invalid string to an integer ratio:

    def test_as_integer_ratio(self):
        Decimal = self.decimal.Decimal

        # exceptional cases
        self.assertRaises(OverflowError,
                          Decimal.as_integer_ratio, Decimal('inf'))
        self.assertRaises(OverflowError,
                          Decimal.as_integer_ratio, Decimal('-inf'))
        self.assertRaises(ValueError,
                          Decimal.as_integer_ratio, Decimal('-nan'))
        self.assertRaises(ValueError,
                          Decimal.as_integer_ratio, Decimal('snan123'))

For the sake of consistency, should we include that here as well? I'm not certain that it's necessary, but I figured it was worth mentioning.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@rhettinger rhettinger Aug 11, 2019

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need. Fractions don't have that concept.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

aeros reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
@aeros

aeros commented Aug 11, 2019 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

I didn't include this in my review since it's not directly related to the PR, but I noticed some minor inconsistencies in the tests between the different versions of *.as_integer_ratio(). For example, the test function in float was called test_floatasratio() instead of test_as_integer_ratio() (which is used by decimal.py and now in this PR), and it also seemed to be missing the test that decimal uses to ensure a ValueError is raised when attempting to use an invalid string:

       self.assertRaises(ValueError,
                          Decimal.as_integer_ratio, Decimal('snan123'))

Also, as far as I can tell, there's no test coverage at all for the int version of the method. Should I open a new issue for this?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

rhettinger added 2 commits August 11, 2019 14:04
@rhettinger
Address reviewer comments
b521c42
@rhettinger
Minor word-smithing.
b55d9d8
* The other methods spell fraction with a capital F.
* The word "original" doesn't make sense because the original
  fraction is reduced:
     Fraction(4, 6).as_integer_ratio() |-> (2, 3)
@rhettinger
rhettinger merged commit f03b4c8 into python:master Aug 11, 2019
@rhettinger
rhettinger deleted the fraction_ratio branch August 11, 2019 21:41
@miss-islington

miss-islington commented Aug 11, 2019

Copy link
Copy Markdown
Contributor

Thanks @rhettinger for the PR 🌮🎉.. I'm working now to backport this PR to: 3.8.
🐍🍒⛏🤖

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-bot bedevere-bot removed the awaiting core review label Aug 11, 2019
miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Aug 11, 2019
@rhettinger @miss-islington
bpo-37819: Add Fraction.as_integer_ratio() (pythonGH-15212)
8a97a86
(cherry picked from commit f03b4c8)

Co-authored-by: Raymond Hettinger <[email protected]>
@bedevere-bot

bedevere-bot commented Aug 11, 2019

Copy link
Copy Markdown

GH-15215 is a backport of this pull request to the 3.8 branch.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-bot bedevere-bot removed the needs backport to 3.8 label Aug 11, 2019
rhettinger added a commit that referenced this pull request Aug 11, 2019
@miss-islington @rhettinger
bpo-37819: Add Fraction.as_integer_ratio() (GH-15212) (GH-15215)
5ba1cb0
(cherry picked from commit f03b4c8)

Co-authored-by: Raymond Hettinger <[email protected]>
@jdemeyer

jdemeyer commented Aug 13, 2019

Copy link
Copy Markdown
Contributor

Should this as_integer_ratio instead be moved to the numbers.Rational base class? The implementation already makes sense on that level, so it seems more natural to do it that way.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@aeros aeros mentioned this pull request Aug 19, 2019
bpo-37884: Optimize Fraction() and statistics.mean() #15329
Closed
lisroach pushed a commit to lisroach/cpython that referenced this pull request Sep 10, 2019
@rhettinger @lisroach
bpo-37819: Add Fraction.as_integer_ratio() (pythonGH-15212)
d738b5c
DinoV pushed a commit to DinoV/cpython that referenced this pull request Jan 14, 2020
@rhettinger @DinoV
bpo-37819: Add Fraction.as_integer_ratio() (pythonGH-15212)
476a8a4
websurfer5 pushed a commit to websurfer5/cpython that referenced this pull request Jul 20, 2020
@rhettinger @websurfer5
bpo-37819: Add Fraction.as_integer_ratio() (pythonGH-15212)
91441a2
@skirpichev skirpichev mentioned this pull request Feb 12, 2023
gh-101825: mention, that as_integer_ratio() output is normalized #101843
Merged
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@methane methane methane left review comments
@gvanrossum gvanrossum gvanrossum left review comments
@mdickinson mdickinson Awaiting requested review from mdickinson
+1 more reviewer
@aeros aeros aeros left review comments
Reviewers whose approvals may not affect merge requirements

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

type-feature A feature request or enhancement

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

8 participants

@rhettinger @aeros @miss-islington @bedevere-bot @jdemeyer @methane @gvanrossum @the-knights-who-say-ni
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.