Functions ========= .. admonition:: Precap A function is a named sequence of statements. Positional and keyword arguments can be defined to be used as input values. The ``return`` keyword can be used to return a result value. Defining a function ------------------- The ``def`` keyword is used to *define* a function. In general a function consists of: * The ``def`` keyword * followed by an identifier as the function name * a pair of round brackets ``()`` * within the round brackets an *optional* list of comma-separeted identifiers as positional or keyword arguments (both types of arguments can be used like variables) * a colon ``:`` after the round bracket * an indented list of statements * and *optional* return values using the ``return`` keyword. .. interactive_code_block:: :caption: Pseudo code of a function def function_name(argument_1, argument_2, keyword_argument_1 = 123, keyword_argument_2 = 'Abc'): # Statement 1 # Statement 2 # Statement 3 return # Statement 4 variable = function_name(value_1, value_2, keyword_argument_2 = 'Xyz') **NOTE**: The pseudo code above will throw an error and syntax coloring also fails. .. interactive_code_block:: :caption: Calculating the surface and volume of a cuboid # Defining the function def cuboid(width, depth, height): # Calculate the return values surface_area = 2 * (width * depth + width * height + depth * height) volume = width * depth * height # Return the calculated values as a tuple return surface_area, volume # Calling the function and storing the return value in a variable result = cuboid(2, 3, 4) # Multiple result values are returned as a tuple, thus the individual values have to be accessed using their indices print('The calculated surface area={} and volume={}.'.format(result[0], result[1])) # Another way would be to unpack the tuple and assign the single values to variables. result_1, result_2 = cuboid(2, 3, 4) print('The calculated surface area={} and volume={}.'.format(result_1, result_2)) # Preceding the variable with a star '*' also unpacks the tuple print('The calculated surface area={} and volume={}.'.format(*result)) Positional and keyword arguments -------------------------------- The difference between a positional and a keyword argument is, that the latter have a default value assigned to it and that. Values for **positional arguments** * *must* be supplied when the function is called (i.e. if there are 3 positional arguments, 3 values have to be supplied) * in the *order* they are listed in the function definition * *before* any keyword arguments whereas values for **keyword arguments** * *can* be supplied optionally when the function is called * and in *any order if preceded by the keyword arguments identifier* * *after* any positional arguments .. interactive_code_block:: :caption: Calculating the surface and volume of a cuboid # Defining the same function as above but with shorter argument names # 'w' is a positional and 'd', 'h' are keyword arguments (= have default values) def cuboid(w, d = 3, h = 4): # Calculate the return values a = 2 * (w * d + w * h + d * h) v = w * d * h # Return the calculated values as a tuple return a, v result = cuboid(2) print('The calculated surface area={} and volume={}.'.format(*result)) # Keyword arguments result = cuboid(2, h = 5) print('The calculated surface area={} and volume={}.'.format(*result)) Variable scope -------------- Positional and keyword arguments are variables with a limited outreach and lifespan. .. interactive_code_block:: :caption: Accessing a variable defined within a function from after the function has been called fails # Defining the same function as above but without any comments in-between def cuboid(w, d = 3, h = 4): a = 2 * (w * d + w * h + d * h) v = w * d * h return a, v # At the end of the function all arguments and variables w, d, h and variables a, v are erased from memory # Calling the function result = cuboid(2) # The variable a does not exist anymore print(a) Variables within a function definition have only *local scope* as long as they are not defined globally. .. interactive_code_block:: :caption: Accessing a variable defined within a function from after the function has been called fails # Defining the same function as above but giving 'a' global scope def cuboid(w, d = 3, h = 4): # Giving 'a' global scope global a a = 2 * (w * d + w * h + d * h) v = w * d * h return a, v # At the end of the function all arguments w, d, h and local variables v are erased from memory # Calling the function result = cuboid(2) # Variable with global scope are kept in memory even after the function has been called print(a) Excercise --------- .. interactive_code_block:: :caption: Rewrite the code to use a function for the calculation to avoid repeating it celsius = 0 fahrenheit = celsius * 9 / 5 + 32 print('{} degrees Celsius = {} degrees Fahrenheit.'.format(celsius, fahrenheit)) celsius = 37 fahrenheit = celsius * 9 / 5 + 32 print('{} degrees Celsius = {} degrees Fahrenheit.'.format(celsius, fahrenheit)) celsius = 100 fahrenheit = celsius * 9 / 5 + 32 print('{} degrees Celsius = {} degrees Fahrenheit.'.format(celsius, fahrenheit))