1. Python / Говнокод #26768

    0

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    8. 8
    def is_tuple(node: Node) -> bool:
        match node:
            case Node(children=[LParen(), RParen()]):
                return True
            case Node(children=[Leaf(value="("), Node(), Leaf(value=")")]):
                return True
            case _:
                return False

    https://www.python.org/dev/peps/pep-0622/

    Запостил: MAKAKA, 23 Июня 2020

    Комментарии (53) RSS

    • коко
      утиная тупизация
      Ответить
    • птрнмтчн в птн
      Ответить
      • nemyx matching
        Ответить
        • We believe this will improve both readability and reliability of relevant code. To illustrate the readability improvement, let us consider an actual example from the Python standard library:

          def is_tuple(node):
              if isinstance(node, Node) and node.children == [LParen(), RParen()]:
                  return True
              return (isinstance(node, Node)
                      and len(node.children) == 3
                      and isinstance(node.children[0], Leaf)
                      and isinstance(node.children[1], Node)
                      and isinstance(node.children[2], Leaf)
                      and node.children[0].value == "("
                      and node.children[2].value == ")")


          омерзительно
          Ответить
    • показать все, что скрытоvanished
      Ответить
    • О, за 29 лет до питонухов дошло, что портянки из «elif» — это дерьмо, а TOOWTDI — просто попытка Гвидо прикрыть свою ленивую жопу?
      Ответить
      • Касе не нужен, он его легко слепить из дикта и лямбд.
        Ответить
      • показать все, что скрытоvanished
        Ответить
        • Так я и не говорил, что он TOOWTDI, просто, ЕМНИП, в обсуждениях switch-case Гвидо им прикрывался — мол, нахуй не нужон (паттерн-) матчинг ваш, у нас TOOWTDI, жуйте if-elif-elif и радуйтесь.

          > struct User
          class User:
              def __init__(self, name: str, age: int):
                  self.name = name
                  self.age = age

          import dataclasses
          
          
          @dataclasses.dataclass
          class User:
              name: str
              age: int

          import collections
          
          
          User = collections.namedtuple('User', ['name', 'age'])
          Ответить
          • показать все, что скрытоvanished
            Ответить
            • Потому что «TypedDict» — это обычный словарь.
              Ответить
              • показать все, что скрытоvanished
                Ответить
                • > что мешает его использовать для этой задачи?
                  Несоответствие условиям задачи.
                  Ответить
                  • показать все, что скрытоvanished
                    Ответить
                    • показать все, что скрытоvanished
                      Ответить
                    • > что не соответствует

                      Скобочки вместо точки юзать придётся.
                      Ответить
                      • >Скобочки вместо точки
                        Говно, кстати.

                        Говно, говно, говно.
                        Зачем это ненужное различие?

                        Мне нравится, как сделано в JS и Lua.
                        Ответить
                    • То, что это — описание структуры для внешних утилит, а не в «Питоне». В «Питоне» «Movie» — это просто словарь. С тем же успехом «описанием структуры» можно считать комментарей к джейсону вида «в этом джейсоне есть поля name и age».
                      >>> class Movie(TypedDict):
                      ...     name: str
                      ...     year: int
                      ...
                      >>> movie = Movie('Green Elephant', 1999)  # хуй
                      Traceback (most recent call last):
                        File "<stdin>", line 1, in <module>
                        File "C:\Program Files\Python38\lib\typing.py", line 1706, in _dict_new
                          return dict(*args, **kwargs)
                      TypeError: dict expected at most 1 argument, got 2
                      >>> movie = Movie((('not name', 'Green Elephant'), ('kukareku', 1999)))
                      >>> movie
                      {'not name': 'Green Elephant', 'kukareku': 1999}
                      >>> movie: Movie = {'not name': 'Green Elephant', 'kok': 1999}
                      >>> movie
                      {'not name': 'Green Elephant', 'kok': 1999}
                      >>> type(Movie())
                      <class 'dict'>
                      Ответить
                      • не понял, почему для внешних?

                        Где сказано, что тайпдикт не рекомендуется использовать в качестве структуры данных?
                        Ответить
                        • > не понял, почему для внешних?
                          Потому что в «Питоне» «TypedDict» — это просто «dict». В «Питоне» нет никаких различий между «dict» и «TypedDict».

                          > Где сказано, что тайпдикт не рекомендуется использовать в качестве структуры данных?
                          В качестве структуры данных можно использовать что угодно, включая массив и словарь. А вот описание структуры данных — совсем другой вопрос.
                          Ответить
                          • показать все, что скрытоvanished
                            Ответить
                            • Тем, что dict не описывает структуру данных.
                              Ответить
                              • показать все, что скрытоvanished
                                Ответить
                                • Класс, описывающий юзера.

                                  Один хер это откуда-нибудь из базы.
                                  Ответить
                                • Если это одноразовая вспомогательная функция внутри мудуля без доступа снаружи, то, скорее всего, кортеж (user_name, user_id).
                                  Если это экспортируемая функция (либо если в мудуле она используется во многих местах) и какого-либо расширения её функционала не планируется (например, добавления e-mail'а или какой-то логики), то namedtuple('...', ['user_name', 'user_id']) или @dataclass.
                                  Если в дальнейшем может потребоваться расширить возвращаемое значение (добавить поля, добавить какие-то методы) — то @dataclass.

                                  Ну а если делать не как лениво, а как правильно, то только @dataclass.

                                  А если совсем правильно, то, как подсказывает, Борманд, объект класса «User» из ORM.

                                  И, конечно, в изначальной задаче речь шла про другое. Дело в том, что «структура данных» и просто «структура» — это два совершенно разных понятия. «Структура данных» — она же «абстрактный тип данных» — это описание интерфейса и поведения некоторого способа хранения данных: «список», «двоичное дерево», «куча», etc. А указанная в задаче «структура» — это, собственно, описание типа данных, их интерфейса.
                                  «TypedDict» не подходит для задачи просто потому, что он не описывает требуемый интерфейс в самом языке. На уровне языка (а не внешних утилит вроде «mypy») экземпляр подкласса «TypedDict» полностью эквивалентен (ну, конечно, если не переопределять __init__() и другие методы, но в этом смысла нет) экземпляру класса «dict», то есть словарю.
                                  Ответить
                                  • показать все, что скрытоvanished
                                    Ответить
                                    • Не «ADT», а тип данных (или, скорее, интерфейс). Да, его можно описать на чём угодно (я уже привёл реальный пример: комментарий «этот джейсон состоит из полей name и age» тоже можно считать описанием типа данных), но в изначальных условиях задачи требовалось описать его в питоне. Ни об «UML», ни о «mypy»/«pyright»/etc речи не шло.

                                      > (кстати, по твоему получается, что описать ADT там нельзя?).
                                      Я про «ADT» ничего не говорил.
                                      Ответить
                                      • >Не «ADT», а тип данных
                                        расшифруй пжлста ADT
                                        Ответить
                                        • Блядь, я что ли эти ебанутые термины придумывал?
                                          >>> Формально АТД может быть определён как множество объектов, определяемое списком компонентов (операций, применимых к этим объектам, и их свойств). Вся внутренняя структура такого типа спрятана от разработчика программного обеспечения — в этом и заключается суть абстракции. Абстрактный тип данных определяет набор функций, независимых от конкретной реализации типа, для оперирования его значениями. Конкретные реализации АТД называются структурами данных.

                                          Список — ADT, дерево — ADT, словарь — ADT, User — не ADT, Movie — не ADT.
                                          Ответить
                                          • >Абстрактный тип данных
                                            Спасибо.

                                            Подставим теперь расшифровку в твою фразу:

                                            >Не «Абстрактный тип данных», а тип данных
                                            Тебя ничего не смущает?
                                            Ответить
                                            • > Тебя ничего не смущает?
                                              Нет. «Абстрактный тип данных» и «тип данных» — это два разных понятия с разными значениями. Повторюсь: эти названия придумывал не я.
                                              Ответить
                                              • А вики говорит
                                                "In computer science, an abstract data type (ADT) is a mathematical model for data types"

                                                То-есть ADT это математическая модель типов, как же она может быть "разным понятием"?

                                                Но мы отвлеклись: если информацию можно получить в рантайме, то мы говорим, что сущность описана в питоне

                                                Если нельзя, то не описана

                                                верно?
                                                Ответить
                                                • > То-есть ADT это математическая модель типов, как же она может быть "разным понятием"?
                                                  Формула «x^2 + y^2 + z^2 = r^2» — это математическая модель футбольного мяча. Следует ли из этого, что формула «x^2 + y^2 + z^2 = r^2» и футбольный мяч — это два одинаковых понятия?

                                                  > верно?
                                                  Нет, неверно. Обратимся ко википедийному определению понятия «Data type»:
                                                  In computer science and computer programming, a data type or simply type is an attribute
                                                  of data which tells the compiler or interpreter how the programmer intends to use the data.
                                                  [...]
                                                  A data type constrains the values that an expression, such as a variable or a function, might take.
                                                  This data type defines the operations that can be done on the data, the meaning
                                                  of the data, and the way values of that type can be stored. A data type provides a set
                                                  of values from which an expression (i.e. variable, function, etc.) may take its values.

                                                  Сообщает ли Movie(TypedDict) компилятору или интерпретатору способ, которым программист собирается использовать соответствующие данные? Нет, не сообщает: он в точности равен способу использования обычного dict.

                                                  Ограничивает ли Movie(TypedDict) множество значений, которое может принимать соответствующая переменная? Нет, не ограничивает: оно в точности равно множеству значений dict.

                                                  Определяет ли Movie(TypedDict) набор операций, которые могут быть выполнены над соответствующими данными? Нет, не определяет: этот набор в точности равен таковому для dict.

                                                  Является ли Movie(TypedDict) отдельным типом? Нет, не является.
                                                  Ответить
                                                  • > Является ли Movie(TypedDict) отдельным типом? Нет, не является.
                                                    >>> from typing import TypedDict
                                                    >>> class Movie(TypedDict):
                                                    ...     name: str
                                                    ...     year: int
                                                    ...
                                                    >>> movie1 = Movie({'name': 'Green Elephant', 'year': 1999})
                                                    >>> movie2 = {'name': 'Green Elephant', 'year': 1999}
                                                    >>> type(movie1) == type(movie2)
                                                    True
                                                    Ответить
                                                  • показать все, что скрытоvanished
                                                    Ответить
                                                    • Начнём с того, что не появится, потому что в «Питоне» вообще нельзя создать объект типа TypedDict (или какого-то из его наследников), не хакая интерпретатор. TypedDict для этого в принципе не предназначен.

                                                      Продолжим тем, что ADT — это математическая модель, и к дискуссии это понятие не имеет никакого отношения. Ты что, ма-те-ма-тик из раш-ки?

                                                      Закончим на том, что если в языке появится директива, которая изменяет семантику языка, то измениться может что угодно, и даже TypedDict стать типом данных (data type).

                                                      И для уточнения давай уточним: что такое структура из исходной задачи?
                                                      >>>
                                                      как бы ты описал следующую структуру в питоне
                                                      Ответить
                          • Кстати у dataclass'а типы тоже для красоты и нихуя не делают.
                            Ответить
                            • показать все, что скрытоvanished
                              Ответить
                            • Подтверждаю. В «Питоне» вся типизация — для красоты и внешних утилит.
                              Ответить
                              • Вся статическая типизация -- да, для утилит

                                В рантайме же типизация вполне есть
                                Ответить
                                • Да. Статическая — для утилит, динамическая — в рантайме.
                                  Ответить
                                  • показать все, что скрытоvanished
                                    Ответить
                                    • Именно поэтому я за «PHP».
                                      Ответить
                                    • > не однозначное решение
                                      Подтверждаю. У питоньей статотипизации две беды основных проблемы.
                                      Во-первых, из-за очень высокой степени динамичности организовать статическую типизацию может быть сложно (всяческие декораторы и создание классов в рантайме а-ля «namedtuple» делают статическую проверку типов очень весёлым и увлекательным занятием).
                                      Во-вторых, из-за слишком позднего введения (3.5, кажется) в экосистеме «Питона» оказалось огромное количество либ, которые к статотипизации в принципе не готовы, а переписывать их — огромный геморрой. Реальные примеры: «numpy», «Flask», «Tensorflow» — в общем, практически любая крупная либа, написанная раньше 2014-го года. Конечно, отдельные энтузиасты пилят всяческие «type stubs», но это весьма посредственное, кривое и неполноценное решение.
                                      В итоге получается, что сейчас статическая типизация «Питона» — это скорее «игрушечная» штука, PoC. Писать с ней что-то крупное практически бессмысленно, и вряд ли в будущем что-то изменится — ещё одного 2->3 «Питон» точно не переживёт, а без этого PEP484 так и останется просто забавным курьёзом.
                                      Ответить
                                      • А чем тебе не нравятся стабы, кстати?
                                        Имхо, вполне нормально (напоминает .h файлы, лол), но только их надо делать. А их не делают. Потому что всем похуй.


                                        >из-за очень высокой степени динамичности
                                        ..которая в 90% случаев не нужна.

                                        Какие-то штуки (к примеру Django ORM) статически не типизировать, во всяком случае не такой типизацией, как в 484.

                                        Но большую часть вполне можно было бы покрыть.
                                        Но всем похуй.

                                        В итоге PyCharm у меня часть типов берет из хинтов, часть сам выводит, часть вообще не понимает.. Метод безопасно не переименовать даже.
                                        Ответить
                                        • > А чем тебе не нравятся стабы, кстати?
                                          Просто их делают хуй пойми кто, и хуй пойми кто поддерживает.
                                          Помню, несколько месяцев назад пытался прикрутить типизацию к «NumPy» — наткнулся на что-то вроде https://github.com/numpy/numpy-stubs, посмотрел на «2 years ago», кучу незакрытых ишшуев, описание наполеоновских планов в ридми, да и плюнул. Ну а 20 дней назад они перенеслись в основную репу «NumPy» — не прошло и трёх лет.

                                          > Какие-то штуки (к примеру Django ORM) статически не типизировать, во всяком случае не такой типизацией, как в 484.
                                          Ну да, я ж и говорю, что всяческие ORM'ы сосут. ЕМНИП, «mypy» до сих пор даже декораторы и «namedtuple» нормально вывести не может.
                                          Ответить
                  • показать все, что скрытоvanished
                    Ответить

    Добавить комментарий