Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a function composer

Tags:

I am trying to make a function that rounds other functions for my university degree . For example I would like to call the round_sqrt = round(sqrt) and when i call the round_sqrt(5) it has to shows me 2 instead of 2.23606797749979. What I am trying is this:

def rounding(funct):
    return round(funct)

but this doesn't work.

EDIT: The function should have only one parameter. For example the start of the function should be

def rounding(func):

so in this function the funct function needs to be rounded. so when I call rounding(abs)(3.2) it shows me 3.

like image 245
php kubrick Avatar asked Nov 07 '18 17:11

php kubrick


People also ask

How do you compose functions in JavaScript?

Function Composition in JavaScript Function composition is the pointwise application of one function to the result of another. Developers do it in a manual manner every day when the nest functions: compose = (fn1, fn2) => value => fn2 (fn1 (value))

What is composition in functional programming?

Functional Programming – Composition. One of the coolest things about functional programming is the ability to compose functions, meaning we take a set of pure functions and compose a new function that is a composition of all the functions.

What is the best way to implement compose?

A simple implementation of compose would be: To get even more flexibility we can use the reduceRight function: Reading compose from left to right allows a clear chaining of higher order functions. Real world examples are adding authentications, logging and context properties. It’s a technique that enables reusability on the highest level.

How do you find the composition of a function?

In order to figure out function composition (or to decompose a function), you must be familiar with the eight common function types and with basic function transformations, like: Adding a constant shifts the function’s graph to the left that number of units.


2 Answers

You should check out closures:

def rounder(func):
    def inner(*args, **kwargs):
        return round(func(*args, **kwargs))
    return inner

Then you can decorate functions using the @ character:

@rounder
def adder(x, y):
    return x + y

print(adder(1.1, 2.2))

outputs 3

Supplementary:

  1. You can use functools.wraps in your closure so you don't lose information (e.g. docstring, function name) about the original function.
  2. There are a bunch of resources for learning about closures (e.g. 1, 2) and decorators (e.g. 1, 2) that you can find by Googling those terms.
like image 83
Alex Avatar answered Sep 27 '22 22:09

Alex


For your specific example, you can write

def round_sqrt(x):
    return round(sqrt(x))

Alex's answer generalizes this; he defines a function that creates round_sqrt for you. If the function is already defined, you just pass it as an argument to rounder:

round_sqrt = rounder(sqrt)

Of course, you don't need to define round_sqrt if you don't want to. rounder(sqrt)(3.2) can be called directly, although it's far more efficient to safe the return value of rounder if you expect to use it multiple times, rather than redefining it each time.

Otherwise, the decorator syntax is just short for (using Alex's example)

def adder(x, y):
    return x + y

adder = rounder(adder)

As I said in my comment, this is an example of implementing composition. Mathematically, composition is simple, because mathematical functions always take a single argument and return a single argument. As such, the composition of two functions f and g could always be defined simply as

def compose(f, g):
    def h(x):   # The name doesn't matter
        return f(g(x))
    return h

Then

round_sqrt = compose(round, sqrt)

(Ignoring all sorts of practical concerns around the implementation, Python could in theory even provide a Unicode operator for functions: round_sqrt = round ∘ sort. Explaining why this won't happen is beyond the scope of this answer.)

In Python, though, functions are far more complicated. They can take multiple arguments, they can accept arbitrary numbers of arguments and arbitrary keyword arguments, and while each technically returns a single value, that value can be a tuple which is thought of as multiple values or a dict. As a result, there may be many ways you might expect to pass the return value of g to a function f, more than can easily be accommodated in a simple compose function.

like image 30
chepner Avatar answered Sep 27 '22 20:09

chepner