Local vs global

View: New views
10 Messages — Rating Filter:   Alert me  

Local vs global

by bibi midi :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi gang,

Although i have read up quite a lot about local and global scope in functions i still 'suffer' understanding it, i'm afraid. I have this dragon's realm code modified to my liking or the way i know it. In the original ebook there is no global variable but i have one on mine. I tried removing it but i get error variable undeclared or something. It is in the function choose_Cave.

I know that variables inside a function are local in scope and is gone after the lifetime of the function, i mean after that function is called. That is why there is the return statement. What i understand you can access whatever that function did through the return statement.

I tried assigning the function to a variable outside the function definition but still it doesnt work. Something like:

x = choose_Cave()
checkCave(x)

I'm slow in this programming thing haha but i want to learn. There are lots to know in python and how i wish i have all the time. Unfortunately i have my day job too and first things first. So I'm just managing my time. Below is the code. Thanks.


#!/usr/bin/env python
# -*- coding: utf-8 -*-

'''
Tutorial book Invent Your Own Computer Games with Python 2nd Edition
Author: Al Sweigart
Chapter 6: Dragon Realm
Filename: dragon.py
Created: 02-Nov-2009
edited: 06-Nov-2009; added functions
'''

import random
import time

location = '/home/bboymen/pyscripts/invent-with-Python/intro.txt'
file = open(location)
intro = file.read()
file.close()

def choose_Cave():
global choose
choose = raw_input('choose a cave! (1 or 2): ')
while choose != '1' and choose != '2': #(a)
print('enter 1 or 2 only.')
choose = raw_input('try again: ')
return choose

def checkCave(chosenCave):
print('you approach the cave...')
time.sleep(2)
print('it is dark and spooky...')
time.sleep(2)
print('a large dragon jumps over you! he open his jaws and....')
time.sleep(2)
friendlyCave = random.randint(1, 2)
if chosenCave == str(friendlyCave):
print('gives you his treasure!')
else:
print('gobbles you down in one bite!')

print(intro)
choose_Cave()
checkCave(choose)
while True:
ask = raw_input('play again? (y/[N])')
reply = ['y', 'ye', 'yea', 'yeah', 'yep', 'yes']
if ask.lower() in reply:
print "\n", intro
choose_Cave()
checkCave(choose)
else:
break

print('thanks for playing, goodbye!')


#(a) boolean operator `and` will evaluate 2 boolean values (to its left and right)
# and return a single boolean value



--
Best Regards,
bibimidi



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

Re: Local vs global

by Alan Gauld :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


"bibi midi" <bibsmendez@...> wrote in

> Although i have read up quite a lot about local and global scope in
> functions i still 'suffer' understanding it, ... I tried
> removing it but i get error variable undeclared or something. It is in
> the
> function choose_Cave.

We need to see the exact error text, the whole error.
Python error messages are very informative and usually
tell you exactly what is wrong and where (once you get used to them).

> I know that variables inside a function are local in scope and is gone
> after
> the lifetime of the function, i mean after that function is called. That
> is
> why there is the return statement. What i understand you can access
> whatever
> that function did through the return statement.

Specifically you can access the values that the return exposes,
you cannot access anything else from the function body.

> I tried assigning the function to a variable outside the function
> definition
> but still it doesnt work. Something like:
>
> x = choose_Cave()
> checkCave(x)

That should work
So what happened? How did the program run and what error did you get?

> location = '/home/bboymen/pyscripts/invent-with-Python/intro.txt'
> file = open(location)
> intro = file.read()
> file.close()
>
> def choose_Cave():
>    global choose
>    choose = raw_input('choose a cave! (1 or 2): ')
>    while choose != '1' and choose != '2':  #(a)
>        print('enter 1 or 2 only.')
>        choose = raw_input('try again: ')
>    return choose

You can lose the global line at the top, you are no longer
modifying the global value you are returning the local one.

> def checkCave(chosenCave):
>    print('you approach the cave...')
>    time.sleep(2)
>    print('it is dark and spooky...')
>    time.sleep(2)
>    print('a large dragon jumps over you! he open his jaws and....')
>    time.sleep(2)
>    friendlyCave = random.randint(1, 2)
>    if chosenCave == str(friendlyCave):
>        print('gives you his treasure!')
>    else:
>        print('gobbles you down in one bite!')

> print(intro)
> choose_Cave()

you are not assigning the return to a value

choose=choose_Cave()

> checkCave(choose)
> while True:
>    ask = raw_input('play again? (y/[N])')
>    reply = ['y', 'ye', 'yea', 'yeah', 'yep', 'yes']
>    if ask.lower() in reply:
>        print "\n", intro
>        choose_Cave()
>        checkCave(choose)
>    else:
>        break

