• built-in pow() vs. math.pow()

    From Andreas Eisele@21:1/5 to All on Thu Mar 30 02:15:51 2023
    I sometimes make use of the fact that the built-in pow() function has an optional third argument for modulo calculation, which is handy when dealing with tasks from number theory, very large numbers, problems from Project Euler, etc. I was unpleasantly
    surprised that math.pow() does not have this feature, hence "from math import *" overwrites the built-in pow() function with a function that lacks functionality. I am wondering for the rationale of this. Does math.pow() do anything that the built-in
    version can not do, and if not, why is it even there?
    Thanks in advance for any enlightening comment on this.
    Best regards, Andreas

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stefan Ram@21:1/5 to Andreas Eisele on Thu Mar 30 09:58:36 2023
    Andreas Eisele <andreas.eisele@gmail.com> writes:
    hence "from math import *" overwrites the built-in pow()
    function with a function that lacks functionality.

    You can reimport the built-in "pow" after "from math import *":

    main.py

    from math import *

    print( pow.__doc__ )

    print( '\n~~\n' )

    from builtins import pow

    print( pow.__doc__ )

    sys.stdout

    Return x**y (x to the power of y).

    ~~

    Equivalent to base**exp with 2 arguments or base**exp % mod
    with 3 arguments

    Some types, such as ints, are able to use a more efficient
    algorithm when
    invoked using the three argument form.

    .

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stefan Ram@21:1/5 to Andreas Eisele on Thu Mar 30 11:37:56 2023
    Andreas Eisele <andreas.eisele@gmail.com> writes:
    why is it even there?

    The documentation of the standard module "math" says:

    |This module provides access to the mathematical functions
    |defined by the C standard.

    . The "pow" function of the module "builtins" is not
    defined by the C standard, so it's not in "math".

    The "mathematical functions" defined by C's header
    <math.h> are about floating point numbers.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Barry Scott@21:1/5 to All on Thu Mar 30 18:11:31 2023
    On 30 Mar 2023, at 10:15, Andreas Eisele <andreas.eisele@gmail.com> wrote:

    I sometimes make use of the fact that the built-in pow() function has an optional third argument for modulo calculation, which is handy when dealing with tasks from number theory, very large numbers, problems from Project Euler, etc. I was unpleasantly
    surprised that math.pow() does not have this feature, hence "from math import *" overwrites the built-in pow() function with a function that lacks functionality. I am wondering for the rationale of this. Does math.pow() do anything that the built-in
    version can not do, and if not, why is it even there?

    Maybe math.pow() aways using IEEE 754(?) float point via the C runtime math routines.
    pow() will give int answer if called with int args.

    Barry


    Thanks in advance for any enlightening comment on this.
    Best regards, Andreas
    --
    https://mail.python.org/mailman/listinfo/python-list


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Roel Schroeven@21:1/5 to Andreas Eisele on Thu Mar 30 19:22:53 2023
    Andreas Eisele schreef op 30/03/2023 om 11:15:
    I sometimes make use of the fact that the built-in pow() function has an optional third argument for modulo calculation, which is handy when dealing with tasks from number theory, very large numbers, problems from Project Euler, etc. I was unpleasantly
    surprised that math.pow() does not have this feature, hence "from math import *" overwrites the built-in pow() function with a function that lacks functionality. I am wondering for the rationale of this. Does math.pow() do anything that the built-in
    version can not do, and if not, why is it even there?
    According to the docs, "Unlike the built-in ** operator, math.pow()
    converts both its arguments to type float. Use ** or the built-in pow() function for computing exact integer powers." I think that means that math.pow() is more meant to work with floats, while the built-in is more
    meant for integers (even though the built-in works with floats just fine).

    In any case, I would strongly advocate against "from math import *" (not
    just for math but for any module really). One of the reasons is the
    potential for name conflicts, which is exactly what you experience here.

    Either import the things you need explicitly: "from math import sin,
    cos, exp" (for example).
    Or a plain import: "import math" combined with "math.sin", "math.cos".
    Or use an abbreviation: "import math as m" combined with "m.sin", "m.cos".

    --
    "There is no cause so noble that it will not attract fuggheads."
    -- Larry Niven

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Passin@21:1/5 to Andreas Eisele on Thu Mar 30 13:25:30 2023
    On 3/30/2023 5:15 AM, Andreas Eisele wrote:
    I sometimes make use of the fact that the built-in pow() function has an optional third argument for modulo calculation, which is handy when dealing with tasks from number theory, very large numbers, problems from Project Euler, etc. I was unpleasantly
    surprised that math.pow() does not have this feature, hence "from math import *" overwrites the built-in pow() function with a function that lacks functionality. I am wondering for the rationale of this. Does math.pow() do anything that the built-in
    version can not do, and if not, why is it even there?

    Not an answer to your question, but it's better not to use "import *".
    It's usually better to import just the names you actually need.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Barry Scott@21:1/5 to All on Thu Mar 30 18:15:57 2023
    On 30 Mar 2023, at 18:11, Barry Scott <barry@barrys-emacs.org> wrote:



    On 30 Mar 2023, at 10:15, Andreas Eisele <andreas.eisele@gmail.com> wrote: >>
    I sometimes make use of the fact that the built-in pow() function has an optional third argument for modulo calculation, which is handy when dealing with tasks from number theory, very large numbers, problems from Project Euler, etc. I was
    unpleasantly surprised that math.pow() does not have this feature, hence "from math import *" overwrites the built-in pow() function with a function that lacks functionality. I am wondering for the rationale of this. Does math.pow() do anything that the
    built-in version can not do, and if not, why is it even there?

    Maybe math.pow() aways using IEEE 754(?) float point via the C runtime math routines.
    pow() will give int answer if called with int args.

    And the C version of pow only supports 2 arg call.

    SYNOPSIS
    #include <math.h>

    double
    pow(double x, double y);

    long double
    powl(long double x, long double y);

    float
    powf(float x, float y);



    Barry


    Thanks in advance for any enlightening comment on this.
    Best regards, Andreas
    --
    https://mail.python.org/mailman/listinfo/python-list


    --
    https://mail.python.org/mailman/listinfo/python-list


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Grant Edwards@21:1/5 to Thomas Passin on Thu Mar 30 12:15:03 2023
    On 2023-03-30, Thomas Passin <list1@tompassin.net> wrote:
    On 3/30/2023 5:15 AM, Andreas Eisele wrote:

    [...] I was unpleasantly surprised that math.pow() does not have
    this feature, hence "from math import *" overwrites the built-in
    pow() function with a function that lacks functionality. [...]

    Not an answer to your question, but it's better not to use "import *".
    It's usually better to import just the names you actually need.

    Or to imporot math and then use math.pow().

    Unfortunately, the official Python documentation always seems to
    assume you do "from <whatever> import *". I think that leads people to
    believe it's a good practice when, in fact, it's a frequent source of
    trouble as the OP found out.

    --
    Grant

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dennis Lee Bieber@21:1/5 to All on Thu Mar 30 15:49:54 2023
    On Thu, 30 Mar 2023 19:22:53 +0200, Roel Schroeven <roel@roelschroeven.net> declaimed the following:

    Either import the things you need explicitly: "from math import sin,
    cos, exp" (for example).
    Or a plain import: "import math" combined with "math.sin", "math.cos".
    Or use an abbreviation: "import math as m" combined with "m.sin", "m.cos".

    Or, for this particular example of not wanting math.pow...

    from math import *
    pow(3, 4)
    81.0
    del pow
    pow(3, 4)
    81


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From avi.e.gross@gmail.com@21:1/5 to All on Thu Mar 30 17:02:18 2023
    Some questions are more reasonable than others.

    If the version of a function used in a package were IDENTICAL to the
    built-in, then why have it?

    There are many possible reasons a package may tune a function for their own preferences or re-use a name that ends up blocking the view of another name.

    The bottom line is if you do not want the other one, then don't ask for it
    by not importing the entire module into your namespace or by explicitly
    asking for the base function in the ways python provides.

    Others have replied about differences in various implementations of pow()
    and reiterated my point above that if you want a specific function instance,
    it is your responsibility to make sure you get it.

    One method I would mention that I have not seen is to copy pow() to your own name before importing other things. Something like:

    pow3 = pow
    import ...

    Then use the new name.

    Or import all of math (despite advice not to) and then make pow3 a synonym
    for the base version.

    Most people most of the time will want a small and fast function that does
    what they asked for and does not waste time looking for an optional third argument and doing something additional. Would you be satisfied if
    math::pow() simply checked for a third argument and turned around and called base::pow() to handle it?

    A deeper question I can appreciate is wondering if it is a bug or feature
    that python (and many other languages) allow results where you can hide a variable or function name. I call it a feature. As with all such variables, scope rules and other such things apply and make the language powerful and sometimes a tad dangerous.



    -----Original Message-----
    From: Python-list <python-list-bounces+avi.e.gross=gmail.com@python.org> On Behalf Of Andreas Eisele
    Sent: Thursday, March 30, 2023 5:16 AM
    To: python-list@python.org
    Subject: built-in pow() vs. math.pow()

    I sometimes make use of the fact that the built-in pow() function has an optional third argument for modulo calculation, which is handy when dealing with tasks from number theory, very large numbers, problems from Project
    Euler, etc. I was unpleasantly surprised that math.pow() does not have this feature, hence "from math import *" overwrites the built-in pow() function
    with a function that lacks functionality. I am wondering for the rationale
    of this. Does math.pow() do anything that the built-in version can not do,
    and if not, why is it even there?
    Thanks in advance for any enlightening comment on this.
    Best regards, Andreas
    --
    https://mail.python.org/mailman/listinfo/python-list

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Oscar Benjamin@21:1/5 to Andreas Eisele on Thu Mar 30 22:11:33 2023
    On Thu, 30 Mar 2023 at 17:31, Andreas Eisele <andreas.eisele@gmail.com> wrote:

    I sometimes make use of the fact that the built-in pow() function has an optional third argument for modulo calculation, which is handy when dealing with tasks from number theory, very large numbers, problems from Project Euler, etc. I was unpleasantly
    surprised that math.pow() does not have this feature, hence "from math import *" overwrites the built-in pow() function with a function that lacks functionality. I am wondering for the rationale of this. Does math.pow() do anything that the built-in
    version can not do, and if not, why is it even there?

    It is useful for when you want the pure floating point power which has
    an approximately fixed computational cost (unlike integer powers).
    Perhaps it would have been better if it was named fpow similar to fsum
    vs sum.

    --
    Oscar

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Chris Angelico@21:1/5 to Oscar Benjamin on Fri Mar 31 08:27:39 2023
    On Fri, 31 Mar 2023 at 08:13, Oscar Benjamin <oscar.j.benjamin@gmail.com> wrote:

    On Thu, 30 Mar 2023 at 17:31, Andreas Eisele <andreas.eisele@gmail.com> wrote:

    I sometimes make use of the fact that the built-in pow() function has an optional third argument for modulo calculation, which is handy when dealing with tasks from number theory, very large numbers, problems from Project Euler, etc. I was
    unpleasantly surprised that math.pow() does not have this feature, hence "from math import *" overwrites the built-in pow() function with a function that lacks functionality. I am wondering for the rationale of this. Does math.pow() do anything that the
    built-in version can not do, and if not, why is it even there?

    It is useful for when you want the pure floating point power which has
    an approximately fixed computational cost (unlike integer powers).
    Perhaps it would have been better if it was named fpow similar to fsum
    vs sum.


    It's called math.pow. That on its own should be a strong indication
    that it's designed to work with floats.

    ChrisA

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Barry@21:1/5 to All on Fri Mar 31 07:39:25 2023
    On 30 Mar 2023, at 22:30, Chris Angelico <rosuav@gmail.com> wrote:

    On Fri, 31 Mar 2023 at 08:13, Oscar Benjamin <oscar.j.benjamin@gmail.com> wrote:

    On Thu, 30 Mar 2023 at 17:31, Andreas Eisele <andreas.eisele@gmail.com> wrote:

    I sometimes make use of the fact that the built-in pow() function has an optional third argument for modulo calculation, which is handy when dealing with tasks from number theory, very large numbers, problems from Project Euler, etc. I was
    unpleasantly surprised that math.pow() does not have this feature, hence "from math import *" overwrites the built-in pow() function with a function that lacks functionality. I am wondering for the rationale of this. Does math.pow() do anything that the
    built-in version can not do, and if not, why is it even there?

    It is useful for when you want the pure floating point power which has
    an approximately fixed computational cost (unlike integer powers).
    Perhaps it would have been better if it was named fpow similar to fsum
    vs sum.


    It's called math.pow. That on its own should be a strong indication
    that it's designed to work with floats.

    So long as you know that the math module is provided to give access the C math.h functions.

    Barry


    ChrisA
    --
    https://mail.python.org/mailman/listinfo/python-list


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Peter J. Holzer@21:1/5 to Barry on Fri Mar 31 21:21:37 2023
    On 2023-03-31 07:39:25 +0100, Barry wrote:
    On 30 Mar 2023, at 22:30, Chris Angelico <rosuav@gmail.com> wrote:
    It's called math.pow. That on its own should be a strong indication
    that it's designed to work with floats.

    So long as you know that the math module is provided to give access
    the C math.h functions.


    Well, that's the first line in the docs:

    | This module provides access to the mathematical functions defined by
    | the C standard.

    Of course a Python programmer may not necessarily know what mathematical functions the C standard defines or even what C is.

    hp

    --
    _ | Peter J. Holzer | Story must make more sense than reality.
    |_|_) | |
    | | | hjp@hjp.at | -- Charles Stross, "Creative writing
    __/ | http://www.hjp.at/ | challenge!"

    -----BEGIN PGP SIGNATURE-----

    iQIzBAABCgAdFiEETtJbRjyPwVTYGJ5k8g5IURL+KF0FAmQnMrwACgkQ8g5IURL+ KF00Gw//Zm8Gy/81nAwlxllO6qJb0TkPuX1t0AuwEQt9AhdnOVy5BmX7/zbDxLYB Mqn2oqXasas5QsQnkccDQ22kvnOd0gzj/UOXVTaItynaM7mUfWN3ZyIj/F3zqK5K Cwk3FZeCpAQJQ33Sw2VYAa/7uPTGt4VLhrSnOwD27FRctq1jsWNvFI9uxjulFEm+ FSE/kC1cOg7r5oAqIQjH2x+Revbe6PVjo8H4UTL4RI9KYmNrMKLxTFZg97d/6L68 7cU+oOeZc83bVsrN8HO1y9DBv5M0oxrPdaDDUuRhMcgnbtRLMr0cNojb0nse0nAr mVeTCTVvPaWAy//j+DEVcbxKd6lbvyx+Id8AV02BH6C6UP/UB2hSDVJNe4aAw5E4 4bdIQj5IlvMLDrp+G6fN8l9GaGo6QjR4silMmUjmZq9FRe3t+RW+LHC+uJamf9ae Jko3VQWZom0xpkiarlr+B9bHkCPH5/HHBqjAp//BMjV/7NTy5rQlMNRObwi57rE2 4g+PDjgkRz45qBjQSnLrAtJMWu7v+9OhS9wLiG8xVFUi0KslTf8UhZxwo8dKmi55 b78+AacOpVeP58yMtJdl0xQNw+vMASRf9f1bYmrfGzsCJTYUzAH1vtiwLm43pYuS pyeLeWXBYZlSU5fcWxyRf5h1t00vlT0XXtljhSO
  • From Oscar Benjamin@21:1/5 to Peter J. Holzer on Sat Apr 1 01:50:54 2023
    On Fri, 31 Mar 2023 at 20:24, Peter J. Holzer <hjp-python@hjp.at> wrote:

    On 2023-03-31 07:39:25 +0100, Barry wrote:
    On 30 Mar 2023, at 22:30, Chris Angelico <rosuav@gmail.com> wrote:
    It's called math.pow. That on its own should be a strong indication
    that it's designed to work with floats.

    So long as you know that the math module is provided to give access
    the C math.h functions.


    Well, that's the first line in the docs:

    | This module provides access to the mathematical functions defined by
    | the C standard.

    Of course a Python programmer may not necessarily know what mathematical functions the C standard defines or even what C is.

    Or they might know that and might also realise that it is not really
    an accurate description of Python's math module e.g. math.factorial,
    math.gcd, math.isqrt which are all integer functions. How many of
    these 60 names are defined by the C standard:

    In [6]: dir(math)
    Out[6]:
    ['__doc__',
    '__loader__',
    '__name__',
    '__package__',
    '__spec__',
    'acos',
    'acosh',
    'asin',
    'asinh',
    'atan',
    'atan2',
    'atanh',
    'ceil',
    'comb',
    'copysign',
    'cos',
    'cosh',
    'degrees',
    'dist',
    'e',
    'erf',
    'erfc',
    'exp',
    'expm1',
    'fabs',
    'factorial',
    'floor',
    'fmod',
    'frexp',
    'fsum',
    'gamma',
    'gcd',
    'hypot',
    'inf',
    'isclose',
    'isfinite',
    'isinf',
    'isnan',
    'isqrt',
    'ldexp',
    'lgamma',
    'log',
    'log10',
    'log1p',
    'log2',
    'modf',
    'nan',
    'perm',
    'pi',
    'pow',
    'prod',
    'radians',
    'remainder',
    'sin',
    'sinh',
    'sqrt',
    'tan',
    'tanh',
    'tau',
    'trunc']

    --
    Oscar

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Andreas Eisele@21:1/5 to Andreas Eisele on Sat Apr 1 08:16:46 2023
    Andreas Eisele schrieb am Donnerstag, 30. März 2023 um 11:16:02 UTC+2:
    I sometimes make use of the fact that the built-in pow() function has an optional third argument for modulo calculation, which is handy when dealing with tasks from number theory, very large numbers, problems from Project Euler, etc. I was unpleasantly
    surprised that math.pow() does not have this feature, hence "from math import *" overwrites the built-in pow() function with a function that lacks functionality. I am wondering for the rationale of this. Does math.pow() do anything that the built-in
    version can not do, and if not, why is it even there?
    Thanks in advance for any enlightening comment on this.
    Best regards, Andreas

    Thanks a lot to all of you for the insightful replies!
    I now understand why math.pow() behaves the way it does and whoever tells me I should have read the doc of the math module before using it is 100% on point.
    BTW, there is another difference: built-in pow() deals with complex arguments, while functions in math won't accept them at all.
    I also agree with the warning that importing * from any module is generally a bad idea, and I normally would not do it. But here I had written a little tool that evaluates an expression given on the command line, and in this case having math functions
    available without further ado is very convenient, so it seemed appropriate to make an exeption to this rule.
    I ended up assigning the built-in pow function to a different name before importing the math module, which is a good way to keep both variants accessible.
    Best regards, and thanks again, Andreas

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From 2QdxY4RzWzUUiLuE@potatochowder.com@21:1/5 to Andreas Eisele on Mon Apr 3 15:49:45 2023
    On 2023-04-01 at 08:16:46 -0700,
    Andreas Eisele <andreas.eisele@gmail.com> wrote:

    BTW, there is another difference: built-in pow() deals with complex arguments, while functions in math won't accept them at all.

    See also <https://docs.python.org/3/library/cmath.html>.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)