Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
3 views

Functions in Python

The document outlines various types of arguments in functions, including parametric, keyword, and default arguments, as well as different types of functions such as built-in, library, string methods, and user-defined functions. It also discusses concepts like call by value, matrix multiplication, iterators, generators, lambda functions, and built-in functions like enumerate, zip, map, and filter. Each concept is illustrated with code examples to demonstrate their usage in Python programming.

Uploaded by

infinity9151
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

Functions in Python

The document outlines various types of arguments in functions, including parametric, keyword, and default arguments, as well as different types of functions such as built-in, library, string methods, and user-defined functions. It also discusses concepts like call by value, matrix multiplication, iterators, generators, lambda functions, and built-in functions like enumerate, zip, map, and filter. Each concept is illustrated with code examples to demonstrate their usage in Python programming.

Uploaded by

infinity9151
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 8

Types of Arguments in functions

• Parametric Arguments : These are the arguments passed to the func-


tion for it to perform its designated action. When multiple arguments
are provided, their positions become keys for the interpretation and
correct execution of the function. E.g. :
def cumulative_difference(a,b,c):
result = a + b - c
return result
In the example above, a,b and c are the parameters for the function thus forming
the parametric arguments.
• Keyword Arguments : To mitigate the positional significance of the argu-
ment, we assign them to their respective key words when inputting. E.g.
:
def cumulative_difference(a,b,c):
result = a + b - c
return result
print( cumulative_difference(a = 10, b = 20, c = 30) )
Now the sequence of arguments has nothing to do with the sequence of the
parameters, namely: a, b and c.
• Default Arguments : Often times we also notice that the number of argu-
ments passed must equate to the number of parameters in our function.
If this condition is not met, the function will throw an error. This can be
mitigated by introducing default values (assigning values to parameters at
the time of writing the function). E.g.
def cumulative_difference(a = 10, b = 20, c = 30):
result = a + b - c
return result
print( cumulative_difference(a = 40))
→ Notice that we’ve only passed one argument above, i.e. a = 40, yet the code
runs. This is because we used default values for our parameters.
We can have any combination of these three types of arguments in our function.

Types of Functions
1. In-built Functions: They’re built into Python and utilized without im-
porting any library. E.g. print(), input(), len()

1
2. Library Functions: They’re the functions that can be used by importing
them from libraries like, string, math, numpy, os etc. E.g. : log(),
random(), calendar().
3. String-Methods: These also do not need to be used after importing a
library but are limited to strings, thus are called string methods. E.g.
count(), strip(), index(), lower() etc.
4. User - Defined Functions: We can define and use these functions. E.g.
The factorial function.
• $ Every function is always followed by a parenthesis.

Call by Value
• Whenever we define a function and assign a parameter to it, the assigned
parameter is passed to the function as a value and not the variable itself.
E.g.:
def function(u):
prod = 2*u
return prod
u = 25
print(function(u))
Here, when we say u = 25 and pass u to the function, only the value of u is
passed to the function, thus we are calling the function by value.

Matrix Multiplication Function (Modular)


• To write up a matrix, we can write them as individual rows and combine
the rows to form the whole matrix. The columns are all the elements.
Column 0 would be all the first elements in all the matrices. E.g.
r1 = [1, 2, 3]
r2 = [4, 5, 6]
r3 = [7, 8, 9]

A = []
A.append(r1)
A.append(r2)
A.append(r3)

s1 = [1, 2, 1]

2
s2 = [6, 2, 3]
s3 = [4, 2, 1]

B = []
B.append(s1)
B.append(s2)
B.append(s3)

C = [[0 ,0 ,0], [0 ,0 ,0], [0 ,0 ,0]]

dim = 3

# C[i][j] is the dot product of the ith row of A and the jth column of B

for i in range(dim):
for j in range(dim):
for k in range(dim):
C[i][j] = C[i][j] + A[i][k]*B[k][j]

print(C)

Functional Approach to Matrix Multiplication


• Firstly we initialize the matrix. Ensure the dimensions are correct and
the elements are in accordance to the dimensions inputted.
def initialize_matrix(dim):
C = []
for i in range(dim):
C.append([])
for i in range (dim):
for j in range(dim):
C[i].append(0)
return C

# Test Case
print(initialize_matrix(3))
• Secondly we make a Dot Product function.
def dot_product(row:list,column:list):
if len(row) != len(column):
raise ValueError("Mismatched dimensions for row and column.")

answer = 0
dim = len(row)
for i in range(dim):

3
answer += (row[i] * column[i])
return answer

