Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #52628 > unrolled thread

Importing variables non-deterministic?

Started bytmellman@googlemail.com
First post2013-08-17 07:25 -0700
Last post2013-08-20 11:14 +1000
Articles 20 on this page of 27 — 9 participants

Back to article view | Back to comp.lang.python


Contents

  Importing variables non-deterministic? tmellman@googlemail.com - 2013-08-17 07:25 -0700
    Re: Importing variables non-deterministic? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-08-17 15:01 +0000
      Re: Importing variables non-deterministic? Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2013-08-19 09:14 +0200
      Re: Importing variables non-deterministic? Dave Angel <davea@davea.name> - 2013-08-19 07:45 +0000
      Re: Importing variables non-deterministic? Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2013-08-19 10:16 +0200
        Re: Importing variables non-deterministic? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-08-19 16:57 +0000
          Re: Importing variables non-deterministic? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-08-19 17:16 +0000
            Re: Importing variables non-deterministic? Chris Angelico <rosuav@gmail.com> - 2013-08-19 18:25 +0100
          Re: Importing variables non-deterministic? Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2013-08-19 19:40 +0200
      Re: Importing variables non-deterministic? Chris Angelico <rosuav@gmail.com> - 2013-08-19 09:32 +0100
        Re: Importing variables non-deterministic? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-08-19 17:05 +0000
          Re: Importing variables non-deterministic? Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2013-08-19 22:34 +0200
            Re: Importing variables non-deterministic? Steven D'Aprano <steve@pearwood.info> - 2013-08-20 05:48 +0000
              Re: Importing variables non-deterministic? wxjmfauth@gmail.com - 2013-08-19 23:40 -0700
              Re: Importing variables non-deterministic? Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2013-08-20 08:55 +0200
                Re: Importing variables non-deterministic? wxjmfauth@gmail.com - 2013-08-20 00:31 -0700
                  Re: Importing variables non-deterministic? Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2013-08-20 09:55 +0200
                    Re: Importing variables non-deterministic? wxjmfauth@gmail.com - 2013-08-20 02:15 -0700
      Re: Importing variables non-deterministic? Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2013-08-19 11:03 +0200
      Re: Importing variables non-deterministic? Chris Angelico <rosuav@gmail.com> - 2013-08-19 10:18 +0100
      Re: Importing variables non-deterministic? Peter Otten <__peter__@web.de> - 2013-08-19 11:49 +0200
      Re: Importing variables non-deterministic? Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2013-08-19 13:54 +0200
      Re: Importing variables non-deterministic? Dave Angel <davea@davea.name> - 2013-08-19 12:33 +0000
      Re: Importing variables non-deterministic? Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2013-08-19 16:55 +0200
      Re: Importing variables non-deterministic? Chris Angelico <rosuav@gmail.com> - 2013-08-19 16:04 +0100
      Re: Importing variables non-deterministic? Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2013-08-19 19:25 +0200
      Re: Importing variables non-deterministic? Ben Finney <ben+python@benfinney.id.au> - 2013-08-20 11:14 +1000

Page 1 of 2  [1] 2  Next page →


#52628 — Importing variables non-deterministic?

Fromtmellman@googlemail.com
Date2013-08-17 07:25 -0700
SubjectImporting variables non-deterministic?
Message-ID<a75383ec-b363-4ad4-9703-ca5d8ea614df@googlegroups.com>
  I have this file that has this:

    from struct_global import y
    from struct_global import x

  and this usage (a few lines later in a class method definition in the same file):

        if y == x:

  If I stop there in pdb, I can observe this:

    (Pdb) p x
    66
    (Pdb) p y
    -1
    (Pdb) from struct_global import y
    (Pdb) p y
    62

How did my first import get hidden?  Is there any way to see where a variable resolves to?

[toc] | [next] | [standalone]


#52630

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-08-17 15:01 +0000
Message-ID<520f9054$0$30000$c3e8da3$5496439d@news.astraweb.com>
In reply to#52628
On Sat, 17 Aug 2013 07:25:43 -0700, tmellman wrote:

> I have this file that has this:
> 
>     from struct_global import y
>     from struct_global import x

The import of x appears to be irrelevant, so I'll ignore it.

Here you import y from the struct_global module. This creates a new name 
y in the current module. y is bound to the same object that 
struct_global.y happens to be at the moment of the import, but y is *not* 
a reference to the *name* struct_global.y.

This means that the two names, "y in current module" and "y in 
struct_global module" point to the same object, but they aren't two 
aliases for the same variable. They are different variables that just 
happen to share the same value (an object).

If the object mutates (which ints cannot do), then both "y"s will see the 
change (naturally, since both refer to the same object). But if either 
name is rebound to a different object, the other name is unaffected.

We can see the same behaviour locally, without an import, by doing this:

