Importing an output from another function

B

Byte

Probably a stupid question, but I'm a newbie and this really pisses me
off. Run this script:

import random

def Func1():
choice = ('A', 'B', 'C')
output = random.choice(choice)

def Func2():
print output

Func1()
Func2()

And: an error message...... It says:

Traceback (most recent call last):
File "ptls-demo.py", line 11, in ?
Func2()
File "how -the-hell-do-i-fix-this.py", line 8, in Func2
print output
NameError: global name 'output' is not defined

Obviosly, I need to import the variable 'output' from Func1() into
Func2(), but how?

Thanks in advance,
-- /usr/bin/byte
 
B

bearophileHUGS

Generally, a name defined into a function can't be read outside of it,
so you have to return the function result explicitely:

import random

def Func1():
choice = ('A', 'B', 'C')
output = random.choice(choice)
return output

def Func2(item):
print item

output1 = Func1()
Func2(output1)


Bye,
bearophile
 
B

Byte

Now what do I do if Func1() has multiple outputs and Func2() requires
them all to give its own output, as follows:

import random

def Func1():
choice = ('A', 'B', 'C')
output = random.choice(choice)
output2 = random.choice(choice)
return output
return output2

def Func2(item1, item2):
print item1, item2

output1 = Func1()
Func2(output1)

Thanks in advance,
-- /usr/bin/byte
 
J

John Salerno

Byte said:
Now what do I do if Func1() has multiple outputs and Func2() requires
them all to give its own output, as follows:

You can return them as a tuple:
output1 = 'hi'
output2 = 'bye'
return (output1, output2)
print data
('hi', 'bye')

def Func1():
choice = ('A', 'B', 'C')
output = random.choice(choice)
output2 = random.choice(choice)
return output
return output2

Only the first return statement would run in that code.
 
J

James Stroud

Byte said:
Now what do I do if Func1() has multiple outputs and Func2() requires
them all to give its own output, as follows:

import random

def Func1():
choice = ('A', 'B', 'C')
output = random.choice(choice)
output2 = random.choice(choice)
return output
return output2

The function will return at "return output", so "return output2" will
never be reached.

def Func2(item1, item2):
print item1, item2

output1 = Func1()
Func2(output1)

Thanks in advance,
-- /usr/bin/byte

