воскресенье, апреля 1

opscode chef

Я разобрался с opscode chef. Это система управления однотипными конфигурациями для кучи машин. Законченный кусок конфигурации это «рецепт».

Поставил chef-server на ubuntu 11.04 (кстати они её еще не поддерживают), одну админскую машину и одну виртуалку-клиента. Я использую его для поднятия девелоперского окружения, чтобы наливать машину для разработчика. Получается, что чистая виртуалка на ubuntu готова для разработки проекта за 10 минут. Это удобно.

chef доступен в нескольких версиях, 0.9 и 0.10, а так же через пакеты и через gems. Я ставил версию 0.10 из пакетов и версию 0.9 из них же. 0.10 у меня не заработала. 0.9 встала очень хорошо.

вторник, декабря 20

Интернет-магазин

Привет. Я несколько месяцев после работы программировал интернет-магазин. Получилась основа - бекэнд, витрина, и админка.

Витрина в состоянии "просит дизайна", там есть корзина, которая обновляется аяксом, каталог товаров, которые через AJAX добавляются в корзину. Страница оформления заказа умеет показывать точки самовывоза и само находит ближайший до вашего места пункт самовывоза через сервис геолокации, встроенные в современные браузеры. Если не находит через браузер, то обновляет через геолокацию Яндекса. В оформлении заказа оно показывает на карте пункты самовывоза. Все это естественно настраивается в админке и требует ключа Яндекс.Карт.

Админка позволяет настраивать все объекты, в том числе заводить страницы, которые оформляются с помощью разметки MediaWiki.
Бекэнд использует mongodb + MySQL.
Есть система почтовых уведомлений. Я по работе писал генераторы для почтовых уведомлений, и уже потом возникли мысли, как его надо было написать. В этом магазине я переосмыслил почтовые уведомления.

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

Сам магазин устанавливается на Ubuntu и сделан в виде debian пакета, который можно скачать с сайта Народ.Яндекс. Он требует пакет mongodb10gen, который можно установить с сайта разработчика mongo. Я не смог использовать пакет, который идет в поставке с Ubuntu, потому что он не поддерживает UTF-8 без настройки. А разбираться с тонкой настройкой монго я не считаю нужным.

Mongo Db в нем используется в качестве эксперимента, в основе лежит все равно MySQL, в котором хранятся все критичные данные. В монго хранятся почтовые уведомления и тому подобное.

Яваскрипт и css сжаты. В качестве вебсервера требуется nginx. Если вы зальете на сервер дамп данных городов и стран из моего прошлого поста, то чудесным образом у вас заработает саджест при вводе страны и города вашего адреса на вашем языке, который передается в Accept-Language и в админке при создании пунктов доставки и самовывоза.

Я выкладываю эту версию без всяких ограничений. Мне стало трудно работать над ним, т.к. я не вижу вот прямо сейчас ни одного магазина, который я мог бы взять, сделать на основе этой разработки и дальше его вести. Я хочу его разрабатывать, получая или удовольствие, или деньги.
Удовольствие медленно заканчивается, потому что в одиночку им заниматься скучно. Есть приватный git репозиторий, в который я готов пустить разработчиков, или перенести его на гитхаб в публичный репозиторий, если от вас увижу какие-то отзывы, и подумаю "Ага, кому-то это нужно".

пятница, сентября 30

База городов и стран для mysql

Я сделал урезанную базу с информацией о городах и странах на разных языках.

Структура таблиц такая:
CREATE TABLE `geocoding_geoalternate` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`geoname_id` int(10) unsigned DEFAULT NULL,
`variant` varchar(200) NOT NULL,
`isolanguage` varchar(3) NOT NULL,
`preferred` tinyint(1) NOT NULL DEFAULT '0',
`short` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `geocoding_geoalternate_variant` (`variant`)
)
CREATE TABLE `geocoding_geomodel` (
`typ` smallint(5) unsigned NOT NULL,
`geonameid` int(10) unsigned NOT NULL,
`name` varchar(100) NOT NULL,
`population` int(10) unsigned NOT NULL DEFAULT '0',
`country_code` varchar(3) NOT NULL,
PRIMARY KEY (`geonameid`),
KEY `geocoding_geomodel_52094d6e` (`name`)
)

Таблица `geocoding_geoalternate` содержит варианты названия пункта на разных языках. Поле preferred означает что это - предпочитаемое родное название. Например, есть Россия и Российская Федерация, второе будет предпочитаемым, зато первое - коротким (short=1).

