Re: [Tutor] Functions returning multiple values

2010-02-23 Thread Giorgio
I have an update:

I can easily undertand why this example doesn't work:

def nochange(x):
x = 0

y = 1
nochange(y)
print y # Prints out 1

X is a local variable, and only gets modified in the function, that doesn't
return any value.

But it's very difficult for me to understand WHY this works:

def change(some_list):
some_list[1] = 4

x = [1,2,3]
change(x)
print x # Prints out [1,4,3]

some_list is a local list, isn't it? Maybe i can't have lists that are
only existing in a function?

Thankyou all

2010/2/22 Kent Johnson ken...@tds.net

 On Mon, Feb 22, 2010 at 9:13 AM, Giorgio anothernetfel...@gmail.com
 wrote:

  And, i have some difficulties understanding the other strange example
 in
  that howto. Just scroll down to: However, the point is that the value
  of x is picked up from the environment at the time when the function is
  defined. How is this useful? Let’s take an example — a function which
  composes two other functions.
  He is working on a function that compose other 2 functions. This is the
  final solution
  def compose(fun1, fun2):
  def inner(x, fun1=fun1, fun2=fun2):
  return fun1(fun2(x))
  return inner
  But also tries to explain why this example:
  # Wrong version
  def compose(fun1, fun2):
  def inner(x):
  return fun1(fun2(x))
  return inner
  def fun1(x):
  return x +  world!
  def fun2(x):
  return Hello,
  sincos = compose(sin,cos)  # Using the wrong version
  x = sincos(3)
  Won't work. Now, the problem is that the inner function gets fun1 and
 fun2
  from other 2 functions.
  My question is: why? inner is a sub-function of compose, where fun1 and
 fun2
  are defined.

 It does work:
 In [6]: def compose(fun1, fun2):
...: def inner(x):
   ...: return fun1(fun2(x))
   ...: return inner
...:

 In [7]: def fun1(x):
   ...: return x +  world!
   ...:

 In [8]: def fun2(x):
   ...: return Hello,
   ...:

 In [9]: from math import sin, cos

 In [10]: sincos = compose(sin,cos)  # Using the wrong version

 In [11]:

 In [12]: x = sincos(3)

 In [13]:

 In [14]: x
 Out[14]: -0.8360218615377305

 That is a very old example, from python 2.1 or before where nested
 scopes were not supported. See the note A Note About Python 2.1 and
 Nested Scopes - that is now the default behaviour.

 Kent




-- 
--
AnotherNetFellow
Email: anothernetfel...@gmail.com
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Functions returning multiple values

2010-02-23 Thread Christian Witts

Giorgio wrote:

I have an update:

I can easily undertand why this example doesn't work:

def nochange(x):
x = 0

y = 1
nochange(y)
print y # Prints out 1

X is a local variable, and only gets modified in the function, that 
doesn't return any value.


But it's very difficult for me to understand WHY this works:

def change(some_list):
some_list[1] = 4

x = [1,2,3]
change(x)
print x # Prints out [1,4,3]

some_list is a local list, isn't it? Maybe i can't have lists that 
are only existing in a function?


Thankyou all

2010/2/22 Kent Johnson ken...@tds.net mailto:ken...@tds.net

On Mon, Feb 22, 2010 at 9:13 AM, Giorgio
anothernetfel...@gmail.com mailto:anothernetfel...@gmail.com
wrote:

 And, i have some difficulties understanding the other strange
example in
 that howto. Just scroll down to: However, the point is that the
value
 of x is picked up from the environment at the time when the
function is
 defined. How is this useful? Let’s take an example — a function
which
 composes two other functions.
 He is working on a function that compose other 2 functions. This
is the
 final solution
 def compose(fun1, fun2):
 def inner(x, fun1=fun1, fun2=fun2):
 return fun1(fun2(x))
 return inner
 But also tries to explain why this example:
 # Wrong version
 def compose(fun1, fun2):
 def inner(x):
 return fun1(fun2(x))
 return inner
 def fun1(x):
 return x +  world!
 def fun2(x):
 return Hello,
 sincos = compose(sin,cos)  # Using the wrong version
 x = sincos(3)
 Won't work. Now, the problem is that the inner function gets
