Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Илья Беда (bro.engineering) - Data DSL на Python

Илья Беда (bro.engineering) - Data DSL на Python

Доклад с Moscow Python Conf 2016 (http://conf.python.ru)
Видео: https://conf.python.ru/data-dsl-na-python/

Все мы сталкиваемся с различными видами DSL. Это и общеизвестные внешние DSL - HTML CSS SQL, и более специализированные внутренние DSL - такие как модели и формы в веб-фреймворке Django.
- Чем же так хороши DSL?
- За счет узкой специализации языка вы можете выразить больше логики меньшим количеством конструкций.
- Почему бы не применять этот подход для решения повседневных задач.
- К сожалению, создание DSL сложная задача.
- Как можно упростить её?
- Нужно максимально использовать то, что уже готово. Зачем писать парсеры или разбирать AST python кода, когда можно использовать стандартные структуры данных, такие как списки и словари. Более того, в мире Clojure это является общепринятым стандартом.
В своем докладе я покажу примеры DSL, построенных на данных.
Вы узнаете, как реализовать DSL в python на основе списков и словарей. Я расскажу, в чем преимущество такого подхода, и на реальных примерах продемонстрирую для каких задач стоит применять данную технология, а для каких нет.

Moscow Python Meetup
PRO

October 12, 2016
Tweet

More Decks by Moscow Python Meetup

Other Decks in Programming

Transcript

  1. 1
    DATA DSL HA PYTHON
    Илья Беда

    View Slide

  2. 2
    КТО Я?
    Разрабатываю бэкэнды на python в течение 9 лет
    Разрабатываю фронтенд на React в течение 2 лет
    Продвигаю функциональное программирование
    Провожу воркшопы и мастер-классы
    Люблю выступать на конференциях

    View Slide

  3. 3
    КТО НЕ ЛЮБИТ ПИСАТЬ
    ШАБЛОННЫЙ КОД?

    View Slide

  4. 4
    КТО НЕ ЛЮБИТ, КОГДА КОД
    РАБОТАЕТ НЕЯВНО?

    View Slide

  5. 5
    WHAT WOULD YOU LIKE TO
    COMPLAIN ABOUT?
    [ ] Too much magic
    [ ] Too much boilerplate

    View Slide

  6. 6
    WHAT WOULD ZEN OF PYTHON LIKE
    TO COMPLAIN ABOUT?
    [✅] Too much magic
    [ ] Too much boilerplate

    View Slide

  7. 7
    WHAT WOULD ILYA BEDA LIKE TO
    COMPLAIN ABOUT?
    [] Too much magic
    [✅] Too much boilerplate

    View Slide

  8. 8
    КАК ЖЕ БЫТЬ?

    View Slide

  9. 9
    КАК НАМ ПОЛЬЗОВАТЬСЯ
    ВСЕЙ МОЩНОСТЬЮ
    МЕТАПРОГРАММИРОВАНИЯ И
    БЛЮСТИ ZEN OF PYTHON
    в языке, совершенно не приспособленном к
    метапрограммированию?

    View Slide

  10. 10
    МЕТАПРОГРАММИРОВАНИЕ В
    ДРУГИХ ЯЗЫКАХ:
    Ruby
    Scala
    Haskell
    Clojure

    View Slide

  11. 11
    МЕТАПРОГРАММИРОВАНИЕ В
    ДРУГИХ ЯЗЫКАХ:
    Ruby
    Scala
    Haskell
    CLOJURE

    View Slide

  12. 12
    CLOJURE

    View Slide

  13. 13
    МАКРОСЫ В CLOJURE
    (
    d
    e
    f
    n i
    s
    ­
    s
    m
    a
    l
    l
    ? [
    n
    u
    m
    b
    e
    r
    ]
    (
    i
    f (
    < n
    u
    m
    b
    e
    r 1
    0
    0
    ) "
    y
    e
    s
    " "
    n
    o
    "
    )
    )

    View Slide

  14. 14
    МАКРОСЫ В CLOJURE
    (
    d
    e
    f
    n h
    e
    l
    l
    o
    ­
    b
    i
    l
    l [
    u
    s
    e
    r
    ­
    n
    a
    m
    e
    ]
    (
    w
    h
    e
    n (
    = u
    s
    e
    r
    ­
    n
    a
    m
    e "
    b
    i
    l
    l
    "
    )
    (
    p
    r
    i
    n
    t
    l
    n "
    h
    e
    l
    l
    o b
    i
    l
    l
    "
    )
    )
    )

    View Slide

  15. 15
    МАКРОСЫ В CLOJURE
    (
    m
    a
    c
    r
    o
    e
    x
    p
    a
    n
    d '
    (
    w
    h
    e
    n (
    = u
    s
    e
    r
    ­
    n
    a
    m
    e "
    b
    i
    l
    l
    "
    )
    (
    p
    r
    i
    n
    t
    l
    n "
    h
    e
    l
    l
    o b
    i
    l
    l
    "
    )
    )
    )
    (
    i
    f (
    = u
    s
    e
    r
    ­
    n
    a
    m
    e "
    b
    i
    l
    l
    "
    )
    (
    d
    o (
    p
    r
    i
    n
    t
    l
    n "
    h
    e
    l
    l
    o b
    i
    l
    l
    "
    )
    )
    )

    View Slide

  16. 16
    МАКРОСЫ В CLOJURE
    (
    d
    e
    f
    n h
    e
    l
    l
    o
    ­
    b
    i
    l
    l [
    u
    s
    e
    r
    ­
    n
    a
    m
    e
    ]
    (
    w
    h
    e
    n (
    = u
    s
    e
    r
    ­
    n
    a
    m
    e "
    b
    i
    l
    l
    "
    )
    (
    p
    r
    i
    n
    t
    l
    n "
    h
    e
    l
    l
    o b
    i
    l
    l
    "
    )
    )
    )
    (
    d
    e
    f
    n h
    e
    l
    l
    o
    ­
    b
    i
    l
    l [
    u
    s
    e
    r
    ­
    n
    a
    m
    e
    ]
    (
    i
    f (
    = u
    s
    e
    r
    ­
    n
    a
    m
    e "
    b
    i
    l
    l
    "
    )
    (
    d
    o (
    p
    r
    i
    n
    t
    l
    n "
    h
    e
    l
    l
    o b
    i
    l
    l
    "
    )
    )
    )
    )

    View Slide

  17. 17
    ПОЧЕМУ МЫ НЕ ДЕЛАЕМ ТАК В
    PYTHON?

    View Slide

  18. 18
    ВОЗМОЖНОСТЬ ТАКАЯ ЕСТЬ
    f
    r
    o
    m p
    a
    t
    t
    e
    r
    n
    s i
    m
    p
    o
    r
    t p
    a
    t
    t
    e
    r
    n
    s
    @
    p
    a
    t
    t
    e
    r
    n
    s
    d
    e
    f f
    a
    c
    t
    o
    r
    i
    a
    l
    (
    )
    :
    i
    f 0
    : 1
    i
    f n i
    s i
    n
    t
    : n * f
    a
    c
    t
    o
    r
    i
    a
    l
    (
    n
    ­
    1
    )
    i
    f [
    ]
    : [
    ]
    i
    f [
    x
    ] + x
    s
    : [
    f
    a
    c
    t
    o
    r
    i
    a
    l
    (
    x
    )
    ] + f
    a
    c
    t
    o
    r
    i
    a
    l
    (
    x
    s
    )
    i
    f {
    '
    n
    '
    : n
    , '
    f
    '
    : f
    }
    : f
    (
    f
    a
    c
    t
    o
    r
    i
    a
    l
    (
    n
    )
    )

    View Slide

  19. 19
    ВОЗМОЖНОСТЬ ТАКАЯ ЕСТЬ
    d
    e
    f f
    a
    c
    t
    o
    r
    i
    a
    l
    (
    n
    )
    :
    i
    f n =
    = 0
    : r
    e
    t
    u
    r
    n 1
    i
    f i
    s
    i
    n
    s
    t
    a
    n
    c
    e
    (
    n
    , i
    n
    t
    )
    : r
    e
    t
    u
    r
    n n * f
    a
    c
    t
    o
    r
    i
    a
    l
    (
    n
    ­
    1
    )
    i
    f n =
    = [
    ]
    : r
    e
    t
    u
    r
    n [
    ]
    i
    f i
    s
    i
    n
    s
    t
    a
    n
    c
    e
    (
    n
    , l
    i
    s
    t
    )
    : r
    e
    t
    u
    r
    n [
    f
    a
    c
    t
    o
    r
    i
    a
    l
    (
    x
    [
    0
    ]
    )
    ] \
    + f
    a
    c
    t
    o
    r
    i
    a
    l
    (
    x
    [
    1
    :
    ]
    )
    i
    f i
    s
    i
    n
    s
    t
    a
    n
    c
    e
    (
    n
    , d
    i
    c
    t
    )
    : r
    e
    t
    u
    r
    n n
    [
    '
    f
    '
    ]
    (
    f
    a
    c
    t
    o
    r
    i
    a
    l
    (
    n
    [
    '
    n
    '
    ]
    )
    )

    View Slide

  20. 20
    ПОЧЕМУ МЫ НЕ ДЕЛАЕМ ТАК В
    PYTHON

    View Slide

  21. 21
    PYTHON SOURCE CODE
    d
    e
    f i
    s
    _
    s
    m
    a
    l
    l
    (
    n
    u
    m
    b
    e
    r
    )
    :
    i
    f n
    u
    m
    b
    e
    r < 1
    0
    0
    :
    r
    e
    t
    u
    r
    n "
    y
    e
    s
    "
    e
    l
    s
    e
    :
    r
    e
    t
    u
    r
    n "
    n
    o
    "

    View Slide

  22. 22
    PYTHON AST
    F
    u
    n
    c
    t
    i
    o
    n
    (
    N
    o
    n
    e
    , '
    i
    s
    _
    s
    m
    a
    l
    l
    '
    , [
    '
    n
    u
    m
    b
    e
    r
    '
    ]
    , 0
    , N
    o
    n
    e
    ,
    S
    t
    m
    t
    (
    I
    f
    (
    C
    o
    m
    p
    a
    r
    e
    (
    N
    a
    m
    e
    (
    '
    n
    u
    m
    b
    e
    r
    '
    )
    ,
    '
    <
    '
    ,
    C
    o
    n
    s
    t
    (
    1
    0
    0
    )
    )
    ,
    S
    t
    m
    t
    (
    R
    e
    t
    u
    r
    n
    (
    C
    o
    n
    s
    t
    (
    '
    y
    e
    s
    '
    )
    )
    )
    ,
    S
    t
    m
    t
    (
    R
    e
    t
    u
    r
    n
    (
    C
    o
    n
    s
    t
    (
    '
    n
    o
    '
    )
    )
    )
    )
    )
    )

    View Slide

  23. 23
    НЕ ВСЕ ТАК ПРОСТО

    View Slide

  24. 24
    HOMOICONICITY

    View Slide

  25. 25
    CLOJURE SOURCE CODE
    (
    d
    e
    f
    n i
    s
    ­
    s
    m
    a
    l
    l
    ? [
    n
    u
    m
    b
    e
    r
    ]
    (
    i
    f (
    < n
    u
    m
    b
    e
    r 1
    0
    0
    ) "
    y
    e
    s
    " "
    n
    o
    "
    )
    )

    View Slide

  26. 26
    CLOJURE AST
    '
    (
    d
    e
    f
    n i
    s
    ­
    s
    m
    a
    l
    l
    ? [
    n
    u
    m
    b
    e
    r
    ]
    (
    i
    f (
    < n
    u
    m
    b
    e
    r 1
    0
    0
    ) "
    y
    e
    s
    " "
    n
    o
    "
    )
    )

    View Slide

  27. 27
    В PYTHON НИКОГДА НЕ БУДЕТ
    ГОМОИКОННОСТИ

    View Slide

  28. 28
    В PYTHON НИКОГДА НЕ БУДЕТ
    ГОМОИКОННОСТИ
    Как и нормального метапрограммирования

    View Slide

  29. 29
    СПАСИБО ЗА ВНИМАНИЕ

    View Slide

  30. 30
    СПАСИБО ЗА ВНИМАНИЕ?

    View Slide

  31. 31
    DATA DSL

    View Slide

  32. 32
    HICCUP
    (
    h
    t
    m
    l [
    :
    s
    p
    a
    n {
    :
    c
    l
    a
    s
    s "
    f
    o
    o
    "
    } "
    b
    a
    r
    "
    ]
    )

    View Slide

  33. 33
    HICCUP-PY
    h
    t
    m
    l
    (
    [
    "
    s
    p
    a
    n
    "
    , {
    "
    c
    l
    a
    s
    s
    "
    : "
    f
    o
    o
    "
    } "
    b
    a
    r
    "
    ]
    )

    View Slide

  34. 34
    HICCUP-PY
    48 lines of code

    View Slide

  35. 35
    http://docs.python-cerberus.org/en/stable/schemas.html
    http://python-eve.org/quickstart.html
    ПРИМЕРЫ DATA DSL НА PYTHON

    View Slide

  36. 36
    PYTHON-CERBERUS
    s
    c
    h
    e
    m
    a = {
    '
    n
    a
    m
    e
    '
    : {
    '
    t
    y
    p
    e
    '
    : '
    s
    t
    r
    i
    n
    g
    '
    , '
    m
    a
    x
    l
    e
    n
    g
    t
    h
    '
    : 1
    0
    }
    }

    View Slide

  37. 37
    EVE
    D
    O
    M
    A
    I
    N = {
    '
    w
    o
    r
    k
    s
    '
    : {
    '
    c
    a
    c
    h
    e
    _
    c
    o
    n
    t
    r
    o
    l
    '
    : '
    m
    a
    x
    ­
    a
    g
    e
    =
    1
    0
    ,
    m
    u
    s
    t
    ­
    r
    e
    v
    a
    l
    i
    d
    a
    t
    e
    '
    ,
    '
    c
    a
    c
    h
    e
    _
    e
    x
    p
    i
    r
    e
    s
    '
    : 1
    0
    ,
    '
    a
    d
    d
    i
    t
    i
    o
    n
    a
    l
    _
    l
    o
    o
    k
    u
    p
    '
    : {
    '
    u
    r
    l
    '
    : '
    r
    e
    g
    e
    x
    (
    "
    [
    \
    w
    ]
    +
    "
    )
    '
    ,
    '
    f
    i
    e
    l
    d
    '
    : '
    t
    i
    t
    l
    e
    '
    }
    ,
    '
    s
    c
    h
    e
    m
    a
    '
    : {
    '
    t
    i
    t
    l
    e
    '
    : {
    '
    t
    y
    p
    e
    '
    : '
    s
    t
    r
    i
    n
    g
    '
    ,
    '
    r
    e
    q
    u
    i
    r
    e
    d
    '
    : T
    r
    u
    e
    ,
    }
    }
    }
    }

    View Slide

  38. 38
    НАСКОЛЬКО ЭТО ПОДХОДИТ
    ДЛЯ РЕШЕНИЯ
    ПОВСЕДНЕВНЫХ ЗАДАЧ?

    View Slide

  39. 39
    НОВОСТИ

    View Slide

  40. 40
    ЗАМЕТКИ

    View Slide

  41. 41
    ГАЛЕРЕЯ

    View Slide

  42. 42
    ДОКУМЕНТЫ

    View Slide

  43. 43
    ЗАДАЧА
    Новости (wysiwys, есть подблоки текста c wysiwys)
    Заметки (нет wysiwys, есть подблоки текста)
    Галерея (нет wysiwys, есть подблоки изображения)
    Документы (нет wysiwys, есть подблоки файлы)

    View Slide

  44. 44
    ЧТО БУДЕТ ЗАВТРА?

    View Slide

  45. 45
    ЧТО БУДЕТ ЗАВТРА?

    View Slide

  46. 46
    ЧТО БУДЕТ ЗАВТРА?

    View Slide

  47. 47
    МОДЕЛЬ
    группа
    текстовое поле
    подблоки текст
    подблоки изображения
    подблоки файлы

    View Slide

  48. 48
    АДМИНКА

    View Slide

  49. 49
    АДМИНКА ДЛЯ НОВОСТЕЙ

    View Slide

  50. 50
    АДМИНКА ДЛЯ ЗАМЕТОК

    View Slide

  51. 51
    АДМИНКА ДЛЯ ГАЛЕРЕЙ

    View Slide

  52. 52
    АДМИНКА ДЛЯ ФАЙЛОВ

    View Slide

  53. 53
    НУЖНА КАСТОМИЗАЦИЯ
    Прокси модель на каждый случай
    Миксин на каждую опцию для админки
    Админка для каждой прокси модели со своим
    набором миксинов

    View Slide

  54. 54
    НУЖНА КАСТОМИЗАЦИЯ
    У нас уже есть формализованное знание

    View Slide

  55. 55
    У НАС УЖЕ ЕСТЬ
    ФОРМАЛИЗОВАННОЕ ЗНАНИЕ
    Новости (wysiwys, есть подблоки текста c wysiwys)
    Заметки (нет wysiwys, есть подблоки текста)
    Галерея (нет wysiwys, есть подблоки изображения)
    Документы (нет wysiwys, есть подблоки файлы)

    View Slide

  56. 56
    ОПИШЕМ СТРУКТУРОЙ
    ДАННЫХ
    G
    R
    O
    U
    P
    _
    S
    C
    H
    E
    M
    A = {
    '
    N
    e
    w
    s
    '
    : {
    '
    w
    y
    s
    i
    w
    y
    g
    '
    : T
    r
    u
    e
    ,
    '
    h
    a
    s
    _
    i
    m
    a
    g
    e
    s
    '
    : F
    a
    l
    s
    e
    ,
    '
    h
    a
    s
    _
    f
    i
    l
    e
    s
    '
    : F
    a
    l
    s
    e
    ,
    '
    h
    a
    s
    _
    s
    u
    b
    b
    l
    o
    c
    k
    '
    : T
    r
    u
    e
    ,
    }
    ,
    '
    N
    o
    t
    e
    '
    : {
    '
    w
    y
    s
    i
    w
    y
    g
    '
    : F
    a
    l
    s
    e
    ,
    '
    h
    a
    s
    _
    i
    m
    a
    g
    e
    s
    '
    : F
    a
    l
    s
    e
    ,
    '
    h
    a
    s
    _
    f
    i
    l
    e
    s
    '
    : F
    a
    l
    s
    e
    ,
    '
    h
    a
    s
    _
    s
    u
    b
    b
    l
    o
    c
    k
    '
    : T
    r
    u
    e
    ,
    }
    ,
    '
    G
    a
    l
    l
    e
    r
    y
    '
    : {
    '
    w
    y
    s
    i
    w
    y
    g
    '
    : F
    a
    l
    s
    e
    ,
    '
    h
    a
    s
    _
    i
    m
    a
    g
    e
    s
    '
    : T
    r
    u
    e
    ,
    '
    h
    a
    s
    _
    f
    i
    l
    e
    s
    '
    : F
    a
    l
    s
    e
    ,
    '
    h
    a
    s
    _
    s
    u
    b
    b
    l
    o
    c
    k
    '
    : F
    a
    l
    s
    e
    ,
    }
    ,
    '
    D
    o
    c
    u
    m
    e
    n
    t
    '
    : {
    '
    w
    y
    s
    i
    w
    y
    g
    '
    : F
    a
    l
    s
    e
    ,
    '
    h
    a
    s
    _
    i
    m
    a
    g
    e
    s
    '
    : F
    a
    l
    s
    e
    ,
    '
    h
    a
    s
    _
    f
    i
    l
    e
    s
    '
    : T
    r
    u
    e
    ,
    '
    h
    a
    s
    _
    s
    u
    b
    b
    l
    o
    c
    k
    '
    : F
    a
    l
    s
    e
    ,
    }
    }

    View Slide

  57. 57
    ПИШЕМ ИНТЕРПРЕТАТОР
    0
    1 d
    e
    f c
    r
    e
    a
    t
    e
    _
    f
    l
    a
    t
    b
    l
    o
    c
    k
    _
    f
    o
    r
    _
    g
    r
    o
    u
    p
    _
    m
    o
    d
    e
    l
    (
    n
    a
    m
    e
    , g
    r
    o
    u
    p
    _
    i
    n
    f
    o
    )
    :
    0
    2 c
    l
    a
    s
    s G
    r
    o
    u
    p
    B
    l
    o
    c
    k
    M
    a
    n
    a
    g
    e
    r
    (
    m
    o
    d
    e
    l
    s
    .
    M
    a
    n
    a
    g
    e
    r
    )
    :
    0
    3 d
    e
    f g
    e
    t
    _
    q
    u
    e
    r
    y
    s
    e
    t
    (
    s
    e
    l
    f
    )
    :
    0
    4 r
    e
    t
    u
    r
    n s
    u
    p
    e
    r
    (
    G
    r
    o
    u
    p
    B
    l
    o
    c
    k
    M
    a
    n
    a
    g
    e
    r
    , s
    e
    l
    f
    )
    \
    0
    5 .
    g
    e
    t
    _
    q
    u
    e
    r
    y
    s
    e
    t
    (
    )
    \
    0
    6 .
    f
    i
    l
    t
    e
    r
    (
    g
    r
    o
    u
    p
    =
    n
    a
    m
    e
    .
    l
    o
    w
    e
    r
    (
    )
    )
    0
    7 c
    l
    a
    s
    s G
    r
    o
    u
    p
    B
    l
    o
    c
    k
    M
    e
    t
    a
    :
    0
    8 p
    r
    o
    x
    y = T
    r
    u
    e
    0
    9 v
    e
    r
    b
    o
    s
    e
    _
    n
    a
    m
    e = n
    a
    m
    e
    1
    0 v
    e
    r
    b
    o
    s
    e
    _
    n
    a
    m
    e
    _
    p
    l
    u
    r
    a
    l = g
    r
    o
    u
    p
    _
    i
    n
    f
    o
    .
    g
    e
    t
    (
    1
    1 '
    v
    e
    r
    b
    o
    s
    e
    _
    n
    a
    m
    e
    _
    p
    l
    u
    r
    a
    l
    '
    )
    1
    2
    1
    3 c
    l
    a
    s
    s
    _
    n
    a
    m
    e = '
    {
    }
    B
    l
    o
    c
    k
    '
    .
    f
    o
    r
    m
    a
    t
    (
    n
    a
    m
    e
    )
    1
    4 r
    e
    t
    u
    r
    n t
    y
    p
    e
    (
    c
    l
    a
    s
    s
    _
    n
    a
    m
    e
    ,
    1
    5 (
    B
    l
    o
    c
    k
    , )
    ,
    1
    6 {
    1
    7 '
    o
    b
    j
    e
    c
    t
    s
    '
    : G
    r
    o
    u
    p
    B
    l
    o
    c
    k
    M
    a
    n
    a
    g
    e
    r
    (
    )
    ,
    1
    8 '
    _
    _
    m
    o
    d
    u
    l
    e
    _
    _
    '
    : _
    _
    n
    a
    m
    e
    _
    _
    ,
    1
    9 '
    M
    e
    t
    a
    '
    : G
    r
    o
    u
    p
    B
    l
    o
    c
    k
    M
    e
    t
    a
    2
    0 }
    )
    2
    1
    2
    2 g
    r
    o
    u
    p
    _
    m
    o
    d
    e
    l
    s = {
    n
    a
    m
    e
    : c
    r
    e
    a
    t
    e
    _
    f
    l
    a
    t
    b
    l
    o
    c
    k
    _
    f
    o
    r
    _
    g
    r
    o
    u
    p
    _
    m
    o
    d
    e
    l
    (
    2
    3 n
    a
    m
    e
    , g
    r
    o
    u
    p
    ) f
    o
    r n
    a
    m
    e
    , g
    r
    o
    u
    p i
    n g
    r
    o
    u
    p
    _
    s
    c
    h
    e
    m
    a
    .
    i
    t
    e
    m
    s
    (
    )
    }

    View Slide

  58. 58
    ПИШЕМ ИНТЕРПРЕТАТОР
    0
    1 b
    u
    i
    l
    d
    _
    a
    d
    m
    i
    n
    _
    c
    l
    a
    s
    s
    (
    n
    a
    m
    e
    , g
    r
    o
    u
    p
    _
    i
    n
    f
    o
    )
    :
    0
    2 b
    a
    s
    e
    s = [
    ]
    0
    3 i
    n
    l
    i
    n
    e
    s = [
    ]
    0
    4
    0
    5 i
    f g
    r
    o
    u
    p
    _
    i
    n
    f
    o
    [
    '
    w
    y
    s
    i
    w
    y
    g
    '
    ]
    :
    0
    6 b
    a
    s
    e
    s
    .
    a
    p
    p
    e
    n
    d
    (
    A
    d
    m
    i
    n
    W
    y
    s
    i
    w
    y
    g
    M
    i
    x
    i
    n
    )
    0
    7 i
    f g
    r
    o
    u
    p
    _
    i
    n
    f
    o
    [
    '
    h
    a
    s
    _
    i
    m
    a
    g
    e
    s
    '
    ]
    :
    0
    8 i
    n
    l
    i
    n
    e
    s
    .
    a
    p
    p
    e
    n
    d
    (
    B
    l
    o
    c
    k
    I
    m
    a
    g
    e
    I
    n
    l
    i
    n
    e
    )
    0
    9 i
    f g
    r
    o
    u
    p
    _
    i
    n
    f
    o
    [
    '
    h
    a
    s
    _
    f
    i
    l
    e
    s
    '
    ]
    :
    1
    0 i
    n
    l
    i
    n
    e
    s
    .
    a
    p
    p
    e
    n
    d
    (
    B
    l
    o
    c
    k
    F
    i
    l
    e
    I
    n
    l
    i
    n
    e
    )
    1
    1 i
    f g
    r
    o
    u
    p
    _
    i
    n
    f
    o
    [
    '
    h
    a
    s
    _
    s
    u
    b
    b
    l
    o
    c
    k
    '
    ]
    :
    1
    2 i
    n
    l
    i
    n
    e
    s
    .
    a
    p
    p
    e
    n
    d
    (
    S
    u
    b
    B
    l
    o
    c
    k
    W
    y
    s
    i
    w
    y
    g
    A
    d
    m
    i
    n
    1
    3 i
    f g
    r
    o
    u
    p
    _
    i
    n
    f
    o
    [
    '
    w
    y
    s
    i
    w
    y
    g
    '
    ] e
    l
    s
    e S
    u
    b
    B
    l
    o
    c
    k
    A
    d
    m
    i
    n
    )
    1
    4
    1
    5 b
    a
    s
    e
    s
    .
    a
    p
    p
    e
    n
    d
    (
    M
    o
    d
    e
    l
    A
    d
    m
    i
    n
    )
    1
    6
    1
    7 r
    e
    t
    u
    r
    n t
    y
    p
    e
    (
    '
    {
    }
    M
    o
    d
    e
    l
    A
    d
    m
    i
    n
    '
    .
    f
    o
    r
    m
    a
    t
    (
    n
    a
    m
    e
    )
    ,
    1
    8 t
    u
    p
    l
    e
    (
    b
    a
    s
    e
    s
    )
    ,
    1
    9 {
    '
    i
    n
    l
    i
    n
    e
    s
    '
    : i
    n
    l
    i
    n
    e
    s
    }
    )
    2
    0
    2
    1
    2
    2 f
    o
    r n
    a
    m
    e
    , g
    r
    o
    u
    p
    _
    i
    n
    f
    o i
    n g
    r
    o
    u
    p
    _
    s
    c
    h
    e
    m
    a
    .
    i
    t
    e
    m
    s
    (
    )
    :
    2
    3 a
    d
    m
    i
    n
    .
    s
    i
    t
    e
    .
    r
    e
    g
    i
    s
    t
    e
    r
    (
    g
    r
    o
    u
    p
    _
    m
    o
    d
    e
    l
    s
    [
    n
    a
    m
    e
    ]
    ,
    2
    4 b
    u
    i
    l
    d
    _
    a
    d
    m
    i
    n
    _
    c
    l
    a
    s
    s
    (
    n
    a
    m
    e
    , g
    r
    o
    u
    p
    _
    i
    n
    f
    o
    )
    )

    View Slide

  59. 59
    API
    G
    R
    O
    U
    P
    _
    S
    C
    H
    E
    M
    A = {
    '
    N
    e
    w
    s
    '
    : {
    '
    w
    y
    s
    i
    w
    y
    g
    '
    : T
    r
    u
    e
    ,
    '
    h
    a
    s
    _
    i
    m
    a
    g
    e
    s
    '
    : F
    a
    l
    s
    e
    ,
    '
    h
    a
    s
    _
    f
    i
    l
    e
    s
    '
    : F
    a
    l
    s
    e
    ,
    '
    h
    a
    s
    _
    s
    u
    b
    b
    l
    o
    c
    k
    '
    : T
    r
    u
    e
    ,
    }
    ,
    '
    N
    o
    t
    e
    '
    : {
    '
    w
    y
    s
    i
    w
    y
    g
    '
    : F
    a
    l
    s
    e
    ,
    '
    h
    a
    s
    _
    i
    m
    a
    g
    e
    s
    '
    : F
    a
    l
    s
    e
    ,
    '
    h
    a
    s
    _
    f
    i
    l
    e
    s
    '
    : F
    a
    l
    s
    e
    ,
    '
    h
    a
    s
    _
    s
    u
    b
    b
    l
    o
    c
    k
    '
    : T
    r
    u
    e
    ,
    }
    ,
    '
    G
    a
    l
    l
    e
    r
    y
    '
    : {
    '
    w
    y
    s
    i
    w
    y
    g
    '
    : F
    a
    l
    s
    e
    ,
    '
    h
    a
    s
    _
    i
    m
    a
    g
    e
    s
    '
    : T
    r
    u
    e
    ,
    '
    h
    a
    s
    _
    f
    i
    l
    e
    s
    '
    : F
    a
    l
    s
    e
    ,
    '
    h
    a
    s
    _
    s
    u
    b
    b
    l
    o
    c
    k
    '
    : F
    a
    l
    s
    e
    ,
    }
    ,
    '
    D
    o
    c
    u
    m
    e
    n
    t
    '
    : {
    '
    w
    y
    s
    i
    w
    y
    g
    '
    : F
    a
    l
    s
    e
    ,
    '
    h
    a
    s
    _
    i
    m
    a
    g
    e
    s
    '
    : F
    a
    l
    s
    e
    ,
    '
    h
    a
    s
    _
    f
    i
    l
    e
    s
    '
    : T
    r
    u
    e
    ,
    '
    h
    a
    s
    _
    s
    u
    b
    b
    l
    o
    c
    k
    '
    : F
    a
    l
    s
    e
    ,
    }
    }

    View Slide

  60. 60
    АБСТРАКЦИЯ МОЖЕТ БЫТЬ
    ВЫШЕ
    N
    e
    w
    s
    :
    w
    y
    s
    i
    w
    y
    g
    : t
    r
    u
    e
    h
    a
    s
    _
    i
    m
    a
    g
    e
    s
    : f
    a
    l
    s
    e
    h
    a
    s
    _
    f
    i
    l
    e
    s
    : f
    a
    l
    s
    e
    h
    a
    s
    _
    s
    u
    b
    b
    l
    o
    c
    k
    : t
    r
    u
    e
    N
    o
    t
    e
    :
    w
    y
    s
    i
    w
    y
    g
    : f
    a
    l
    s
    e
    h
    a
    s
    _
    i
    m
    a
    g
    e
    s
    : f
    a
    l
    s
    e
    h
    a
    s
    _
    f
    i
    l
    e
    s
    : f
    a
    l
    s
    e
    h
    a
    s
    _
    s
    u
    b
    b
    l
    o
    c
    k
    : t
    r
    u
    e
    G
    a
    l
    l
    e
    r
    y
    :
    w
    y
    s
    i
    w
    y
    g
    : f
    a
    l
    s
    e
    h
    a
    s
    _
    i
    m
    a
    g
    e
    s
    : t
    r
    u
    e
    h
    a
    s
    _
    f
    i
    l
    e
    s
    : f
    a
    l
    s
    e
    h
    a
    s
    _
    s
    u
    b
    b
    l
    o
    c
    k
    : f
    a
    l
    s
    e
    D
    o
    c
    u
    m
    e
    n
    t
    :
    w
    y
    s
    i
    w
    y
    g
    : f
    a
    l
    s
    e
    h
    a
    s
    _
    i
    m
    a
    g
    e
    s
    : f
    a
    l
    s
    e
    h
    a
    s
    _
    f
    i
    l
    e
    s
    : t
    r
    u
    e
    h
    a
    s
    _
    s
    u
    b
    b
    l
    o
    c
    k
    : f
    a
    l
    s
    e

    View Slide

  61. 61
    АБСТРАКЦИЯ МОЖЕТ БЫТЬ
    ЕЩЕ ВЫШЕ
    G
    R
    O
    U
    P
    _
    S
    C
    H
    E
    M
    A = G
    r
    o
    u
    p
    S
    c
    h
    e
    m
    a
    .
    o
    b
    j
    e
    c
    t
    s
    .
    a
    s
    _
    s
    c
    h
    e
    m
    a
    (
    )

    View Slide

  62. 62
    ВАШИ ВОПРОСЫ
    https://github.com/ir4y/hicupp-py
    https://github.com/ir4y/blocks
    @ir4y_ix

    View Slide