Она связана с `geocoding_geomodel` через поле geoname_id. В `geocoding_geomodel` содержится информация о населенном пункте . Тип - страна или населенный пункт, количество населения на 2011 год, код страны, например "RU" для России.
База это выжимка с geonames.org. Я сейчас работаю над django приложением которое бы могло ходить в geonames.org и синхронизировать местную базу с их базой, а это - сокращенный вариант (261 MB в распакованном виде), там нет большого количества ненужной для меня информации и нет населенных пунктов с численностью населения меньше 5000 человек.

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

четверг, сентября 2

Задача по SQL

Мне была предложена задача:
Игровой сервер. Таблица с двумя полями: id, race. race - строка с расой, их, рас, понятное дело счетное множество. Надо за один запрос, без join, без вложенности, подсчитать долю записей, сделанных людьми, "human".
Скрипт для создания таблицы: mysql, MS SQL Server
CREATE TABLE t(
 ID INT,
        RACE ENUM('ork', 'human', 'troll')
);
Напомню, что такое доля: отношение количества записей которые нас интересуют к общему количеству записей.
Решения: MS SQL (автор Игорь), Oracle (автор Алексей), MySQL

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

пятница, августа 20

Обход прошитого дерева

Элемент бинарного дерева содержит две ссылки: на левое и правое поддерево. Чтобы обойти обычное бинарное дерево требуется алгоритм, использующий стек, т.к. нижележащие деревья не содержат информации о своих предках. Поэтому, чтобы вернуться в узел, в котором возможно ветвление, мы помещаем его в стек. Если же процедура обхода не находит следующего элемента, то мы берем его из стека и повторяем её.
Учитывая то, что многие узлы могут иметь одну из ссылок незанятыми, можно прийти к выводу, что дерево можно представить более эффективно в памяти и сделать обход его более быстрым.
А. Дж. Перлис и Ч. Торнтон предложили использовать эти незанятые ссылки в качестве "нитей", которые связаны с остальными частями дерева. Дерево с такими связями называют "прошитым бинарным деревом".
Прошитое дерево. Из книги Кнут Д. "Искусство программирования."
Чтобы отличать нити от обычных ссылок используются два бита, характеризующие тип связи. Для определенности, если бит RS = 0, то правая связь обычная, если RS = 1, то это связь типа "нить". Аналогично для бита LS. В памяти оба бита естественно представимы в виде одного слова.
Для удобных реализаций алгоритма обхода прошитого дерева вводится ограничение на дерево:
  1. корневой элемент имеет правую ссылку на само себя, 
  2. построение дерево начинается только влево от корня. 
Корень в таком случае называют "заголовком списка". Для ясности можно делать его значение равным None или Null или любым другим значением, таким которое явно не встречается в элементах дерева, чтобы точно отличать его от остальных элементов дерева и избавить себя от этого искусственного ограничения на построение дерева.
Пример организации прошитого дерева с учетом всех ограничений.

Реализация на Питоне (в виде пакета) включает в себя
  • Дерево,
  • генератор произвольного дерева,
  • алгоритм обхода,
  • алгоритм вставки одного произвольного элемента в произвольную часть дерева (либо в середину, либо в качестве продолжения дерева),
  • пробную программу с генерацией дерева автоматически и вручную.
  • А так же, весьма вероятно, ненужный вам проект для Eclipse.
Скачивайте.

среда, августа 18

Обход бинарного дерева

Определение: бинарное дерево это множество, которое либо пусто, либо состоит из корневого элемента и двух бинарных деревьев: левого и правого.
Это определение рекурсивно. Оно отличается от определения обычного дерева возможностью существования "пустого" бинарного дерева.
Разные двоичные деревья.
Типичны задачи обхода этого дерева. Стандартных алгоритмов обхода три.
Прямой алгоритм обхода бинарного дерева
  1. Зайти в левое дерево,
  2. зайти в корень,
  3. зайти в правое дерево.
Центрированный алгоритм обхода дерева
  1. Зайти в корень,
  2. зайти в левое дерево,
  3. зайти в правое.
Обратный алгоритм обхода
  1. Зайти в левое дерево,
  2. зайти в правое дерево,
  3. зайти в корень.
Общее количество вариантов алгоритма обхода вычисляется как размещение без повторений из 3 по 3 (т.е. как перестановка объектов) и оно равно $3! = 6$. Но так как нам не указан приоритет одного из деревьев над другим, то можно считать симметричные относительно выбора левого и правого деревьев алгоритмы обхода одинаковыми.
Реализация на Java бинарного дерева, а так же прямого и центрированного алгоритма обходов, доступна для скачивания. Кстати, мое бинарное дерево использует обобщения (generics) для контейнера данных. А вот алгоритмы обхода реализованы только для Integer.