fun1 and fun2
 from other 2 functions.
 My question is: why? inner is a sub-function of compose, where
fun1 and fun2
 are defined.

It does work:
In [6]: def compose(fun1, fun2):
  ...: def inner(x):
  ...: return fun1(fun2(x))
  ...: return inner
  ...:

In [7]: def fun1(x):
  ...: return x +  world!
  ...:

In [8]: def fun2(x):
  ...: return Hello,
  ...:

In [9]: from math import sin, cos

In [10]: sincos = compose(sin,cos)  # Using the wrong version

In [11]:

In [12]: x = sincos(3)

In [13]:

In [14]: x
Out[14]: -0.8360218615377305

That is a very old example, from python 2.1 or before where nested
scopes were not supported. See the note A Note About Python 2.1 and
Nested Scopes - that is now the default behaviour.

Kent




--
--
AnotherNetFellow
Email: anothernetfel...@gmail.com mailto:anothernetfel...@gmail.com


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

Take a look at the Python gothcha's:
http://www.ferg.org/projects/python_gotchas.html#contents_item_6

--
Kind Regards,
Christian Witts


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


Re: [Tutor] Functions returning multiple values

2010-02-23 Thread Giorgio
Thankyou.

It's clear, this definitely helps me with the first question. But still
doesn't explain almost anything about the example i've posted in the last
post, right?

Giorgio

2010/2/23 Christian Witts cwi...@compuscan.co.za

 Giorgio wrote:

 I have an update:

 I can easily undertand why this example doesn't work:

 def nochange(x):
x = 0

 y = 1
 nochange(y)
 print y # Prints out 1

 X is a local variable, and only gets modified in the function, that
 doesn't return any value.

 But it's very difficult for me to understand WHY this works:

 def change(some_list):
some_list[1] = 4

 x = [1,2,3]
 change(x)
 print x # Prints out [1,4,3]

 some_list is a local list, isn't it? Maybe i can't have lists that are
 only existing in a function?

 Thankyou all

 2010/2/22 Kent Johnson ken...@tds.net mailto:ken...@tds.net


On Mon, Feb 22, 2010 at 9:13 AM, Giorgio
anothernetfel...@gmail.com mailto:anothernetfel...@gmail.com

wrote:

 And, i have some difficulties understanding the other strange
example in
 that howto. Just scroll down to: However, the point is that the
value
 of x is picked up from the environment at the time when the
function is
 defined. How is this useful? Let’s take an example — a function
which
 composes two other functions.
 He is working on a function that compose other 2 functions. This
is the
 final solution
 def compose(fun1, fun2):
 def inner(x, fun1=fun1, fun2=fun2):
 return fun1(fun2(x))
 return inner
 But also tries to explain why this example:
 # Wrong version
 def compose(fun1, fun2):
 def inner(x):
 return fun1(fun2(x))
 return inner
 def fun1(x):
 return x +  world!
 def fun2(x):
 return Hello,
 sincos = compose(sin,cos)  # Using the wrong version
 x = sincos(3)
 Won't work. Now, the problem is that the inner function gets
fun1 and fun2
 from other 2 functions.
 My question is: why? inner is a sub-function of compose, where
fun1 and fun2
 are defined.

It does work:
In [6]: def compose(fun1, fun2):
  ...: def inner(x):
  ...: return fun1(fun2(x))
  ...: return inner
  ...:

In [7]: def fun1(x):
  ...: return x +  world!
  ...:

In [8]: def fun2(x):
  ...: return Hello,
  ...:

In [9]: from math import sin, cos

In [10]: sincos = compose(sin,cos)  # Using the wrong version

In [11]:

In [12]: x = sincos(3)

In [13]:

In [14]: x
Out[14]: -0.8360218615377305