You could tidy that up by moving the first lines inside the loop:

> while True:
>    print "\n", intro
>    choose = choose_Cave()
>    checkCave(choose)
>    ask = raw_input('play again? (y/[N])')
>    reply = ['y', 'ye', 'yea', 'yeah', 'yep', 'yes']
>    if ask.lower() not in reply:
>          break

HTH,

Alan G.


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

Re: Local vs global

by Dave Angel :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Alan Gauld wrote:

> "bibi midi" <bibsmendez@...> wrote in
>
>> Although i have read up quite a lot about local and global scope in
>> functions i still 'suffer' understanding it, ... I tried
>> removing it but i get error variable undeclared or something. It is
>> in the
>> function choose_Cave.
>
> We need to see the exact error text, the whole error.
> Python error messages are very informative and usually
> tell you exactly what is wrong and where (once you get used to them).
>
>> I know that variables inside a function are local in scope and is
>> gone after
>> the lifetime of the function, i mean after that function is called.
>> That is
>> why there is the return statement. What i understand you can access
>> whatever
>> that function did through the return statement.
>
> Specifically you can access the values that the return exposes,
> you cannot access anything else from the function body.
>
>> I tried assigning the function to a variable outside the function
>> definition
>> but still it doesnt work. Something like:
>>
>> x = choose_Cave()
>> checkCave(x)
>
> That should work
> So what happened? How did the program run and what error did you get?
>
>> location = '/home/bboymen/pyscripts/invent-with-Python/intro.txt'
>> file = open(location)
>> intro = file.read()
>> file.close()
>>
>> def choose_Cave():
>>    global choose
>>    choose = raw_input('choose a cave! (1 or 2): ')
>>    while choose != '1' and choose != '2':  #(a)
>>        print('enter 1 or 2 only.')
>>        choose = raw_input('try again: ')
>>    return choose
>
> You can lose the global line at the top, you are no longer
> modifying the global value you are returning the local one.
>
>> def checkCave(chosenCave):
>>    print('you approach the cave...')
>>    time.sleep(2)
>>    print('it is dark and spooky...')
>>    time.sleep(2)
>>    print('a large dragon jumps over you! he open his jaws and....')
>>    time.sleep(2)
>>    friendlyCave = random.randint(1, 2)
>>    if chosenCave == str(friendlyCave):
>>        print('gives you his treasure!')
>>    else:
>>        print('gobbles you down in one bite!')
>
>> print(intro)
>> choose_Cave()
>
> you are not assigning the return to a value
>
> choose=choose_Cave()
>
>> checkCave(choose)
>> while True:
>>    ask = raw_input('play again? (y/[N])')
>>    reply = ['y', 'ye', 'yea', 'yeah', 'yep', 'yes']
>>    if ask.lower() in reply:
>>        print "\n", intro
>>        choose_Cave()
>>        checkCave(choose)
>>    else:
>>        break
>
> You could tidy that up by moving the first lines inside the loop:
>
>> while True:
>>    print "\n", intro
>>    choose = choose_Cave()
>>    checkCave(choose)
>>    ask = raw_input('play again? (y/[N])')
>>    reply = ['y', 'ye', 'yea', 'yeah', 'yep', 'yes']
>>    if ask.lower() not in reply:
>>          break
>
> HTH,
>
> Alan G.
>
>
Alan - Excellent comments, as usual.

bibimidi - I would point out that after you remove the 'global choose' line as Alan said, you should rename the global variable you're using to store the return value.  They're allowed to have the same name, but it's confusing to a beginner if they do, since you might assume they somehow share the value.

So I'd do something like:

while True:
    ....
    my_cave = choose_Cave()
    checkCave(my_cave)
    ....



Incidentally, as a matter of terminology, you have lots of 'global
variables' in this code.  location, file, intro, ask and reply are all
global.  If it were my code, I'd probably move all that logic to one
more function, call it main().  And the only top-level code would be a
call to main().

One more important thing.  You used 'file' as a variable name, but it
already has a meaning in Python, as a built-in type for file
operations.  No problem in this script, but it's a good practice to
avoid names in built-ins, as well as names used by stdlib imports  (os,
sys, math, random, time, ...)

DaveA

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

Re: Local vs global

by Eri Mendz :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sat, Nov 7, 2009 at 3:26 PM, Dave Angel <davea@...> wrote:

> Alan Gauld wrote:
>>
> Alan - Excellent comments, as usual.
>
> bibimidi - I would point out that after you remove the 'global choose' line
> as Alan said, you should rename the global variable you're using to store
> the return value.  They're allowed to have the same name, but it's confusing
> to a beginner if they do, since you might assume they somehow share the
> value.
>

