Pull to refresh

Comments 31

эм, а чем этот способ лучше, чем просто написать if (something1 or something2) and something 3?
Я тоже похожий код выношу в декораторы\django template tag's, иначе шаблоны становятся похожи на развесистые деревья с кучей ифов и логикой которая копипастится от шаблона к шаблону
А как в этом случае также вернуть сообщение о том какие условия (ветки) выразения вернули False?
Красивая, запись, и простая, как-то сам не додумался до такого варианта. Возможно мне стоит взять ее за основу и допилить чтобы она генерировала такие отчеты, как сейчас делает моя либа. Спасибо.
Строки из вашего примера:

33 result = _me("123","first") and _me(False, "second") or  _me(calculate_me(),"calculated")
34 self.assertEqual(result.msg,"calculated")

вот как раз в таких случаях я добивался от своей библиотеки возвращать в сообщении не просто "calculated", а "second, calculated", так как мне надо знать все условия, вычислившиеся в False — это дает больше полезной информации. А как добиться такого поведения используюя операторы питона, пока не могу придумать. По крайней мере, чтобы это выглядело более-менее красиво.
Строки из вашего примера:

33 result = _me("123","first") and _me(False, "second") or _me(calculate_me(),"calculated")
34 self.assertEqual(result.msg,"calculated")

Здесь мы ожидаем получить сообщение лишь одного условия "calculated", одного из тех, которые вычислились в False, а в своей либе я добивался результата, который бы в данном случае вернул "second, calculated", т.е. все условия вычислившиеся в False. К тому же у меня реализовано построение полного отчета, с возможностью вложенных сообщений. Как реализовать такие отчеты на вашем примере пока придумать не могу.
а зачем ленивость тогда, если все равно все вычисляется? :)
Видимо я недопонял мысль топика :)
Вы все верно поняли, вычисления происходят по укороченной схеме. Но ведь _or_ вычисляет свои аргументы до первого True, и может получить несколько False пока не наткнется на первый True или не вычислит все свои аргументы. Таким образом все сообщения False-условий и будут перечислены в отчете.

Как пример привожу фрагмент из тестов для либы:

def do_test(s):
    return _and_(
        lambda: (s, u"Empty string"),
        lambda: _and_(
            lambda: (3 <= len(s), u"Must be at least 3 characters long"),
            lambda: (len(s) <= 10, u"Must be not more than 10 characters long"),
            report=u"String length is incorrect"
        ), 
        lambda: _or_(
            lambda: (s == "aaa", u"Is not 'aaa' string"),
            lambda: (s == "bbb", u"Is not 'bbb' string"),
            lambda: (s == "ccc", u"Is not 'ccc' string"),
            lambda: _and_(
                lambda: (s.startswith("_"), u"Does not start with '_' character"),
                lambda: (s.endswith("_"), u"Does not end with '_' character"),
                report="String must be enclosed with underscore characters"
            ),
            report=u"Is not any of 'aaa', 'bbb' or 'ccc' string or not enclosed with '_' character"
        ),
        report=u"Incorrect string",
    )

...
result = do_test(u"_abc")
assert bool(result) == False
# default report
assert unicode(result) == u"Is not 'aaa' string, Is not 'bbb' string, Is not 'ccc' string, Does not end with '_' character"
# full report displaying hierarchy of messages
assert result.build_report() == u"Incorrect string(Is not any of 'aaa', 'bbb' or 'ccc' string or not enclosed with '_' character(Is not 'aaa' string, Is not 'bbb' string, Is not 'ccc' string, String must be enclosed with underscore characters(Does not end with '_' character)))"
# full report as html
assert result.build_html_report() == u"Incorrect string<ul><li>Is not any of 'aaa', 'bbb' or 'ccc' string or not enclosed with '_' character<ul><li>Is not 'aaa' string</li><li>Is not 'bbb' string</li><li>Is not 'ccc' string</li><li>String must be enclosed with underscore characters<ul><li>Does not end with '_' character</li></ul></li></ul></li></ul>"
такой вариант тоже реализуем, но будет более многословен и с побитовыми операторами & | =(
gist.github.com/646574 — потерялась ленивость, теперь она как и у вас только для callable

про подразделы я не очень понял какой функционал нужен :)
Сори, глюк, сутра хабр не показал мне моего сообщения, и я продублировал его снова )) Ночью надо спать.
а не проще просто не показывать элементы, действия с которыми недоступны пользователю, дабы не вводить его в заблуждение?
зачем например пользователю видеть кнопку «редактировать», если это может делать только администратор сайта, да и зачем ему вообще знать, что администратор сайта может это делать?
Иногда нужно показать все плюшки какие пользователь сможет получить достигнув чего-то.
Показать что он упускает, давить на психику. )))
Разве что в таком исполнении =)
предложенный способ замечательно подходит для тестирования, или как вариант для внутренней админки
Пример конечно не претендует на идеал, конечно же есть случаи когда кнопку лучше спрятать, выбор делаем исходя из обстоятельств. А сообщение на кнопке в данном случае просто соответствует правилу. В реальной ситуации правило будет адекватным (насколько это возможно) и, соответственно, сообщение на кнопке тоже.
Сообщение тут не причём, просто ИМХО для юзабилити лучше, если пользователь видит только те кнопки, действия с которыми он может предпринять (в данном случае разговор о сайте идёт), а не 20 кнопок, из которых он может нажать 2 (потенциально возможный вариант), т.к. такая картина повергнет в шок.

P.S. я не спорю, что при заблокированных 2-4 кнопках из 20 представленный вариант имеет место быть.
Мне кажется, сабж намекает сам за себя откуда вообще это всё появилось)
ну, вы на хабре видели надпись «у вас недостаточно энергии для голосования» и много других подобных надписей? Вот это оно)
Вот иногда хочется, чтобы правило _and_ вычисляло не по укороченной схеме, а полностью, и показывало все False. А то видишь одну ошибку/проблему/етц, исправляешь, тебе показывают следующую, исправляешь, следующую, исправляешь… Иногда такой итеративный процесс занимает много времени.

Например, можно было бы управлять поведением через опциональный именованный параметр calculate_all.
Согласен, хорошее предложение, спасибо, надо будет реализовать. Это особенно полезно при валидации форм.
Timmy должно быть зачеркнутым… только с минусами оказывается нельзя html-разметку использовать… (

А Tipsy, кто не знает, это отличная либа для jquery для всплывающих тултипов…
Южный парк смотрели? кстати новый сезон продолжается… :)
Намек на то что стандартные недо-тултипы надо заменить на продвинутую версию попапов? :) К стати, мне понравилось как на Хабре сделаны тултипы в правом верхнем углу для аяксовых действий. Что-то подобное встречали для jQuery?
Хотя такое и самому быстро смастерить не проблема.
Мне лично этот плагин понравился, небольшой, шустрый, крепится к чему угодно, можно выводить HTML-код (я туда при необходимости и фотки вывожу и развернутые сообщения об ошибках в строке), цвет менять несколько геморрно, но это уже называется — лень… )

На хабре сверху это не тултип, это notifications… В поиске по запросу «jquery+notifications» много чего хорошего выдаст… :)
в функцию _and_ я бы кортежи передавал вместо лямбд.

например _and_((user.is_status_active(), “Ваша учетная запись заблокирована”),(etc),(etc))

зачем lambda постоянно писать? лишние буквы. пускай _and_ анализирует параметры свои
тогда не будет работать укороченная схема вычисления для операторов and и or
Sign up to leave a comment.

Articles