<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Functions
In Python it's realy easy to define your own functions. Once defined, you can use them just like any standard Python function. By condensing functionality into a function, your code will get structured and is way more readable. Beside that this specific chunk of code can be used over and over again with way less effort. A good function is as general and abstract, that it cannot only be used in the project it was written for, but in any Python project. 
Every Python function   is composed by some main parts
Step1:  group the two print statements into a print_all function
Extend print_all. It should accept a user name as an attribute and should substitute the World in the first print call with that name. Name the new function welcome.
Using the input function, we could first prompt for a name and them use it in welcome. 
What does make more sense
Step2:  Rewrite welcome in the style of greet. It should substitute the user name and return the result.
Arguments
Using input in productive Pyhton code is very uncommon. It is quite complicated to reuse the code, as it will not always be executed in a python console. Beyond that, it's more readable to define possible inputs as attributes and function arguments as it makes debugging way easier. Then, it is up to a developer how the input value shall be obtained. The input function, a configuration file, a web formular, a text file or a global variable could be used to get the value for the argument.<br>
The example below will take two number and return their sum. This is very clear and reuseable.
Step3:  A function argument can also be optional. Therefore a default value has to be defined in the signature. You woould call this attribute an optinal attribute or more pythonic
Step4:  locals / globals
Another important topic for functions is variable validity and life span. A variable is alife until you overwrite or explicitly delete it. In case you re-assign a variable the life span ends, even if the variable typse stays the same. That means, the new value will allocate another position in the memory.
Step5:  Additionally one can declare and assign a variable, but it may only be valid in specific sections of your code. These sections of validity are called namespace. Any function defines its own namespace (the function body) and any variable declared within that scope is not valid outside this namespace. Nevertheless, namespaces can be nested. Then any outer namespace is also valid inside the inner namespaces.
Step6:  The running Python session also defines a namespace. This is called the global namespace. The built-in function <span style='color
Step7:  *args, **kwargs
Two very specific and important attributes are *args and **kwargs attributes. You can use any name for these two variables, but it is highly recommented to use default name to prevent confusions!. The star is a operator that is also called the asterisk operator. The single operator stacks or unstacks a varying number of positional arguments into a list, while the double operator does the same thing to keyword arguments and dictionaries. For a better understanding use the function below, just returning the content of args and kwargs.
Step8:  lambda
The <span style='color
Step9:  Returning functions
In Python it is also possible to define a function, that will return another function. There is even a built-in function called <span style="color
Step10:  Recursive functions
A recursive function calls itself in the body. This technique can dramatically decrease the code size and shifts the code often very close to mathematical algorithms, but there are also some downsides. If a 'break' condition is never met or implemented, the recursive calling will never stop. (In fact it will stop, as Python will stop it but it will also stop your code.). The other downside is the dramatical loss of performance for highly nested functions. As an example the faculty function is implemented below
Step11:  Now define the Fibonacci series into <span style="color
Step12:  Nested functions
In Python it is also possible to define a function within the namespace of another function. Just like variables, this function also has a validity. You can use this concept to define a very specific auxiliary function, that cannot be used in another scope just in that namespace where it is valid. Then other developers cannot misuse your function. 
The second use case is that an outer function wants to influence the definition of the inner function. The outer will be declared as your code is imported. The inner first as the outer is run. Therefore anything happening during runtime could still influence the declaration of the inner function. Here, the default values of a model are dependent on the boundary conditions.
<ASSISTANT_TASK:>
Python Code:
print('Hello, Wolrd!')
print('This is Python.')
Explanation: Functions
In Python it's realy easy to define your own functions. Once defined, you can use them just like any standard Python function. By condensing functionality into a function, your code will get structured and is way more readable. Beside that this specific chunk of code can be used over and over again with way less effort. A good function is as general and abstract, that it cannot only be used in the project it was written for, but in any Python project. 
Every Python function   is composed by some main parts: the function name, signature and the body. Optionally, a return value and arguments can be defined. The arguments are also referred to as attributes.
Syntax
The function sytanc is as follows:   
<code>
<span style="color: purple">def</span> name (attributes): 
body   
return value 
</code>
End of explanation
def greet():
    return 'Hello, World!'
