# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3.9.1 64-bit (system)
#     name: python3
# ---

# # Python Functions

# A function is a block of code that only runs when it is called.
#
# You can pass data to the function using its parameters.
#
# A function can return data as a result.

# ## Creating the first function

def first_function():
    print('Hello world!') 


# Calling the function:

# + tags=[]
first_function()


# -

# ## Defining a function with an argument

# Information can be passed into functions as `arguments`.
#
# Arguments are specified after the function name inside the parentheses. You can add as many arguments as you want; just separate them with a comma.
#
# Arguments are often shortened to `args` in Python documentations.
#

def hello(name):
    print('Hello',name)


# Calling the function:

# + tags=[]
hello('John')

# + tags=[]
hello('Mary')
# -

# `Number of arguments`: a function must be called with the correct number of arguments.

hello('Mary', 'John')           # This will raise an error


# `Arbitrary Arguments`: if the number of arguments is unknown, add a * before the parameter name. This way the function will receive a tuple of arguments, and can access the items accordingly.
#
# Arbitrary Arguments are often shortened to `*args` in Python documentations.

def youngest_kid(*kids):
    print('The youngest child is', kids[0])


# The function youngest_kid assumes that the list of kids is sorted, and that way the youngest kid is always the first one. 

# + tags=[]
youngest_kid('John','Mary','Anna')

# + tags=[]
youngest_kid('John','Mary','Anna','Raul')
# -

youngest_kid('Anna', 'John','Mary','Raul')


# `Keywords Arguments`: You can also send arguments with the key = value syntax. This way the order of the arguments does not matter.

def youngest_kid(child3, child2, child1):
    print('The youngest child is', child1)


# + tags=[]
youngest_kid(child1='John',child2='Mary',child3='Anna')

# + tags=[]
youngest_kid(child2='Mary',child3='Anna',child1='John')


# -

# `Arbitrary Keyword Arguments`: If you do not know how many keyword arguments that will be passed into your function, add two asterisk: ** before the parameter name in the function definition. This way the function will receive a dictionary of arguments, and can access the items accordingly.
#
# The phrase Keyword Arguments are often shortened to `kwargs` in Python documentations.

def youngest_kid(**kid):
    print('The youngest child is', kid['child1'])


# + tags=[]
youngest_kid(child1='Mary',child3='Anna')

# + tags=[]
youngest_kid(child1='John',child2='Mary',child4='Anna')


# -

# `Default parameter value`: If we call the function without argument, it uses the default value.

def my_country(country='USA'):
    print('I am from',country)


# + tags=[]
my_country('Colombia')

# + tags=[]
my_country('Spain')

# + tags=[]
my_country()


# -

# ### Passing a list as an argument

# Passing a list as an argument
def my_food(food):
    for x in food:
        print(x)


# + tags=[]
food = ['orange', 'apple', 'grapes', 'patata']
my_food(food)


# -

# `return value`: use return statement to let the function returns a value

def mult_by_5(x):
    return(5 * x)


# + tags=[]
print('0 multiply by 5 is', mult_by_5(0))
print('1 multiply by 5 is', mult_by_5(1))
print('5 multiply by 5 is', mult_by_5(5))
print('8 multiply by 5 is', mult_by_5(8))


# -

# ## Recursion

# Python also accepts function recursion, which means a defined function can call itself.

def factorial(n):
    if n>1:
        result = n * factorial(n-1)
    else:
        result = 1
    return(result)


factorial(3)

factorial(0)

factorial(10)

StarcoderdataJupyterScriptsDedupFiltered