Functions as arguments:

Example:
def func_a(a):
  print 'inside func_a'

def func_b(y):
  print 'inside func_b'
  return y

def func_c(z):
  print 'inside func_c'
  return z()

print func_a()  # func_a takes no parameters
print 5 + func_b(2)  # func_b takes one parameter
print func_c(func_a)  # func_c takes one parameter, another function

Show global scope and func_a scope while func_a is executing. Notice that it returns None, which gets printed. Similarly, func_b returns 2 and so 7 is printed.

Show three scopes: global, func_c, and func_a.

Scope example

Examples:

Complex example:

def g(x):
  x = x + 1
  print('g: y = ', y, 'x = ', x)  # this causes an error, as y is neither defined in the current scope nor defined in the (static) outer scope
  return x

def h(w):
  y = 'abc'
  return g(w)

x = 3
z = h(x)

More complex example:

def g(x):
  def h():
    x = 'abc'
  x = x + 1
  print('g: x = ', x)
  h()
  return x

x = 3
z = g(x)
Global scope has g -> some code and x -> 3. The g scope has x -> 4 (reads from the outer object and defines an inner object) and h -> some code. This behaviour of reading from the outer scope and defining a new variable in the inner scope, is no longer possible in recent versions of Python (to avoid programming errors). The h scope has x -> 'abc' and returns None. On the return path, g returns 4 (for x) and in the global scope, this value is assigned to z.

Decomposition and abstraction are powerful together:

Tuples

Have seen variable types like int, float, bool, string. Today, we will introduce compound data types:

Tuples

When a tuple is used on the left-hand side (LHS) of an assignment, then it can be used to assign to multiple variables simultaneously. For example, this can be conveniently used to swap variable values.
First try:

x = y
y = x
#This is an incorrect way to swap two variables

Second try:
temp = x
x = y
y = temp
#Correct way to swap two variables, but this can be written in a shorter way

Best way to swap two variables (this way uses tuples both on the LHS and RHS of an assignment):
(x, y) = (y, x)

A tuple can be used to return more than one value from a function

def quotient_and_remainder(x, y):
  q = x // y   #integer division
  r = x % y
  return (q, r)

(quot, rem) = quotient_and_remainder(43, 5)