message = greet()
print(message)
Explanation: group the two print statements into a print_all function
Extend print_all. It should accept a user name as an attribute and should substitute the World in the first print call with that name. Name the new function welcome.
Using the input function, we could first prompt for a name and them use it in welcome. 
What does make more sense: extending welcome or defining a second function for prompting a name and then pass it to welcome?
Execute this function in a endlessly until the phrase <span style='color:red'>'exit'</span> or <span style='color:red'>'Exit'</span> was passed by the user.
Return Values
Up to now, no of the defined functions returned a value. In Python, there is no need to define a return value in the function signature (different from C++ or Java). It's also possible to return values only conditionally or to return a varying number of values. 
Different to welcome the function greet will return the 'Hello World' Phares instead of printing it.
End of explanation
def sum_a_and_b(a, b):
    return a + b
print(sum_a_and_b(5, 3))
Explanation: Rewrite welcome in the style of greet. It should substitute the user name and return the result.
Arguments
Using input in productive Pyhton code is very uncommon. It is quite complicated to reuse the code, as it will not always be executed in a python console. Beyond that, it's more readable to define possible inputs as attributes and function arguments as it makes debugging way easier. Then, it is up to a developer how the input value shall be obtained. The input function, a configuration file, a web formular, a text file or a global variable could be used to get the value for the argument.<br>
The example below will take two number and return their sum. This is very clear and reuseable.
End of explanation
def print_arguments(arg1, arg2, arg3='Foo', arg4='Bar', g=9.81):
    print('arg1:\t', arg1)
    print('arg2:\t', arg2)
    print('arg3:\t', arg3)
    print('arg4:\t', arg4)
    print('g:\t', g)
    print('-' * 14)
Explanation: A function argument can also be optional. Therefore a default value has to be defined in the signature. You woould call this attribute an optinal attribute or more pythonic: keyword argument. Without this default value, an argument is also called a positional argument as Python can only reference it by the passing order. Thus, one cannot mix positional and keyword arguments. Nevertheless, the keyword arguemnts can be mixed in their ordner as they can be identified by thier keyword. As a last option, you can set any keyword argument in a positional manner, but then the order matters again.
End of explanation
x = 5
print('x = 5\t\tmemory address:', hex(id(x)))
x = 6
print('x = 6\t\tmemory address:', hex(id(x)))
Explanation: locals / globals
Another important topic for functions is variable validity and life span. A variable is alife until you overwrite or explicitly delete it. In case you re-assign a variable the life span ends, even if the variable typse stays the same. That means, the new value will allocate another position in the memory.
End of explanation
a = 5
def f():
    b = 3
    print('a: ', a, 'b: ', b)
# call
f()
b
Explanation: Additionally one can declare and assign a variable, but it may only be valid in specific sections of your code. These sections of validity are called namespace. Any function defines its own namespace (the function body) and any variable declared within that scope is not valid outside this namespace. Nevertheless, namespaces can be nested. Then any outer namespace is also valid inside the inner namespaces.
End of explanation
a = 5
print('Global a: ', globals()['a'], '\t\tmemory address: ', hex(id(a)))
def f(b):
    print('Local b:', locals()['b'], '\t\tmemory address: ', hex(id(b)))
f(a)
Explanation: The running Python session also defines a namespace. This is called the global namespace. The built-in function <span style='color: blue'>globals</span> can be used to return the global namespace content as a <span style='color: green'>dict</span>. The <span style='color: blue'>locals</span> function does the same for the local (inner) namespaces.
End of explanation
def get_attributes(*args, **kwargs):
    return args, kwargs
