вторник, 29 марта 2011 г.

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

Петров пришел во вторник на совещание. Ему там вынули мозг, разложили по блюдечкам и стали есть, причмокивая и вообще выражая всяческое одобрение. Начальник Петрова, Недозайцев, предусмотрительно раздал присутствующим десертные ложечки. И началось.
— Коллеги, — говорит Морковьева, — перед нашей организацией встала масштабная задача. Нам поступил на реализацию проект, в рамках которого нам требуется изобразить несколько красных линий. Вы готовы взвалить на себя эту задачу?
— Конечно, — говорит Недозайцев. Он директор, и всегда готов взвалить на себя проблему, которую придется нести кому-то из коллектива. Впрочем, он тут же уточняет: — Мы же это можем?
Начальник отдела рисования Сидоряхин торопливо кивает:
— Да, разумеется. Вот у нас как раз сидит Петров, он наш лучший специалист в области рисования красных линий. Мы его специально пригласили на совещание, чтобы он высказал свое компетентное мнение.
— Очень приятно, — говорит Морковьева. — Ну, меня вы все знаете. А это — Леночка, она специалист по дизайну в нашей организации.
Леночка покрывается краской и смущенно улыбается. Она недавно закончила экономический, и к дизайну имеет такое же отношение, как утконос к проектированию дирижаблей.
— Так вот, — говорит Морковьева. — Нам нужно нарисовать семь красных линий. Все они должны быть строго перпендикулярны, и кроме того, некоторые нужно нарисовать зеленым цветом, а еще некоторые — прозрачным. Как вы считаете, это реально?
— Нет, — говорит Петров.
— Давайте не будем торопиться с ответом, Петров, — говорит Сидоряхин. — Задача поставлена, и ее нужно решить. Вы же профессионал, Петров. Не давайте нам повода считать, что вы не профессионал.
— Видите ли, — объясняет Петров, — термин «красная линия» подразумевает, что цвет линии — красный. Нарисовать красную линию зеленым цветом не то, чтобы невозможно, но очень близко к невозможному…
— Петров, ну что значит «невозможно»? — спрашивает Сидоряхин.
— Я просто обрисовываю ситуацию. Возможно, есть люди, страдающие дальтонизмом, для которых действительно не будет иметь значения цвет линии, но я не уверен, что целевая аудитория вашего проекта состоит исключительно из таких людей.
— То есть, в принципе, это возможно, мы правильно вас понимаем, Петров? — спрашивает Морковьева.
Петров осознает, что переборщил с образностью.
— Скажем проще, — говорит он. — Линию, как таковую, можно нарисовать совершенно любым цветом. Но чтобы получилась красная линия, следует использовать только красный цвет.
— Петров, вы нас не путайте, пожалуйста. Только что вы говорили, что это возможно.
Петров молча проклинает свою болтливость.
— Нет, вы неправильно меня поняли. Я хотел лишь сказать, что в некоторых, крайне редких ситуациях, цвет линии не будет иметь значения, но даже и тогда — линия все равно не будет красной. Понимаете, она красной не будет! Она будет зеленой. А вам нужна красная.
Наступает непродолжительное молчание, в котором отчетливо слышится тихое напряженное гудение синапсов.
— А что если, — осененный идеей, произносит Недозайцев, — нарисовать их синим цветом?
— Все равно не получится, — качает головой Петров. — Если нарисовать синим — получатся синие линии.
Опять молчание. На этот раз его прерывает сам Петров.
— И я еще не понял… Что вы имели в виду, когда говорили о линиях прозрачного цвета?
Морковьева смотрит на него снисходительно, как добрая учительница на отстающего ученика.
— Ну, как вам объяснить?.. Петров, вы разве не знаете, что такое «прозрачный»?
— Знаю.
— И что такое «красная линия», надеюсь, вам тоже не надо объяснять?
— Нет, не надо.
— Ну вот. Вы нарисуйте нам красные линии прозрачным цветом.
Петров на секунду замирает, обдумывая ситуацию.
— И как должен выглядеть результат, будьте добры, опишите пожалуйста? Как вы себе это представляете?
— Ну-у-у, Петро-о-ов! — говорит Сидоряхин. — Ну давайте не будем… У нас что, детский сад? Кто здесь специалист по красным линиям, Морковьева или вы?
— Я просто пытаюсь прояснить для себя детали задания…
— Ну, а что тут непонятного-то?.. — встревает в разговор Недозайцев. — Вы же знаете, что такое красная линия?
— Да, но…
— И что такое «прозрачный», вам тоже ясно?
— Разумеется, но…
— Так что вам объяснять-то? Петров, ну давайте не будем опускаться до непродуктивных споров. Задача поставлена, задача ясная и четкая. Если у вас есть конкретные вопросы, так задавайте.
— Вы же профессионал, — добавляет Сидоряхин.
— Ладно, — сдается Петров. — Бог с ним, с цветом. Но у вас там еще что-то с перпендикулярностью?..
— Да, — с готовностью подтверждает Морковьева. — Семь линий, все строго перпендикулярны.
— Перпендикулярны чему? — уточняет Петров.
Морковьева начинает просматривать свои бумаги.
— Э-э-э, — говорит она наконец. — Ну, как бы… Всему. Между собой. Ну, или как там… Я не знаю. Я думала, это вы знаете, какие бывают перпендикулярные линии, — наконец находится она.
— Да конечно знает, — взмахивает руками Сидоряхин. — Профессионалы мы тут, или не профессионалы?..
— Перпендикулярны могут быть две линии, — терпеливо объясняет Петров. — Все семь одновременно не могут быть перпендикулярными по отношению друг к другу. Это геометрия, 6 класс.
Морковьева встряхивает головой, отгоняя замаячивший призрак давно забытого школьного образования. Недозайцев хлопает ладонью по столу:
— Петров, давайте без вот этого: «6 класс, 6 класс». Давайте будем взаимно вежливы. Не будем делать намеков и скатываться до оскорблений. Давайте поддерживать конструктивный диалог. Здесь же не идиоты собрались.
— Я тоже так считаю, — говорит Сидоряхин.
Петров придвигает к себе листок бумаги.
— Хорошо, — говорит он. — Давайте, я вам нарисую. Вот линия. Так?
Морковьева утвердительно кивает головой.
— Рисуем другую… — говорит Петров. — Она перпендикулярна первой?
— Ну-у…
— Да, она перпендикулярна.
— Ну вот видите! — радостно восклицает Морковьева.
— Подождите, это еще не все. Теперь рисуем третью… Она перпендикулярна первой линии?..
Вдумчивое молчание. Не дождавшись ответа, Петров отвечает сам:
— Да, первой линии она перпендикулярна. Но со второй линией она не пересекается. Со второй линией они параллельны.
Наступает тишина. Потом Морковьева встает со своего места и, обогнув стол, заходит Петрову с тыла, заглядывая ему через плечо.
— Ну… — неуверенно произносит она. — Наверное, да.
— Вот в этом и дело, — говорит Петров, стремясь закрепить достигнутый успех. — Пока линий две, они могут быть перпендикулярны. Как только их становится больше…
— А можно мне ручку? — просит Морковьева.
Петров отдает ручку. Морковьева осторожно проводит несколько неуверенных линий.
— А если так?..
Петров вздыхает.
— Это называется треугольник. Нет, это не перпендикулярные линии. К тому же их три, а не семь.
Морковьева поджимает губы.
— А почему они синие? — вдруг спрашивает Недозайцев.
— Да, кстати, — поддерживает Сидоряхин. — Сам хотел спросить.
Петров несколько раз моргает, разглядывая рисунок.
— У меня ручка синяя, — наконец говорит он. — Я же просто чтобы продемонстрировать…
— Ну, так может, в этом и дело? — нетерпеливо перебивает его Недозайцев тоном человека, который только что разобрался в сложной концепции и спешит поделиться ею с окружающими, пока мысль не потеряна. — У вас линии синие. Вы нарисуйте красные, и давайте посмотрим, что получится.
— Получится то же самое, — уверенно говорит Петров.
— Ну, как то же самое? — говорит Недозайцев. — Как вы можете быть уверены, если вы даже не попробовали? Вы нарисуйте красные, и посмотрим.
— У меня нет красной ручки с собой, — признается Петров. — Но я могу совершенно…
— А что же вы не подготовились, — укоризненно говорит Сидоряхин. — Знали же, что будет собрание…
— Я абсолютно точно могу вам сказать, — в отчаянии говорит Петров, — что красным цветом получится точно то же самое.
— Вы же сами нам в прошлый раз говорили, — парирует Сидоряхин, — что рисовать красные линии нужно красным цветом. Вот, я записал себе даже. А сами рисуете их синей ручкой. Это что, красные линии по-вашему?
— Кстати, да, — замечает Недозайцев. — Я же еще спрашивал вас про синий цвет. Что вы мне ответили?
Петрова внезапно спасает Леночка, с интересом изучающая его рисунок со своего места.
— Мне кажется, я понимаю, — говорит она. — Вы же сейчас не о цвете говорите, да? Это у вас про вот эту, как вы ее называете? Перпер-чего-то-там?
— Перпендикулярность линий, да, — благодарно отзывается Петров. — Она с цветом линий никак не связана.
— Все, вы меня запутали окончательно, — говорит Недозайцев, переводя взгляд с одного участника собрания на другого. — Так у нас с чем проблемы? С цветом или с перпендикулярностью?
Морковьева издает растерянные звуки и качает головой. Она тоже запуталась.
— И с тем, и с другим, — тихо говорит Петров.
— Я ничего не могу понять, — говорит Недозайцев, разглядывая свои сцепленные в замок пальцы. — Вот есть задача. Нужно всего-то семь красных линий. Я понимаю, их было бы двадцать!.. Но тут-то всего семь. Задача простая. Наши заказчики хотят семь перпендикулярных линий. Верно?
Морковьева кивает.
— И Сидоряхин вот тоже не видит проблемы, — говорит Недозайцев. — Я прав, Сидоряхин?.. Ну вот. Так что нам мешает выполнить задачу?
— Геометрия, — со вздохом говорит Петров.
— Ну, вы просто не обращайте на нее внимания, вот и все! — произносит Морковьева.
Петров молчит, собираясь с мыслями. В его мозгу рождаются одна за другой красочные метафоры, которые позволили бы донести до окружающих сюрреализм происходящего, но как назло, все они, облекаясь в слова, начинаются неизменно словом «Блять!», совершенно неуместным в рамках деловой беседы.
Устав ждать ответа, Недозайцев произносит:
— Петров, вы ответьте просто — вы можете сделать или вы не можете? Я понимаю, что вы узкий специалист и не видите общей картины. Но это же несложно — нарисовать какие-то семь линий? Обсуждаем уже два часа какую-то ерунду, никак не можем прийти к решению.
— Да, — говорит Сидоряхин. — Вы вот только критикуете и говорите: «Невозможно! Невозможно!» Вы предложите нам свое решение проблемы! А то критиковать и дурак может, простите за выражение. Вы же профессионал!
Петров устало изрекает:
— Хорошо. Давайте я нарисую вам две гарантированно перпендикулярные красные линии, а остальные — прозрачным цветом. Они будут прозрачны, и их не будет видно, но я их нарисую. Вас это устроит?
— Нас это устроит? — оборачивается Морковьева к Леночке. — Да, нас устроит.
— Только еще хотя бы пару — зеленым цветом, — добавляет Леночка. — И еще у меня такой вопрос, можно?
— Да, — мертвым голосом разрешает Петров.
— Можно одну линию изобразить в виде котенка?
Петров молчит несколько секунд, а потом переспрашивает:
— Что?
— Ну, в виде котенка. Котеночка. Нашим пользователям нравятся зверюшки. Было бы очень здорово…
— Нет, — говорит Петров.
— А почему?
— Нет, я конечно могу нарисовать вам кота. Я не художник, но могу попытаться. Только это будет уже не линия. Это будет кот. Линия и кот — разные вещи.
— Котенок, — уточняет Морковьева. — Не кот, а котенок, такой маленький, симпатичный. Коты, они…
— Да все равно, — качает головой Петров.
— Совсем никак, да?.. — разочарованно спрашивает Леночка.
— Петров, вы хоть дослушали бы до конца, — раздраженно говорит Недозайцев. — Не дослушали, а уже говорите «Нет».
— Я понял мысль, — не поднимая взгляда от стола, говорит Петров. — Нарисовать линию в виде котенка невозможно.
— Ну и не надо тогда, — разрешает Леночка. — А птичку тоже не получится?
Петров молча поднимает на нее взгляд и Леночка все понимает.
— Ну и не надо тогда, — снова повторяет она.
Недозайцев хлопает ладонью по столу.
— Так на чем мы остановились? Что мы делаем?
— Семь красных линий, — говорит Морковьева. — Две красным цветом, и две зеленым, и остальные прозрачным. Да? Я же правильно поняла?
— Да, — подтверждает Сидоряхин прежде, чем Петров успевает открыть рот.
Недозайцев удовлетворенно кивает.
— Вот и отлично… Ну, тогда все, коллеги?.. Расходимся?.. Еще вопросы есть?..
— Ой, — вспоминает Леночка. — У нас еще есть красный воздушный шарик! Скажите, вы можете его надуть?
— Да, кстати, — говорит Морковьева. — Давайте это тоже сразу обсудим, чтобы два раза не собираться.
— Петров, — поворачивается Недозайцев к Петрову. — Мы это можем?
— А какое отношение ко мне имеет шарик? — удивленно спрашивает Петров.
— Он красный, — поясняет Леночка.
Петров тупо молчит, подрагивая кончиками пальцев.
— Петров, — нервно переспрашивает Недозайцев. — Так вы это можете или не можете? Простой же вопрос.
— Ну, — осторожно говорит Петров, — в принципе, я конечно могу, но…
— Хорошо, — кивает Недозайцев. — Съездите к ним, надуйте. Командировочные, если потребуется, выпишем.
— Завтра можно? — спрашивает Морковьева.
— Конечно, — отвечает Недозайцев. — Я думаю, проблем не будет… Ну, теперь у нас все?.. Отлично. Продуктивно поработали… Всем спасибо и до свидания!
Петров несколько раз моргает, чтобы вернуться в объективную реальность, потом встает и медленно бредет к выходу. У самого выхода Леночка догоняет его.
— А можно еще вас попросить? — краснея, говорит Леночка. — Вы когда шарик будете надувать… Вы можете надуть его в форме котенка?..
Петров вздыхает.
— Я все могу, — говорит он. — Я могу абсолютно все. Я профессионал.
Отсюда.

понедельник, 21 марта 2011 г.

Работа с XML в SQL запросах

В современных проектах XML встречается довольно часто. Несмотря на избыточность, этот язык разметки данных стал очень популярным из-за своей универсальности. Если нам нужно распарсить какой-то конфиг файл на XML, то практически в каждом языке программирования есть удобная библиотека. В C++ мне нравится Xerces-C++ своей кроссплатформенностью, однако, готов согласиться, если кто-то скажет, что это, местами, не самый удобный инструмент.

Сейчас я хочу рассмотреть сценарий работы с данными в виде XML, которые могут храниться в базе данных. Современные серверы БД поддерживают, в разной степени, тип данных XML. Я буду приводить примеры в MySql, т. к. под рукой в данный момент есть только он. Например, у нас есть таблица xmltest:
CREATE TABLE `xmltest` (
  `conf` varchar(500) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
Далее, будем считать, что в поле conf хранятся данные каждого пользователя системы следующего вида:
<Root>
 <CoreOptions>
  <Option type="str" value="test" />
 </CoreOptions>
 <UserOptions>
  <Favorites>
    <Page id="1">http://www.codeatcpp.com</Page>
    <Page id="2">http://www.google.com</Page>
    <Page id="3">http://www.yandex.ru</Page>
    <Page id="4">http://www.stackoverflow.com</Page>
  </Favorites>
 </UserOptions>
</Root>
Итак, можно загрузить все данные пользователей и каждый конфиг разобрать своим любимым парсером XML, но что, если мы всего лишь хотим посмотреть сколько у каждого пользователя любимых сайтов? Это можно узнать за один SQL запрос используя язык XQuery+XPath:
SELECT ExtractValue(conf, 'count(/Root[1]/UserOptions[1]/Favorites[1]/Page)') 
FROM `xmltest`
Этот запрос для каждого пользователя выдаст количество элементов Page в поле conf. Поскольку в XML элементы не уникальны и могут повторятся, то указываем в квадратных скобках, что нужен первый по порядку элемент. Если это не указать, то запрос вернет набор элементов, как в случае с Page.
Если мы хотим получить атрибут элемента, то показываем это символом @:
SELECT ExtractValue(conf, '/Root[1]/UserOptions[1]/Favorites[1]/Page[1]/@id') 
FROM `xmltest`
Такой запрос выдаст идентификатор первой страницы для каждого пользователя.

Стоит отметить, что для разных реализаций SQL синтаксис запроса будет отличаться, например, в MS SQL Server последний запрос будет выглядеть так:
SELECT conf.value('/Root[1]/UserOptions[1]/Favorites[1]/Page[1]/@id', 'int')
FROM xmltest

Поля XML можно не только выводить, но и использовать в условиях поиска, например:
SELECT ExtractValue(conf, '/Root[1]/CoreOptions[1]/Option[1]/@value') 
FROM `xmltest` 
WHERE
  ExtractValue(conf, 'count(/Root[1]/UserOptions[1]/Favorites[1]/Page)') > 0
Такой запрос выдаст параметр Option из раздела CoreOptions для всех пользователей, у которых есть закладки.

В такой маленькой статье невозможно рассмотреть все возможности работы с XML в SQL запросах, поэтому даю список ресурсов, с которыми стоит познакомиться:
  1. Методы типа данных XML в MS SQL Server.
  2. XML функции сервера MySQL.
  3. xpathtester.com — сайт, где можно проверить свои XPath запросы.
  4. Вопросы и ответы по использованию XML в SQL запросах.

четверг, 10 марта 2011 г.

Visual Studio 2010 SP1

Наконец-то вышел релиз SP1 для Visual Studio 2010. До этого приходилось пользоваться бэтой из-за страшных багов, вроде утечки памяти при использовании std::vector<std::string>. При этом Intel Parallel Studio не хотела работать с бэтой и суппорт Интела не хотел ничего делать... теперь им не отмазаться.

В данном выпуске те же новшества, что были в SP1 Beta: Direct2D в MFC и поддержка Intel AVX инструкций. Почитать про другие плюшки, а также посмотреть список исправленных багов, можно тут. Скачать SP1 можно тут, а подписчики MSDN могут качать из MSDN, чем стоит воспользоваться, т. к. ссылка очень медленная (хотя, может, только у меня).

Если у вас был установлен отдельно Windows SDK для Windows 7, то стоит почитать эту статью, т.к. при установке сервис пака могут быть проблемы.

вторник, 1 марта 2011 г.

Regex is simple

Регулярные выражения — очень удобное средство для валидации, поиска и замены строк. Пользоваться ими не сложно, хотя, ходят упорные слухи, что инструмент сложный и больше путает, чем помогает. Но, волков бояться — в лес не ходить, поэтому рекомендую к использованию. Например, простейший пример с использованием Boost.Regex будет выглядеть так:
// regex_test.cpp
#include <iostream>
#include <boost/regex.hpp>

int main()
{
  // правило поиска
  boost::wregex exrp( L"(https?:\\/\\/[\\w\\-_]+(?>\\.[\\w\\-_]+)+"
    L"(?>[\\w\\-\\.,@?^=%&:/~\\+#]*[\\w\\-\\@?^=%&/~\\+#]))" );
  boost::match_results<std::wstring::const_iterator> what;
  // входная строка
  std::wstring input = L"My homepage is http://jia3ep.blogspot.com";
  // поиск
  if( regex_search( input,  what, exrp ) ) {
    // ога, нашли что-то
    std::wstring found( what[1].first, what[1].second );
    // выводим
    std::wcout << found << std::endl;    
  }

  return 0;
}

// в Boost немного вещей требуют линковки и Regex — одна из них,
// поэтому в Ubuntu компилим этот пример так:
// g++ -lboost_regex regex_test.cpp
Данный код найдет и выдаст Веб-адрес в заданной строке. Как сравочник синтаксиса можно использовать MSDN (мне тут нравится табличка, но аналогов в сети полно), а поискать готовые выражения можно, например, тут (правда, по ссылке встречаются и неработающие примеры).

Бывают, конечно, примеры в жизни и посложнее, чем приведенный. Например, вот более 6Кб кода для проверки email адреса соответствию стандарту RFC822. Но, к счастью, этот пример уже написан и его можно взять и скопировать.