Introduction to Higher Order Functions Python

 

Introduction to Higher Order Functions

A higher order function (HOF) is a function that takes one or more functions as arguments or return a function as a result, or both. They are supported by a wide range of programming languages including the most popular ones such as Python, C++ and JavaScript.

An example of Higher Order Functions that typically built-in within programming languages are:

map fold filter Although they are simple concepts, knowing how to use them can very much improve the way you write code :). So let’s get started!

In this tutorial we’ll use Python, without any loss of generalization the same concepts apply to any other language.

1. map

The signature of map function in Python is map(function, iterable,)

map operates on iterables (lists, tuples, strings or any sequence that can be iterated on with a for loop)

map is used to apply a function to each item in the iterable, or in other words to map each item to something else.

Example: Let’s say we have this list of numbers, and we would to return zero for each negative number, and return the square of each positive number.

import math

list_of_nums = [1, 5, 10, -5, 8, -4, 3]

def my_function(x):
    if x < 0:
        return 0
    else:
        return math.pow(x, 2)

new_list_of_nums = list(map(my_function, list_of_nums))

print(new_list_of_nums)

#Output: [1, 25, 100, 0, 64, 0, 9]

2. reduce

reduce is the Pythonic version of foldl in Functional Programming, it can be used to apply operations that can accumulate the iterable, such as summing numbers, or concatenation of strings.

The reduce in Python is available in the functools module

The signature of reduce function in Python is reduce(function, iterable)

In reduce, the function we apply must have two arguments. This time we’ll use a lambda,

A lambda is an anonymous function that has the following syntax: lambda arguments : expression

In the following example, we are finding the sum of the first 100 natural numbers, the way this works is as follows it starts from the first item of the list from left to right: ((((1+2)+3)+4)+5)...+100) = 5050

import functools

list_of_nums = list(range(1, 101))

sum_of_nums = functools.reduce(lambda x, y: x + y, list_of_nums)

print(sum_of_nums)

#Output: 5050

3. filter

The filter function as the name suggests, filters an iterable based on the boolean value returned by the function we pass.

The signature of filter function in Python is filter(function, iterable)

In the following example, we are filtering the list such that lowercase characters are removed.

list_of_chars= ['A','B','c','D','e','F',]

filtered_list = list(filter(lambda x: x.isupper(), list_of_chars))

print(filtered_list)

#Output: ['A', 'B', 'D', 'F']

More Examples :


"""
Playing with Lambda Functions
From section 1.6.7 of composing programs
In general, python prefers def statements, but lambdas are useful where there is a simple nested function as an argument or return value.
"""
def compose(f, g):
return lambda x: f(g(x))
f = compose(
lambda x : x*x,
lambda y : y+1 )
result = f(11)
print(result)
#I'd like to come back and write an acutal test for this instead of a print
"""
Example of simple recursive function
"""
def sum_digits(n):
if n < 10:
return n
else:
all_but_last, last = n // 10, n % 10
return sum_digits(all_but_last) + last
summed_result = sum_digits(552)
print(summed_result)
"""
Example of mutual recursion
"""
def is_even(n):
if n == 0:
return True
else:
return is_odd(n-1)
def is_odd(n):
if n == 0:
return False
else:
return is_even(n-1)
result3 = is_even(4)
print(result3)
"""
Example of tree recursion
"""
def fib(n):
"""
Returns Nth number in fibonacci series
"""
if n == 1:
return 0
if n == 2:
return 1
else:
return fib(n-2) + fib(n-1)
result_fib = fib(6)
print(result_fib)
"""
List Comprehension
"""
def divisors(n):
return [1] + [x for x in range(2,n) if n % x == 0]
result_divisors = divisors(8)
print(result_divisors)
#keep if function
#takes an list and a filter
#So if want all posts from a user
#have a general keep if
#pass that by_user
#by user definted elsewhere -------------
'''
Lets Understaned Higher Order Function (HOF)
HOF if Function which will accept argument as function
and return function as well.
NOTE : Use Debugger to Understand the flow of code.
'''
''' Example '''
# 1
print('\nHigher Order Function\n')
def Login(func,username,password):
isValid = func(username, password)
if isValid:
return f'Welcome {username}'
else:
return 'Invalid username or password... ?'
def validate_user_data(temp_uname, temp_pass):
if temp_uname.strip()=='Mike' and temp_pass.strip()=='mikeee128':
return True
def get_user_details():
uname = str(input('Enter your username:'))
passwrd = str(input('Enter your password:'))
return uname,passwrd
if __name__=='__main__':
usrname, paswd = get_user_details()
print(f'1.{Login(validate_user_data, usrname, paswd)}')
'''
In above example i have created 3 function but if you Notice
In "Login" Function i have passed the "validate_user_data" as
an arrgument and used that function future in my code.
'''
print('#'*58)
####################################################################################################################################################################################################################################################################################################################
''' Currying '''
'''
We can use higher-order functions to convert a function that takes
multiple arguments into a chain of functions that each take a single
argument. More specifically, given a function f(x, y), we can define
a function g such that g(x)(y) is equivalent to f(x, y). Here, g is a
higher-order function that takes in a single argument x and returns
another function that takes in a single argument y. This transformation
is called currying.
'''
''' Example '''
print('\n\nCurrying\n')
# 1.
def get_1st_number(num_1):
def get_2nd_number(num_2):
return num_1+num_2
return get_2nd_number
if __name__=='__main__':
print(f'1. Addition of two Number: {get_1st_number(10)(20)}')
''' The above function is pure function because is completely depend on input.'''
# 2.
def pas_function(user_func):
def get_x(x):
def get_y(y):
return user_func(x,y)
return get_y
return get_x
def mul_function(a,b):
return a+b
pas_func = pas_function(mul_function)
print(f'2. Currying With user define or pre define function:{pas_func(2)(4)}\n')
'''
In above example you can apply any function which applicable for two arrguments such as "max","min", "pow". etc.
You can also passs user define function ..in our case i have passed "mul_function", you guys can yours
Function but make sure that function will work on 2 prameter.
'''
print('#'*58)
####################################################################################################################################################################################################################################################################################################################
''' Higher Order Function With Currying '''
print('\nHigher order fucntion with Currying\n')
#1.
def Login(func,welcom_func):
def get_username(uname):
def get_password(pas):
isValid = func(get_user_details,uname,pas)
if isValid:
return welcom_func(uname)
else:
return Invalid_user()
return get_password
return get_username
def check_valid_User(func_user_input,usernm,userpas):
tempUname,tempPass = func_user_input()
return ((tempUname.strip()==usernm) and (tempPass.strip()==userpas.strip()))
def welcome_user(uname):
return f'Welcome {uname}'
def Invalid_user():
return 'invalid username or password'
def get_user_details():
tempName = str(input('Username:'))
tempPass = str(input('Password:'))
return str(tempName).strip(), str(tempPass).strip()
login = Login(check_valid_User,welcome_user)
print(login('Mike')('Mikeee'))
print('#'*58)

Comments

Popular posts from this blog

Flutter for Single-Page Scrollable Websites with Navigator 2.0

A Data Science Portfolio is More Valuable than a Resume

Better File Storage in Oracle Cloud