py> x = [1]
py> y = x  # y is bound to the same object as x
py> print(y)
[1]
py> x.append(2)  # mutate x in place
py> print(y)
[1, 2]
py> x = [1, 2, 3]  # re-bind x to a new object
py> print(y)  # y still bound to the first object
[1, 2]


"from struct_globals import y" is a binding operation, no different from 
"y = something".


>   and this usage (a few lines later in a class method definition in the
>   same file):
> 
>         if y == x:
> 
>   If I stop there in pdb, I can observe this:
> 
>     (Pdb) p x
>     66
>     (Pdb) p y
>     -1
>     (Pdb) from struct_global import y
>     (Pdb) p y
>     62

And here you re-import the name "y" from struct_global. That rebinds the 
current module's "y" with whatever value struct_global.y has *now*, 
rather than a second (or a minute, or an hour) earlier when the first 
import took place. Obviously at some point between the first import and 
the second import, struct_global.y must have been reassigned from -1 to 
62.

This goes to show why global variables are considered harmful, and why 
clean, modern program design tries to reduce the use of them as much as 
possible. Global variables are too easily modified by, well, *anything*. 
The sort of behaviour you are seeing is sometimes called "action at a 
distance" -- something, anything, anywhere in your program, possibly 
buried deep, deep down inside some function you might never suspect, is 
changing the global variable.


> How did my first import get hidden?

You reassigned to it. "from struct_global import y" is practically 
syntactic sugar for this:

import struct_global
y = struct_global.y


> Is there any way to see where a
> variable resolves to?

You just did. You inspected the variable "y", and you saw that it is 
assigned the value 62.


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#52674

FromAntoon Pardon <antoon.pardon@rece.vub.ac.be>
Date2013-08-19 09:14 +0200
Message-ID<mailman.13.1376896513.19984.python-list@python.org>
In reply to#52630
Op 17-08-13 17:01, Steven D'Aprano schreef:
> 
> And here you re-import the name "y" from struct_global. That rebinds the 
> current module's "y" with whatever value struct_global.y has *now*, 
> rather than a second (or a minute, or an hour) earlier when the first 
> import took place. Obviously at some point between the first import and 
> the second import, struct_global.y must have been reassigned from -1 to 
> 62.
> 
> This goes to show why global variables are considered harmful, and why 
> clean, modern program design tries to reduce the use of them as much as 
> possible. Global variables are too easily modified by, well, *anything*. 
> The sort of behaviour you are seeing is sometimes called "action at a 
> distance" -- something, anything, anywhere in your program, possibly 
> buried deep, deep down inside some function you might never suspect, is 
> changing the global variable.

I think you are overstating your case. Classes and functions are
variables too and in general nobody seems to have a problem with them
being global.

-- 
Antoon Pardon

[toc] | [prev] | [next] | [standalone]


#52676

FromDave Angel <davea@davea.name>
Date2013-08-19 07:45 +0000
Message-ID<mailman.14.1376898318.19984.python-list@python.org>
In reply to#52630
Antoon Pardon wrote:

> Op 17-08-13 17:01, Steven D'Aprano schreef:
>> 
>> And here you re-import the name "y" from struct_global. That rebinds the 
>> current module's "y" with whatever value struct_global.y has *now*, 
>> rather than a second (or a minute, or an hour) earlier when the first 
>> import took place. Obviously at some point between the first import and 
>> the second import, struct_global.y must have been reassigned from -1 to 
>> 62.
>> 
>> This goes to show why global variables are considered harmful, and why 
>> clean, modern program design tries to reduce the use of them as much as 
>> possible. Global variables are too easily modified by, well, *anything*. 
>> The sort of behaviour you are seeing is sometimes called "action at a 
>> distance" -- something, anything, anywhere in your program, possibly 
>> buried deep, deep down inside some function you might never suspect, is 
>> changing the global variable.
>
> I think you are overstating your case. Classes and functions are
> variables too and in general nobody seems to have a problem with them
> being global.
>

It's global *variables* that are to be avoided.  constants like clsases
and functions are fine.  On the other hand, class attributes can be
variable, and thus are to be avoided when reasonable.

There *are* places where global variables make sense, such as for
caching, or counting.  But those are typically hidden, so they are
global in lifetime, but not in scope.

-- 
DaveA

[toc] | [prev] | [next] | [standalone]


#52677