That is a very old example, from python 2.1 or before where nested
scopes were not supported. See the note A Note About Python 2.1 and
Nested Scopes - that is now the default behaviour.

Kent




 --
 --
 AnotherNetFellow
 Email: anothernetfel...@gmail.com mailto:anothernetfel...@gmail.com
 


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


 Take a look at the Python gothcha's:
 http://www.ferg.org/projects/python_gotchas.html#contents_item_6

 --
 Kind Regards,
 Christian Witts





-- 
--
AnotherNetFellow
Email: anothernetfel...@gmail.com
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Functions returning multiple values

2010-02-23 Thread Hugo Arts
On Tue, Feb 23, 2010 at 1:13 PM, Giorgio anothernetfel...@gmail.com wrote:
 I have an update:
 I can easily undertand why this example doesn't work:
 def nochange(x):
     x = 0
 y = 1
 nochange(y)
 print y # Prints out 1
 X is a local variable, and only gets modified in the function, that doesn't
 return any value.
 But it's very difficult for me to understand WHY this works:
 def change(some_list):
     some_list[1] = 4
 x = [1,2,3]
 change(x)
 print x # Prints out [1,4,3]
 some_list is a local list, isn't it? Maybe i can't have lists that are
 only existing in a function?

Here is what happens, as I understand it:
When you enter the function, a new name (x, in your case) is created
in the local scope. That name points to the object you supplied when
you called the function (an integer object, with a value of 1). the x
= 0 statement creates a new object, and has the name x now pointing to
this new object. The old integer object still exists, and y still
points to it. This is why the global y name is not affected by the
change in x

Now, in the second example, the same thing basically happens. A new
name is created and pointed at the object you supplied. However, the
statement some_list[1] = 4 is different from the assignment, in that
it doesn't create a new object; It modifies the existing one. Since
the global and local names both point to the same object, the change
you make is reflected in both.

You can of course create a new list object, so that the original is
not affected:

def nochange(some_list):
# create shallow copy of list. NOTE: Shallow copies may still bite
you if you change the list members.
some_list = some_list[:]
some_list[1] = 2

 x = [1, 2, 3]
 nochange(x)
 x
[1, 2, 3]

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


Re: [Tutor] Functions returning multiple values

2010-02-23 Thread Giorgio
Thankyou Hugo!

Ok, so i think the key is of my problem is that when doing X = 0 i'm
creating a new object, that only exist in the local namespace. BUT, when
using a list as a parameter for a function i'm only giving it a new name,
but the object it's referring to it's always the same, and is in the global
namespace.

Right?

2010/2/23 Hugo Arts hugo.yo...@gmail.com

 On Tue, Feb 23, 2010 at 1:13 PM, Giorgio anothernetfel...@gmail.com
 wrote:
  I have an update:
  I can easily undertand why this example doesn't work:
  def nochange(x):
  x = 0
  y = 1
  nochange(y)
  print y # Prints out 1
  X is a local variable, and only gets modified in the function, that
 doesn't
  return any value.
  But it's very difficult for me to understand WHY this works:
  def change(some_list):
  some_list[1] = 4
  x = [1,2,3]
  change(x)
  print x # Prints out [1,4,3]
  some_list is a local list, isn't it? Maybe i can't have lists that are
  only existing in a function?

 Here is what happens, as I understand it:
 When you enter the function, a new name (x, in your case) is created
 in the local scope. That name points to the object you supplied when
 you called the function (an integer object, with a value of 1). the x
 = 0 statement creates a new object, and has the name x now pointing to
 this new object. The old integer object still exists, and y still
 points to it. This is why the global y name is not affected by the
 change in x

 Now, in the second example, the same thing basically happens. A new
 name is created and pointed at the object you supplied. However, the
 statement some_list[1] = 4 is different from the assignment, in that
 it doesn't create a new object; It modifies the existing one. Since
 the global and local names both point to the same object, the change
 you make is reflected in both.

 You can of course create a new list object, so that the original is
 not affected:

 def nochange(some_list):
