python > functions or methods
Topic
We are gonna do some exercises on Functions or Methods which are blocks of code that be can be reused at various parts of the program.
Prerequistes
- Python3 should be installed.
- You should know how the if else statement works.
BuiltIn
There are certain built-in functions or methods that can be used with any datatype, examples are print(), dir().
>>> (type(print))
<class 'builtin_function_or_method'>
>>> (type(dir))
<class 'builtin_function_or_method'>
Methods are like functions, except that the term method is used to specify a function, which is available to an object that is an instance of a Class. So, methods are functions which are defined in Classes. Since, we can use print(), dir() etc. with any datatype, these are often referred to as built in functions.
Another difference to note is that objectnames or values are followed by the functions, for instance print('orange')
,
where as methods are follwoed by the objectname and a dot ‘.’.
Let’s define a string
>>> color = 'orange'
So color is our object name and it belongs to the class ‘str’
>>> print(type(color))
<class 'str'>
Since color is an instance of the ‘str’ class, it should be able to use the methods defined in the ‘str’ class. upper() is one of the valid methods for the ‘str’ class, so as said earlier, we need to call the method using the format objectname.methodname(arguments if any)
>> color.upper()
'ORANGE'
Function with defaults
Let’s define a function to add three numbers In the snippet below, def is the keyword that defines a function, sumOfThree is the name of the function, a,b,c are parameters of the function. 1,2, and 3 are the default values for a,b, and c.
>>> def sumOfThree(a=1, b=2, c=3):
... print(a + b + c)
...
Call the function
Since the function is defined, we can now call it in our program in different ways…
Note that when we pass values to a function, we call those values as arguments
, where as we call the variables
within our function as parameters
.
All Defaults
>>> sumOfThree()
6
All Arguments
Next, we would pass all 3 arguments so they take specific values instead of default values.
>>> a = 10
>>> b = 20
>>> c = 30
>>> sumOfThree(a, b, c)
60
Two Arguments, One Default
>>> a = 10
>>> b = 20
>>> sumOfThree(a, b)
33
One Argument, Two Defaults
>>> a = 10
>>> sumOfThree(a)
15
This way, if we have setup default values in our function for the parameters, we can either pass specific values to those, or let them use their default values. Choice is ours. However, its only optional to define default values for parameters in a function.
Function with out parameters
Its not always necessary to define a function with parameters
>>> def fn():
... print('Hello World!')
...
>>> fn()
Hello World!
So this function fn() doesn’t have any parameters, and hence there was no need to pass any arguments while calling the function
Function with out defaults
Let’s define a function with parameters, but with out any default values for those parameters.
def findIfMultiple(x, y): # parameters
if x % y == 0:
return 'yes'
else:
return 'no'
This function should help finding if the value x is an exact multiple of y, note that the math operator ‘%’ is used to
find the remainder. And the return
statement is passed back to the program, so if we try to print this function,
the value that gets passed by the return
statement would be printed, in this case yes
or no
. Note
that we can use return
statements for a function irrespective of the function has parameters or not. If we don’t have
a return statement in a function, i.e. if the function is not returning any value, we can call that a void
function.
Alright, let’s now call the function
>>> a = 100
>>> b = 11
>>> print(findIfMultiple(a, b)) # arguments
no
Positional arguments
So here we passed a
and b
as arguments, which would become x
and y
respectively with in the function.
So the names we use for the variables that we pass as arguments doesn’t really matter, the position matters, so the
argument in the first position a
corresponds to the first parameter x
and similarly the second argument b
would map with the second paremeter y
Well we got the value as no
cause 100 divided by 11 gives 9 as quotient and remainder is 1
, so if you take a
look at the function again, you see that the function should return no
when the remainder is not 0
.
Let’s pass another set of arguments
>>> x = 100
>>> y = 5
>>> print(findIfMultiple(x, y)) # arguments
yes
So 100 / 5 gives quotient 20 and remainder 0, hence it returns yes
.
Multiplication example
$ cat multiply.py
def mul(number1, number2):
print(number1 * number2)
mul(100, 10)
mul(10, 90)
mul(15, 50)
Here we have kept the code in a file and then would execute it as a script. The example above was done in Linux, however can be tried in any operating system where Python is installed. Above, we have used the cat utility in Linux to display the file’s contents.
$ python3 multiply.py
1000
900
750
Keyword arguments
Keyword arguments can also be passed to a function as follows
>>> findIfMultiple(x = 200, y = 100)
'yes'
>>> findIfMultiple(x = 200, y = 99)
'no'
So we pass values for arguments while calling the function itself, by sepcifying the exact parameter, here position doesn’t matter
>>> findIfMultiple(y = 99, x = 200)
'no'
Positional and Keyword args
We can also mix positional and arguments while calling the function but the only condition to note is that the postional arguments must be mentioned first and the keyword arguments next, if we do vice versa, it would throw an error
>>> findIfMultiple(200, y = 99)
'no'
The code above executes as the positional argument(200 which maps with x) is specified first, where as the following code would break and throws a SyntaxError
>>> findIfMultiple(x=200, 99)
--TRUNCATED--
SyntaxError: positional argument follows keyword argument
Another example
Here is another example to try keyword arguments and positional arguments
>>> def fn(a, b, c):
... print(a * b / c)
...
>>> fn(10, 2, 5)
4.0
>>>
>>> fn(a=10, b=2, c=5) # keyword args
4.0
>>>
>>> fn(b=2, c=5, a=10) # keyword args
4.0
>>>
>>> fn(10, c=5, b=2)
4.0
>>> fn(a=10, 2, c=5) # SyntaxError: positional argument follows keyword argument
--TRUNCATED--
SyntaxError: positional argument follows keyword argument
Void
We have discussed earlier, that if a function doesn’t have a return statement, it can be called a void function. Alternatly
we can also pass retun None
explicitly to acheieve the same behaviour.
>>> def fn2():
... print('hi')
... return None # this is equivalent to having no return statement in the function
...
>>> fn2()
hi
Scope
We can define outside a function in our main program with global
scope, or inside a function with local
scope
Local only
>>> def fn1():
... x = 5 # local scope
... print(x)
...
>>> fn1()
5
Global only
>>> def fn2():
... print(y)
...
>>> y = 10 # global scope
>>> fn2()
10
Local and Global
Local will be preferred
>>> def fn3():
... z = 100 # local scope
... print(z)
...
>>> z = 1 # global scope
>>> fn3()
100
Use or in format
A default value can be specified in format, when an argument is passed to a function
>>> def howareyou(name=None):
... return('Hi {}, how are you' .format(name or 'friend'))
...
>>> howareyou('Ahmed')
'Hi Ahmed, how are you'
>>> howareyou()
'Hi friend, how are you'
Recursion
Functions can be recursive, meaning they can be called repeatedly from within, until a condition is arrived.
The following example, would call the function continuously, as there is no terminating condition, and finally break until the maximum recursion depth is reached.
>>> def fn():
... print('Hello')
... fn()
...
>>> fn()
Hello
Hello
Hello
Hello
--TRUNCATED--
Hello
Hello
Hello
Hello
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in fn
File "<stdin>", line 3, in fn
File "<stdin>", line 3, in fn
[Previous line repeated 992 more times]
File "<stdin>", line 2, in fn
RecursionError: maximum recursion depth exceeded while calling a Python object
Hello
Let’s write a factorial function, which a famous recursive use case.
>>> def fact(n):
... if n == 0:
... return 1
... else:
... return n * fact(n-1)
...
The number keeps reducing by 1 each time, and finally there is a condition to return to the main program, when the number becomes 0.
Let’s call the function with different numbers.
>>> print(fact(4))
24
>>> print(fact(0))
1
>>> print(fact(10))
3628800
–end-of-post–