1 апреля 2013 г.

Мои впечатления о последнем CodeFest

Организаторы и докладчики были на высоте, примерно на уровне прошлой конференции. В этот раз впервые были англоязычные докладчики, подробнее ниже. Как всегда, было много стендов разных компаний, ребята из JetBrains даже соблазнили меня попробовать PyCharm, но после пяти минут я плюнул и вернулся к старому доброму Vim — очень уж давно я с ним работаю, всё настроено под себя, и с клавиатурой работать гораздо быстрее, чем с мышкой.

Теперь немного о запомнившихся докладах.

День первый

Аксель Раушмайер выступил с докладом о будущем JavaScript — ECMAScript 6. Обещается много нового и полезного, большую часть из чего можно обеспечить уже сейчас в ECMAScript 5 с помощью CoffeeScript, underscore и CommonJS.

Майкл Палотас из eBay в Цюрихе (привет аборигенам!) рассказал о QA в его компании, как их развивают, холят и лелеют, ну хоть прям щас в eBay, менять специализацию.

Окончание докладов я пропустил, нужно было торопиться на ДР дочери. День вышел насыщенным.

День второй

Харизматичный Денис Шергин из томской компании Unigine заставил испытать гордость за отечественных программистов — команда из 25 человек успешно конкурирует с крупнейшими конторами из сотен и тысяч людей в области 3D-движков.

Интересно было послушать про опыт открытия нового офиса 2ГИС в Киеве. Ещё интереснее было бы услышать, в чём разница между украинскими и российскими разработчиками, докладчики упомянули об этом, но, к сожалению, без подробностей.

Вадим Макеев из Opera рассказал, почему же они бросили свой браузерный движок и переключились на Webkit. Вкратце — из-за проблем совместимости сайтов, игнорировании Оперы западными программистами и т.п. Теперь Опера тоже будет вносить патчи в код Webkit.

Никита Прокопов зажигательно поведал о Clojure, сразу захотелось попробовать ClojureScript в деле.

Денис Бесков рассказал о том, как создавать новый продукт. Доклад был интересным, но многое (если не всё) из этого освещено в знаменитой книжке 37signals «Getting Real».

И в заключение Глеб Кудрявцев весело и живо сделал доклад о том, как PM найти общий язык с программистами к взаимному удовлетворению.

Мораль

В очередной раз убедился, что не так важна тема доклада, как личность докладчика. Нужно тренироваться делать доклады, снимать себя на видео, смотреть, анализировать и учиться.

CodeFest очень вдохновляет. Я понял, как соскучился по работе с людьми offline, в одном офисе. Всё-таки два года удалёнки дают о себе знать. Погрел самооценку осознанием своей востребованности для многих компаний, в том числе интересных мне. Нужно больше общаться. :)

11 ноября 2012 г.

Типографика в Kindle

Status quo

Давным-давно я работал верстальщиком, а последние 10 лет — программистом, но любовь к красиво оформленному тексту осталась. Ещё я заядлый библиофил, львиную долю книг поглощаю в электронном виде, последний год с помощью Amazon Kindle.

Kindle, к сожалению, не поддерживает переноса текста по слогам; при этом выравнивание у него не левое и даже не полное, а «недополное» (обратите внимание на предпоследнюю строчку первого абзаца):

«Недополное» выравнивание

Слева

Бесплатные или платные книги, скаченные с самого Amazon, можно привести к левому выравниванию. Правда, способ этот работает не для всех книг, а только для тех, где явно не указывается выравнивание текста. Для этого нужно закрыть текущую книгу, подключить Kindle через USB к компьютеру и отредактировать там скрытый файл system/com.amazon.ebook.booklet.reader/reader.pref, добавив строчку ALLOW_JUSTIFICATION_CHANGE=true. После чего файл сохраняем, книжку отключаем и перезагружаем её. Для этого нужно зайти в меню Settings, а там уже выбираем меню Restart. Вуаля! — появился новый элемент меню «Justification»:

Меню «Justification»

Этот финт ушами, к сожалению, не работает с книжками, купленными в Литрес или скаченными в русскоязычных пиратских библиотеках — там выравнивание в файлах mobi указано явно. Нам поможет программа для конвертации форматов электронных книг Calibre. Она содержит набор программ для командной строки (для Mac OS их нужно дополнительно установить).

