Confused: Newbie Function Calls

F

fuglyducky

I am a complete newbie to Python (and programming in general) and I
have no idea what I'm missing. Below is a script that I am trying to
work with and I cannot get it to work. When I call the final print
function, nothing prints. However, if I print within the individual
functions, I get the appropriate printout.

Am I missing something??? Thanks in advance!!!!

################################################
# Global variable
sample_string = ""

def gen_header(sample_string):
HEADER = """
mymultilinestringhere
"""

sample_string += HEADER
return sample_string

def gen_nia(sample_string):
NIA = """
anothermultilinestringhere
"""

sample_string += NIA
return sample_string


gen_header(sample_string)
gen_nia(sample_string)

print(sample_string)
 
M

Michael Torrie

I am a complete newbie to Python (and programming in general) and I
have no idea what I'm missing. Below is a script that I am trying to
work with and I cannot get it to work. When I call the final print
function, nothing prints. However, if I print within the individual
functions, I get the appropriate printout.

Am I missing something??? Thanks in advance!!!!

Yes. You are passing sample_string into the functions, but not doing
anything with the return value.
def gen_header(sample_string):
^^^^^^^^^^^^^^^
The sample_string name is rebound to the parameter now, completely
hiding the global variable, if that's really what you wanted.
def gen_nia(sample_string):
^^^^^^^^^^^^^^^^^^^
Again.
NIA = """
anothermultilinestringhere
"""

sample_string += NIA
return sample_string


gen_header(sample_string)
gen_nia(sample_string)

Try this:

sample_string = gen_header(sample_string)
sample_string = gen_nia(sample_string)

You could drop the arguments to your functions and use the "global"
keyword to get access to sample_string from within the functions, but
normally that's a bad idea.
 
P

Pinku Surana

I am a complete newbie to Python (and programming in general) and I
have no idea what I'm missing. Below is a script that I am trying to
work with and I cannot get it to work. When I call the final print
function, nothing prints. However, if I print within the individual
functions, I get the appropriate printout.

Am I missing something??? Thanks in advance!!!!

################################################
# Global variable
sample_string = ""

def gen_header(sample_string):
    HEADER = """
    mymultilinestringhere
    """

    sample_string += HEADER
    return sample_string

def gen_nia(sample_string):
    NIA = """
    anothermultilinestringhere
    """

    sample_string += NIA
    return sample_string

gen_header(sample_string)
gen_nia(sample_string)

print(sample_string)

There are 2 problems with your program.

(1) If you want to use a global variable in a function, you have to
add the line "global sample_string" to the beginning of that
function.

(2) Once you do (1), you will get an error because you've got
sample_string as a global and a function parameter. Which one do you
want to use in the function? You should change the name of the
parameter to "sample" to solve that confusion.

Here's the result, which works for me:

sample_string = ""
def gen_header(sample):
global sample_string
HEADER = """
mymultilinestringhere
"""
sample_string = sample + HEADER
return sample_string
def gen_nia(sample):
global sample_string
NIA = """
anothermultilinestringhere
"""
sample_string = sample + NIA
return sample_string
gen_header(sample_string)
gen_nia(sample_string)
print(sample_string)
 
R

Robert Kern

I am a complete newbie to Python (and programming in general) and I
have no idea what I'm missing. Below is a script that I am trying to
work with and I cannot get it to work. When I call the final print
function, nothing prints. However, if I print within the individual
functions, I get the appropriate printout.

Am I missing something??? Thanks in advance!!!!

################################################
# Global variable
sample_string = ""

def gen_header(sample_string):
HEADER = """
mymultilinestringhere
"""

sample_string += HEADER
return sample_string

By default, all assignments inside of a function are local to the function. Even
augmented assignments like +=. Python strings are immutable, so

sample_string += HEADER

works exactly like

sample_string = sample_string + HEADER

The string referred to by the global name sample_string is never modified and
the global name is never reassigned.

http://docs.python.org/py3k/tutorial/classes.html#python-scopes-and-namespaces
gen_header(sample_string)
gen_nia(sample_string)

print(sample_string)

You probably want something like the following:

sample_string = gen_header(sample_string)
sample_string = gen_nia(sample_string)

print(sample_string)

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
 
E

EW

This will work:
------------------------------------------------------------------------
sample_string=""

def gen_header(sample_string=""):
HEADER = """
mymultilinestringhere
"""

