Me As A Programmer



Reblogged from whatupdave
We live in a world operated by science and technology. We have also arranged things so that almost no one understands science and technology. This is a prescription for disaster. We might get away with it for a while, but sooner or later this combustible mixture of ignorance and power is going to blow up in our faces. Carl Sagan (via whatupdave)
Reblogged from fuckyeahmath

(Source: fuckyeahmath)

math.stackexchange.com & mathoverflow.net

Про http://mathoverflow.net узнал полгода назад, а про http://math.stackexchange.com месяц, тогда они мне показались слишком специализированными, а так как я со специальностью “математик-программист” не собирался быть математиком, то и бесполезными. Развивая свой поисковик http://uniquation.com я добавил эти сайты в индекс и посмотрел на них более пристально. Оказалось, что помимо специальных обсуждений, там есть и достаточно общие и интересные. Сейчас у меня отложено несколько обсуждений для чтения, чтобы разгрузить вкладки решил скинуть ссылки суда:

Counter-intuitive theorems that can be translated into everyday language

Why do functions in complex analysis behave so well? и How is C different than R2

Interesting results in algebraic geometry accessible to 3rd year undergraduates

Demystifying complex numbers

Your favorite surprising connections in Mathematics

Другие интересные ресурсы про математику

Это уже из вики Ramsey theory

Яндекс.Старт

Только что вернулся с Яндекс.Старта, до конца не понял, что это было, но это было здорово.

В начале напишу то, как я вижу цель мероприятия.

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

- Эй, босс, посмотри, что я придумал

Вне, инициатор - Яндекс, так как проект или идею нужно найти. Это мероприятие, мне кажется, является попыткой переложить инициализацию процесса на стартапы.

Для фильтрации заявок было заключено партнерство с компанией Startuppoint. Скорее всего, опять моя догадка, Startuppoint получил бы % от сделок с теми проектами, которые бы приобрел Яндекс. Таким образом, помимо фильтрации заявок, Startuppoint начал предлагать проектам участвовать в этой программе (чем больше предложить интересных проектов Яндексу, тем больше шансов получить деньги). Я очень благодарен ребятам из Startuppoint’а за то, что они предложили мне участвовать, организовывали встречи с нужными людьми в Я. и уговорили поехать на встречу. Единственным минусом такого подхода оказалось то, что ни я себя не чувствовал инициатором (мне предложили), ни Я. (ему прислали заявку). Это привело к нескольким неудобным моментам, например, я ожидал, что мне оплатят дорогу в Москву. Другим конфузом оказалось то, что я не смог ответить вопросы ребят из Я. о том, какие мне нужны ресурсы и какие у меня цели развития http://uniquation.ru (как, забыл сказать, это мой проект). Смысл в том, что я думал, что это они меня нашли, а значит у них есть цели, которые они хотят достичь с помощью моего проекта, а мои цели несущественны, поэтому вопроса о них я просто не ожидал. А услышав, не знал, что сказать, ведь очевидно, что цели должны быть релевантны Я., а у меня 100500 недетерминированных вариантов развития проекта=)

Итак, о мероприятии.