# create shallow copy of list. NOTE: Shallow copies may still bite
 you if you change the list members.
some_list = some_list[:]
some_list[1] = 2

  x = [1, 2, 3]
  nochange(x)
  x
 [1, 2, 3]

 HTH,
 Hugo




-- 
--
AnotherNetFellow
Email: anothernetfel...@gmail.com
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Functions returning multiple values

2010-02-23 Thread Hugo Arts
On Tue, Feb 23, 2010 at 2:28 PM, Giorgio anothernetfel...@gmail.com wrote:
 Thankyou Hugo!
 Ok, so i think the key is of my problem is that when doing X = 0 i'm
 creating a new object, that only exist in the local namespace. BUT, when
 using a list as a parameter for a function i'm only giving it a new name,
 but the object it's referring to it's always the same, and is in the global
 namespace.
 Right?

Well, mostly, yes. It's important to see that it's not so much the
objects that live in namespaces, it's the names (otherwise they would
be called object-spaces, yes?). The objects do not live inside a
namespace, but are in a conceptually separate place altogether. A name
lives in a namespace, and can only be referenced inside that space. An
object can be referenced from anywhere, as long as you have a name
that points to it.

So, when you're doing x = 0, you're creating a new object, and the
name x (in the local namespace) points to that object. That doesn't
mean the object itself is confined to the local namespace. You could
write 'return x', which allows you to have a name in the global
namespace point to that same object.

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


Re: [Tutor] Functions returning multiple values

2010-02-23 Thread Giorgio
Ok Hugo,

so, going back to your example:

def nochange(some_list):
   # create shallow copy of list. NOTE: Shallow copies may still bite
you if you change the list members.
   some_list = some_list[:]
   some_list[1] = 2

Here we've created a new list. It's an object in the global object-space
:) but i can't access it outside the function because i don't have a name
referring to it in the global namespace.

Right?

And, please let me ask a question: Kent told that nested_namespace(s) are
default in python 2.6. And i found a line confirming this in py2.6 library.
But, what about python 2.5 that as you know is the default on linux?

Thankyou

Giorgio

2010/2/23 Hugo Arts hugo.yo...@gmail.com

 On Tue, Feb 23, 2010 at 2:28 PM, Giorgio anothernetfel...@gmail.com
 wrote:
  Thankyou Hugo!
  Ok, so i think the key is of my problem is that when doing X = 0 i'm
  creating a new object, that only exist in the local namespace. BUT, when
  using a list as a parameter for a function i'm only giving it a new name,
  but the object it's referring to it's always the same, and is in the
 global
  namespace.
  Right?

 Well, mostly, yes. It's important to see that it's not so much the
 objects that live in namespaces, it's the names (otherwise they would
 be called object-spaces, yes?). The objects do not live inside a
 namespace, but are in a conceptually separate place altogether. A name
 lives in a namespace, and can only be referenced inside that space. An
 object can be referenced from anywhere, as long as you have a name
 that points to it.

 So, when you're doing x = 0, you're creating a new object, and the
 name x (in the local namespace) points to that object. That doesn't
 mean the object itself is confined to the local namespace. You could
 write 'return x', which allows you to have a name in the global
 namespace point to that same object.

 Hugo




-- 
--
AnotherNetFellow
Email: anothernetfel...@gmail.com
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Functions returning multiple values

2010-02-23 Thread Kent Johnson
On Tue, Feb 23, 2010 at 1:55 PM, Giorgio
 And, please let me ask a question: Kent told that nested_namespace(s) are
 default in python 2.6. And i found a line confirming this in py2.6 library.
 But, what about python 2.5 that as you know is the default on linux?

Yes, since 2.2 nested namespaces have been standard.

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


Re: [Tutor] Functions returning multiple values

2010-02-22 Thread Giorgio
Ok, thankyou.

So, in other words, i must pay attention to what i set as default value in a
function. I should NEVER set empty lists as default values.

The guide i've linked says To learn more about this, you should read the
documentation and look for the difference between *identity* and *equality*.
.