Thank you all for the helpful insights. I will keep in mind the naming
rules in Python, so as not to have it in collision with Python's
builtins.

The mention to tidy up e.g. "compartmentalize" code is also noted. I
agree definitely.

I'm reworking my code and will post back.




--
Best Regards

Marie von Ebner-Eschenbach  - "Even a stopped clock is right twice a
day." - http://www.brainyquote.com/quotes/authors/m/marie_von_ebnereschenbac.html
_______________________________________________
Tutor maillist  -  Tutor@...
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Parent Message unknown Re: Local vs global

by bibi midi :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Sat, Nov 7, 2009 at 3:26 PM, Dave Angel <davea@...> wrote:
> Alan Gauld wrote:
>>
> Alan - Excellent comments, as usual.
>
> bibimidi - I would point out that after you remove the 'global choose' line
> as Alan said, you should rename the global variable you're using to store
> the return value.  They're allowed to have the same name, but it's confusing
> to a beginner if they do, since you might assume they somehow share the
> value.
>

Thank you all for the helpful insights. I will keep in mind the naming
rules in Python, so as not to have it in collision with Python's
builtins.

The mention to tidy up e.g. "compartmentalize" code is also noted. I
agree definitely.

I'm reworking my code and will post back.




--
Best Regards

Marie von Ebner-Eschenbach  - "Even a stopped clock is right twice a
day." - http://www.brainyquote.com/quotes/authors/m/marie_von_ebnereschenbac.html



--
Best Regards,
bibimidi



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

Re: Local vs global

by bibi midi :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message



On Sun, Nov 8, 2009 at 6:20 AM, bibi midi <bibsmendez@...> wrote:


Thank you all for the helpful insights. I will keep in mind the naming
rules in Python, so as not to have it in collision with Python's
builtins.

The mention to tidy up e.g. "compartmentalize" code is also noted. I
agree definitely.

I'm reworking my code and will post back.

For reason unknown to me the script dont repeat itself
when asked if to play again or not no matter what juggling of the
while/if conditionals i do, the result is the same. What am i
missing?

Also, I'm not sure I'm right in the assignment ans = choose_Cave.
I code it like so because the assignment ans = choose_Cave()
the prompt 'Choose a cave' is repeated when the script is run.
Dont want this. I tested this when run in ipython.

I dont know if there is a way to just retrieve the return value to a
variable AND not run the whole function i mean in the case of
ans = choose_Cave(). Would love to hear your expert insights by return.
http://paste.debian.net/51004/


--
Best Regards,
bibimidi


On Sat, Nov 7, 2009 at 3:26 PM, Dave Angel <davea@...> wrote:
> Alan Gauld wrote:
>>
> Alan - Excellent comments, as usual.
>
> bibimidi - I would point out that after you remove the 'global choose' line
> as Alan said, you should rename the global variable you're using to store
> the return value.  They're allowed to have the same name, but it's confusing
> to a beginner if they do, since you might assume they somehow share the
> value.
>


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

Re: Local vs global

by Dave Angel :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

bibi midi wrote:

> On Sun, Nov 8, 2009 at 6:20 AM, bibi midi <bibsmendez@...> wrote:
>
>
>  
>> Thank you all for the helpful insights. I will keep in mind the naming
>> rules in Python, so as not to have it in collision with Python's
>> builtins.
>>
>> The mention to tidy up e.g. "compartmentalize" code is also noted. I
>> agree definitely.
>>
>> I'm reworking my code and will post back.
>>
>>    
>
> For reason unknown to me the script dont repeat itself
> when asked if to play again or not no matter what juggling of the
> while/if conditionals i do, the result is the same. What am i
> missing?
>
> Also, I'm not sure I'm right in the assignment ans = choose_Cave.
> I code it like so because the assignment ans = choose_Cave()
> the prompt 'Choose a cave' is repeated when the script is run.
> Dont want this. I tested this when run in ipython.
>
> I dont know if there is a way to just retrieve the return value to a
> variable AND not run the whole function i mean in the case of
> ans = choose_Cave(). Would love to hear your expert insights by return.
>
> http://paste.debian.net/51004/
>
>
>  
You have the following line at top-level:

    if ask.lower not in reply:

But you're not calling the method str.lower(), you're just creating a
function object from it.  You need those parentheses.

    if ask.lower() not in reply:


You have the following fragment in main():

    print(intro)
    choose_Cave()
    ans = choose_Cave    # use: pass function by reference
    checkCave(ans)


which has two references to choose_Cave().  The first one calls it, but
throws away the return value.  The second does not call it at all, but
merely creates a function object and stores it in ans.  You need to
combine your two intents in one line:

    print(intro)
    ans = choose_Cave()    # use: pass function by reference
    checkCave(ans)