Еще до мероприятия я познакомился с ребятами из startuppoint, Виталием Акимовым (http://vitakimov.moikrug.ru/) и Евгенией Селивантьевой (http://www.facebook.com/profile.php?id=1524252230). Как раз они занимались фильтрацией и организацией взаимодействия с Яндексом.

После того, как я узнал о том, что мой проект прошел все этапы отбора, я сел делать презентацию (по сравнению с elevator pitch (30 сек), времени было навалом (5 минут)). В начале, я подготовил основные тезисы, затем слайды. В презентации делал упор на то, что сделано. Потом я написал все, что я должен сказать, не тезисы, а именно все: от слов приветствия до последнего слайда. Такая практика очень помогает устранить кашу в голове, а так же позволяет точно проверить временные рамки. Еще главное не врать, тогда не попадешь в неудобное положение. Когда презентация была закончена, была репетиция с Виталием и Евгенией по skype. Презентация доступна по адресу http://uniquation.ru/yandex/, позже будет доступно видео со встречи.

В Москву я добрался утренним сапсаном (из Питера). Внимание! Оказывается розетки есть только в первом и последим вагоне, поэтому все 4 часа я читал свою текст своей презентации и прокручивал её в голове. Да-да-да мой ноут почти не живет без батареи.

Встреча была назначена на 14, а поезд приехал в 11, поэтому я позвонил Ольге Никитушкиной (http://o-nikitushkina.moikrug.ru/), менеджеру по развитию бизнеса в Я., я с ней раньше переписывался, и напросился в Я. пораньше. Ольга оказалась милой девушкой, а так же с ней очень легко общаться. Она посадила меня в переговорочную и организовала чай с печеньями. В переговорочной был WiFi и розетки, поэтому я продолжил работать над uniquation. Позже пришел Григорий Бакунов (http://bakunov.moikrug.ru/) выпил колу и сказал, что после презентаций уже можно будет пообщаться нормально. 

Презентации проходили, кажется, в “7ом небе”. Среди слушателей я узнал Илью Сегаловича (http://segalovich.moikrug.ru/) и Аркадия Морейниса (http://moreynis.moikrug.ru/).

Первый проект был про почту, а я был вторым. Мне с этим повезло. Был очень большой контраст, я описывал то, что сделал, а они, то что планируют сделать.

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

Во-первых, это Ziwa (http://ziwa.org). Они занимаются тем, что анализируют и извлекают информацию из потока новостей. Они сказали, что в основе лежат хитрые методы, если это действительно хитрые методы, то это круто, мне интересны проекты, когда я не понимаю, как они работают. Докладчик упомянул, что систему быстро портировали на работу с английским и казахским языками, а сейчас идет работа над добавлением японского. А это ведь совсем разные группы языков! К тому же этот проект разрабатывается прежде всего 4fun, как и uniquation, а это напрямую влияет на качество. Кроме самого проекта, выделялись его создатели, они были старше, имели опыт работы над схожей системой и в них чувствовалось какая-то стать. Мне, кажется, они даже не продавать пришли, а поговорить.

Другой проект, который мне приглянулся, это EPythia (http://epythia.com). В отличии от Ziwa, он имеет продуманную бизнес составляющую и низкую эссенциальную сложность, но в нем нет вызова, хотя я бы, наверное, не увидет бы вызова в идеи бродкастить смски (twitter =). Суть сервиса в том, чтобы привязывать планы к месту, например, идешь мимо магазина, а телефон тебе - не забудь купить молока. Круто! Плюсом является то, что прототип готов, а так же сильная команда, в этот проект легко поверить.

Был еще проект, похожий на EPythia, - GooTime, я в них не верю, кажется, что у них одна только идея, но они очень веселые) Чего стоит только фраза “… подсовывать рекламу под видом важного дела”.

Из проектов был так же WebVisor (http://webvisor.ru/), он анализирует действия пользователей на сайте. Скучно, но нужный проект, хорошее дополнение к яндекс аналитике.

Кроме того, был GetLocker (http://www.getlocker.com/) Ничего не понятно, презентация оформлена в стиле сайтов GNU - черный текст на белом фоне. Докладчик - настоящий гик, во время презентации постоянно тер свой локоть. Кажется, система помогает определить, что тебе понравиться и показывает это. Может пригодиться в яндекс директе.

После презентации ко мне подошел Илья Сегалович и спросил знаю ли я сайт http://www.latexsearch.com/. Это оказалось очень кстати, я проводил мониторинг математических поисковых сайтов давно, а этот открылся в начале лета и я про него не знал. Оказалось, что мой поиск работает лучше, чем у ребят из Springer. Надо будет им написать.. Илья мне показался очень добрым и открытым человеком.

Помимо него, я поговорил с Львом Гершензоном (вертикальный поиск в яндексе) и еще один сотрудником Я., к сожалению, я не могу вспомнить имя. Понял, что мне нужно тренировать навык общения в калуарах. Ну почему, когда зашла о том, что все, что работает под нагрузкой а Я., должно писаться на C++, я сказал понятно и замолчал. Я бы мог спросить почему плюсы, почему не OCaml, например, или Go!, нет, я не жажду это знать, но почему я замолчал? Почему не поговорил с создателями Ziwa? Учиться, учиться, учиться..

После все разошлись, а я остался в Яндексе до 19:00 - у меня поезд в 23:40. Вечером пошел в ирландский паб, вкусно поел, взял виски и поболтал с барменом.

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

Не перестаю удивляться MySQL’ом

Похоже, не проходит и недели, как я натыкаюсь на очередную странность MySQL (ведет себя не так, как я ожидаю). На этот раз передо мной стаяла задача обеспечить уникальность значений колонки в базе, пусть, в этом примере это будут имена CS ученых.

CREATE TABLE guru (
    FullName TEXT
);

Что бы логика работы с базой была максимально прозрачной (нет лишних транзакций, запросов на проверку перед вставкой и так далее), я решил переложить заботу об уникальности на плечи движка MySQL, поэтому попытался использовать индекс UNIQUE:

CREATE UNIQUE INDEX guru_fullname ON guru(FullName);

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

CREATE UNIQUE INDEX guru_fullname ON guru(FullName(4));

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

INSERT INTO guru(FullName) VALUES ('Alan Kay'),('Alan Turing');

Оказались, что в индексе сохраняется только (!) префикс и с точки зрения MySQL Алан Тьюринг и Алан Кей один и тот же человек.

Мне кажется странной такая реализация, так как вряд ли задача обеспечить уникальность префиксов встречается чаще задачи обеспечить уникальность всего поля.

Reblogged from ebonymoon

Function Application unicode symbol

Сегодня работал над кодом паука для uniquation. Основная его задача - обходить определенный сайт и извлекать формулы в формате TeX со страниц. Часто они представлены значением атрибута alt картинки с формулой, например

<img class="tex" alt="\int_a^b \! f(x)\,dx = F(b) - F(a)\," src="..."/>

В первой версии паука, которую я использовал до этого, была допущена ошибка - она не обрабатывала случаи, когда некоторые символы закодированы через html entities. В новой версии я это исправил, поставив в соответствие каждой сущности команду tex, например

&omega; → \omega{}

Создавая эту таблицу, я наткнулся на очень интересную сущность, а именно Function Application (U+2061 или &#8289;).

Это невидимый знак пунктуации, который помогает различать “f(x+y)” как умножение “f” на “(x+y)” от ”f&#8289;(x+y)” как применения функции “f” к аргументу “(x+y)”.

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

P.S. Существуют так же невидимый знак пунктуации для умножения.

WTF, опять MySQL

Разработка моего дипломного проекта (uniquation.ru) ведется в windows. Тестирование проходит как в windows, используя и .net, и mono, так и в виртуальной машине debian lenny, используя mono. После того, как новая версия протестирована она выкладывается на production сервер от AWS под управлением debian lenny.

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

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

К сожалению, иногда случается так, что ошибки конфигурации являются следствием несовместимости разных версий используемого ПО. Недавно с такой ошибкой, вызванной моей ‘любимой’ MySQL, мне пришлось разбираться.

В текущий момент индекс поисковика не очень большой, поэтому я могу легко перенести его с одной машины на другую используя mysqldump. При попытке это сделать я получил странную ошибку. В конце концов дело оказалось в несовместимости между MySQL 5.0 (используется в lenny) и MySQL 5.1 (используется в windows). Понять в чем дело можно достаточно просто, рассмотрим результат mysqldump для следующей таблицы:

CREATE TABLE part (
  ID INT NOT NULL, 
  PRIMARY KEY(ID),
  Lambda TEXT NOT NULL,
  LambdaHash INT NOT NULL DEFAULT 0
) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE utf8_bin;

CREATE INDEX hash_lambda_index USING HASH ON part (LambdaHash, Lambda(30));

В 5.0:

CREATE TABLE `part` (
  `ID` int(11) NOT NULL,
  `Lambda` text collate utf8_bin NOT NULL,
  `LambdaHash` int(11) NOT NULL default '0',
  PRIMARY KEY  (`ID`),
  KEY `hash_lambda_index` USING HASH (`LambdaHash`,`Lambda`(30))
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

И в 5.1:

CREATE TABLE `part` (
  `ID` int(11) NOT NULL,
  `Lambda` text COLLATE utf8_bin NOT NULL,
  `LambdaHash` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`ID`),
  KEY `hash_lambda_index` (`LambdaHash`,`Lambda`(30)) USING HASH
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

Видно, что изменился формат описания индексов, и новая версия не поддерживается старой. При одновременной работе с MySQL 5.0 и MySQL 5.1 про эти отличия стоит помнить.

Этого не может быть, потому что этого не может быть никогда

Проглотил книгу Тома ДеМарко “Deadline. Роман об управлении проектами”. В форме романа автор очень увлекательно рассказывает основные принципы управления. Книга разделена на главы, в которых главный герой преодолевает возникающие перед ним трудности, а в конце каждой главы он записывает в своем дневнике то, чему научился. Эти записи являются резюме к главе. Иногда они относятся только к управлению проектами, но часто их можно применить и в других ситуациях. Ниже одна из них.

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

Конечно же я наступал на эти грабли. В .NET, как и в Java каждый объект имеет метод, который возвращает хеш код объекта. Для более простой индексации текстового поля в persistence хранилище я решил ввести дополнительное поле и хранить в нем хеш код строки. Основываясь на том, что для одинаковых строк (объектов) хеш код одинаковый и на том, что “qwerty”.GetHashCode() является инвариантом времени работы программы, я не задал себе во время следующие вопросы:

  1. Является ли ”qwerty”.GetHashCode() инвариантом между запусками программы?
  2. Является ли ”qwerty”.GetHashCode() инвариантом относительно разным версий .NET Framework и Mono?

Если бы я это сделал, то избежал бы досадной ошибок, так как ответы на эти вопросы - нет.

The default implementation of the GetHashCode method does not guarantee unique return values for different objects. Furthermore, the .NET Framework does not guarantee the default implementation of the GetHashCode method, and the value it returns will be the same between different versions of the .NET Framework. Consequently, the default implementation of this method must not be used as a unique object identifier for hashing purposes.

Большая свинья от MySql

В продолжение темы MySQL, начатую в одном из предыдущих постов - I promise to read the manuals before coding.

Рассмотрим пару нехитрых таблиц, представляющих посты в блог и комментарии к ним:

CREATE TABLE post(
  `ID` INT NOT NULL,
  `Text` TEXT NOT NULL,
  PRIMARY KEY(`ID`)
) ENGINE=INNODB;

CREATE TABLE comments(
  `ID` INT NOT NULL,
  `PostID` INT NOT NULL,
  `Text` TEXT NOT NULL,
  PRIMARY KEY(`ID`),
  FOREIGN KEY(`PostID`) REFERENCES post(ID)
) ENGINE=INNODB;

Конечно же я захотел записать объявление более компактно и опрятно, поэтому воспользовался inline декларацией:

CREATE TABLE post(
   `ID` INT NOT NULL PRIMARY KEY,
   `Text` TEXT NOT NULL
) ENGINE=INNODB; 

CREATE TABLE comments(
   `ID` INT NOT NULL PRIMARY KEY,
   `PostID` INT NOT NULL REFERENCES post(ID),
   `Text` TEXT NOT NULL
) ENGINE=INNODB;

Далее, я забыл об этом до того момента, как много месяцев спустя после 4 часов отладки пришел к выводу, что единственной возможной ошибкой приложения является противоречивость данных в базе. Тут мой мозг взорвался.. как данные могут быть противоречивы, если за их целостностью следит база данных? Ответ очевидный - база данных не следит, foreign key не был создан; после того как я это понял, раздался WTF.

Началось расследование на на одной странице документации по MySql обнаружил следующее:

The inline REFERENCES specifications where the references are defined as part of the column specification are silently ignored by InnoDB. InnoDB only accepts REFERENCES clauses defined as part of a separate FOREIGN KEY specification.

Свинья заключается не в том, что игнорируется, а в том, что silently.

Какие уроки я для себя вынес:

  • даже невероятные ошибки иногда случаются
  • я слишком времени трачу на отладку