FromAntoon Pardon <antoon.pardon@rece.vub.ac.be>
Date2013-08-19 10:16 +0200
Message-ID<mailman.16.1376900198.19984.python-list@python.org>
In reply to#52630
Op 19-08-13 09:45, Dave Angel schreef:
> Antoon Pardon wrote:
> 
>> Op 17-08-13 17:01, Steven D'Aprano schreef:
>>>
>>> And here you re-import the name "y" from struct_global. That rebinds the 
>>> current module's "y" with whatever value struct_global.y has *now*, 
>>> rather than a second (or a minute, or an hour) earlier when the first 
>>> import took place. Obviously at some point between the first import and 
>>> the second import, struct_global.y must have been reassigned from -1 to 
>>> 62.
>>>
>>> This goes to show why global variables are considered harmful, and why 
>>> clean, modern program design tries to reduce the use of them as much as 
>>> possible. Global variables are too easily modified by, well, *anything*. 
>>> The sort of behaviour you are seeing is sometimes called "action at a 
>>> distance" -- something, anything, anywhere in your program, possibly 
>>> buried deep, deep down inside some function you might never suspect, is 
>>> changing the global variable.
>>
>> I think you are overstating your case. Classes and functions are
>> variables too and in general nobody seems to have a problem with them
>> being global.
>>
> 
> It's global *variables* that are to be avoided.  constants like clsases
> and functions are fine.  On the other hand, class attributes can be
> variable, and thus are to be avoided when reasonable.

Python has no constants. Classes and functions can be changed just like
any other variable. I agree that classes and function are generally
meant to be constant, but often enought so are global int variables.

And some of those that do change, only do so in the initialisation phase
and should be considered constant for the rest of the program.

My point was that Steven has no way of knowing what exactly is going on
here and so shouldn't be making such a sweeping statement.

-- 
Antoon Pardon

[toc] | [prev] | [next] | [standalone]


#52694

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-08-19 16:57 +0000
Message-ID<52124e81$0$29986$c3e8da3$5496439d@news.astraweb.com>
In reply to#52677
On Mon, 19 Aug 2013 10:16:36 +0200, Antoon Pardon wrote:

> Op 19-08-13 09:45, Dave Angel schreef:
>> Antoon Pardon wrote:
>> 
>>> Op 17-08-13 17:01, Steven D'Aprano schreef:
>>>>
>>>> And here you re-import the name "y" from struct_global. That rebinds
>>>> the current module's "y" with whatever value struct_global.y has
>>>> *now*, rather than a second (or a minute, or an hour) earlier when
>>>> the first import took place. Obviously at some point between the
>>>> first import and the second import, struct_global.y must have been
>>>> reassigned from -1 to 62.
>>>>
>>>> This goes to show why global variables are considered harmful, and
>>>> why clean, modern program design tries to reduce the use of them as
>>>> much as possible. Global variables are too easily modified by, well,
>>>> *anything*. The sort of behaviour you are seeing is sometimes called
>>>> "action at a distance" -- something, anything, anywhere in your
>>>> program, possibly buried deep, deep down inside some function you
>>>> might never suspect, is changing the global variable.
>>>
>>> I think you are overstating your case. Classes and functions are
>>> variables too and in general nobody seems to have a problem with them
>>> being global.
>>>
>>>
>> It's global *variables* that are to be avoided.  constants like clsases
>> and functions are fine.  On the other hand, class attributes can be
>> variable, and thus are to be avoided when reasonable.
> 
> Python has no constants. Classes and functions can be changed just like
> any other variable. I agree that classes and function are generally
> meant to be constant, but often enought so are global int variables.

You are technically correct, but missing the point. If I wrote code that 
went around reassigning names from one function to another function, I 
would very likely soon work myself into a state of utter confusion:

def func(x):
    ...

# later
save_func = func
func = lambda x, y: do_stuff(x, 3*y)-4
result = something_that_calls_func()
func = save_func


Nasty, horrible code, yes? But it's nasty and horrible because "func" is 
bound to a function, it would be equally nasty and horrible if it was a 
data type (a string, a list, an int, a flag, ...) instead.

Since classes and functions are First Class objects in Python, naturally 
if you treat them as global *variables* rather than global *constants* 
you can end up with problems. The problem is not the global part alone. 
Global constants, or pseudo-constant-by-convention-only, are fine.


> And some of those that do change, only do so in the initialisation phase
> and should be considered constant for the rest of the program.
> 
> My point was that Steven has no way of knowing what exactly is going on
> here and so shouldn't be making such a sweeping statement.

On the contrary, I can read the Original Poster's description of the 
problem, and then use my ability to reason to deduce what the most likely 
explanation was.

Now of course I might be wrong. I don't claim infallibility or 
omniscience. But I'm not an idiot, and if the OP says that a global 
variable has one value at one time, and then some time later has a 
different value, there are two likely possibilities:

* The variable was changed by some other piece of code, i.e. it 
  actually was being used as a *global variable*.

* The OP is completely confused, and (inadvertently, we hope) 
  reporting things which are actually not true.

Much less likely:

* Despite 15+ years of experience with Python, and reading the
  documentation, I have failed to notice that, yes, the OP is 
  correct and importing variables is non-deterministic.