sample_string+= HEADER
return sample_string

def gen_nia(sample_string=""):

NIA = """
anothermultilinestringhere
"""
sample_string += NIA
return sample_string

sample_string = gen_header(sample_string)
sample_string = gen_nia(sample_string)
print(sample_string)

------------------------------------------------------------------------
and this will work
------------------------------------------------------------------------

sample_string=""

def gen_header(OtherString):
global sample_string
HEADER = """
mymultilinestringhere
"""

sample_string+= HEADER


def gen_nia(OtherString):
global sample_string
NIA = """
anothermultilinestringhere
"""
sample_string += NIA


gen_header(sample_string)
gen_nia(sample_string)
print(sample_string)

------------------------------------------------------------------------


The first one is the better of the 2 in this example but the second
one will show you how to use global variables if you really need to
use them

So your problem was that you thought you were working on a global
variable in your functions when you were not. Since the your def
lines contained sample_string that make it a local variable. So when
you were doing your += statements you were working on a local variable
and not a global variable. You were returning the value of the local
variable but you didn't have anything in the main body of your script
catching that value. So simply changing these 2 lines:
sample_string = gen_header(sample_string)
sample_string = gen_nia(sample_string)

made the global sample_string variable store the values of the return
data.


If you want to use global variables then you just have to do 2
things. First you have to make sure you don't have any local
variables it the function with the same name. So I change the name to
OtherString in the def line. Then you need a global statement at the
start of your function (global sample_string) that tells python that
you really do want to use that global variable.

Global variables can cause you no end of heartache so python forces
you to explicitly state that you want to use them.

Hope that helps.
 
F

fuglyducky

There are 2 problems with your program.

(1) If you want to use a global variable in a function, you have to
add the line "global sample_string" to the beginning of that
function.

(2) Once you do (1), you will get an error because you've got
sample_string as a global and a function parameter. Which one do you
want to use in the function? You should change the name of the
parameter to "sample" to solve that confusion.

Here's the result, which works for me:

sample_string = ""
def gen_header(sample):
    global sample_string
    HEADER = """
    mymultilinestringhere
    """
    sample_string = sample + HEADER
    return sample_string
def gen_nia(sample):
    global sample_string
    NIA = """
    anothermultilinestringhere
    """
    sample_string = sample + NIA
    return sample_string
gen_header(sample_string)
gen_nia(sample_string)
print(sample_string)

Thanks! That did the trick.

I am a bit confused though. I tried to follow a sample in a book
(which works) where I didn't have to 1) pass the global variable as a
parameter into the function, 2) did not have to define the global
variable within the function. I apologize if this is a super stupid
question but if it is global, why do I have to pass it into the
function? Shouldn't the global variable be accessible from anywhere???
 
J

Jean-Michel Pichavant

fuglyducky said:
I am a complete newbie to Python (and programming in general) and I
have no idea what I'm missing. Below is a script that I am trying to
work with and I cannot get it to work. When I call the final print
function, nothing prints. However, if I print within the individual
functions, I get the appropriate printout.

Am I missing something??? Thanks in advance!!!!

################################################
# Global variable
sample_string = ""

def gen_header(sample_string):
HEADER = """
mymultilinestringhere
"""

sample_string += HEADER
return sample_string

def gen_nia(sample_string):
NIA = """
anothermultilinestringhere
"""

sample_string += NIA
return sample_string


gen_header(sample_string)
gen_nia(sample_string)

print(sample_string)
sample_string = gen_header(sample_string)
sample_string = gen_nia(sample_string)

print sample_string

That should work.

I guess you made an error thinking that

sample_string += HEADER

would change the value of the given parameter. It does not. The value is
changed only for sample_string within the function This is the case for
any immutable object (strings are immutable) in Python.

Example:


class AMutable(object):
def __init__(self):
self.description = 'I am X'

myString = 'I am a immutable string' # an immutable object
myMutable = AMutable() # a mutable object

def bar(myMutable):
myMutable.description = 'I am Y' # change the attribute description
of the object

def foo(aString):
aString = 'fooooooooo' # will have no effect outside the function

print 'before calling bar: ', myMutable.description
bar(myMutable)
print 'after calling bar: ', myMutable.description
print 'before calling foo: ', myString
foo(myString)
print 'after calling foo: ', myString

