<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
Functions and function arguments
Functions are the building blocks of writing software. If a function is associated with an object and it's data, it is called a method. 
Functions are defined using the keyword def.
There are two types of arguments
* regular arguments, which must always be given when calling the function
* keyword arguments, that have a default value that can be overriden if desired
Values are returned using the return keyword. If not return is defined, the default return value of all functions and methods is None, which is the null object in Python.
Step1:  Python has special syntax for catching an arbitary number of parameters. For regular parameters it is a variable with one asterisk * and for keyword parameters it is a variable with two asterisks. It is conventional to name these *args and **kwargs, but this is not required.
Step3:  The length of sequences can be checked using the built-in len() function.
It is standard practice to document a function using docstrings. A docstring is just a simple triple-quoted string immediately after the function definition. It is also possible to have docstrings in the beginning of a source code file and after a class definition.
Step4:  Functions as parameters
Functions are first-class citizens in Python, which means that they can be e.g. passed to other functions. This is the first step into the world of functional programming, an elegant weapon for a more civilized age.
Step5:  Extra
Step6:  Now if we want to sort it using Python's built-in sort() function the sort won't know which attribute to base the sorting on.
Fortunately the sort() function takes a named parameter called key which is a function to be called on each item in the list. The return value will be used for the name.
(Python's sort() sorts the list in-place. If you want to keep the list unmodified use sorted())
Step7:  This is all nice and well, but now you have a function called get_age that you don't intend to use a second time.
An alternative way to give this would be using a lambda expression.
<ASSISTANT_TASK:>
Python Code:
def my_function(arg_one, arg_two, optional_1=6, optional_2="seven"):
    return " ".join([str(arg_one), str(arg_two), str(optional_1), str(optional_2)])
print(my_function("a", "b"))
print(my_function("a", "b", optional_2="eight"))
#go ahead and try out different components
Explanation: Functions
Functions and function arguments
Functions are the building blocks of writing software. If a function is associated with an object and it's data, it is called a method. 
Functions are defined using the keyword def.
There are two types of arguments
* regular arguments, which must always be given when calling the function
* keyword arguments, that have a default value that can be overriden if desired
Values are returned using the return keyword. If not return is defined, the default return value of all functions and methods is None, which is the null object in Python.
End of explanation
def count_args(*args, **kwargs):
    print("i was called with " + str(len(args)) + " arguments and " + str(len(kwargs)) + " keyword arguments")
    
count_args(1, 2, 3, 4, 5, foo=1, bar=2)
Explanation: Python has special syntax for catching an arbitary number of parameters. For regular parameters it is a variable with one asterisk * and for keyword parameters it is a variable with two asterisks. It is conventional to name these *args and **kwargs, but this is not required.
End of explanation
def random():
    
    Always the number 4. 
    Chosen by fair dice roll. Guaranteed to be random.
    
    return 4
Explanation: The length of sequences can be checked using the built-in len() function.
It is standard practice to document a function using docstrings. A docstring is just a simple triple-quoted string immediately after the function definition. It is also possible to have docstrings in the beginning of a source code file and after a class definition.
End of explanation
def print_dashes():
    print("---")
    
def print_asterisks():
    print("***")
    
def pretty_print(string, function):
    function()
    print(string)
    function()
    
pretty_print("hello", print_dashes)
pretty_print("hey", print_asterisks)
Explanation: Functions as parameters
Functions are first-class citizens in Python, which means that they can be e.g. passed to other functions. This is the first step into the world of functional programming, an elegant weapon for a more civilized age.
End of explanation
dictionaries = [
    {"name": "Jack", "age": 35, "telephone": "555-1234"},
    {"name": "Jane", "age": 40, "telephone":  "555-3331"},
    {"name": "Joe", "age": 20, "telephone": "555-8765"}
]
Explanation: Extra: Lambda
When we use the keyword def we are making a named function. Sometimes we want a simple function to use once without without binding it to any name.
Consider the following data structure.
End of explanation
def get_age(x):
    return x["age"]
dictionaries.sort(key=get_age)
dictionaries
Explanation: Now if we want to sort it using Python's built-in sort() function the sort won't know which attribute to base the sorting on.
Fortunately the sort() function takes a named parameter called key which is a function to be called on each item in the list. The return value will be used for the name.
(Python's sort() sorts the list in-place. If you want to keep the list unmodified use sorted())
End of explanation
dictionaries.sort(key=lambda x: x["age"], reverse=True)
dictionaries
Explanation: This is all nice and well, but now you have a function called get_age that you don't intend to use a second time.
An alternative way to give this would be using a lambda expression.
End of explanation
<END_TASK>