Can you please help me also with that? Where can i read what is the
difference?

And, i have some difficulties understanding the other strange example in
that howto. Just scroll down to: However, the *point* is that the value of
x is picked up from the *environment* at the time when the function is
defined. How is this useful? Let’s take an example — a function which
composes two other functions.

He is working on a function that compose other 2 functions. This is the
final solution

def compose(fun1, fun2):
def inner(x, fun1=fun1, fun2=fun2):
return fun1(fun2(x))
return inner

But also tries to explain why this example:

# Wrong version
def compose(fun1, fun2):
def inner(x):
return fun1(fun2(x))
return inner

def fun1(x):
return x +  world!

def fun2(x):
return Hello,

sincos = compose(sin,cos)  # Using the wrong version

x = sincos(3)

Won't work. Now, the problem is that the inner function gets fun1 and fun2
from other 2 functions.

My question is: why? inner is a sub-function of compose, where fun1 and fun2
are defined.

Giorgio

2010/2/21 Steven D'Aprano st...@pearwood.info

 On Mon, 22 Feb 2010 03:00:32 am Giorgio wrote:
  Hi,
 
  do you know if there is a way so that i can get multiple values from
  a function?
 
  For example:
 
  def count(a,b):
   c = a + b
   d = a - b
 
  How can I return the value of C and D?

 Return a tuple of c and d:

  def count(a, b):
 ... c = a + b
 ... d = a - b
 ... return c, d
 ...
  t = count(15, 11)
  t
 (26, 4)

 You can also unpack the tuple immediately:

  x, y = count(15, 11)
  x
 26
  y
 4



  Then, i have another question: i've read, some time ago, this guide
  http://hetland.org/writing/instant-python.html, skipping the
  object-related part. Now i've started reading it, and have found
  something strange: just go where it says Of course, now you know
  there is a better way. And why don’t we give it the default value of
  [] in the first place? Because of the way Python works, this would
  give all the Baskets the same empty list as default contents.. Can
  you please help me understanding this part?

 When you declare a default value in a function like this:

 def f(a, b, c=SOMETHING):

 the expression SOMETHING is calculated once, when the function is
 defined, and *not* each time you call the function.

 So if I do this:

 x = 1
 y = 2

 def f(a, b, c=x+y):
return a+b+c

 the default value for c is calculated once, and stored inside the
 function:

  f(0, 0)
 3

 Even if I change x or y:

  x = 
  f(0, 0)
 3

 So if I use a list as a default value (or a dict), the default is
 calculated once and stored in the function. You can see it by looking
 at the function's defaults:

  def f(alist=[]):
 ... alist.append(1)
 ... return alist
 
  f.func_defaults[0]
 []

 Now, call the function without an argument:

  f()
 [1]
  f()
 [1, 1]
  f()
 [1, 1, 1]
  f.func_defaults[0]
 [1, 1, 1]

 How is this happening? Because every time you call the function, it
 appends 1 to the argument. If you don't supply an argument, it appends
 1 to the default, changing it in place.

 Why doesn't the same thing happen here?

  def g(x=0):
 ... x += 1
 ... return x
 ...
  g.func_defaults[0]
 0
  g()
 1
  g()
 1
  g.func_defaults[0]
 0

 The answer is that ints are immutable: you can't change their value.
 When you do x+=1, it doesn't modify the int 0 in place, turning it into
 1. It leaves 0 as zero, and gives you a new int equal to one. So the
 default value stored in the function never changes.

 The difference boils down to immutable objects, which can't be changed
 in place, and mutable objects, which can.

 Immutable:
 ints, floats, strings, tuples, frozensets

 Mutable:
 lists, dicts, sets, most custom classes



 --
 Steven D'Aprano
 ___
 Tutor maillist  -  Tutor@python.org
 To unsubscribe or change subscription options:
 http://mail.python.org/mailman/listinfo/tutor




-- 
--
AnotherNetFellow
Email: anothernetfel...@gmail.com
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Functions returning multiple values

