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

How to write python code so people would love y...

How to write python code so people would love you (or not)

Sobolev Nikita

August 21, 2019
Tweet

More Decks by Sobolev Nikita

Other Decks in Programming

Transcript

  1. def recommended_books(books): book_names = [ book.name for book in books

    ] good_books = [ book_name for book_name in book_names if book_name not in ('Twilight', 'Learning Go Lang') ] recommended_books = [ find_similar(book_name) for book_name in book_names ] return recommended_books !5
  2. def recommended_books(books): book_names = [ book.name for book in books

    ] good_books = [ book_name for book_name in book_names if book_name not in ('Twilight', 'Learning Go Lang') ] recommended_books = [ find_similar(book_name) for book_name in book_names ] return recommended_books !6
  3. def recommended_books(books): book_names = [ book.name for book in books

    ] good_books = [ book_name for book_name in book_names if book_name not in ('Twilight', 'Learning Go Lang') ] recommended_books = [ find_similar(book_name) for book_name in book_names ] return recommended_books !7
  4. def recommended_books(books): book_names = [ book.name for book in books

    ] good_books = [ book_name for book_name in book_names if book_name not in ('Twilight', 'Learning Go Lang') ] recommended_books = [ find_similar(book_name) for book_name in book_names ] return recommended_books !8
  5. def recommended_books(books): book_names = [ book.name for book in books

    ] good_books = [ book_name for book_name in book_names if book_name not in ('Twilight', 'Learning Go Lang') ] recommended_books = [ find_similar(book_name) for book_name in book_names ] return recommended_books !9
  6. def recommended_books(books): book_names = [ book.name for book in books

    ] good_books = [ book_name for book_name in book_names if book_name not in ('Twilight', 'Learning Go Lang') ] recommended_books = [ find_similar(book_name) for book_name in book_names ] return recommended_books !17
  7. class RecommendedBooks(object): def __init__(self, book_repo, filter_api, cache): self._repo = book_repo

    self._api = filter_api self._cache = cache def __call__(self, books): book_names = self._repo.names_by_ids(books) good_books = self._api.by_preferences(book_names) recommended = self._cache.not_shown(good_books) return recommended !32
  8. Что понять ООП и писать нормально, нам нужно: • Прочитать

    уйму умных книг • Посмотреть на ужас Java и C++ !37
  9. Что понять ООП и писать нормально, нам нужно: • Прочитать

    уйму умных книг • Посмотреть на ужас Java и C++ • Понять прототипы из JS, протоколы из TypeScript !37
  10. Что понять ООП и писать нормально, нам нужно: • Прочитать

    уйму умных книг • Посмотреть на ужас Java и C++ • Понять прототипы из JS, протоколы из TypeScript • Выучить SmallTalk !37
  11. Что понять ООП и писать нормально, нам нужно: • Прочитать

    уйму умных книг • Посмотреть на ужас Java и C++ • Понять прототипы из JS, протоколы из TypeScript • Выучить SmallTalk • Поработать с акторами и Erlang. Выслушать тонну критики !37
  12. Что понять ООП и писать нормально, нам нужно: • Прочитать

    уйму умных книг • Посмотреть на ужас Java и C++ • Понять прототипы из JS, протоколы из TypeScript • Выучить SmallTalk • Поработать с акторами и Erlang. Выслушать тонну критики • Понять, что ООП нужно только для очень высокого уровня абстракции в некоторых типах систем !37
  13. FP

  14. class RecommendedBooks(object): def __init__(self, book_repo, filter_api, cache): self._repo = book_repo

    self._api = filter_api self._cache = cache def __call__(self, books): book_names = self._repo.names_by_ids(books) good_books = self._api.by_preferences(book_names) recommended = self._cache.not_shown(good_books) return recommended !40
  15. Типы курильщика Типы здорового человека uint double &mut str uint16_t

    std::boxed::Box<dyn Any + 'static> List[int] data Bool = False | True float Callable[[int], int] IO[Result[User, Exception]]
  16. class RecommendedBooks(object): def __init__( self, book_repo, filter_api, cache, ): self._repo

    = book_repo self._api = filter_api self._cache = cache def __call__(self, books): book_names = self._repo(books) good_books = self._api(book_names) recommended = self._cache(good_books) return recommended !48
  17. class RecommendedBooks(object): def __init__( self, book_repo: Callable[[List[int]], List[str]], filter_api, cache,

    ) -> None: self._repo = book_repo self._api = filter_api self._cache = cache def __call__(self, books: List[int]): book_names = self._repo(books) good_books = self._api(book_names) recommended = self._cache(good_books) return recommended !49
  18. class RecommendedBooks(object): def __init__( self, book_repo: Callable[[List[int]], List[str]], filter_api: Callable[[List[str]],

    List[Book]], cache, ) -> None: self._repo = book_repo self._api = filter_api self._cache = cache def __call__(self, books: List[int]): book_names = self._repo(books) good_books = self._api(book_names) recommended = self._cache(good_books) return recommended !50
  19. class RecommendedBooks(object): def __init__( self, book_repo: Callable[[List[int], List[str]], filter_api: Callable[[List[str]],

    List[Book]], cache: Callable[[List[Book]], List[Book]], ) -> None: self._repo = book_repo self._api = filter_api self._cache = cache def __call__(self, books: List[int]) -> List[Book]: book_names = self._repo(books) good_books = self._api(book_names) recommended = self._cache(good_books) return recommended !51
  20. @final @attr.dataclass(frozen=True, slots=True) class RecommendedBooks(object): _repo: Callable[[List[int]], List[str]] _api: Callable[[List[str]],

    List[Book]] _cache: Callable[[List[Book]], List[Book]] def __call__(self, books): book_names = self._repo(books) good_books = self._api(book_names) recommended_books = self._cache(good_books) return recommended_books !53
  21. !56

  22. import punq # Types: BookNamesByIds = Callable[[List[int]], List[str]] FilterPreferedBooks =

    Callable[[List[str]], List[Book]] NotShownBooks = Callable[[List[Book]], List[Book]] !56
  23. import punq # Types: BookNamesByIds = Callable[[List[int]], List[str]] FilterPreferedBooks =

    Callable[[List[str]], List[Book]] NotShownBooks = Callable[[List[Book]], List[Book]] # DI: container = punq.Container() container.register(BookNamesByIds, my_book_repo) container.register(FilterPreferedBooks, my_api) container.register(NotShownBooks, my_cache) !56
  24. import punq # Types: BookNamesByIds = Callable[[List[int]], List[str]] FilterPreferedBooks =

    Callable[[List[str]], List[Book]] NotShownBooks = Callable[[List[Book]], List[Book]] # DI: container = punq.Container() container.register(BookNamesByIds, my_book_repo) container.register(FilterPreferedBooks, my_api) container.register(NotShownBooks, my_cache) # Somewhere: container.resolve(RecommendedBooks)([1, 2, 3]) !56
  25. Callable[[List[int]], List[str]] • Выбросит ли она исключение? Да? Result[List[int], Exception]

    • Будет ли добиться в базу или http? Да? IO[List[int]] !62
  26. Callable[[List[int]], List[str]] • Выбросит ли она исключение? Да? Result[List[int], Exception]

    • Будет ли добиться в базу или http? Да? IO[List[int]] • Все вместе? Конечно! IO[Result[List[int], Exception]] !62
  27. class FetchUserProfile(object): def __call__(self, user: int) -> IO[Result['User', Error]]: return

    pipe( user_id, self._make_request, IO.lift(box(self._parse_json)), ) @impure @safe def _make_request(self, user_id: int) -> Response: ... @safe def _parse_json(self, response: Response) -> 'User': ... !64
  28. 65

  29. !67

  30. Полезные ссылки • https://guide.elm-lang.org/architecture/ • https://blog.ploeh.dk/2016/03/18/functional- architecture-is-ports-and-adapters/ • https://fsharpforfunandprofit.com/rop/ •

    https://www.destroyallsoftware.com/screencasts/ catalog/functional-core-imperative-shell • https://www.youtube.com/watch?v=o9pEzgHorH0 • https://sobolevn.me/ !72