Hope that helps.  Remember, that unlike Pascal, in Python you don't call
the function unless you include the parentheses.

DaveA



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

Re: Local vs global

by Alan Gauld :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Some parts of this message have been removed. Learn more about Nabble's security policy.

> Remember, that unlike Pascal, in Python you don't call the 
> function unless you include the parentheses.

And since you are unlikely to be old enough to have programmed 
in Pascal(!), I'll add unlike VB you don't call the function unless 
you include parentheses.

:-)

Alan G.


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

Re: Local vs global

by Lie Ryan :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

bibi midi wrote:

>
>
> On Sun, Nov 8, 2009 at 6:20 AM, bibi midi <bibsmendez@...
> <mailto:bibsmendez@...>> wrote:
>
>
>     Thank you all for the helpful insights. I will keep in mind the naming
>     rules in Python, so as not to have it in collision with Python's
>     builtins.
>
>     The mention to tidy up e.g. "compartmentalize" code is also noted.. I
>     agree definitely.
>
>     I'm reworking my code and will post back.
>
>
> For reason unknown to me the script dont repeat itself
> when asked if to play again or not no matter what juggling of the
>
> while/if conditionals i do, the result is the same. What am i
> missing?

You don't check for whether the answer is 'no'. A single if-statement
branches the code into TWO line of execution, you wanted to have THREE
line of execution (i.e. a 'yes' part, a 'no' part, and an invalid answer
part).

> Also, I'm not sure I'm right in the assignment ans = choose_Cave.
> I code it like so because the assignment ans = choose_Cave()

In:
def choose_Cave():
     global choose
     ...

you declared that `choose` is a global variable.

You should remove this as it adds an unnecessary global variable. Even
if you wish to retain it as a global, you probably should choose a
better name (e.g. current_cave) since the name `choose` has no meaning
outside choose_Cave function.

Also, at the end:

def choose_Cave():
     ....
     return choose


you returned a global variable. Although in some cases it may be
necessary or wanted to return a global variable, you most likely don't
need it since you can always access a global variable from anywhere in a
script. You should make `choose` a local and assign the return value of
choose_Cave() to another name (e.g. current_cave).

> the prompt 'Choose a cave' is repeated when the script is run.
> Dont want this. I tested this when run in ipython.
>
> I dont know if there is a way to just retrieve the return value to a
> variable AND not run the whole function i mean in the case of
>
> ans = choose_Cave(). Would love to hear your expert insights by return.

A function can be run multiple times, and its return value may be
different every time it is run (in fact if the return value is always
the same there is no point in using function). "accessing the return
value and not run the function" doesn't make sense as it is unclear what
you're wanting to access. What you wanted is to access the latest return
value of choose_Cave, which means you want to store the return value of
choose_Cave in a variable (i.e. current_cave = choose_Cave() or ans =
choose_Cave())

An alternative would be to store the latest return value in a global
variable, but I strongly recommend against this as global variable is
harmful.

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

Parent Message unknown Re: Local vs global

by bibi midi :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Sun, Nov 8, 2009 at 8:38 AM, Dave Angel <davea@...> wrote:
>
> You have the following line at top-level:
>
>   if ask.lower not in reply:
>
> But you're not calling the method str.lower(), you're just creating a
> function object from it.  You need those parentheses.
>
>   if ask.lower() not in reply:
>
>
> You have the following fragment in main():
>
>   print(intro)
>   choose_Cave()
>   ans = choose_Cave    # use: pass function by reference
>   checkCave(ans)
>
>
> which has two references to choose_Cave().  The first one calls it, but
> throws away the return value.  The second does not call it at all, but
> merely creates a function object and stores it in ans.  You need to combine
> your two intents in one line:
>
>   print(intro)
>   ans = choose_Cave()    # use: pass function by reference
>   checkCave(ans)
>
> Hope that helps.  Remember, that unlike Pascal, in Python you don't call the
> function unless you include the parentheses.

Hi Dave and all,

My eyes failed me spotting the bugs :-) They are just staring at me
yet i miss to catch them. I guess thats the net result when one take
it too seriously haha (joke).

I fully agree function is not called when the parenthesis is missing,
you only call the object. About Pascal or VB i cant comment on them
:-)

The code works as expected now. I guess i have to move on to the other examples.

Will be back here to bug you guys with questions :-) Thank you for so helpful.


--
Best Regards

Jonathan Swift  - "May you live every day of your life." -
http://www.brainyquote.com/quotes/authors/j/jonathan_swift.html



--
Best Regards,
bibimidi



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