a, b = get_attributes('foo', 'bar', g=9.81, version=2.7, idiot_president='Donald Trump')
print('args:', a)
print('kwargs:', b)
Explanation: *args, **kwargs
Two very specific and important attributes are *args and **kwargs attributes. You can use any name for these two variables, but it is highly recommented to use default name to prevent confusions!. The star is a operator that is also called the asterisk operator. The single operator stacks or unstacks a varying number of positional arguments into a list, while the double operator does the same thing to keyword arguments and dictionaries. For a better understanding use the function below, just returning the content of args and kwargs.
End of explanation
list(map(lambda x:x**2, [1,2,3,4,5,6,7,8,9]))
list(map(lambda x:len(x), 'This is a sentence with rather with rather short and extraordinary long words.'.split()))
list(map(lambda x:(x,len(x)), 'This is a sentence with rather with rather short and extraordinary long words.'.split()))
Explanation: lambda
The <span style='color: blue'>lambda</span> function is a special case, as it is an anonymous function. This is the only function without a function name. On the other side, <span style='color: blue'>lambda</span>s does not accept keyword arguments. <span style='color: blue'>lambda</span>s are helpful to write short auxiliary functions, or inline functions that are used as arguments themselves. The seconda field are list comprehensions.
End of explanation
def mean(data):
    return sum(data) / len(data)
def get_aggregator(variable_name):
    if variable_name.lower() == 'temperature':
        return mean
    elif variable_name.lower() == 'rainfall':
        return sum
data = [2,4,7,9,2,3,5]
# Temperature data
agg = get_aggregator('Temperature')
print('Temperature: ', agg(data), '°C')
agg = get_aggregator('Rainfall')
print('Rainfall:    ', agg(data), 'mm')
Explanation: Returning functions
In Python it is also possible to define a function, that will return another function. There is even a built-in function called <span style="color:purple">callable</span>, taht tests python objects for being callable. Caution: This does still not guarantee, that the object is a function, because Python also defines callable class instances. 
The example below could be used in a data management environment.
End of explanation
def factorial(n):
    return n*factorial(n-1) if n > 1 else 1
Explanation: Recursive functions
A recursive function calls itself in the body. This technique can dramatically decrease the code size and shifts the code often very close to mathematical algorithms, but there are also some downsides. If a 'break' condition is never met or implemented, the recursive calling will never stop. (In fact it will stop, as Python will stop it but it will also stop your code.). The other downside is the dramatical loss of performance for highly nested functions. As an example the faculty function is implemented below:
$$
n! = n+ (n-1)!~~~~~~~~~ n > 1, 1! = 1
$$
End of explanation
def fibonacci_iterative(n):
    a,b = 0, 1
    for i in range(n):
        a,b = b, a + b
    return a
def fibonacci_recursive(n):
    pass
    
print('iterative:', fibonacci_iterative(10))
print('recursive:', fibonacci_recursive(10))
%time fibonacci_iterative(40)
%time fibonacci_recursive(40)
Explanation: Now define the Fibonacci series into <span style="color:blue">fibonacci_recursive</span> below.
$$F_n = F_{n - 1} + F_{n - 2} $$ using the start values $F_0 = 0$ and $F_1 = 1$.
End of explanation
def get_model(arid=True):
    if arid:
        a = 1.2
    else:
        a = 1.4
    def _model(rain, evap, a=a):
        return (rain - evap)**a if rain > evap else 0
    return _model
rain_values = [3, 0, 0, 16, 4]
evap_values = [1, 1, 5, 3, 2]
print(list(map(get_model(arid=True), rain_values, evap_values)))
print(list(map(get_model(arid=False), rain_values, evap_values)))
Explanation: Nested functions
In Python it is also possible to define a function within the namespace of another function. Just like variables, this function also has a validity. You can use this concept to define a very specific auxiliary function, that cannot be used in another scope just in that namespace where it is valid. Then other developers cannot misuse your function. 
The second use case is that an outer function wants to influence the definition of the inner function. The outer will be declared as your code is imported. The inner first as the outer is run. Therefore anything happening during runtime could still influence the declaration of the inner function. Here, the default values of a model are dependent on the boundary conditions.
End of explanation
<END_TASK>