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


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

stupid simple scope issue

Started byJohnD <john@nowhere.com>
First post2013-08-04 18:20 +0000
Last post2013-08-05 07:21 +0000
Articles 5 — 2 participants

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


Contents

  stupid simple scope issue JohnD <john@nowhere.com> - 2013-08-04 18:20 +0000
    Re: stupid simple scope issue Chris Angelico <rosuav@gmail.com> - 2013-08-04 19:39 +0100
      Re: stupid simple scope issue JohnD <john@nowhere.com> - 2013-08-04 19:21 +0000
        Re: stupid simple scope issue Chris Angelico <rosuav@gmail.com> - 2013-08-04 21:03 +0100
          Re: stupid simple scope issue JohnD <john@nowhere.com> - 2013-08-05 07:21 +0000

#51933 — stupid simple scope issue

FromJohnD <john@nowhere.com>
Date2013-08-04 18:20 +0000
Subjectstupid simple scope issue
Message-ID<51fe9b6b$0$1689$e4fe514c@dreader35.news.xs4all.nl>
After 5 year of no Python programming I decided that I needed to brush
up my skills. Started writing on a reasonably complicated problem.
Unfortunately my basic Python skill are gone.

I present the bare-bore problem. This code does not produce the expected
result: can anyone tell me why? As you will guess, I want the first
three lines of output identical to the second three lines...

Can anyone point out the solution? Thanks!

#~/usr/bin/python
import random
class boys:
    state={}
class boy:
    state={
        'name':'',
        'age':''
        }
names=['a','b','c']

def add_names():
    global boys
    for n in names:
        boy.state['name']=n
        boy.state['age']=random.randint(1, 1000)
        boys.state[n]=boy.state
        print boy.state['name'], boy.state['age']

add_names()

for n in boys.state:
    boy.state=boys.state[n]
    print boy.state['name'], boy.state['age']

[toc] | [next] | [standalone]


#51937

FromChris Angelico <rosuav@gmail.com>
Date2013-08-04 19:39 +0100
Message-ID<mailman.190.1375641581.1251.python-list@python.org>
In reply to#51933
On Sun, Aug 4, 2013 at 7:20 PM, JohnD <john@nowhere.com> wrote:
> #~/usr/bin/python

If this is meant to be a Unix-style shebang, the second character
needs to be ! not ~. This has no effect on Python though.

> import random
> class boys:
>     state={}
> class boy:
>     state={
>         'name':'',
>         'age':''
>         }

At no time do you actually instantiate any objects from these types.
In fact, you may as well drop the class blocks and the ".state" usage
and simply use:

boys = {}
boy = {'name':'', 'age':''}

as this will achieve the exact same thing.

> def add_names():
>     global boys

The global declaration is needed only if you assign to the name, eg
"boys = <...>" - it's superfluous here.

>     for n in names:
>         boy.state['name']=n
>         boy.state['age']=random.randint(1, 1000)
>         boys.state[n]=boy.state
>         print boy.state['name'], boy.state['age']

Each time you do this, you're modifying the same 'boy' mapping, then
putting another reference to it in 'boys'. I think possibly what you
want here is to construct a new boy() instance for each one.

> add_names()
>
> for n in boys.state:
>     boy.state=boys.state[n]
>     print boy.state['name'], boy.state['age']

I'd look at doing it more like this:

class boy:
    def __init__(self,name,age):
        self.name=name; self.age=age
boys = {}

def add_name(n):
    b = boy(n,random.randint(1, 1000))
    boys[n] = b
    print b.name, b.age

for n in 'a','b','c':
    add_name(n)

for n,b in boys.items():
    print b.name, b.age


Or possibly even dispense with the boy class altogether and simply use
a dictionary - or simply map a name to an age, since (as you can see
in the final loop) it's easy enough to iterate over the dictionary.
(Note that the code above is untested and probably has an egregious
bug in it somewhere.)

ChrisA

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


#51938

FromJohnD <john@nowhere.com>
Date2013-08-04 19:21 +0000
Message-ID<51fea9bb$0$1677$e4fe514c@dreader35.news.xs4all.nl>
In reply to#51937
On 2013-08-04, Chris Angelico <rosuav@gmail.com> wrote:
[...]
Thank you very much. The dust is slowly starting to move.
The code posted is nothing like the real thing, but I tried
to capture the essence. 

From your commants I think I see my mistake.

Thank you very much for your reply!

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


#51939

FromChris Angelico <rosuav@gmail.com>
Date2013-08-04 21:03 +0100
Message-ID<mailman.191.1375646610.1251.python-list@python.org>
In reply to#51938
On Sun, Aug 4, 2013 at 8:21 PM, JohnD <john@nowhere.com> wrote:
> On 2013-08-04, Chris Angelico <rosuav@gmail.com> wrote:
> [...]
> Thank you very much. The dust is slowly starting to move.
> The code posted is nothing like the real thing, but I tried
> to capture the essence.
>
> From your commants I think I see my mistake.
>
> Thank you very much for your reply!

No probs!

Python does have a slightly odd (compared to other languages)
interpretation of "variable assignments" (name bindings, really)
inside a class block. Trips up a lot of people.

ChrisA

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


#51953

FromJohnD <john@nowhere.com>
Date2013-08-05 07:21 +0000
Message-ID<51ff5265$0$3165$e4fe514c@dreader36.news.xs4all.nl>
In reply to#51939
On 2013-08-04, Chris Angelico <rosuav@gmail.com> wrote:
> On Sun, Aug 4, 2013 at 8:21 PM, JohnD <john@nowhere.com> wrote:
>> On 2013-08-04, Chris Angelico <rosuav@gmail.com> wrote:
[...]
>
> Python does have a slightly odd (compared to other languages)
> interpretation of "variable assignments" (name bindings, really)
> inside a class block. Trips up a lot of people.

Changed the code: >10% smaller, more elegant, and it seems to work!
If it really works I am close to half-way...

[toc] | [prev] | [standalone]


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


csiph-web