# Test case
result = dot_product([25,1,17], [22,5,21])
print(result)
• Now we need to just place the dot products in a matrix. For this we define
a function that iterates through the i'th row and the j'th column.
def row_iterator(M:list,i:int) -> list:
dim = (len(M))
l_row = []
for k in range(dim):
l_row.append(M[i][k])
return l_row
# test
A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(row_iterator(A, 0))
• Now we write a column iterator in same fashion.
def column_iterator(M:list, j:int) -> list:
dim = len(M)
l_column = []
for k in range(dim):
l_column.append(M[k][j])
return l_column
# testcase
A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(column_iterator(A, 0))
• Now for the final part, we need to define the matrix multiplication as a
function.
# Getting all other functions too so that code runs.
def initialize_matrix(dim):
C = []
for i in range(dim):
C.append([])
for i in range (dim):
for j in range(dim):
C[i].append(0)
return C
#-------------------------------------------------------------------
def dot_product(row:list,column:list):
if len(row) != len(column):
raise ValueError("Mismatched dimensions for row and column.")

4
answer = 0
dim = len(row)
for i in range(dim):
answer += (row[i] * column[i])
return answer
#-------------------------------------------------------------------
def row_iterator(M:list,i:int) -> list:
dim = (len(M))
l_row = []
for k in range(dim):
l_row.append(M[i][k])
return l_row
#-------------------------------------------------------------------
def column_iterator(M:list, j:int) -> list:
dim = len(M)
l_column = []
for k in range(dim):
l_column.append(M[k][j])
return l_column
#-------------------------------------------------------------------
def matrix_multiplication(A:list, B:list) -> list:
dim = len(A)

C = initialize_matrix(dim)
for i in range(dim):
for j in range(dim):
C[i][j] = dot_product( row_iterator(A, i), column_iterator(B, j))

return C
#-------------------------------------------------------------------
# Test Case:
A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
B = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(matrix_multiplication(A, B))

Iterators and Generators


• Iterators and Generators are both parts of Functional Program-
ming

Iterators
• iter(collection_name) will act as a basket does in real life. It becomes
an accumulation of elements and we can toggle through it. It converts

5
any iterable entity into an iterator E.g. :
fruits = [ 'Apple', 'Mango', 'Grapes', 'Banana' ]
basket = iter(fruits)

print(next(basket))
print(next(basket))
print(next(basket))
→As evident, basket acts like a basket does in real life due to the iter() key
word. Thus it is an iterator. Also notice that a list is iterable, thus converted
into an iterator. Had it been an integer, we couldn’t have converted it into an
iterator.
• When we iterate using a loop, internally it does the same thing as an
iterator, but we do not have the same control over it as an iterator.

Generators
• We may be interested in iterating through without creating a list or string.
In such cases we may use a Generator. In a generator we use yield
instead of return and we may toggle through different yields using the
next() function like we do in any iterator. E.g. :
def square(limit):
x = 0
while x < limit:
yield x
yield x*x
x += 1

a = square(5)
print(next(a), next(a))
print(next(a), next(a))
print(next(a), next(a))
print(next(a), next(a))
→ We’ve successfully written a generator above. We may have more than one
yield and toggle through them using next().

The Lambda Function


• Using a lambda function we can write functions without giving the func-
tion a name. Lambda functions are anonymous.
• Sometimes we only have functions with one line of code. In such cases,
giving it a name isn’t that important, in such cases, we use the lambda

6
function. It reduces the length of our program. E.g. :
add = lambda x, y: x+y
subtract = lambda x, y: x-y

print(add(10, 20))
print(subtract(30, 20))
→ We see that the function runs without any errors. lambda functions are of
form : function_name = lamda arg_1, arg_2: function_definition
• The function is stored inside the variable name assigned to it. The function
call is just as usual.

The Enumerate Function


• Let’s say we want to index a list along with its content. We can iterate
through it normally but i and list[i] are different entities. If we make
any miscalculations, we will get de synced outcomes. To avoid this, we
can use the enumerate() function.
• E.g. :
fruits = [ 'Apple', 'Mango', 'Grapes', 'Banana' ]
for fruit in enumerate(fruits):
print(fruit)
→ Notice now, the index and the item are coupled together inside a
single tuple.

Zip
• We may want to couple elements from two different lists. For that we may
use the zip(list_1, list_2) function.
• The arguments inside the zip() function are the two lists we are coupling.
• E.g. :
fruits = [ 'Apple', 'Mango', 'Grapes', 'Banana' ]
fruit_count = [2, 4, 25, 12]
print(list(zip( fruits, fruit_count)))
print(dict(zip(fruits, fruit_count)))

7
Map Function
• Let’s say we need to subtract a matrix B (list form) from another matrix
A (list form).
• map( function_name, list_1, list_2). Map takes the name of the
function and then the names of the lists to be mapped. E.g. :
a = [10, 20, 30, 40, 50]
b = [5, 10, 15, 20, 25]

subtract = lambda x,y: x - y


c = map(subtract, a, b)
print(list(c))
• We can even increment all the elements inside a list using map without
any iteration.
a = [10, 20, 30, 40, 50]
def increment(x):
return x + 1
new_list = map( increment, a)
print(list(new_list))

Filter Function
• It is used to filter elements out as the name suggests. filter(condition,
list_name / input variable name) E.g.
import math

a = [25, -16, 9, 81, -100]

def square_root(n):
return math.sqrt(n)

def is_positive(n):
if n >= 0:
return n
output = map(square_root, filter(is_positive,a))
print(list(output))

You might also like