2010-02-22 Thread Kent Johnson
On Mon, Feb 22, 2010 at 9:13 AM, Giorgio anothernetfel...@gmail.com wrote:

 And, i have some difficulties understanding the other strange example in
 that howto. Just scroll down to: However, the point is that the value
 of x is picked up from the environment at the time when the function is
 defined. How is this useful? Let’s take an example — a function which
 composes two other functions.
 He is working on a function that compose other 2 functions. This is the
 final solution
 def compose(fun1, fun2):
     def inner(x, fun1=fun1, fun2=fun2):
         return fun1(fun2(x))
     return inner
 But also tries to explain why this example:
 # Wrong version
 def compose(fun1, fun2):
     def inner(x):
         return fun1(fun2(x))
     return inner
 def fun1(x):
     return x +  world!
 def fun2(x):
     return Hello,
 sincos = compose(sin,cos)  # Using the wrong version
 x = sincos(3)
 Won't work. Now, the problem is that the inner function gets fun1 and fun2
 from other 2 functions.
 My question is: why? inner is a sub-function of compose, where fun1 and fun2
 are defined.

It does work:
In [6]: def compose(fun1, fun2):
   ...: def inner(x):
   ...: return fun1(fun2(x))
   ...: return inner
   ...:

In [7]: def fun1(x):
   ...: return x +  world!
   ...:

In [8]: def fun2(x):
   ...: return Hello,
   ...:

In [9]: from math import sin, cos

In [10]: sincos = compose(sin,cos)  # Using the wrong version

In [11]:

In [12]: x = sincos(3)

In [13]:

In [14]: x
Out[14]: -0.8360218615377305

That is a very old example, from python 2.1 or before where nested
scopes were not supported. See the note A Note About Python 2.1 and
Nested Scopes - that is now the default behaviour.

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


Re: [Tutor] Functions returning multiple values

2010-02-22 Thread Giorgio
Ahah Kent this is amazing.

I was reading the ITALIAN
http://www.python.it/doc/articoli/instpy-0.html version
of that guide that is not updated. But, when i decided to post there i've
posted the link of the guide in english, but actually that's not what i've
readen.

Ok, so in the new python version it works. Tha manual also states that: The
features recognized by Python 2.6 are unicode_literals, print_function,
absolute_import, division, generators, nested_scopes andwith_statement.
generators, with_statement, nested_scopes are redundant in Python version
2.6 and above because they are always enabled.

Kent, as i'm learning py, can you please spend some words on nested scopes?
What are them? And why are supported anymore?

And, if i'm not asking you too much: can you plase post an example on how
that function can return HEllo World in py 2.6?

Thankyou!

Giorgio

2010/2/22 Kent Johnson ken...@tds.net

 On Mon, Feb 22, 2010 at 9:13 AM, Giorgio anothernetfel...@gmail.com
 wrote:

  And, i have some difficulties understanding the other strange example
 in
  that howto. Just scroll down to: However, the point is that the value
  of x is picked up from the environment at the time when the function is
  defined. How is this useful? Let’s take an example — a function which
  composes two other functions.
  He is working on a function that compose other 2 functions. This is the
  final solution
  def compose(fun1, fun2):
  def inner(x, fun1=fun1, fun2=fun2):
  return fun1(fun2(x))
  return inner
  But also tries to explain why this example:
  # Wrong version
  def compose(fun1, fun2):
  def inner(x):
  return fun1(fun2(x))
  return inner
  def fun1(x):
  return x +  world!
  def fun2(x):
  return Hello,
  sincos = compose(sin,cos)  # Using the wrong version
  x = sincos(3)
  Won't work. Now, the problem is that the inner function gets fun1 and
 fun2
  from other 2 functions.
  My question is: why? inner is a sub-function of compose, where fun1 and
 fun2
  are defined.

 It does work:
 In [6]: def compose(fun1, fun2):
...: def inner(x):
   ...: return fun1(fun2(x))
   ...: return inner
