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

    −165

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    def getrows(c):
        return \
            sum( # суммируем по категориям
                map(
                    lambda category:
                        sum( # суммируем по itemid
                            map(
                                lambda itemidset:
                                    sum( # суммируем по itemstring
                                        map(
                                            lambda itemstring:
                                                map(
                                                    lambda info:
                                                        transaction(category, itemstring, info),
                                                    itemidset[itemstring].values()
                                                ),
                                            itemidset.keys()
                                        ),
                                    []),
                                c[category].values()
                            ),
                            []
                        ),
                    ("completedAuctions", "failedAuctions", "completedBidsBuyouts")
                ),
                []
            )

    Залез в свой старый скрипт, генерирующий отчеты, думал кое-что подправить...
    Увидел одну из функций (эту) и решил лучше забить тут что-то править хД

    Причины такого ужаса - наверно отсутствие явной типизации в питоне и средств рефакторинга (rename variable, extract method, ...) в "IDE"

    Запостил: burdakovd, 27 Октября 2010

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

    • А мне нравиться )
      Ответить
    • ехал лямбда через лямбда
      Ответить
    • Так нельзя писать. Это очень плохо. Это невозможно поддерживать. И я не пишу так.
      Но от этого просто десткий восторг наступает. Запишите в одну строчку.
      Это что-то из http://www.nestor.minsk.by/sr/2006/02/sr60201.html, только очень красиво.
      Ответить
      • Ну вообще говоря когдя я писал это оно было в одну строчку, точнее разрывы строки были каждые 80 символов. И даже всё понятно было.

        Это сейчас чтоб хоть как-то разобраться что происходит - отформатировал.
        Кстати помогло, нужное исправление сделал и рефакторить не пришлось. В конце концов это не ПО а скрипт=)
        Ответить
        • Вот ещё кусочек, столь же монструозный, но не столь симметричный:

          ul(
                  map(
                      lambda realm:
                          "%s %s" %
                              (
                                  realm,
                                  ul(
                                      map(
                                          lambda (character, f):
                                              u"%s, запас %s, данные от %s" % 
                                                  (
                                                      link(
                                                          "%s-%s-data-1.html" % (realm, character),
                                                          faction(f, character),
                                                          "character"
                                                      ),
                                                      gold(BeanCounterDB.settings[realm][character]["wealth"]),
                                                      time.strftime(
                                                          "%Y-%m-%d %H:%M:%S",
                                                          time.localtime(
                                                              max(
                                                                  map(
                                                                      lambda transaction: int(transaction.time),
                                                                      getrows(data[realm][character])
                                                                  )
                                                              )
                                                          )
                                                      )
                                                  ),
                                          realchars[realm]
                                      )
                                  )
                              ),
                      realchars.keys()
                  )
              )
          Ответить
          • Красиво, чуви, красиво)
            Ответить
          • И это можно упростить:
            ul("%s %s" % (
                    realm,
                    ul(u"%s, запас %s, данные от %s" % (
                            link(
                                "%s-%s-data-1.html" % (realm, character),
                                faction(f, character),
                                "character"
                            ),
                            gold(BeanCounterDB.settings[realm][character]["wealth"]),
                            time.strftime(
                                "%Y-%m-%d %H:%M:%S",
                                time.localtime(max(int(transaction.time) for transaction in getrows(data[realm][character])))
                            )
                        ) for character, f in realchars[realm]
                    )
                ) for realm in realchars
            )

            Ох, недаром лямбду собирались выпилить.

            Интересно, к чему относится этот код?
            Ответить
            • Не надо лямбду выпиливать, я больше так не буду! :D

              > Интересно, к чему относится этот код?
              Есть такая игра - WoW, в нем есть аукцион.
              Есть такой аддон - http://auctioneeraddon.com/ , для анализа цен на игровом рынке и ведения логов торговли.

              А я писал скрипт для внеигрового анализа "базы данных" этого аддона и представления html отчета по торговле своих персонажей, с графиками, топами и т.д.
              Ответить
              • Надеюсь, что к четвёртому Питону выпилят. Это одна из ошибок Гвидо, вроде целочисленного деления или строк-исключений.

                1) Лямбда в Питоне не нужна. Есть удобнее средства. Более 90% случаев использования лямбды можно записать более ясно и понятно с помощью list comprehensions или yield (вот ещё добавят yield from (PEP 380) и будет вообще хорошо). Остальное делается с помощью локальных или глобальных именованных функций. Или готовых кирпичиков operator.

                2) Лямбда в Питоне убога. Допускаются только простые выражения, ничего серьёзного. И не может быть, учитывая особенности питоновского синтаксиса. Вот лямбды, предлагаемые для C++ и Java лишены этого недостатка.
                Ответить
    • > Залез в свой старый скрипт

      Насколько стар этот скрипт -- точнее, версия питона, под которую он был написан? Лет пять назад альтернатив было куда меньше, чем сейчас. Если на чем-то глаз и спотыкается -- то на пустых листах [] в качестве второго аргумента map и sum.
      Ответить
      • Полтора года скрипту. Для меня пока и такой срок "старый"=)
        Python 2.5 или 2.6, не помню какой тогда у меня стоял.

        А там суммируются списки, и так как по умолчанию он суммирует с 0, то пришлось указать стартовое значение []. Хотя вероятно такое суммирование не эффективно (в памяти создаётся много временных списков), но пока не нашёл стандартной функции для объединения произвольного количества списков.
        Ответить
        • > стандартной функции для объединения произвольного
          А так?
          >>> [1,2,3] + [4,5,6]
          [1, 2, 3, 4, 5, 6]
          Ответить
          • sum(lists, []) это и было использование оператора "+"

            Но это квадратичная сложность, для линейной я уже нашёл itertools.chain
            http://stackoverflow.com/questions/716477/join-list-of-lists-in-python
            Ответить
    • def getrows(c):
          return (transaction(category, itemstring, info)
                  for info in itemvalues
                  for itemstring, itemvalues in itemidset.iteritems()
                  for itemidset in c[category].itervalues()
                  for category in ("completedAuctions", "failedAuctions", "completedBidsBuyouts")
              )

      или
      def getrows(c):
          for category in ("completedAuctions", "failedAuctions", "completedBidsBuyouts"):
              for itemidset in c[category].itervalues():
                  for itemstring, itemvalues in itemidset.iteritems():
                      for info in itemvalues:
                          yield transaction(category, itemstring, info)
      Ответить
      • Восхищен.
        Код делает то же самое, что у меня, но намного красивее. И видимо эффективнее, так как у меня там форсировалось вычисление списков в sum.

        Как-то не пришло в голову использовать ни множественный for в list comprehensions, ни yield, хотя знал о них.
        Ответить
    • >Причины такого ужаса - наверно отсутствие явной типизации в питоне и средств рефакторинга (rename variable, extract method, ...) в "IDE"
      Нет, милейший, проблема в другом...
      Ответить

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