Try this (I think its called "argument expansion", but I really don't
know what its called, so I can't point you to docs):

def Func1():
choice = ('A', 'B', 'C')
output = random.choice(choice)
output2 = random.choice(choice)
return output, output2

def Func2(*items):
print items

output = Func1()
Func2(output1)


BETTER:
=======

You can also make a "generator" (which I have made generalized, which
seems to be what you are striving for):


def Gener1(num):
choice = ('A', 'B', 'C')
for i in xrange(num):
yield random.choice(choice)

def Func2(item):
print item

for item in Gener1(2):
Func2(item)


James

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
 
J

James Stroud

Byte said:
Now what do I do if Func1() has multiple outputs and Func2() requires
them all to give its own output, as follows:

import random

def Func1():
choice = ('A', 'B', 'C')
output = random.choice(choice)
output2 = random.choice(choice)
return output
return output2


The function will return at "return output", so "return output2" will
never be reached.
def Func2(item1, item2):
print item1, item2

output1 = Func1()
Func2(output1)

Thanks in advance,
-- /usr/bin/byte


Try this (I think its called "argument expansion", but I really don't
know what its called, so I can't point you to docs):

def Func1():
choice = ('A', 'B', 'C')
output = random.choice(choice)
output2 = random.choice(choice)
return output, output2

def Func2(*items):
print items

output = Func1()
Func2(*output1)


BETTER:
=======

You can also make a "generator" (which I have made generalized, which
seems to be what you are striving for):


def Gener1(num):
choice = ('A', 'B', 'C')
for i in xrange(num):
yield random.choice(choice)

def Func2(item):
print item

for item in Gener1(2):
Func2(item)


James

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
 
J

John Salerno

James said:
Try this (I think its called "argument expansion", but I really don't
know what its called, so I can't point you to docs):

def Func1():
choice = ('A', 'B', 'C')
output = random.choice(choice)
output2 = random.choice(choice)
return output, output2

def Func2(*items):
print items

output = Func1()
Func2(*output1)

I was wondering about '*items' when I wrote my response. I left out the
asterisk in my version and it still seems to work. Is it necessary?
 
J

James Stroud

John said:
I was wondering about '*items' when I wrote my response. I left out the
asterisk in my version and it still seems to work. Is it necessary?

Yours is better, after I wrote mine, I realized the asterisk was
unnecessary for this particular example, except that it makes Func2 more
general.

James

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
 
J

John Salerno

James said:
Yours is better, after I wrote mine, I realized the asterisk was
unnecessary for this particular example, except that it makes Func2 more
general.

Yeah, I tested it. Func2 prints a tuple of a tuple when the asterisk is
used.

But your generator still wins. :)
 
J

James Stroud

John Salerno wrote
James Stroud wrote

Try this (I think its called "argument expansion", but I reall don'
know what its called, so I can't point you to docs)

def Func1()
choice = ('A', 'B', 'C'
output = random.choice(choice
output2 = random.choice(choice
return output, output

def Func2(*items)
print item

output = Func1(
Func2(*output1


I was wondering about '*items' when I wrote my response. I left ou th
asterisk in my version and it still seems to work. Is it necessary
Yours is better, after I wrote mine, I realized the asterisk was
unnecessary for this particular example, except that it makes Func
more
general

Jame

--
James Strou
UCLA-DOE Institute for Genomics and Proteomic
Box 95157
Los Angeles, CA 9009

http://www.jamesstroud.com
 
P

Paul Rubin

Byte said:
Probably a stupid question, but I'm a newbie and this really pisses me
off. Run this script:

import random

def Func1():
choice = ('A', 'B', 'C')
output = random.choice(choice)

def Func2():
print output

Func1()
Func2()

You could declare output to be global, but it's kind of poor style.
Preferable is something like:

def Func1():
choice = ('A', 'B', 'C')
output = random.choice(choice)
return output

def Func2(x):
print x

output = Func1() # this "output" is not the same as the one in Func1
Func2(output)
 
T

Terry Hancock

Probably a stupid question, but I'm a newbie and this
really pisses me off. Run this script:

import random

def Func1():
choice = ('A', 'B', 'C')
output = random.choice(choice)

def Func2():
print output

Func1()
Func2()

Several possible solutions. The simplest (but least
informative):

"""
import random

def Func1():
global output
choice = ('A', 'B', 'C')
output = random.choice(choice)

def Func2():
print output

Func1()
Func2()
"""

i.e. make output a global variable

But as has already been pointed out, you aren't really using
the nature of functions here. Better:

"""
import random

def Func1():
return random.choice(('A', 'B', 'C'))

def Func2(output):
print output

Func2(Func1())
"""

You later ask about returning multiple values. Python is
pretty cool in this respect -- you can return multiple
values in a tuple, which can then be "unpacked"
automatically. This gives you a nice many-to-many idiom for
function calls, e.g.:

x, y = random_point(x_min, x_max, y_min, y_max)

And if you need to pass that to a function which takes two
arguments (x,y), you can:

set_point(*random_point(x_min, x_max, y_min, y_max))

Of course, some people would rather see that expanded out,
and indeed, too many nested function calls can be hard on
the eyes, so you might want to do this anyway:

x, y = random_point(x_min, x_max, y_min, y_max)
set_point(x, y)

or

P = random_point(x_min, x_max, y_min, y_max)
set_point(P)

and of course, it's possible that the function requires the
arguments in a different order, e.g.:

x, y = random_point(1,80,1,25)
set_rowcol(y, x, 'A')

or some such thing.

By far the coolest thing about tuple-unpacking, though, is
that this works like you'd expect it to:

x, y = y, x

instead of being a dumb mistake like this is:

x = y
y = x

which of course should be

temp = y
x = y
y = temp

But ewww that's ugly.

Cheers,
Terry
 
B

Ben Cartwright

James said:
Try this (I think its called "argument expansion", but I really don't
know what its called, so I can't point you to docs):

def Func1():
choice = ('A', 'B', 'C')
output = random.choice(choice)
output2 = random.choice(choice)
return output, output2

def Func2(*items):
print items

output = Func1()
Func2(*output1)


Single asterisk == "arbitrary argument list". Useful in certain
patterns, but not something you use every day.

Documentation is in the tutorial:
http://www.python.org/doc/current/tut/node6.html#SECTION006730000000000000000

PS: Like "self" for class instance methods, "*args" is the
conventional name of the arbitrary argument list.

--Ben
 
B

Byte

"Try this (I think its called "argument expansion", but I really don't
know what its called, so I can't point you to docs):"

This works, thanks. But how acn I get rid of the ugly surrounding
brackets and commas?

e.g. If the scripts overall output was (('B', 'C'),), how to change it
to just B C?
 
J

John Salerno

Byte said:
"Try this (I think its called "argument expansion", but I really don't
know what its called, so I can't point you to docs):"

This works, thanks. But how acn I get rid of the ugly surrounding
brackets and commas?

e.g. If the scripts overall output was (('B', 'C'),), how to change it
to just B C?

You can get rid of the outer parentheses by removing the asterisk from
the parameter list. But the other parentheses: ('B', 'C') will remain,
because it's a tuple. You can access the values by indexing.
 
M

Magnus Lycka

Byte said:
Now what do I do if Func1() has multiple outputs and Func2() requires
them all to give its own output, as follows:

import random

def Func1():
choice = ('A', 'B', 'C')
output = random.choice(choice)
output2 = random.choice(choice)
return output
return output2

def Func2(item1, item2):
print item1, item2

output1 = Func1()
Func2(output1)

Some more options (untested):

def func1(n, choice=('A', 'B', 'C')):
# n=number of choices
# choice can now be overridden with
# other values
choices = []
for i in range(n):
choices.append(random.choice(choice))
return choices

def func2(choices):
for choice in choices:
print choice,
print

func2(func1(2))

#########################################

class ChoosePrinter(object):
def __init__(self, to_choose_from=('A', 'B', 'C')):
self.to_choose_from=to_choose_from
self.choosen = []
def get_choices(self, n=2):
for i in range(n):
self.choosen.append(random.choice(choice))
def dump_choosen(self):
print " ".join(self.choosen)
self.choosen = []

cp = ChoosePrinter()
cp.get_choices(2)
cp.dump_choosen()
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top