Знак принадлежности мы в 7-8 классе школы проходили, когда про множества нам немного рассказывали на уроках математики. Квантор всеобщности — это уже универ, из области формальной логики штука (у нас было вроде на первом курсе матанализа). Мне кажется, теорию множеств значительно больше людей знает, чем формальную логику. + Если человек знает, что такое «принадлежать множеству», то он с большой вероятностью знает символ принадлежности — в случае с утверждением «для всех» и квантором всеобщности это не так.
Дальше вопрос логически следует — а как избежать перекрытия имен?
Мне кажется, решение не в том, чтоб детально разобраться, как работает импорт в 2.7 и потом следить, чтоб ненароком что-то не то не импортировать (например, выбирая безопасные названия для модулей).
Ну т.е. так вопрос решить можно, и его решают: например, если в какой-нибудь django-библиотеке foo шаблонные теги нужно загружать как {% load "foo_tags" %}, то вероятность 92.64%, что боролись с семантикой импортов (либо это cargo-cult, оставшийся от какой-то библиотеки, боровшейся с семантикой импортов).
Мне кажется, что все-же лучше проблему решить тем, что всегда писать
from __future__ import absolute_imports
в коде на 2.х (например, засунув эту строчку в шаблон для .py файла в IDE) и/или переходить на Python 3.x, где этот алгоритм импортирования уже по умолчанию.
Этот future-импорт убивает двух зайцев: код по семантике импортов становится как 3.х (а значит переход будет проще), и устраняется возможность сломать питоний код, просто создав рядом в папочке файл с неудачным именем. Кроме того, явное ведь лучше неявного — с absolute_imports относительные импорты нужно указывать явно.
С другими future-импортами есть проблема — их нужно писать сверху файла, и когда читаешь код, чтоб его правильно понять, нужно держать в уме, какие future-импорты действуют. С absolute_imports этой проблемы нет, т.к. во-первых, он влияет на импорты (а их тоже пишут сверху файла), а во-вторых, он меняет поведение, котрое в большинстве случаев и так было неявным или ошибочным.
В английском тоже терминология «скачет»: одно и то же рассматривается в смежных областях науки («machine learning», «statistics», вычислительная математика), и люди часто придумывают/используют свои термины — например, features == inputs == predictors == independent variables (пример из The Elements of Statistical Learning, Hastie et al. )
Понятно, что в статье пример академический и написан с целью научиться-разобраться, а советы «как лучше на практике графики строить» немного не в тему. Но все-же :)
Немного замечаний:
* в nltk wordnet работает без обращения к серверам;
* в nltk код из ветки 2and3 под Python3.3 работает (не все, но wordnet работает);
* у collections.Counter есть метод most_common;
* в aot для английского языка лемматизация работает тоже на основе wordnet (только словари упакованы в формат, который позволяет держать все в памяти и делать быстрые выборки).
Поставил минус, объясню почему. Каждое обсуждение способа развертывания питоньих проектов неизбежно скатывается в fastcgi vs uwsgi vs gunicorn vs apache mod_wsgi vs ..., как будто этот вопрос имеет хоть какое-то значение. Ну да, они все немного отличаются друг от друга по фичам и по способу настройки, но они не сделают магическим образом сайт быстрее или надежнее.
Значение имеет не набора букв в описании веб-стека, а то, как все настроено; чтоб все настроить хорошо, нужно понимание того, как все работает, и того, чего же хочется получить-то. Интернетные советы «uwsgi быстрее mod_wsgi», как мне кажется, от этого понимания отдаляют, а не приближают — вместо того, чтоб разобраться в проблеме, люди начинают верить в наборы букв (иногда еще обосновывая свою веру идиотскими бенчмарками хелло-вордов).
Кстати, мне кажется (судя по тому, что коммент про uwsgi заплюсован), что еще вам минусов понаставили из-за того, что в конкретный набор букв (fastcgi) не верят.
pip freeze — да, но там разные «но» есть (с -e пакетами freeze может не справиться + после pip install -U уже не выяснить правильные зависимости). Проще сразу версии указывать явно, и обновления версий в VCS фиксировать (т.к. версии сторонних пакетов, по сути, тоже ведь код проекта определяют). Это не критика, дополнения просто, описано все хорошо.
В зависимостях лучше всегда указывать версии (причем даже ==, а не >= или <=) и коммиты в git-репозиториях. Сначала кажется, что это не очень важно, что вроде следишь за обновлениями и поправишь код, если что. Но когда через год проект перестает работать из-за того, что какой-то там пакет обновился, половина программистов, которые над кодом работали, занята чем-то другим, а другая уже и не помнит, о чем там речь была… Короче, лишняя ненужная работа получается.
supervisord еще можно в виртуаленв ставить (pip install supervisord): если на сервере несколько проектов, то у каждого будет свой supervisord, и sudo не нужно будет дергать для перезапуска.
какой из меня гуру, ну спасибо конечно) По поводу слайдов небольшая история. Я в проекте занимался примерно тем, что там на слайдах; было интересно, и примерно за месяц до начала конференции заявку на DevConf отправил — думал, как раз за месяц в тонкостях доразбираюсь. Но как отправил, проект сразу накрылся (по нетехническим причинам), и в итоге ничего в продакшн не пошло, а я другими вещами занялся. Так что на практике не знаю, хороший ли там подход, или плохой, и доклад пришлось рассказывать по теме, в которой опыта почти нет (доклад был ужасным). В слайдах есть пара штук, которые точно лучше поправить (вместо порта лучше использовать поддомен + вместо socket.io лучше socks.js + магия там экспериментальная). Авторы socket.io, похоже, больше самопиаром занимаются (успешно), чем тем, чтоб код работал.
С другой стороны, основная идея (что не нужно все переписывать, и лучший вариант часто — это синхронный фреймворк + асинхронный сервер отдельно) мне все еще кажется правильной и заслуживающей бОльшего внимания. Недавно вот Armin Ronacher про то же самое писал: lucumr.pocoo.org/2012/8/5/stateless-and-proud/
Т.е. в php есть Mersenne Twister? Ну здорово, но он для криптографии не подходит (о чем в доке к питону написано). В справке к mt_rand упоминания о том, что он не подходит для криптографии, опять нет. Или вы имеете в виду, что rand для криптографии подходит? Так тоже ведь не подходит.
К слову, в официальной документации к питоньему модулю random (http://docs.python.org/library/random.html) явно написано «Mersenne Twister… is completely unsuitable for cryptographic purposes». В документации к php-шному rand ( php.net/manual/en/function.rand.php ) — нет.
Второе, о чём Вы должны помнить — динамическая типизация и сборщик мусора занимают много ресурсов. Иногда — очень много. Например, массивы целых чисел в PHP занимают примерно в 18 раз больше памяти (до 35 раз в зависимости от различных параметров компиляции PHP), чем в C/C++ для того же объема данных, поэтому задумайтесь о накладных расходах для сравнительно больших структур данных.
Массивы в PHP — это ведь хэш-таблицы со значениями — указателями? Динамическая типизация и сборщик мусора никакого отношения к тому, что они занимают больше памяти, не имеют. Массив чисел в C обычно в совсем другой структуре данных хранятся, вот и все. Хэш-таблица со значениями-указателями и в C/C++ будет много места занимать. Тут не в языке дело, а в выборе структуры данных.
В динамических языках тоже есть возможность выбирать структуры данных (и создавать свои). Например, в питоне есть тип list — это массив указателей, по сути. А есть array.array — это одномерный массив чисел. И вот array.array будет столько же места в памяти занимать, сколько и соответствующий ему массив на C. На создание объекта array.array есть небольшие накладные расходы (порядка 50 байт, чтоб завернуть в объект), но это совершенно не важно именно для «больших структур данных» — какая разница, 50 + N*sizeof(elem) или N*sizeof(elem).
В php наверное что-то похожее тоже есть, но не спец тут.
Мне кажется, решение не в том, чтоб детально разобраться, как работает импорт в 2.7 и потом следить, чтоб ненароком что-то не то не импортировать (например, выбирая безопасные названия для модулей).
Ну т.е. так вопрос решить можно, и его решают: например, если в какой-нибудь django-библиотеке foo шаблонные теги нужно загружать как
{% load "foo_tags" %}
, то вероятность 92.64%, что боролись с семантикой импортов (либо это cargo-cult, оставшийся от какой-то библиотеки, боровшейся с семантикой импортов).Мне кажется, что все-же лучше проблему решить тем, что всегда писать
в коде на 2.х (например, засунув эту строчку в шаблон для .py файла в IDE) и/или переходить на Python 3.x, где этот алгоритм импортирования уже по умолчанию.
Этот future-импорт убивает двух зайцев: код по семантике импортов становится как 3.х (а значит переход будет проще), и устраняется возможность сломать питоний код, просто создав рядом в папочке файл с неудачным именем. Кроме того, явное ведь лучше неявного — с absolute_imports относительные импорты нужно указывать явно.
С другими future-импортами есть проблема — их нужно писать сверху файла, и когда читаешь код, чтоб его правильно понять, нужно держать в уме, какие future-импорты действуют. С absolute_imports этой проблемы нет, т.к. во-первых, он влияет на импорты (а их тоже пишут сверху файла), а во-вторых, он меняет поведение, котрое в большинстве случаев и так было неявным или ошибочным.
1) ставим «стек» ipython:
$ pip install ipython tornado zeromq matplotlib numpy
2) запускаем ipython notebook (со включенной поддержкой инлайн-графиков):
$ ipython notebook --pylab=inline
3) переходим в браузере по адресу 127.0.0.1:8888
4) тыкаем там «New Notebook»
5) вбиваем код
6) и жмем Shift-Enter:
* в nltk wordnet работает без обращения к серверам;
* в nltk код из ветки 2and3 под Python3.3 работает (не все, но wordnet работает);
* у collections.Counter есть метод most_common;
* в aot для английского языка лемматизация работает тоже на основе wordnet (только словари упакованы в формат, который позволяет держать все в памяти и делать быстрые выборки).
Значение имеет не набора букв в описании веб-стека, а то, как все настроено; чтоб все настроить хорошо, нужно понимание того, как все работает, и того, чего же хочется получить-то. Интернетные советы «uwsgi быстрее mod_wsgi», как мне кажется, от этого понимания отдаляют, а не приближают — вместо того, чтоб разобраться в проблеме, люди начинают верить в наборы букв (иногда еще обосновывая свою веру идиотскими бенчмарками хелло-вордов).
Кстати, мне кажется (судя по тому, что коммент про uwsgi заплюсован), что еще вам минусов понаставили из-за того, что в конкретный набор букв (fastcgi) не верят.
supervisord еще можно в виртуаленв ставить (pip install supervisord): если на сервере несколько проектов, то у каждого будет свой supervisord, и sudo не нужно будет дергать для перезапуска.
С другой стороны, основная идея (что не нужно все переписывать, и лучший вариант часто — это синхронный фреймворк + асинхронный сервер отдельно) мне все еще кажется правильной и заслуживающей бОльшего внимания. Недавно вот Armin Ronacher про то же самое писал: lucumr.pocoo.org/2012/8/5/stateless-and-proud/
Массивы в PHP — это ведь хэш-таблицы со значениями — указателями? Динамическая типизация и сборщик мусора никакого отношения к тому, что они занимают больше памяти, не имеют. Массив чисел в C обычно в совсем другой структуре данных хранятся, вот и все. Хэш-таблица со значениями-указателями и в C/C++ будет много места занимать. Тут не в языке дело, а в выборе структуры данных.
В динамических языках тоже есть возможность выбирать структуры данных (и создавать свои). Например, в питоне есть тип list — это массив указателей, по сути. А есть array.array — это одномерный массив чисел. И вот array.array будет столько же места в памяти занимать, сколько и соответствующий ему массив на C. На создание объекта array.array есть небольшие накладные расходы (порядка 50 байт, чтоб завернуть в объект), но это совершенно не важно именно для «больших структур данных» — какая разница, 50 + N*sizeof(elem) или N*sizeof(elem).
В php наверное что-то похожее тоже есть, но не спец тут.