2

I have these two functions:

def swap_joker1(afile):
    idx = afile.index(27)
    if idx == len(afile) - 1:
        afile[idx],afile[0]=afile[0],afile[idx]
    else:
        afile[idx],afile[idx+1]=afile[idx+1],afile[idx]
        return afile

def swap_joker2(afile):
    idx = afile1.index(28)
    afile[idx],afile[idx+1],afile[idx+2]=afile[idx+1],afile[idx+2],afile[idx]
    return afile

how can I compose them together. and become a new function called cipher_functions?

4
  • Compose them how? As in apply function swap_joker1 and then apply swap_joker2 ? Commented Nov 7, 2013 at 17:53
  • @GamesBrainiac That's the standard definition of function composition, yes. Commented Nov 7, 2013 at 17:56
  • @chepner just to be sure. Commented Nov 7, 2013 at 17:58
  • Answered, and linked to a website, that should prove helpful in your future endeavours into functional programming as well. Commented Nov 7, 2013 at 18:08

4 Answers 4

10

Well, you can create your own cute function composition function:

import functools


def compose(*functions):
    return functools.reduce(lambda f, g: lambda x: f(g(x)), functions)


def foo(var):
    return var // 2


def bar(var):
    return var + 1

if __name__ == '__main__':
    # Apply bar, then foo
    composition = compose(bar, foo)
    print composition(6)

You can apply the functions in whatever way you like, and in as many ways as you like. This answer was made possible, with the help of this website.

Sign up to request clarification or add additional context in comments.

Comments

3

A few methods:

cipher_functions = lambda afile:swap_joker2(swap_joker1(afile))
def cipher_functions(afile):
    return swap_joker2(swap_joker1(afile))

import functional #third party, not maintained. Alternatives exist
cipher_functions = functional.compose(swap_joker1, swap_joker2)

2 Comments

+1 for reference to the functional module; I knew there was something available, but didn't look it up in time.
@chepner Thanks. Also, I suspect that the functional implementation may be faster than the homebrew version, which must have a lot of calling overhead. Of course, likely to be fastest in C.
1

It would be great if Python offered a composition operator. Unfortunately, you need to do it yourself.

def cipher_functions(afile):
    # This is f(g(x)); swap for g(f(x)) if necessary
    return swap_joker1(swap_joker2(afile))

You can define a composition function easily:

def compose(f, g):
    return lambda *args, **kwargs: f(g(*args, **kwargs))

cipher_functions = compose(swap_joker1, swap_joker2)

Comments

0

Your swap_joker1 function returns either afile or None, which make composition a bit hard.

Assuming it was actually:

def swap_joker1(afile):
    idx = afile.index(27)
    if idx == len(afile) - 1:
        afile[idx],afile[0]=afile[0],afile[idx]
    else:
        afile[idx],afile[idx+1]=afile[idx+1],afile[idx]
    return afile

Which returns afile unconditionally, you can simply write the composition as:

def cipher_functions(afile):
    return swap_joker2(swap_joker1(afile))

And more generally:

def compose(f, g):
    "Returns x -> (f o g)(x) = f(g(x))"
    def fog(*args, **kwargs):
        return f(g(*args, **kwargs))
    return fog

cipher_functions = compose(swap_joker2, swap_joker1)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.