* There's a bug in Python.


Both of these are theoretically possible, but the chance of them is 
somewhere between Buckley's and None.


Of course, if you have an alternate explanation for the issue the OP 
reported, I would love to hear it. Maybe I have completely misunderstood 
the situation.



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#52698

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-08-19 17:16 +0000
Message-ID<521252f2$0$29986$c3e8da3$5496439d@news.astraweb.com>
In reply to#52694
On Mon, 19 Aug 2013 16:57:37 +0000, Steven D'Aprano wrote:

> def func(x):
>     ...
> 
> # later
> save_func = func
> func = lambda x, y: do_stuff(x, 3*y)-4 result =
> something_that_calls_func()
> func = save_func
> 
> 
> Nasty, horrible code, yes? But it's nasty and horrible because "func" is
> bound to a function, it would be equally nasty and horrible if it was a
> data type (a string, a list, an int, a flag, ...) instead.

Oops, I left out a word. It is NOT nasty and horrible specifically 
because "func" is bound to a function, it would be equally horrible if it 
were a data type.



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#52700

FromChris Angelico <rosuav@gmail.com>
Date2013-08-19 18:25 +0100
Message-ID<mailman.36.1376933125.19984.python-list@python.org>
In reply to#52698
On Mon, Aug 19, 2013 at 6:16 PM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> On Mon, 19 Aug 2013 16:57:37 +0000, Steven D'Aprano wrote:
>
>> def func(x):
>>     ...
>>
>> # later
>> save_func = func
>> func = lambda x, y: do_stuff(x, 3*y)-4 result =
>> something_that_calls_func()
>> func = save_func
>>
>>
>> Nasty, horrible code, yes? But it's nasty and horrible because "func" is
>> bound to a function, it would be equally nasty and horrible if it was a
>> data type (a string, a list, an int, a flag, ...) instead.
>
> Oops, I left out a word. It is NOT nasty and horrible specifically
> because "func" is bound to a function, it would be equally horrible if it
> were a data type.

I was having a little trouble parsing that! Thank you for the
Iolanthe-style[1] update.

ChrisA
[1] http://math.boisestate.edu/gas/iolanthe/web_op/iol23d.html

[toc] | [prev] | [next] | [standalone]


#52702

FromAntoon Pardon <antoon.pardon@rece.vub.ac.be>
Date2013-08-19 19:40 +0200
Message-ID<mailman.38.1376934119.19984.python-list@python.org>
In reply to#52694
Op 19-08-13 18:57, Steven D'Aprano schreef:
> On Mon, 19 Aug 2013 10:16:36 +0200, Antoon Pardon wrote:
>
>> Op 19-08-13 09:45, Dave Angel schreef:
>>> Antoon Pardon wrote:
>>>
>>>> Op 17-08-13 17:01, Steven D'Aprano schreef:
>>>>>
>>>>> And here you re-import the name "y" from struct_global. That rebinds
>>>>> the current module's "y" with whatever value struct_global.y has
>>>>> *now*, rather than a second (or a minute, or an hour) earlier when
>>>>> the first import took place. Obviously at some point between the
>>>>> first import and the second import, struct_global.y must have been
>>>>> reassigned from -1 to 62.
>>>>>
>>>>> This goes to show why global variables are considered harmful, and
>>>>> why clean, modern program design tries to reduce the use of them as
>>>>> much as possible. Global variables are too easily modified by, well,
>>>>> *anything*. The sort of behaviour you are seeing is sometimes called
>>>>> "action at a distance" -- something, anything, anywhere in your
>>>>> program, possibly buried deep, deep down inside some function you
>>>>> might never suspect, is changing the global variable.
>>>>
>>>> I think you are overstating your case. Classes and functions are
>>>> variables too and in general nobody seems to have a problem with them
>>>> being global.
>>>>
>>>>
>>> It's global *variables* that are to be avoided.  constants like clsases
>>> and functions are fine.  On the other hand, class attributes can be
>>> variable, and thus are to be avoided when reasonable.
>>
>> Python has no constants. Classes and functions can be changed just like
>> any other variable. I agree that classes and function are generally
>> meant to be constant, but often enought so are global int variables.
>
> You are technically correct, but missing the point. If I wrote code that
> went around reassigning names from one function to another function, I
> would very likely soon work myself into a state of utter confusion:
>
> def func(x):
>      ...
>
> # later
> save_func = func
> func = lambda x, y: do_stuff(x, 3*y)-4
> result = something_that_calls_func()
> func = save_func
>
>
> Nasty, horrible code, yes? But it's nasty and horrible because "func" is
> bound to a function, it would be equally nasty and horrible if it was a
> data type (a string, a list, an int, a flag, ...) instead.
>
> Since classes and functions are First Class objects in Python, naturally
> if you treat them as global *variables* rather than global *constants*
> you can end up with problems. The problem is not the global part alone.
> Global constants, or pseudo-constant-by-convention-only, are fine.

I don't think there is a big disagreement on this, I just thought
you overstated your case as you originally worded it.

>> And some of those that do change, only do so in the initialisation phase
>> and should be considered constant for the rest of the program.
>>
>> My point was that Steven has no way of knowing what exactly is going on
>> here and so shouldn't be making such a sweeping statement.
>
> On the contrary, I can read the Original Poster's description of the
> problem, and then use my ability to reason to deduce what the most likely
> explanation was.
>
> Now of course I might be wrong. I don't claim infallibility or
> omniscience. But I'm not an idiot, and if the OP says that a global
> variable has one value at one time, and then some time later has a
> different value, there are two likely possibilities:
>
> * The variable was changed by some other piece of code, i.e. it
>    actually was being used as a *global variable*.

Sure. But was that because it was intended to be used as a variable
or was the intention to use it as a constant but because of a bug
it was changed anyway? I don't think you have enough information
to discriminate between these two cases and for the possibility
of this being the latter case I found your disgression into the
harm of global variable too strongly worded.

-- 
Antoon Pardon.

[toc] | [prev] | [next] | [standalone]


#52678

FromChris Angelico <rosuav@gmail.com>
Date2013-08-19 09:32 +0100
Message-ID<mailman.17.1376901181.19984.python-list@python.org>
In reply to#52630
On Mon, Aug 19, 2013 at 9:16 AM, Antoon Pardon
<antoon.pardon@rece.vub.ac.be> wrote:
> Op 19-08-13 09:45, Dave Angel schreef:
>> Antoon Pardon wrote:
>>> I think you are overstating your case. Classes and functions are
>>> variables too and in general nobody seems to have a problem with them
>>> being global.
>>>
>>
>> It's global *variables* that are to be avoided.  constants like clsases
>> and functions are fine.  On the other hand, class attributes can be
>> variable, and thus are to be avoided when reasonable.
>
> Python has no constants. Classes and functions can be changed just like
> any other variable. I agree that classes and function are generally
> meant to be constant, but often enought so are global int variables.

# telnet.py
IAC = 0xFF
GA = 0xF9
WILL = 0xFB
WONT = 0xFC
DO = 0xFD
DONT = 0xFE


# connection.py
from telnet import IAC,DO,DONT


To be sure, Python won't stop me from changing the value of DONT. But
it's a constant, and its value is defined elsewhere (RFC 854). (In
this instance, an enum would probably be the better option; but this
is an example of a more general case.)

In connection.py, I don't care that I've taken a "copy" of the integer
0xFE. It's never going to change; it is a constant in the best
tradition of "named number". I could hard-code 0xFE everywhere and the
code would work *just fine*, but it'd be less readable, so I don't.

Python does have constants. It just doesn't have interpreter support
for them. Same as private members, in fact.

ChrisA

[toc] | [prev] | [next] | [standalone]


#52695

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-08-19 17:05 +0000
Message-ID<52125071$0$29986$c3e8da3$5496439d@news.astraweb.com>
In reply to#52678
On Mon, 19 Aug 2013 09:32:53 +0100, Chris Angelico wrote:

> Python does have constants. It just doesn't have interpreter support for
> them. Same as private members, in fact.

"Constant by convention".

I wish Python had stronger support for enforcing constantness, to whit, 
some way to say "you can't rebind or delete this name once it is bound". 
You can do it with attributes, by use of property, or in C extensions, 
but you cannot do it with top-level name bindings. It makes me terribly 
sad that you can do this:

import math
math.pi = 3.0


although I can't decide whether I am less sad or more sad to see that the 
behaviour of math.sin and friends doesn't depend on math.pi.

Now, of course, and I don't expect any such "constants" to be proof 
against a dedicated attacker. One can work around read-only properties, 
and I expect that any future "no-rebind" constants will also be capable 
of being worked around. This is Python, not Haskell or Ada.

But, naming convention or no naming convention, it is still valuable to 
get an exception if you accidentally rebind something that you shouldn't 
rebind. 


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#52705

FromAntoon Pardon <antoon.pardon@rece.vub.ac.be>
Date2013-08-19 22:34 +0200
Message-ID<mailman.40.1376944517.19984.python-list@python.org>
In reply to#52695
Op 19-08-13 19:05, Steven D'Aprano schreef:

>
> I wish Python had stronger support for enforcing constantness, to whit,
> some way to say "you can't rebind or delete this name once it is bound".
> You can do it with attributes, by use of property, or in C extensions,
> but you cannot do it with top-level name bindings. It makes me terribly
> sad that you can do this:
>
> import math
> math.pi = 3.0
>
>
> although I can't decide whether I am less sad or more sad to see that the
> behaviour of math.sin and friends doesn't depend on math.pi.