Скачиваем/покупаем нужную книгу в формате FB2 и обрабатываем с помощью простой команды:

ebook-convert book.fb2 book.mobi --change-justification left
Выравнивание слева

PDF

Другой вариант — преобразовывать FB2 в PDF с помощью кросс-платформенного проекта на Java fb2pdf. Можно достаточно гибко настроить форматировать, текст будет поддерживать буквицы, переносы, висячие строки и прочие вкусности.

Минусы:

  • размер и тип шрифта нельзя менять после создания книги;
  • размер файла PDF в несколько раз больше аналогичного mobi;
  • аннотации не работают. Впрочем, поиск по файлу и просмотр слова в словаре доступны.

«Мягкие» переносы

В Kindle 3 (aka Keyboard) и новее в последних версиях прошивки появилась поддержка нового формата K8. Это значит, что доступны многие теги HTML5 и атрибуты CSS3, вдобавок к ним и мягкие переносы. Они предназначены для разбивки слов по слогам и становится видимы только на правой границе строки — программа использует их для переноса текста по слогам, т.е. то, что нам и нужно.

Минус: размер подготовленного файла незначительно больше «сырого»;

Зато все остальные плюсы в наличии — размер шрифта легко менять по ходу чтения, поиск и аннотации работают корректно, все счастливы.

Для создания таких книг я создал небольшую программку под *nix, расставляющую переносы в FB2-файле. Для конвертирования в AZW3 (это формат для Kindle, который собственно и поддерживает K8), можно использовать в качестве образца прилагаемый скрипт.

Переносы

Для счастливых обладателей Windows есть более удобный вариант.

1 апреля 2012 г.

CodeFest

Очень долго ничего не писал, а тут такой повод появился — CodeFest! Вообще это вторая IT-конференция в моём ленивом опыте, она же крупнейшая. Более 1300 человек, три зала, куча интересных людей, энергия так и пышет. Организаторы на высоте, единственный минус — душно. Но это, наверное, больше проблема помещения.

В первый день на web-секции больше всего запомнился полный харизмы и оптимизма доклад Ивана Евтуховича из «Evil Martians» «Как мы делали Групон». У такого человека я бы хотел работать. Автор — явно многосторонняя личность, первый дан по айкидо среди прочего.

Ещё отжёг весёлый матерщинник Андрей Аксёнов из Sphinx. Но у него я бы работать не хотел. :)

Во второй день в секции PM + HR блеснули Александр Орлов и Вячеслав Панкратов из Стратоплана. Тема доклада — конструктивная обратная связь в менеджменте — мне была не очень близка, но мастерство докладчиков позволяет красиво донести любую инфу, наверное.

Главный бонус посещения конференции — заряд энергии, желания двигаться и шевелиться. Полезно временами вылезать из своей раковины в большой живой мир.

25 апреля 2011 г.

Соглашение о вызовах

Интересная статья о всевозможных вариантах вызова и использования функций: сопрограммы (coroutines), рекурсия, хвостовая рекурсия (tail call optimization), каррирование и многое другое.

http://jjinux.blogspot.com/2011/04/call-me-crazy-calling-conventions.html

14 марта 2011 г.

Делимся Питоном с миром

Когда питоновские скрипты приобретают какую-то готовую форму, и ими хочется поделиться с другими, возникает вопрос: как это правильно и красиво сделать?

Стандартом для распространения программ на Python является Python Package Index, своего рода центральный Python-репозиторий. О процессе публикации много написано, покажу, как это делается, на своём примере.

7 марта 2011 г.

Реанимация данных

Жена с дочкой используют внешний USB-винт для хранения видео и всего такого. На днях прикупил новый, стал копировать данные со старого, и — бац! — I/O error! Битые сектора, они же бэд-блоки.

В итоге не удалось скопировать 4 видеофайла. Тут на помощь приходит старая добрая утилитка ddrescue — при ошибке ввода-вывода продолжает копировать посекторно, пропуская плохие участки, в итоге удаётся бóльшую часть данных вытащить; позволяет копировать как целое устройство, так и отдельный файл. Видео спасти получилось, благо небольшая доля мусора внутри файла не мешает его воспроизводить.