...:

 In [7]: def fun1(x):
   ...: return x +  world!
   ...:

 In [8]: def fun2(x):
   ...: return Hello,
   ...:

 In [9]: from math import sin, cos

 In [10]: sincos = compose(sin,cos)  # Using the wrong version

 In [11]:

 In [12]: x = sincos(3)

 In [13]:

 In [14]: x
 Out[14]: -0.8360218615377305

 That is a very old example, from python 2.1 or before where nested
 scopes were not supported. See the note A Note About Python 2.1 and
 Nested Scopes - that is now the default behaviour.

 Kent




-- 
--
AnotherNetFellow
Email: anothernetfel...@gmail.com
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


[Tutor] Functions returning multiple values

2010-02-21 Thread Giorgio
Hi,

do you know if there is a way so that i can get multiple values from a
function?

For example:

def count(a,b):
 c = a + b
 d = a - b

How can I return the value of C and D?

Then, i have another question: i've read, some time ago, this guide
http://hetland.org/writing/instant-python.html, skipping the object-related
part. Now i've started reading it, and have found something strange: just go
where it says Of course, now you know there is a better way. And why don’t
we give it the default value of [] in the first place? Because of the way
Python works, this would give all the Baskets the same empty list as default
contents.. Can you please help me understanding this part?

Thankyou

Giorgio



-- 
--
AnotherNetFellow
Email: anothernetfel...@gmail.com
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Functions returning multiple values

2010-02-21 Thread Steven D'Aprano
On Mon, 22 Feb 2010 03:00:32 am Giorgio wrote:
 Hi,

 do you know if there is a way so that i can get multiple values from
 a function?

 For example:

 def count(a,b):
  c = a + b
  d = a - b

 How can I return the value of C and D?

Return a tuple of c and d:

 def count(a, b):
... c = a + b
... d = a - b
... return c, d
...
 t = count(15, 11)
 t
(26, 4)

You can also unpack the tuple immediately:

 x, y = count(15, 11)
 x
26
 y
4



 Then, i have another question: i've read, some time ago, this guide
 http://hetland.org/writing/instant-python.html, skipping the
 object-related part. Now i've started reading it, and have found
 something strange: just go where it says Of course, now you know
 there is a better way. And why don’t we give it the default value of
 [] in the first place? Because of the way Python works, this would
 give all the Baskets the same empty list as default contents.. Can
 you please help me understanding this part?

When you declare a default value in a function like this:

def f(a, b, c=SOMETHING):

the expression SOMETHING is calculated once, when the function is 
defined, and *not* each time you call the function.

So if I do this:

x = 1
y = 2

def f(a, b, c=x+y):
return a+b+c

the default value for c is calculated once, and stored inside the 
function:

 f(0, 0)
3

Even if I change x or y:

 x = 
 f(0, 0)
3

So if I use a list as a default value (or a dict), the default is 
calculated once and stored in the function. You can see it by looking 
at the function's defaults:

 def f(alist=[]):
... alist.append(1)
... return alist

 f.func_defaults[0]
[]

Now, call the function without an argument:

 f()
[1]
 f()
[1, 1]
 f()
[1, 1, 1]
 f.func_defaults[0]
[1, 1, 1]

How is this happening? Because every time you call the function, it 
appends 1 to the argument. If you don't supply an argument, it appends 
1 to the default, changing it in place.

Why doesn't the same thing happen here?

 def g(x=0):
... x += 1
... return x
...
 g.func_defaults[0]
0
 g()
1
 g()
1
 g.func_defaults[0]
0

The answer is that ints are immutable: you can't change their value. 
When you do x+=1, it doesn't modify the int 0 in place, turning it into 
1. It leaves 0 as zero, and gives you a new int equal to one. So the 
default value stored in the function never changes.

The difference boils down to immutable objects, which can't be changed 
in place, and mutable objects, which can.

Immutable:
ints, floats, strings, tuples, frozensets

Mutable:
lists, dicts, sets, most custom classes



-- 
Steven D'Aprano
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor