Устанавливаем OpenCV 3 для Python 3 на macOS

Конфигурация OpenCV 3 + Python 3 на macOS внезапно оказалась немного неожиданной в настройке. Изначально я ожидал что надо будет пару раз вызвать Brew, но оказалось несколько сложнее. Последовательность:

Смотрим где находятся site-packages для интерпретатора, которым собираемся пользоваться, понадобится ниже для создания симлинки на OpenCV:

>>> import site; site.getsitepackages()
['/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages', '/Library/Python/3.6/site-packages']
>>>

Ставим, собираем, делаем линку (если нет TBB и/или Qt5, ий стоит либо поставить заранее, либо убрать соответствующие флаги):

brew install numpy --with-python3
brew install opencv3 --with-tbb --with-qt5 --with-python3 --with-examples --with-contrib --c++11
sudo mkdir -p /Library/Python/3.6/site-packages
sudo ln -s /usr/local/opt/opencv3/lib/python3.6/site-packages/cv2.cpython-36m-darwin.so /Library/Python/3.6/site-packages/cv2.so

Почему нужно отдельно создавать линку да и еще с таким загадочным именем как cv2 я так и не разгадал. Проверить что все работает довольно просто:

>>> import cv2; cv2.__version__
'3.2.0'
>>>

Генератор CMakeLists.txt файлов

Довольно часто возникает необходимость быстренько написать тестовое приложение на C++ и опробовать в нем что-то. IDE я не слишком люблю, а каждый раз где-то выискивать завалявшийся шаблон к CMake-у довольно лениво. После очередных поисков запилил небольшой вспомогательный скриптик (само собой на Python) для генерации CMakeLists.txt.

На данный момент поддерживается только генерация приложений, как надоест конвертировать приложения в библиотеки, так будут и они генериться

Сам скриптик с руководством по использованию тут: https://github.com/astavonin/gen-cmake

На что бы заменить Python?

На прошлой неделе интегрировал наши замечательные автотесты не только нам, но и команде тестирования и задумался. А правильно ли я изначально сделал выбрав Python в качестве языка для реализации системы? Мне видится ряд плюсов и минусов, ну и некоторые дополнительные мысли созрели.

Плюсы

В качестве главного плюса этого выбора выступает простота самого языка и, как следствие, требованию к уровню разработчика необходимого для вхождения в проект очень низкие.
Динамическая природа языка способствует экспериментам в REPL и облегчает поиск оптимального решения.
Язык очень емкий, что сильно сокращает объем код и позволяет в пару строк написать очень не тривиальные для многих других языков вещи.
Огромное количество библиотек на все случаи жизни позволяет сосредоточиться на задаче, а не инструменте.
Ряд отличных IDE, например PyCharm, сильно облегчают разработку. Continue reading

Крик души о Python собеседованиях

Прибиваю в несколько офигевшем состоянии после проведенной пары мини-собеседований с SDET-ами на тему знания ими языка Python. Вообще, для меня Python, можно сказать что не родной язык, т.е. никаких вопросов с подковыркой я задать не могу хотя бы потому, что их просто не знаю. Поэтому, спрашивал то, с чем придется столкнуться при написании тестов для нашего нового тестового бота (который я как раз допилил). Список вопросов на который я пытался получить ответ:

  1. Расскажите про особенности многопоточности в Python. Зачем нужен GIL, его плюсы и минусы. (0 ответов)
  2. Как работает конструкция with open(…). Зачем она вообще нужна? (0 ответов)
  3. Что нужно добавить в класс, что бы при передаче объекта соответствующего типа в качестве аргумента функции print была выведена не информация о типе и адресе, а некая пользовательская строка. (1 ответ)
  4. Как в Python описываются абстрактные базовые классы? Зачем они нужны? (0 ответов)
  5. В чем основные особенности написания асинхронных приложений? (0 ответов)

Вот я думаю, может я что-то не то спрашивал? Просто мне не приходят в голову еще более простые вопросы.

Как бороться с динамической типизацией?

Я довольно часто писал на Python какие-то вспомогательные вещи, иногда сравнительно крупные, но почти всегда не знание типа объекта с которым работаешь было не критичным. Плюс возможность разрабатывать в IPython сильно облегчала жизнь. И так было до тех пор, пока я не решил плотно использовать Twisted. И оказалось что в IPython не попишешь нормально, а занание типов параметров в функциях обратного вызова и классов из обширного становится необходимостью.

И вот тут то я оказался в неком тупичке. Есть большое количество разнообразных классов со сложными интерфейсами. Перепробованные IDE (Eclipse, PyCharm и даже Emacs) не позволяют воспользоваться автодополнением в незнакомых им классах, что логично. В результате, весь код начинает выглядеть как пример ниже.

def _call_later(self, request):
"""
тут какое-то описание функции
@param request: тут какое-то описание параметра
@type request: Request (1)
"""

Да, безусловно, указывать 1 для каждой из создаваемых функций типы передаваемых параметров это решение, только оно выглядит как откровенный костыль. В итоге, у меня создается ощущение, что я как-то не верно использую этот замечательный язык… Что не так? Как с этим жить? Наиболее подходящим вариантом выглядит то, что все помнят параметры у API наизусть, я же вполне могу писать на C++ с подстановкой параметров исключительно из открытых файлов.

Разбитые надежды или просто непонимание?

В одной из лекций с PyCon US 2014 проскочила очень заинтересовавшая меня информация о том, что с Python 3.3 CPython поддерживает оптимизацию для классов, и старый вариант использования Python, когда класс могли просто заменить на Dict не верен в корне, т.к. Dict не поддерживает никакой типизации. Вроде все верно и логично: никак не ограничиваемый по данным ассоциативный массив против класса, в котором можно предсказать используемые типы и количество полей. Continue reading

Python 3.4, asyncio

Думаю, ни для кого не секрет то, что основная реализация языка программирования Python фактически не поддерживает многопоточности. Есть модули которые позволяют эмулировать потоки посредствам процессов, но подобный путь крайне требователен к ресурсам и поэтому его применимость крайне ограниченна, особенно для большого количества операций ввода/вывода. При этом, в подавляющем большинстве случаев, распараллеливание задач не несет какого-то серьезного практического смысла и просто является одним из возможных архитектурных решений. В качестве альтернативы потокам могут выступать асинхронные операции, а с учетом ограничений интерпретатора, подобный подход должен бы был быть родным подходом в Python уже много лет как. Тем не менее, появился долгожданный модуль asyncio только в Python 3.4, но это в любом случае лучше чем никогда.
Continue reading

Оптимизация кода Python

Решил прояснить для себя возможности оптимизации приложений написанных на Python. В интернете существует довольно много рекомендаций на этот счет, так что я просто пытаюсь свести всю информацию вместе и выяснить чем вызваны те или иные отличия.

Хотя, на первый взгляд кажется, что Python и быстрый код не совместимые понятия, это не совсем правда.

Все тесты проводились на Python 3.3.3 и, само собой, не обошлось без IPython, который ну просто killer-feature этого языка. Continue reading

Pip, update all

Хотелось бы, да? А нету. Нашлось вот такое решение:

import pip
import sys
from subprocess import call

def pip_ver():
    if sys.version_info.major == 3:
        return "pip3"
    else:
        return "pip"

cmd_line = pip_ver() + " install --upgrade "

for dist in pip.get_installed_distributions():
    call(cmd_line + dist.project_name, shell=True)

Использовать просто:

python script_name.py

Делать файл исполнимым не стал, т.к. при явном вызове Python можно указать нужную версию 2.X или 3.X