Why should you expect math.sin and friends be dependant on math.pi?
AfAIR the numerical algorithms for calulating sin and friends don't
depend on (the value of) pi. So there is no reason to suspect that
altering math.pi would have any effect on the results of these
functions.

-- 
Antoon Pardon

[toc] | [prev] | [next] | [standalone]


#52715

FromSteven D'Aprano <steve@pearwood.info>
Date2013-08-20 05:48 +0000
Message-ID<52130335$0$29885$c3e8da3$5496439d@news.astraweb.com>
In reply to#52705
On Mon, 19 Aug 2013 22:34:00 +0200, Antoon Pardon wrote:

> Op 19-08-13 19:05, Steven D'Aprano schreef:
> 
> 
>> I wish Python had stronger support for enforcing constantness, to whit,
>> some way to say "you can't rebind or delete this name once it is
>> bound". You can do it with attributes, by use of property, or in C
>> extensions, but you cannot do it with top-level name bindings. It makes
>> me terribly sad that you can do this:
>>
>> import math
>> math.pi = 3.0
>>
>>
>> although I can't decide whether I am less sad or more sad to see that
>> the behaviour of math.sin and friends doesn't depend on math.pi.
> 
> Why should you expect math.sin and friends be dependant on math.pi?
> AfAIR the numerical algorithms for calulating sin and friends don't
> depend on (the value of) pi. So there is no reason to suspect that
> altering math.pi would have any effect on the results of these
> functions.


Of course they depend on pi. Or rather, they depend on the geometric 
properties of circles, which are related to pi. If the ratio of the 
circumference of a circle to its diameter was exactly 3, instead of 
3.1415..., then sine and cosine functions would be periodic with period 6 
rather than τ = 2π.

If you consider the implementation of sin and cos functions, they usually 
reduce the argument modulo π to something in the first quadrant, and then 
use symmetry to adjust the value. So changing the value of pi could, in 
principle, change the implementation of sin, cos and tan.


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#52718

Fromwxjmfauth@gmail.com
Date2013-08-19 23:40 -0700
Message-ID<697cde04-0ec2-44d6-85b8-3e95bce3f7f4@googlegroups.com>
In reply to#52715
Le mardi 20 août 2013 07:48:37 UTC+2, Steven D'Aprano a écrit :
> On Mon, 19 Aug 2013 22:34:00 +0200, Antoon Pardon wrote:
> 
> 
> 
> > Op 19-08-13 19:05, Steven D'Aprano schreef:
> 
> > 
> 
> > 
> 
> >> I wish Python had stronger support for enforcing constantness, to whit,
> 
> >> some way to say "you can't rebind or delete this name once it is
> 
> >> bound". You can do it with attributes, by use of property, or in C
> 
> >> extensions, but you cannot do it with top-level name bindings. It makes
> 
> >> me terribly sad that you can do this:
> 
> >>
> 
> >> import math
> 
> >> math.pi = 3.0
> 
> >>
> 
> >>
> 
> >> although I can't decide whether I am less sad or more sad to see that
> 
> >> the behaviour of math.sin and friends doesn't depend on math.pi.
> 
> > 
> 
> > Why should you expect math.sin and friends be dependant on math.pi?
> 
> > AfAIR the numerical algorithms for calulating sin and friends don't
> 
> > depend on (the value of) pi. So there is no reason to suspect that
> 
> > altering math.pi would have any effect on the results of these
> 
> > functions.
> 
> 
> 
> 
> 
> Of course they depend on pi. Or rather, they depend on the geometric 
> 
> properties of circles, which are related to pi. If the ratio of the 
> 
> circumference of a circle to its diameter was exactly 3, instead of 
> 
> 3.1415..., then sine and cosine functions would be periodic with period 6 
> 
> rather than τ = 2π.
> 
> 
> 
> If you consider the implementation of sin and cos functions, they usually 
> 
> reduce the argument modulo π to something in the first quadrant, and then 
> 
> use symmetry to adjust the value. So changing the value of pi could, in 
> 
> principle, change the implementation of sin, cos and tan.
> 
> 
> 
> 
> 
> -- 
> 
> Steven

---------


Never heard about series, Taylor, Maclaurin, ... ?


jmf

[toc] | [prev] | [next] | [standalone]


#52719

