Re: [Tutor] Fwd: Re: would someone please explain this concept to me

2019-06-06 Thread Alan Gauld via Tutor
On 06/06/2019 00:57, Alan Gauld via Tutor wrote:

> But in the second example you actially change the object
> that checklimit refers to.
> 
> checklimit = 22   # immutable value assigned
> feeds['bar'] = checklimit   # both refer to same immutable value
> base_var = 66   # now feeds refers to original object: 22
> # and checklimit refers to new object: 66

Oops, base_var should of course be checklimit!
I started out using base_var then changed it to checklimit
to match the original code.
But this one slipped through unchanged.
Sorry.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Fwd: Re: would someone please explain this concept to me

2019-06-06 Thread nathan tech
Hi alan,

thanks so much for clearing that up.

Now you've explained it in that way, I understand what it is doing and 
how it went wrong.

Thank you so much!

Nathan

On 06/06/2019 00:57, Alan Gauld via Tutor wrote:
> On 05/06/2019 20:47, nathan tech wrote:
>
>> so for example if I do:
>>
>> feeds[feed1]["limit"]=g.checklimit
>>
>> And later did g.checklimit=7000
>>
>> Would it change feeds[feed1]["limit"] too?
> No, because the feeds value is still referencing the
> original value object. The issue arises when you modify a mutable
> object that is references by two (or more) variables. If the value
> is immutable then the references will retain the original value.
>
> Specifically, in your case.
> The first example you set the feeds value to a dictionary. Then you
> modified the contents of the dictionary but did not change the
> dictionary itself.
>
> base_dict = {}   # create object
> feeds['foo'] = base_dict   # reference to same dict object
> base_dict['x'] = bar   # modified dict referred to by both variables
>
>
> But in the second example you actially change the object
> that checklimit refers to.
>
> checklimit = 22   # immutable value assigned
> feeds['bar'] = checklimit   # both refer to same immutable value
> base_var = 66   # now feeds refers to original object: 22
>  # and checklimit refers to new object: 66
>
> In the first case you do not change the object that base_dict refers to,
> you only change its content. In the second case you make checklimit
> refer to a completely new object.
>
> Does that make sense?
>
> PS. Notice that the use of a globals module, g, is completely irrelevant
> to this issue. It has nothing to do with the values being in a module,
> the issue is purely about references to objects and whether you modify
> the referenced object or its contents.
>
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Fwd: Re: would someone please explain this concept to me

2019-06-05 Thread Alan Gauld via Tutor
On 05/06/2019 20:47, nathan tech wrote:

> so for example if I do:
> 
> feeds[feed1]["limit"]=g.checklimit
> 
> And later did g.checklimit=7000
> 
> Would it change feeds[feed1]["limit"] too?

No, because the feeds value is still referencing the
original value object. The issue arises when you modify a mutable
object that is references by two (or more) variables. If the value
is immutable then the references will retain the original value.

Specifically, in your case.
The first example you set the feeds value to a dictionary. Then you
modified the contents of the dictionary but did not change the
dictionary itself.

base_dict = {}   # create object
feeds['foo'] = base_dict   # reference to same dict object
base_dict['x'] = bar   # modified dict referred to by both variables


But in the second example you actially change the object
that checklimit refers to.

checklimit = 22   # immutable value assigned
feeds['bar'] = checklimit   # both refer to same immutable value
base_var = 66   # now feeds refers to original object: 22
# and checklimit refers to new object: 66

In the first case you do not change the object that base_dict refers to,
you only change its content. In the second case you make checklimit
refer to a completely new object.

Does that make sense?

PS. Notice that the use of a globals module, g, is completely irrelevant
to this issue. It has nothing to do with the values being in a module,
the issue is purely about references to objects and whether you modify
the referenced object or its contents.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Fwd: Re: would someone please explain this concept to me

2019-06-05 Thread Alan Gauld via Tutor


> That is why I was going to use g.blank-feed as the template, 
> assign that to d["feed 1's link"] then just update the feed part.

The simplest way is just to assign a new blank dictionary. Don;t assign
the same dictionary to each feed. (Incidentally your description above
is much clearer than the one you initially posted!)

feeds[link] = {key1:value1, key2:value2}