К сожалению, ddrescue не позволяет копировать целые директории рекурсивно. Тогда я написал простой скрипт на Python, rddr (Recursive DDRescue), копирующий каталог целиком с помощью того же ddrescue.

Но этот эпизод с винтом меня смутил — ведь есть же SMART, почему Ubuntu мне не сказал о непригодном состоянии диска? Оказалось, что состояние его "хорошее", но есть несколько плохих секторов. Есть у SMART такой атрибут, показывающий количество секторов, ожидающих замены из специальной дисковой зоны "хороших" секторов, причём замена происходит при попытке записи, а не чтения. Теперь на помощь приходит программа badblocks — она позволяет прогонять тесты чтения/записи по всему устройству. Тесты записи на винт заняли около одиннадцати часов, данные при этом затёрлись. 19 секторов из 20 восстановились из резервной области.

Вердикт: винчестер можно использовать для некритичных данных, видео хранить вполне годится.

P.S. Прекрасное руководство для восстановления данных с помощью Linux можно здесь почитать.

4 марта 2011 г.

Скоро выйдет Django 1.3

3 марта вышел кандидат в релизы Django 1.3. Я не вытерпел и полюбовался на внушительный список изменений будущей версии.

2 марта 2011 г.

Волшебная кнопка

Несколько раз я сталкивался с тем, что запущенная в линуксе программа начинает отжирать всю доступную память, система сваливается в штопор, и закрыть виновницу удаётся с большим трудом... Простой пример для теста — откройте XML файл в несколько мегабайт в Firefox. ;)

Уже гораздо позже я узнал, что есть т.н. "волшебная кнопка" — "бесполезная" клавиша SysRq (она делит место жительства с PrintScreen). Это единственная прямая связь с ядром линукса, работающая всегда (конечно, если работает и ядро). Тест из первого абзаца проходится с помощью SysRq+Alt+f — вызывается обработчик ситуации нехватки памяти, который и завершает самый "тяжёлый" процесс. Из любимого ещё убиение X-сервера — SysRq+Alt+k.

Статический анализ кода в Python

В статье на Хабре наткнулся на упоминание статических анализаторов кода для Python. Инструмент этот очень полезен при регулярном его использовании. Немножко подробнее расскажу о pep8, pylint и pyflakes.

pep8

Этот анализатор проверяет соответствие кода знаменитому PEP 8 — руководству по стилю кода Python. В больших и не очень командах хорошая штука, ибо "Readability counts"!

pylint

Самый придирчивый анализатор из всех трёх, хотя стиль кода проверяет немножко иначе, чем pep8 — акцент на "дурно пахнущем" и неоптимальном коде, выдаёт и предложения о рефакторинге. Бонусная опция — генерация UML-диаграмм с помощью команды pyreverse.
Угодить pylint весьма сложно, порой он ошибается — к счастью, настройки достаточно гибкие.

pyflakes

В отличие от pylint, проверяет только на логические ошибки в программе, стиль не учитывает.


На мой взгляд, золотая середина — pyflakes, поначалу можно использовать и pep8, дабы привить соблюдение стиля.

Бонус для пользователей Vim — вызов pyflakes или pylint после каждого сохранения редактируемого файла, сообщения об ошибках помещаются в окошко "quickfix":
command Pylint :call Pylint()
function! Pylint()
    setlocal makeprg=(echo\ '[%]';\ pylint\ %)
    setlocal efm=%+P[%f],%t:\ %#%l:%m
    silent make
    cwindow
endfunction

command Pyflakes :call Pyflakes()
function! Pyflakes()
    let tmpfile = tempname()
    execute "w" tmpfile
    execute "set makeprg=(pyflakes\\ " . tmpfile . "\\\\\\|sed\\ s@" . tmpfile ."@%@)"
    silent make
    cwindow
endfunction

autocmd BufWrite *.{py} :call Pyflakes()

25 февраля 2011 г.

Обработка ссылок mailto в Google Chrome

Наконец нашёл решение давней несуразности: в отличие от Firefox, линуксовый Google Chrome при попытке открыть почтовую ссылку (протокола "mailto") запускает почтовую программу, а мне нужен Gmail. Замечательный superuser.com подсказал, что в Ubuntu для этого достаточно установить пакет desktop-webmail (плюс к этому я выбрал Desktop Webmail в настройках Preferred Applications/Mail Reader — возможно, это необязательно).