FromAntoon Pardon <antoon.pardon@rece.vub.ac.be>
Date2013-08-20 08:55 +0200
Message-ID<mailman.49.1376981719.19984.python-list@python.org>
In reply to#52715
Op 20-08-13 07:48, Steven D'Aprano schreef:
> On Mon, 19 Aug 2013 22:34:00 +0200, Antoon Pardon wrote:
> 
>> Op 19-08-13 19:05, Steven D'Aprano schreef:
>>
>>
>>> I wish Python had stronger support for enforcing constantness, to whit,
>>> some way to say "you can't rebind or delete this name once it is
>>> bound". You can do it with attributes, by use of property, or in C
>>> extensions, but you cannot do it with top-level name bindings. It makes
>>> me terribly sad that you can do this:
>>>
>>> import math
>>> math.pi = 3.0
>>>
>>>
>>> although I can't decide whether I am less sad or more sad to see that
>>> the behaviour of math.sin and friends doesn't depend on math.pi.
>>
>> Why should you expect math.sin and friends be dependant on math.pi?
>> AfAIR the numerical algorithms for calulating sin and friends don't
>> depend on (the value of) pi. So there is no reason to suspect that
>> altering math.pi would have any effect on the results of these
>> functions.
> 
> 
> Of course they depend on pi. Or rather, they depend on the geometric 
> properties of circles, which are related to pi. If the ratio of the 
> circumference of a circle to its diameter was exactly 3, instead of 
> 3.1415..., then sine and cosine functions would be periodic with period 6 
> rather than τ = 2π.

Which is beside the point. The fact that nπ are the zeropoints of the
sin function doesn't imply in any way that you somehow need to work with
the value of π in order to calculate any result of the function.

Just as the function x^2 - 2 has -√2 and √2 as zeropoints, yet when
given a numerical value, you dont need (the value of) √2 in order to
get the result. So setting a variable like sqrt2 to whatever value
shouldn't lead us to suspect it would influence the zeropoints of
that function. Likewise with π and the calculation of sin.


> If you consider the implementation of sin and cos functions, they usually 
> reduce the argument modulo π to something in the first quadrant, and then 
> use symmetry to adjust the value. So changing the value of pi could, in 
> principle, change the implementation of sin, cos and tan.

Yes there is this aspect, which is a fair point.

-- 
Antoon Pardon

[toc] | [prev] | [next] | [standalone]


#52722

Fromwxjmfauth@gmail.com
Date2013-08-20 00:31 -0700
Message-ID<c5e3e122-06df-49d0-846d-365525cd6380@googlegroups.com>
In reply to#52719
Le mardi 20 août 2013 08:55:18 UTC+2, Antoon Pardon a écrit :
> 
> > 
> 

> 
> 
> 
> > If you consider the implementation of sin and cos functions, they usually 
> 
> > reduce the argument modulo π to something in the first quadrant, and then 
> 
> > use symmetry to adjust the value. So changing the value of pi could, in 
> 
> > principle, change the implementation of sin, cos and tan.
> 
> 
> 
> Yes there is this aspect, which is a fair point.
> 
> 
> 
> -- 
> 
> Antoon Pardon

-----

Not really, see my previous post. This is only a geometric
interpretation, useless for calculation.

Consequence of an implementation: common trick to use
and/or define pi:

>>> const_pi = 4 * atan(1)
>>> const_pi
3.141592653589793

jmf


[toc] | [prev] | [next] | [standalone]


#52723

FromAntoon Pardon <antoon.pardon@rece.vub.ac.be>
Date2013-08-20 09:55 +0200
Message-ID<mailman.51.1376985351.19984.python-list@python.org>
In reply to#52722
Op 20-08-13 09:31, wxjmfauth@gmail.com schreef:
> Le mardi 20 août 2013 08:55:18 UTC+2, Antoon Pardon a écrit :
>>
>>>
>>
> 
>>
>>
>>
>>> If you consider the implementation of sin and cos functions, they usually 
>>
>>> reduce the argument modulo π to something in the first quadrant, and then 
>>
>>> use symmetry to adjust the value. So changing the value of pi could, in 
>>
>>> principle, change the implementation of sin, cos and tan.
>>
>>
>>
>> Yes there is this aspect, which is a fair point.
>>
>>
>>
>> -- 
>>
>> Antoon Pardon
> 
> -----
> 
> Not really, see my previous post. This is only a geometric
> interpretation, useless for calculation.

No it is not. Steven is correct that if for example you
want the value of sin(10), that in a typical implementation
this will be reduced to calculating -sin(10 - 3π).

This for two reasons. It is faster to first reduce the argument
within the first kwadrant, do the series expansion and then
correct for sign than to expand the series with the original
argument and it is more acurate because first reducing asures
that all terms will stay relatively small while using the
original arguments can intrduce some large terms that will
have to cancel each other but that will reduce acuracy.

-- 
Antoon Pardon

[toc] | [prev] | [next] | [standalone]


#52730

