LoginSignup
0
1

More than 3 years have passed since last update.

python で関数合成的な何か

Last updated at Posted at 2021-03-05

関数合成的な何か

$ python -V
Python 3.8.6
a.py
import functools

class F:
    @staticmethod
    def __cmp(f1, f2):
        def __i1(*args1, **kwargs1):
            def __i2(*args2, **kwargs2):
                return f1(*args2, **kwargs2)
            return f2(__i2(*args1, **kwargs1))
        return __i1


    @classmethod
    def composite(cls, *fs):
        return functools.reduce(cls.__cmp, fs)

test

a_test.py
import pytest
import functools

from a import F

def test_args1():
    """1引数の関数合成"""
    def d1(a):
        r = a * 2
        print(f"d1: {a} * 2 = {r}")
        return r

    def d2(a):
        r = a + 1
        print(f"d2: {a} + 1 = {r}")
        return r

    def d3(a):
        r = a // 3
        print(f"d3: {a} / 3 = {r}")
        return r

    f = F.composite(d1, d2, d3, d1, d2)
    assert f(123) == 165

def test_args2():
    """2引数以上はできないので適当にカリー化するとよい"""
    def d1(a, b):
        r = a * b
        print(f"d1: {a} * {b} = {r}")
        return r

    def d2(a, b):
        r = a + b
        print(f"d2: {a} + {b} = {r}")
        return r

    d3 = functools.partial(d1, b=2)
    d4 = functools.partial(d2, b=1)
    d5 = functools.partial(d1, b=3)
    d6 = functools.partial(d2, b=4)

    f = F.composite(d3, d4, d5, d6)
    assert f(123) == 745


def test_args3():
    """2引数以上は(ry"""
    def d1(a, b, c):
        r = a // b - c
        print(f"d1: {a} // {b} - {c} = {r}")
        return r

    def d2(a, b, c):
        r = (a + b) ** c
        print(f"d2: ({a} + {b}) ** {c} = {r}")
        return r

    d3 = functools.partial(d1, b=5, c=5)
    d4 = functools.partial(d2, b=3, c=2)
    d5 = functools.partial(d1, b=345, c=3)
    d6 = functools.partial(d2, b=4, c=8)

    f = F.composite(d3, d4, d5, d6)
    assert f(123) == 256


run test

bash
$ pytest -V
pytest 6.1.2

$ pytest -s -v a_test.py
=============================================== test session starts ===============================================
platform darwin -- Python 3.8.6, pytest-6.1.2, py-1.9.0, pluggy-0.13.1 -- /Users/kuryu/.pyenv/versions/3.8.6/bin/python3.8
cachedir: .pytest_cache
rootdir: /Users/kuryu/workspace/work
plugins: Faker-4.16.0
collected 3 items

a_test.py::test_args1 d1: 123 * 2 = 246
d2: 246 + 1 = 247
d3: 247 / 3 = 82
d1: 82 * 2 = 164
d2: 164 + 1 = 165
PASSED
a_test.py::test_args2 d1: 123 * 2 = 246
d2: 246 + 1 = 247
d1: 247 * 3 = 741
d2: 741 + 4 = 745
PASSED
a_test.py::test_args3 d1: 123 // 5 - 5 = 19
d2: (19 + 3) ** 2 = 484
d1: 484 // 345 - 3 = -2
d2: (-2 + 4) ** 8 = 256
PASSED

================================================ 3 passed in 0.06s ================================================

カレー食べたい。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1