22 февраля 2011 г.

Репликация и устойчивое хэширование в memcached

Memcached работает просто и быстро, как электровеник, и не поддерживает репликации, которая может понадобиться при горизонтальном масштабировании серверов memcached.

Есть как минимум два варианта решения этой задачи. Первый используется для репликации мастер-мастер и не зависит от языка программирования — repcached, патч к memcached, добавляющий репликацию между серверами. (Инструкция по установке.) Из минусов — устанавливать придётся, скорее всего, из исходников и поддерживается не самая последняя версия memcached (примерно полуторагодовалой давности).

Другой способ специфичен для PHP (впрочем, наверняка есть схожие решения и для других языков). Модуль php5-memcache позволяет реализовать подобие репликации с помощью хранения каждого ключа на N серверах. В случае, если один из серверов падает, ключ будет храниться на оставшемся и каком-то N+1 сервере. С помощью этого модуля можно хранить и сессии с избыточностью. Выдержка из readme:
# When enabled the client sends requests to N servers in parallel, resulting in
# a somewhat crude reduncancy or mirroring, suitable when used as a session
# storage.
#
# If data integrity is of greater importance a real replicating memcached
# backend such as "repcached" (http://sourceforge.net/projects/repcached/) is
# recommended

memcache.redundancy = # default 1
memcache.session_redundancy = # default 2


Для большинства приложений такой надёжности достаточно.

Вдобавок этот модуль использует т.н. "устойчивое хэширование" ("consistent hashing"). Вкратце, этот алгоритм позволяет привязывать ключи к определённым серверам memcached и при удалении/добавлении серверов бóльшая часть ключей останется привязана к тем же серверам. Таким образом, для распределения нагрузки без использования репликации достаточно встроенных средств php5-memcache.

Для Python такую функциональность предоставляет модуль hash_ring.

18 февраля 2011 г.

Новое в PHP

Господин Ilia Alshanetsky (судя по всему, выходец из СССР) опубликовал прекрасную презентацию о малоизвестных фичах в PHP, в частности, PHP 5.3: PDF (3 МБ). В свою очередь хочу упомянуть о появлении в PHP 5.3 анонимных функций, с помощью которых можно реализовывать и замыкания (closures). Не так удобно, как в других языках, но сам факт радует.

9 февраля 2011 г.

Чёрная магия Ruby

На работе понадобилось поменять пару вещей в Redmine — написан он на Ruby on Rails. Случилось то, что так давно откладывал — я познакомился с Ruby и RoR.

Ruby произвёл неоднозначное впечатление большого хака, из которого к тому же торчат уши зубодробительного Perl. Но хак этот эффективный и в умелых руках работает со страшной силой. К RoR эти слова применимы в квадрате — это ещё бóльшая чёрная магия. Японское происхождение частично объясняет странность Ruby.

Избранные места из документации Ruby:
  • В Ruby всё — объекты. Даже числа. Чего стоит, например, такой код:
    5.times { |i| print i, ' ' }
    Этот кусочек иллюстрирует ещё одну странную, но мощную фишку — передача кусков кода в виде аргументов функции. Похоже на lambda-функции в Python, но мощнее и применяется повсеместно.
  • При записи числа допустима, например, следующая форма:
    a = 1_000_000
    Чтобы, значит, читабельность кода увеличить.
  • Ruby вообще любит использовать ASCII-таблицу по максимуму. Функция проверки валидности может называться valid?, а сортировка массива "in place" — sort!.
  • Как и многие языки, в Ruby объекты могут наследоваться лишь от одного родителя. Но можно включать в класс код из других модулей, при этом их функции становятся методами данного класса — это ж настоящий monkey patching!
  • Определение класса может состоять из несколько кусков. Т.е. мы начали определять класс A, потом пошло определение класса B, потом мы опять продолжили определить класс A. На практике это означает, что можно переопределить поведение даже базовых классов, того же String. Вот это действительно monkey patching.
  • И ещё для Ruby написано самое странное руководство из тех, что я встречал.
В заключение можно ещё раз повторить: Ruby — очень эффективный инструмент в умелых руках. В неумелых он вносит хаос в код и мозг программиста.

Лично мне ближе элегантность Python, замешанная на дзене. ;)

10 декабря 2010 г.

Новый старый PNG

Оказывается, формат PNG не так уж и прост. Среди прочего он позволяет эффективно сжимать градиентную заливку внутри картинки, отсюда вывод — если требуется на градиентный фон что-то наложить, эффективнее будет сделать фон отдельной картинкой, а сверху наложить другую с объектами переднего плана и прозрачным фоном.
Есть несколько утилит для оптимизации размера PNG, одна из лучших открытых — OptiPNG, есть удобные обёртки под Windows, Mac и Linux. Но ещё лучше по степени сжатия — бесплатная утилитка PNGOUT.

19 ноября 2010 г.

Грабли в MySQL

Сегодня, как обычно случайно, выяснил, что если подключиться к одной базе и начать там транзакцию с помощью START TRANSACTION/BEGIN, то любой запрос к другой базе приостанавливается — MySQL ждёт, когда вы закончите открытую транзакцию к первой базе.

21 октября 2010 г.

Вся мощь Vim

Я люблю Vim странной долгой любовью. :) Встречая такие мануалы, понимаю, что только начинаю изучать его. Осталось понять сей славный документ, и можно называться Vim-гуру. B-)

8 сентября 2010 г.

Server-side jQuery

jQuery настолько прекрасен, что портируется и на серверные языки, дабы упростить написание всевозможных парсеров. Я использую два порта, pyquery и phpquery, соответственно — для Python и PHP. Весьма облегчают жизнь.

25 июня 2010 г.

XtraDB и MariaDB

Оказывается, правильные пацаны потихоньку переходят на XtraDB. Как пишет Википедия:
В последнее время из-за излишней закрытости разработки MySQL компанией Sun Microsystems появилось много сторонних (например, от компании Google) патчей с улучшениями производительности и исправлениями ошибок, большинство из которых были включены в форк InnoDB под названием XtraDB, созданный компанией Percona.

Percona была создана в 2006 году для консультирования и поддержки MySQL-пользователей. И основатели её имеют знакомо звучащие имена, как то Peter Zaitsev и Vadim Tkachenko. В общем, наши люди.

Как известно, InnoDB — это лучший движок для таблиц MySQL с нормальной поддержкой транзакций, внешних ключей и т.п. XtraDB, по заявлениям авторов, работает быстрее плюс позволяет осуществлять бэкап таблиц на лету. У InnoDB тоже есть такой инструмент, но он платный, в отличие от XtraDB. Формат таблиц используют они один и тот же, т.е. можно существующую базу пересадить с одного движка на другой без проблем.

А ещё есть форк MySQL под названием MariaDB. Это детище основателя MySQL Michael "Monty" Widenius. Формат БД, API, имена файлов и т.п. полностью совместимы с MySQL. Взамен обещается ускорение и новые фичи. Ну и движок XtraDB включён в комплект вместо InnoDB.

9 июня 2010 г.

О MySQL в многопоточном Python'е

В проекте возникла необходимость доступа к MySQL из разных потоков (threads). Я внимаааааааааательно прочитал официальную документацию библиотеки для доступа MySQL из Python, и она заявляет, что нельзя использовать одно и то же подключение к БД в разных потоках.

На помощь спешит PySQLPool, в нём есть методы для создания пула подключений к MySQL.

Я использую движок таблиц (table engine) InnoDB с нормальной поддержкой транзакций. Совсем неинтересно каждый раз писать BEGIN TRANSACTION/COMMIT, это ж Python! Должен быть способ! И он нашёлся.

В версии 2.5 добавили оператор with и контекстные менеджеры. Я написал простенький патч, и использование транзакций стало простым и красивым:
q = PySQLPool.getNewQuery(connection)
with q: # внутренние запросы обёрнуты в транзакцию
            q.Query('INSERT INTO peer SET PeerName=%s', (name,))

Есть и маленькая ложка дёгтя в виде заявленного автором бага при работе с транзакциями из нескольких тредов. В общем-то, ко времени релиза нашего проекта либо я исправлю этот баг, либо автор, либо вы. ;)

14 мая 2010 г.

Сетевое программирование в Python

Нашёл хороший туториал (PDF) на английском про сетевое программирование в Python — чётко изложена сама теория, кое-чего я и сам не знал, и даны хорошие базовые примеры на Python.
На сайте автора есть и другие неплохие туториалы про Python.