{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
" Code for topic #11:\n",
"
Higher order functions \n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" Lambda expressions "
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"9\n",
"9\n"
]
}
],
"source": [
"def sum1(x,y):\n",
" return x+y\n",
"sum2 = lambda x,y: x+y\n",
"print(sum1(4,5))\n",
"print(sum2(4,5))"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"7\n",
"7\n"
]
}
],
"source": [
"def plus2(x):\n",
" return x+2\n",
"def plus3(x):\n",
" return x+3\n",
"# this is not a \"clean\" combination\n",
"# since we need an extra parameter\n",
"def sum_fg(f,g,x):\n",
" return f(x)+g(x)\n",
"# a lambda that returns a lambda\n",
"make_sum = lambda f,g: (lambda x: f(x)+g(x)) #parentheses are optional\n",
"# (x+2) + (x+3) is 2*x+5\n",
"print(sum_fg(plus2,plus3,1))\n",
"sum5 = make_sum(plus2, plus3)\n",
"print(sum5(1))"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"7\n"
]
}
],
"source": [
"def make_sum(f,g):\n",
" return lambda x: f(x)+g(x)\n",
"print(make_sum(plus2, plus3)(1))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" parabola(x) = x**2 + 10*x + 1 "
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"12\n"
]
}
],
"source": [
"def square_plus1(x):\n",
" return x*x+1\n",
"\n",
"times_10 = lambda x:x*10\n",
"\n",
"parabola = make_sum(square_plus1, times_10)\n",
"print(parabola(1))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" defining generic parabolas "
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"12\n"
]
}
],
"source": [
"def make_parabola(a,b,c):\n",
" return lambda x: a*x**2 + b*x + c\n",
"\n",
"parabola1 = make_parabola(1,10,1)\n",
"\n",
"print (parabola1(1))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" Lambda with if "
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[True, False, True, False, True, False, True, False, True, False]"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# no lambda version\n",
"def check_odd(x):\n",
" if x%2==0: return True\n",
" return False\n",
"\n",
"#lambda version\n",
"check_odd = lambda x: True if x%2==0 else False\n",
"[check_odd(i) for i in range(10)]"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[True, False, True, False, True, False, True, False, True, False]"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# using map\n",
"res = map(lambda i: True if i%2==0 else False, range(10)) \n",
"list(res)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" Composing functions "
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"64"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def compose(f,g):\n",
" return lambda x: f(g(x))\n",
"\n",
"square = lambda x:x**2\n",
"cube = lambda x:x**3\n",
"power6 = compose (square,cube) \n",
"power6(2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" f^n of x "
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"4\n"
]
}
],
"source": [
"def apply_n_times(f,n,x):\n",
" # 1 times: just apply the functions\n",
" if n==1: return f(x)\n",
" # else apply f to f^(n-1) of x\n",
" return f((apply_n_times(f, n-1, x)))\n",
"\n",
"add1 = lambda x: x+1\n",
"\n",
"add4 = lambda x: apply_n_times(add1, 2, x)\n",
"\n",
"print(add4(2)) "
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"6"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def apply_n_times(f,n):\n",
" if n==1: return f\n",
" return compose(f, apply_n_times(f, n-1))\n",
"\n",
"add1 = lambda x: x+1\n",
"\n",
"add4 = apply_n_times(add1,4)\n",
"\n",
"add4(2)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"import math\n",
"\n",
"\n",
"def diff(f):\n",
" \"\"\" Returns the derivative of a\n",
" one parameter real valued function f.\n",
" \"\"\"\n",
" h = 0.001\n",
" return (lambda x: (f(x+h)-f(x))/h)\n",
"\n",
"def diff2(f):\n",
" \"\"\" Returns the derivative of a\n",
" one parameter real valued function f.\n",
" \"\"\"\n",
" h = 0.001\n",
" def df(x): # a new, inner function\n",
" return (f(x+h)-f(x))/h\n",
" return df\n",
"\n",
"\n",
"def diff_param(f, h=0.001):\n",
" \"\"\" Returns the derivative of a\n",
" one parameter real valued function f.\n",
" When h is not specified, default value h=0.001 is used\n",
" \"\"\"\n",
" return (lambda x: (f(x+h)-f(x))/h)\n",
"\n",
"\n",
"def integral(f, h=0.001):\n",
" \"\"\" definite integral: function of a, b \"\"\"\n",
" return lambda a,b: h * sum(f(a+i*h) for i in range(0, int((b-a)/h )))\n",
" \n",
"\n",
"##########################################\n",
"## Some real valued functions to play with\n",
"##########################################\n",
"\n",
"def euclid(x,y,z) :\n",
" \"\"\" returns the length of the vector from (0,0,0) to (x,y,z) \"\"\"\n",
" return (x**2 + y**2 + z**2)**0.5\n",
"\n",
"euclid2 = lambda x,y,z : (x**2 + y**2 + z**2)**0.5\n",
"\n",
"def square(x):\n",
" return x**2\n",
"\n",
"def penta(x):\n",
" return x**5\n",
"\n",
"def sin_by_million(x):\n",
" return math.sin(10**6*x)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.33283349999999995\n",
"3.9999999999996643\n",
"4.001997999999674\n",
"10000.00000002181\n"
]
}
],
"source": [
"def square(x):\n",
" return x**2\n",
"\n",
"print(integral(square)(0 ,1))\n",
"print(integral(diff(square))(0 ,2))\n",
"print(integral(diff(square),h=0.000001)(0 ,2) )\n",
"print(integral(diff(square))(0 ,100))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" map, filter, reduce "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" map "
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[1, 4, 9, 16, 25]"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"items = [1, 2, 3, 4, 5]\n",
"squared = list(map(lambda x: x**2, items))\n",
"squared"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[0, 1, 8, 27, 64]"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"cube = lambda x: x**3\n",
"[cube(x) for x in range(5)]"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[0, 1, 8, 27, 64]\n"
]
},
{
"data": {
"text/plain": [
"map"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"res = map(lambda x:x**3, range(5) )\n",
"print(list(res))\n",
"type(res)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[0, 0]\n",
"[1, 2]\n",
"[4, 4]\n",
"[9, 6]\n",
"[16, 8]\n"
]
}
],
"source": [
"def multiply(x):\n",
" return (x*x)\n",
"def add(x):\n",
" return (x+x)\n",
"\n",
"funcs = [multiply, add]\n",
"for i in range(5):\n",
" value = list(map(lambda x: x(i), funcs))\n",
" print(value)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" Implementing map with a generator "
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[1, 4, 9, 16, 25]"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def map_generator(func,itr):\n",
" for obj in itr:\n",
" yield func(obj)\n",
"\n",
"items = [1, 2, 3, 4, 5]\n",
"squared = list(map_generator(lambda x: x**2, items))\n",
"squared "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" filter "
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[-5, -4, -3, -2, -1]\n"
]
}
],
"source": [
"number_list = range(-5, 5)\n",
"less_than_zero = list(filter(lambda x: x < 0, number_list))\n",
"print(less_than_zero)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" reduce "
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"24"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"product = 1\n",
"list = [1, 2, 3, 4]\n",
"for num in list:\n",
" product = product * num\n",
"product"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"24"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from functools import reduce\n",
"product = reduce((lambda x, y: x * y), [1, 2, 3, 4])\n",
"product"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}