#
# this function has 3 optional arguments
#
def optional_args(a=None, b='one', c=3):
    print('a={}, b={}, c={}'.format(a,b,c))
optional_args()
#prints
#a=None, b=one, c=3

#
# we can also pass the arguments via a dictionary
# so we can save them/modify them
#

arg_dict=dict(a=4,b=[1,2,3],c='hello')
optional_args(**arg_dict)
#
# prints
# a=4, b=[1, 2, 3], c=hello
#

"""
Explanation: Table of Contents

Expansion of required and optional function arguments reference: Whirlwind Chap 9

-- also, taking variable numbers of arguments in a function call

<a name="expansion"></a>
Expansion of arguments using * and **
Python let's you 
1) pass optional keyword arguments in as a dictionary, and required arguments in as a list. This is how we passed many optional arguments to basemap in the satellite_IV notebook, note the default values.
2) it let's you receive a variable number of optional arguments as a dictionary, and a variable number of required arguments as a list.  This let's you write a function when you don't know what the calling arguments will be.
Optional arguments -- keyword argument unpacking with  **kwargs
End of explanation
"""


def optional_args(**kwargs):
    print('got these args: {}'.format(kwargs))
   
optional_args(bacon=True,fab_4=(1,2,3),bozo='5')

"""
Explanation: Writing a function to take unknown optional arguments 
It also works in the other direction:
End of explanation
"""


def required_args(a,b,c,test_opt=5):
    print('required: a -- {}, b -- {}, c -- {}'.format(a,b,c))
    print('optional arg {}'.format(test_opt))
    
required_args(1,2,3)
#prints:
#required: a -- 1, b -- 2, c -- 3
#optional arg 5
arg_list=[5,'two',[3,1,7]]
required_args(*arg_list,test_opt=10)
#
# prints:
# required: a -- 5, b -- two, c -- [3, 1, 7]
# optional arg 10
#

"""
Explanation: Required arguments:  argument unpacking with *args
Required arguments occur before the optional arguments
End of explanation
"""


def show_expansion(*args, **kwargs):
    print('required arguments are: {}'.format(args))
    print('optional arguments are: {}'.format(kwargs))
    
show_expansion(1,2,[4,5],boys='pink',fish='shiny')


"""
Explanation: Writing a function to take an unknown number of required arguments and optional arguments
This also works in the opposite direction to send variable numbers of arguments
End of explanation
"""