Fromwxjmfauth@gmail.com
Date2013-08-20 02:15 -0700
Message-ID<3875e747-d33d-46ac-94ac-8f03ec5f9736@googlegroups.com>
In reply to#52723
Le mardi 20 août 2013 09:55:44 UTC+2, Antoon Pardon a écrit :
> Op 20-08-13 09:31, wxjmfauth@gmail.com schreef:
> 
> > Le mardi 20 août 2013 08:55:18 UTC+2, Antoon Pardon a écrit :
> 
> >>
> 
> >>>
> 
> >>
> 
> > 
> 
> >>
> 
> >>
> 
> >>
> 
> >>> If you consider the implementation of sin and cos functions, they usually 
> 
> >>
> 
> >>> reduce the argument modulo π to something in the first quadrant, and then 
> 
> >>
> 
> >>> use symmetry to adjust the value. So changing the value of pi could, in 
> 
> >>
> 
> >>> principle, change the implementation of sin, cos and tan.
> 
> >>
> 
> >>
> 
> >>
> 
> >> Yes there is this aspect, which is a fair point.
> 
> >>
> 
> >>
> 
> >>
> 
> >> -- 
> 
> >>
> 
> >> Antoon Pardon
> 
> > 
> 
> > -----
> 
> > 
> 
> > Not really, see my previous post. This is only a geometric
> 
> > interpretation, useless for calculation.
> 
> 
> 
> No it is not. Steven is correct that if for example you
> 
> want the value of sin(10), that in a typical implementation
> 
> this will be reduced to calculating -sin(10 - 3π).
> 
> 
> 
> This for two reasons. It is faster to first reduce the argument
> 
> within the first kwadrant, do the series expansion and then
> 
> correct for sign than to expand the series with the original
> 
> argument and it is more acurate because first reducing asures
> 
> that all terms will stay relatively small while using the
> 
> original arguments can intrduce some large terms that will
> 
> have to cancel each other but that will reduce acuracy.
> 
> 
> 
> -- 
> 
> Antoon Pardon

Ok. Fine. I was aware of the serie expansion, not
about the reduction.

jmf

[toc] | [prev] | [next] | [standalone]


#52680

FromAntoon Pardon <antoon.pardon@rece.vub.ac.be>
Date2013-08-19 11:03 +0200
Message-ID<mailman.19.1376903021.19984.python-list@python.org>
In reply to#52630
Op 19-08-13 10:32, Chris Angelico schreef:
> On Mon, Aug 19, 2013 at 9:16 AM, Antoon Pardon
> <antoon.pardon@rece.vub.ac.be> wrote:
>> Op 19-08-13 09:45, Dave Angel schreef:
>>> Antoon Pardon wrote:
>>>> I think you are overstating your case. Classes and functions are
>>>> variables too and in general nobody seems to have a problem with them
>>>> being global.
>>>>
>>>
>>> It's global *variables* that are to be avoided.  constants like clsases
>>> and functions are fine.  On the other hand, class attributes can be
>>> variable, and thus are to be avoided when reasonable.
>>
>> Python has no constants. Classes and functions can be changed just like
>> any other variable. I agree that classes and function are generally
>> meant to be constant, but often enought so are global int variables.
> 
> # telnet.py
> IAC = 0xFF
> GA = 0xF9
> WILL = 0xFB
> WONT = 0xFC
> DO = 0xFD
> DONT = 0xFE
> 
> 
> # connection.py
> from telnet import IAC,DO,DONT
> 
> 
> To be sure, Python won't stop me from changing the value of DONT. But
> it's a constant, and its value is defined elsewhere (RFC 854). (In
> this instance, an enum would probably be the better option; but this
> is an example of a more general case.)

This is irrelevant. That some context defines a constant, and that you
can use a variable with the same name as a constant in python, doesn't
contradict the statement that python (as a language) doesn't has
constants. There is nothing in the language that would prevent buggy
code from changing any of those variables. So from a python point of
views these are just global variables. Just as the struct_global.y was
in the original contribution.

-- 
Antoon Pardon

[toc] | [prev] | [next] | [standalone]


#52681

FromChris Angelico <rosuav@gmail.com>
Date2013-08-19 10:18 +0100
Message-ID<mailman.20.1376903935.19984.python-list@python.org>
In reply to#52630
On Mon, Aug 19, 2013 at 10:03 AM, Antoon Pardon
<antoon.pardon@rece.vub.ac.be> wrote:
> This is irrelevant. That some context defines a constant, and that you
> can use a variable with the same name as a constant in python, doesn't
> contradict the statement that python (as a language) doesn't has
> constants. There is nothing in the language that would prevent buggy
> code from changing any of those variables. So from a python point of
> views these are just global variables. Just as the struct_global.y was
> in the original contribution.

And there's nothing preventing a program from using ctypes to
overwrite an object's refcount, thus causing a segfault. So? The issue
was regarding imports, and it's perfectly safe to import a constant,
even if the interpreter doesn't protect you from then being a total
idiot and changing it.

ChrisA

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.python


csiph-web