вторник, 24 марта 2015 г.

CherryPy autoreloader

CherryPy классный легкий и удобный фреймворк под Python.
Столкнулся сегодня с такой проблемой: он автоматически перезапускается когда в исходниках происходят изменения (autoreloader). Вроде бы всё отлично, но возникает проблема с дебагом. Когда проект запущен из PyCharm авторелоад отсоединяет процесс от среды разработки и он болтается в памяти. Работает, продолжает обрабатывать запросы и релоадится при изменении фйлов. Но! Подключить дебагер нельзя. Попытка запуска завершается ошибкой с руганью на то, что порт занят и это вполне логично. Приходится искать этот процесс в таск-менеджере и убивать, либо добавлять функционал выключения CerryPy приложению и глушить его через браузер. И так каждый раз. Дико неудобно.
Ответ вроде бы лежит наповерхности, но есть нюанс.
Так вот, доки говорят, что autoreloader отключается через конфигуратор, нужно выставить engine.autoreload.on в False. Я попытался проделать это и пытался выставить это значение в секции [global] файла с конфигом. Долго мучился, но эффекта не добился.

Всё заработало и autoreloader отключился только после того как я добавил строку  cherrypy.config.update({'engine.autoreload.on':False}) перед запуском cherrypy.engine.start()


воскресенье, 22 марта 2015 г.

Python генераторы.

Продолжаю вникать в тонкости Python-а. Разглядывал как-то свой код и понял, что он не очень... в смысле совсем "не очень". А штука в том, что он хоть и написан на Python-е, но не полноценно питоновский. Что это значит? Да всё очень просто. По многолетней привычке я пишу:
result = list()
for itm in items:
    i = dict()
    i['Name'] = itm.name
    i['ItemID'] = itm.item_id
    result.append(i)
return result

Вот, код работает, но... я задумался, вспомнил что читал о Python-е, вспомнил про такую штуку как генераторы. Сказал себе: "Хмммм..." и, покопавшись в доках, написал:

return [{'Name': i.name, 'ItemID': i.item_id} for i in items]

Разница, как говорится, налицо. Код гораздо компактнее, понятнее и доки утверждают, что генераторы в Python работают быстрее циклов.

Генерировать можно не только списки. Словари тоже можно и это тоже очень просто:

result = { i.name: i.item_id for i in items}

Тут генератор возвращает словарь у которого name - это ключ, а item_id - значение. Примеры очень простые, но генераторы в Python очень мощная и гибкая штука и могут создавать довольно сложные объекты.

суббота, 21 марта 2015 г.

Вникаю в Python, генерирую классы для SQLAlchemy

Собственно изучаю Python как платформу для веб-разработки. Пока всё очень нравится. В качестве ORM фреймворка стал изучать SQLAlchemy, т.к. сегодня это стандарт де-факто для Python.

Встал вопрос как для SQLAlchemy сгенерить классы на основе существующей БД, писать всё руками совсем неохота. Поиски привели меня к sqlacodegen. Инсталится он просто: pip install sqlacodegen. Запускается из консольки: sqlacodegen mysql+mysqlconnector://user:password@localhost/dbname

То есть ему нужен коннектор. А вот с установкой коннектора под винду у меня возникли сложности. Ни один из популярных коннекторов из pip ставиться не захотел. Всем им понадобился C компилятор, а ставить студию или mingw мне не захотелось. Простое решение нашлось на сайте MySQL в виде готового инсталлятора под виндовс: http://dev.mysql.com/downloads/connector/python/

Эта связка отлично заработала и сгенерила мне нужные SQLAlchemy классы со всеми связями. sqlacodegen генерит код и выводит его в stdout. Поэтому нужно просто перенаправить вывод в нужный файл: sqlacodegen mysql+mysqlconnector://user:pass@localhost/dbname > model.py

вторник, 27 августа 2013 г.

Бесплатные флеш иры

Готовлю к запуску новый сайт www.get-game.ru. Как видно из темы это портал бесплатных флеш игр. Планирую реализовать на нем несколько интересных технологий, когда созрею - напишу о них. А пока можно там поиграть в свободное время.
Почему именно флеш игры? А дело в том, что иногда нужно отвлечься, расслабиться и игра - это хороший помощник. Но! Обычные компьютерные игры (или, не дай бог, MMORPG) имеют свойство затягивать и пожирают время. В итоге - хотел отвлечься, а потерял кучу времени.
У флеш игр такого недостатка нет (ну практически). В среднем на прохождение флеш-игры уходит 25-30 минут. Отвлекся, отдохнул, поиграл и можешь с новыми силами свершать подвиги в реальности.
Так, что, всем хорошего настроения, играйте с удовольствием и не забывайте о спорте!

понедельник, 12 августа 2013 г.

Снова про соотношение сторон картинки

Пришлось вернуться к вопросу сохранения пропорций картики. Некоторое время назад я писал об изменении размеров изображений с сохранением пропорций
Но возникла необходимость отображать все картинки в ленте одинакового размера.
Решение довольно простое: для контейнера задаем фиксированную высоту и добавляем css атрибут overflow: hidden  а для картинки задаем фиксированную ширину. 
В итоге браузер приведет картинку к нужной ширине, сохранив пропорции, а контейнер отрежет лишнее. Выглядит это нормально, если картинки более-менее схожего формата.

P.S. этот рецепт действует для landscape изображений. Для портретной ориентации в контейнере нужно выставлять ширину, а в картинке высоту. 

суббота, 11 мая 2013 г.

Айкидо техники с мечем и в паре

Недавно мы с нашим будо клубом отсняли ролик, где одновременно исполняются техники в паре и с оружием. Получилось довольно наглядно, параллель между техниками с оружием и без оного хорошо видна.


В ролике продемонстрированы техники:
  • Ikkyo
  • Kaitennage
  • Aihanmi shihonage 
  • Gyakuhanmi shihonage
  • Tsuki sankyo

пятница, 19 апреля 2013 г.

Lucene в .net и словари hunspell

Недавно на работе мне задали такую задачку: замутить в  lucene поиск не только по точному совпадению ключевого слова, а также по его свловоформам.
А, надо сказать, проект у нас написан на .net и порт lucene там довольно старый (lucene 3.0.3). А что это значило для меня? А то, что штатной поддержки морфологии нужного мне языка не было. Я пошерстил интернет в поисках отвеа на вопрос: что же lucene может предложить в вопросах морфологии и стемминга той кучи языков, которую она не поодерживает из коробки?