If you need to pre-populate the dictionary with many values when
you assign it (or need to compute  the values) I'd recommend
writing a small function that creates a new dictionary,
and adds the values then returns the dictionary.

Or maybe, better still, use a class and populate the feeds
dictionary with instances of the class.

class Feed:
   def __init__(self, val1=default1, val2=default2, val3=default3):
   self.key1 = val1
   self.key2 = val2
   self.key3 = val3

feeds[link1] = Feed(v1,v2,v3)
feeds[link2] = Feed()   # use default values

After all that's exactly what a class is - a template for an object.

What you definitely don't want to do is what you have been
doing and assigning the same single dictionary object to each
link entry.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] Fwd: Re: would someone please explain this concept to me

2019-06-05 Thread nathan tech
Thought I addressed this to the list... Aparrently my mail client hates me.


 Forwarded Message 
Subject:Re: [Tutor] would someone please explain this concept to me
Date:   Wed, 5 Jun 2019 02:37:49 +0100
From:   nathan tech 
To: Steven D'Aprano 


Hiya,

Thanks, first, for being able to understand what I was asking.

I admit I read over my own email and went, uh... I think I need to rewrite that.


So, I see what you are saying there, and it makes sense.

I want to actually do the following though:

d={} # a dict of some kind

feed1=somefeed

feed2=another feed of some kind

d["feed 1's url"]=feed1

d["feed 2's url"]=feed2


The way I do this is there are certain properties, if you were, that also need 
to be included, I.e, each entry should be its own dict containing feed, last 
check, check regularity, ETC.

That is why I was going to use g.blank-feed as the template, assign that to 
d["feed 1's link"] then just update the feed part.



Is there a way to do this?

Thanks

Nathan

On 05/06/2019 02:08, Steven D'Aprano wrote:
On Tue, Jun 04, 2019 at 11:37:23PM +, nathan tech wrote:

globals.py:

feeds={}
blank_feed={}
blank_feed["checked"]=1
blank_feed["feed"]=0
That is more easily, and better, written as:

feeds = {}
blank_feed = {"checked": 1, "feed": 0}


main file:

import globals as g
# some code that loads a feed into the variable knm
Do you mean something like this? If so, you should say so.

knm = "some feed"


g.feeds[link]=g.blank_feed;
What's "link" here? And there is no need for the semi-colon.

g.feeds[link]["feed"]=knm
Right... what the above line does is *precisely* the same as

g.blank_feed["feed"] = knm

Follow the program logic. I'm inserting 1970s BASIC style line numbers
to make it easier to discuss the code, remember that you can't actually
do that in Python.

10: g.feeds[link] = g.blank_feed
20: g.feeds[link]["feed"] = knm

Line 10 sets g.feeds[link] to the dict "blank_feed". *Not* a copy: you
now have two ways of referring to the same dict:

"g.blank_feed" and "g.feeds[link]"

both refer to the one dict, just as "Nathan" and "Mr Tech" are two ways
of referring to the same person (you).

So line 20 does this:

- look for the name "g", which gives the "globals.py" module;

- inside that module, look for the name "feeds", which gives
the "feeds" dict;

- look inside that dict for the key "link" (whatever value
that currently holds), which by line 10 has been set to
the same dict "blank_feed".

- inside the blank_feed dict, set key "feed" to "knm".



#in the below code, the variable link has a different value:
# load a feed into the variable r
Something like this?

r = "a different feed"

g.feeds[link]=g.blank_feed
Now you have *three* ways of naming the same dict:

"g.blank_feed", "g.feeds[link]", "g.feeds[different_link]"

but they all point to the same dict.

g.feeds[link]["feed"]=r


Now at this point, python would set the first loaded feed to the same
thing as the second loaded feed. It also set g.blank_feed to the second
feed, as well.
No, there is only one feed in total. You just keep updating the same
feed under different names.


I replaced the last three lines with this:

# load a feed into the variable r
g.feeds[link]=g.blank_feed;
g.feeds[link]["feed"]=r

And it works.
I don't see any difference between the replacement code and the original
code. The code you show does exactly the same thing.


but why does it work?

Why does that semi unlink all the variables?
Semi-colon?

It doesn't. You must have made other changes as well, semi-colons don't
have any runtime effect. They are *purely* syntax to tell the parser to
seperate multiple statements on one line.


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor