Writing your own functions
There exist built-in functions such as str() which converts an object to a string (and lots of more functions)
- Basic function writing
- Simple function. def newsquare():... new_value=4**2 ...: print(new_value) (hit enter where corresponds).
- Single parameter function. def square(value): ...: new_value = value ** 2 ...: print(new_value)
- Function that returns single values. def square(value): ...: """Return the square of a value.""" ...: new_value = value ** 2 ...: return new_value. Where the text in blue is called a Docstring, which describes what your function does, serves as documentation.
- Multiple parameters and return values
- Multiple function parameters. def raise_to_power(value1, value2): ...: """Raise value1 to the power of value2.""" ...: new_value = value1 ** value2 ...: return new_value.
- Return multiple values. For these we need the tuple objects.
- Tuples. ● Like a list - can contain multiple values ● Immutable - can’t modify values! ● Constructed using parentheses ().
- Ex. even_nums = (2, 4, 6), you can unpack the values and save them in the variables a,b,c with a, b, c = even_nums
- You can access them via zero-indexing, just like with lists. even_nums[1].
- Function returning multiple values. def raise_both(value1, value2):... """Raise value1 to the power of value2 and vice versa."""... new_value1 = value1 ** value2...: new_value2 = value2 ** value1...: new_tuple = (new_value1, new_value2) ....: return new_tuple. (Note: we could as well just have returned (new_value1, new_value2) instead of creting new_tuple )
- Ex. Bringing it all together. Bring it all togther.txt
- Observation: When using an if statement, it can be of the form if entry in langs_count.keys().
ch1_Writing_your_own_functions.pdf
Default arguments, variable-length arguments and scope
- Scope: Part of the program where an object or name may be accessible . Not all objects are accessible everywhere in a script
- Global scope - defined in the main body of a script
- Local scope - defined inside a function
- Built-in scope - names in the pre-defined built-ins module
- Observations.
- If we define a variable inside a function, we cannot acces it outside the function.
- If we have a variable defined on the global scope and use it and change it in a local scope then it doesn't affect it globally.
- If we use a global variable inside a function, then the function changes as that global varible does.
- To change the value of a global variable inside a function, inside that function we write global new_val ...: new_val = new_val ** 2
- Nested Functions. It works the same as definining a "normal function" just that this time you add a function inside another. The scopes searched are, in this order, local scpoe, enclosing functions, global and built-in
- Ex. def mod2plus5(x1, x2, x3):..."""Returns the remainder plus 5 of three values."""... def inner(x):... """Returns the remainder plus 5 of a value."""... return x % 2 + 5.... return (inner(x1), inner(x2), inner(x3))
- Returning functions. def raise_val(n):... """Return the inner function."""... def inner(x):... """Raise x to the power of n."""... raised = x ** n... return raised... return inner. In this way, if we call square=raise_val(2) then square is a function on which you enter a parameter which is the value to be squared.
- Using nonlocal. Just as with the use of global, we can use nonlocal inside de nested function to refer to a bigger scope, namely the enclosing-function scope, the global scope and the built-in scope.
- Default arguments. To add a default argument you just have to write the argument as arg_var=def_val like this def power(number, pow=1): ...
- Flexible Arguments.
- *args. Enable you to pass a variable number of arguments to a function. You define your function as def funct(*args):...Within the function definition,
args
is a tuple. - **kwargs. What makes
**kwargs
different is that it allows you to pass a variable number of keyword arguments to functions, **kwargs
is a dictionary.- def print_all(**kwargs):... """Print out key-value pairs in **kwargs."""... # Print out the key-value pairs... for key, value in kwargs.items(): print(key + ": " + value)
- Bringing it all together. Ex.
ch2_Default arguments, variable-length arguments and scope.pdf
Lambda functions and error-handling
You'll learn about lambda functions, which allow you to write functions quickly and on-the-fly. You'll also get practice at handling errors that your functions, at some point, will inevitably throw.
- Lambda Functions. Allow you to write funtions quicky and on the fly, you write lambda for constructiong them. For ex. raise_to_power = lambda x, y: x ** y.
- When you don't actually need the function to be stored, anonymous functions, for ex. using map(func, seq) that applies the function to all elements in the sequence and returns a map object (you can convert it to a list using list()). nums = [48, 6, 9, 21, 1] ... square_all = map(lambda num: num ** 2, nums).
- Ex. using filter(). filter(function or None, iterable) --> filter object
Return an iterator yielding those items of iterable for which function(item)
is true. filter(lambda member: len(member)>6, my_list) - Ex. using reduce().reduce(function, sequence[, initial]) -> value. Apply a function of two arguments cumulatively to the items of a sequence, from left to right, so as to reduce the sequence to a single value. reduce(lambda item1,item2: item1+item2, my_list)
- Introduction to error handling. Python does exception-caught during execution.
- Exceptions. Catch exception with try-except clause: Runs the code following try, if there's an exception, run the code following ecept
- def sqrt(x): ...: try: ...: return x ** 0.5 ...: except: ...: print('x must be an int or float'). For example, sqrt('hi')... x must be an int or float.
- There are many types of exceptions, which you could browse on python documentation, in the previous eexample we could specify what kind of exception to catch.
- Errors. We could come up with any errors we want to, using raise ValueError(). For ex. def sqrt(x): ...: if x < 0: ...: raise ValueError('x must be non-negative') ...: try: ...: return x ** 0.5 ...: except TypeError: ...: print('x must be an int or float').
- Observation. if col_name not in df.columns: is a great way to check wether or not to thrown an error.
ch3_LambdaFunctions_ErrorHandling.pdf