before calling bar: I am X
after calling bar: I am Y
before calling foo: I am a immutable string
after calling foo: I am a immutable string

cheers,

JM
 
E

EW

Thanks! That did the trick.

I am a bit confused though. I tried to follow a sample in a book
(which works) where I didn't have to 1) pass the global variable as a
parameter into the function, 2) did not have to define the global
variable within the function. I apologize if this is a super stupid
question but if it is global, why do I have to pass it into the
function? Shouldn't the global variable be accessible from anywhere???

If it's a global then you don't have to pass it to the function but
you do have to have the line that says:
global sample_string


Now if you think the example in the book didn't do that and it still
worked then if you post that sample I'm sure somebody can tell you why
it worked. The book example might be doing something different.
 
D

Dave Angel

fuglyducky said:
I am a complete newbie to Python (and programming in general) and I
have no idea what I'm missing. Below is a script that I am trying to
work with and I cannot get it to work. When I call the final print
function, nothing prints. However, if I print within the individual
functions, I get the appropriate printout.

Am I missing something??? Thanks in advance!!!!

################################################
# Global variable
sample_string = ""

def gen_header(sample_string):
HEADER = """
mymultilinestringhere
"""

sample_string += HEADER
return sample_string

def gen_nia(sample_string):
NIA = """
anothermultilinestringhere
"""

sample_string += NIA
return sample_string


gen_header(sample_string)
gen_nia(sample_string)

print(sample_string)
It'd be best if you used different names for global scope than you do
inside your functions. It won't change how this case works, but at
least it'd be clearer what's happening. And sometimes you can get an
unintended side effect when you use the same name for two different
variables.

In function gen_header(), you take an argument, and return a modified
version of it. But the call to it never uses the return value. If you
want to make any changes to the global value, you'd do something like this:

sample_string = gen_header(sample_string)
sample_string = gen_nia(sample_string)

print(sample_string)


HTH
DaveA
 
T

Terry Reedy

Rather than patch your code, I think you should see a better approach.

from textwrap import dedent # removes common whitespace prefix

lines = []

def add_header(ss):
"Add header to sequence of string lines"
ss.append(dedent("""\ # No initial blank line
my multi-line
string here
"""))

def add_more(ss):
"Add more to sequence of string lines"
ss.append(dedent(""" # Start with blank line
another
multi-line
string here
"""))

add_header(lines)
add_more(lines)

print(''.join(lines)) # prints
--------------------------------
my multi-line
string here

another
multi-line
string here
 
P

Pinku Surana

Thanks! That did the trick.

I am a bit confused though. I tried to follow a sample in a book
(which works) where I didn't have to 1) pass the global variable as a
parameter into the function, 2) did not have to define the global
variable within the function. I apologize if this is a super stupid
question but if it is global, why do I have to pass it into the
function? Shouldn't the global variable be accessible from anywhere???

Since you're new to programming, it's important to understand the
fundamentals.

x = 0 # GLOBAL

def fun(x): # PARAMETER, a type of LOCAL variable
y = 1 # LOCAL
x += y # Which x do you mean? The local or global?
print x # What is this value?

fun(x)
print x # What is this value?


Even though I used the same name "x" for a local and global variable,
they are actually completely different. When I call "fun(x)" it COPIES
the global value of "x" into the local variable "x" in "fun". In this
code, Python assumes in "x += y" you want to use the LOCAL variable.
To Python the code looks like this:

x_global = 0

def fun(x_local):
y_local = 1
x_local += y_local
print x_local

fun(x_global)
print x_global # This is never changed!

If that's not what you want, then you have to explicitly tell Python
that you want to use the global value (this is not good programming
style, by the way!). That's what the "global" keyword does.

Try to write some small programs that pass around numbers and strings
with different variable names. Try every combination you can think of
until you get good at predicting what the output is.
 
S

Stefan Schwarzer

Hi Pinku,

Even though I used the same name "x" for a local and global variable,
they are actually completely different. When I call "fun(x)" it COPIES
the global value of "x" into the local variable "x" in "fun". [...]

The global value isn't copied when calling the function.
Instead, the global and the local name both point to the
same object when the body of the function starts to run.
def fun(x_local):
y_local = 1
x_local += y_local
print x_local

Only after the assignment "x_local += y_local" x_local
points to a new object which is the result of the addition
of the previously "shared" object and y_local.

Stefan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top