пятница, 31 октября 2008 г.

Вообщем, все плохо...

Мир тонет в информации:

За 2006 год в мире создано около 161 млрд. гигабайт (161 экзабайт) цифровой информации. Такие данные обнародовали эксперты аналитической компании "IDC". 
Как передает радио "Свобода", при подсчетах учитывались данные всех фотографий, видеороликов, сообщений электронной почты, Интернет-сайтов, мгновенных сообщений, телефонных звонков и всех других цифровых источников информации на нашей планете. Предполагается, что каждый цифровой файл воспроизводился в среднем три раза. Для наглядности специалисты сравнили объем созданной цифровой информации с 12 книжными стеллажами, каждый из которых имеет длину, равную расстоянию от Земли до Солнца.
Согласно прогнозам, объем информации в 2010 вырастет более чем в 6 раз и достигнет 988 экзабайт. Одной из причин очень быстрого роста информации специалисты называют распространение камер слежения, а также требования к хранению множества корпоративных данных. 
Представляете насколько поток информации увеличился к 2008 году?

Вот я все rss-ки читаю через Google Reader. Если по какой-либо причине я им не пользуюсь пару дней, то там набирается порядка 800-900 сообщений. Прочитать это физически невозможно: пока читаешь старые - приходят новые...

И вот смотрю я на записи с PDC 2008 и удивляюсь - где же хоть что-нибудь, что поможет справиться с потоками информации именно человеку, а не машинам?

Я хочу, чтобы все электронные книги, что я читаю, были сосредоточены в одном хранилище (с соответствующими требованиями к каталогизации/поиску/добавлению) так, как это сделано с музыкой в том же Windows Media Player (не без проблем, конечно - но хоть так).

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

Причем речь не идет о тупом информировании - как это делается сейчас через почтовые рассылки или rss. Нет, нет и нет! Вот представьте, что вы подписались на rss-рассылку, анпример, какого-нибудь музыкального магазина. В день в будете получать несколько десятков (если не сотен) сообщений о поступлениях новых альбомов. И когда это все читать? А если учесть, что многих интересуют только пара десятков любимых групп, а остальных они не слушают? Или наоборот - как у меня - у человека есть коллекция музыки в 2-3 тысячи исполнителей/групп, все имена/названия которых запомнить в принципе невозможно?

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

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

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

Я хочу... Я хочу... Я хочу... Да много чего еще. И где это все? Ведь никаких технических проблем реализовать это нет! Веб-сервисы, локальная БД, и немного фантазии - и всё. И никаких проблем. И я не буду тратить половину жизни на всякую фигню.

А вместо этого Microsoft мне предлагает отказоустойчивыю платформу под софт. Да нафиг не надо! Я маленький программист - у меня нет таких задач, для которых это имело бы смысл.

Вообщем, такие дела...


Ну а поскольку пока что ничего подобного нет, начем с малого.

Предлагаю разарботать читалку rss-рассылок с автоматической категоризацией новостей. Принципиальных сложностей никаких нет, готов взяться за алгоритм категоризации - тем более, что 80% его можно взять из переводчика.

вторник, 28 октября 2008 г.

Visual Studio 2010 and .NET Framework 4.0 Community Technology Preview (CTP)

PDC 2008 дает свои плоды: Visual Studio 2010 and .NET Framework 4.0 Community Technology Preview (CTP) уже доступны для скачивания. Раздают в виде образа виртуальной машины. Правда некоторые требования меня несколько смущают - в частности "Minimum 75 GB available HDD space" :)


P.S.: Кстати, трансляции с конференции можно скачать тут (день №1) и тут (день №2).

суббота, 25 октября 2008 г.

Вот такие дела...

Сегодня нашел "лишние" 100 Гб свободного места... Некоторое время назад обратил внимание что как-то маловато места стало на одном из разделов. При том, что на разделе 200 Гб, свободного места порядка 40. Ну на него пишут разные программы типа utorrent так что грешил на них.

А сегодня решил его дефрагментировать и обнаружил 100 гигабайтный файл в "System Volume Information", причем еще и залоченный и разбитый на несколько десятков тысяч фрагментов.

Ну что это за папка я знаю. По привычке полез в Мой компьютер->Свойства->Advances System Settings->SystemRestore и что бы вы думали? Ну кто бы что не подумал - а такой вкладки у меня в Windows Server 2008 почему-то нет. Мистика.

Так собственно о чем я? Если кто-нибудь столкнется с подобной ситуацией, сообщаю, что изменить размер этой папки можно из командной строки:

vssadmin resize shadowstorage /for=H: /on=H: /maxsize=2Gb


Примечание: пишут, что минимальный размер папки для Vista должен быть 500 Мб.

вторник, 21 октября 2008 г.

И снова баги...

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

А дело было так.

Правлю я там там что-то в переводчике связанное с интерфейсом взаимодействия между GUI и плагинами и в процессе тестирования вижу странное.

Берем предложение и переводим, получаем два варианта перевода. Все как ожидалось:


А теперь берем и делаем второй вариант перевода предложения основным (т.е. первым в списке переводов):


Упс! А текст-то не тот!

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

Два часа я искал проблему. Я выделил и сравнил логи перевода до и после сортировки - они совпали. Я пересмотрел алгоритм перевода (вызова модулей). Я вспомнил как работает алгоритм склонения слов и пролазил его весь под отладчиком. Я даже переписал алгоритм сортировки! Я сделал еще целую кучу действий - и ничего. До некоторого момента всё нормально, а потом - упс! - и всё плохо.

И совершенно случайно я все-таки нашел в чем была проблема... Вы не поверите.

Итак, где-то в классе TextTranslator (отвечающем за перевод текста) есть такой код:

            for (k = 0; k < ersent.rus.Count;k++ )
                RunProccessRVariantQueue(ersent.rus, par, sent, k);

... который в итоге вызывает такую функцию:

        static void RunProccessRVariantQueue(List<trstr> snt, int par, int sent, int variant)
        {
            for (int i = 0; i < ModulesFactory.Instance.rvar_proccess_queue.Count; i++)
            {
                ((IRStrVariantProcessor) ModulesFactory.Instance.rvar_proccess_queue[i].obj).ProcessRStringVariant(snt, variant, par, sent);
            }
        }

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

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


            if(variant != 0) return;

... что по идее должно было заставлять выполнять сортировку один раз. И оно даже работало. Но с одним интересным побочным эффектом.

Не вдаваясь в детали, скажу, что цепочка вызовов модулей обрабатывающих эти самые варианты перевода предложения состоит из двух элементов: модуля склоения и модуля сортировки. Что же происходило и почему в итоге возникала ошибка? Рассмотрим пошагово работу алгоритма:

Итерация №1
Вызов модуля склонения для варианта №0
Вызов сортировкщика. В сортировщике стоит указние, что надо вариант с нормером 1 поставить в начало списка (т.е. сделать его номером 0).

Итерация №2
Вызов модуля склонения для варианта №1
Сортировщик ничего не делает, т.к. вариант !=0

Так вот, на итерации №1 мы имеем что? Правильно! Тот же самый вариант, что и на итерации №0, т.к. сортировщик свое дело сделал :) В результате, второй вариант перевода не склонялся.

Решением проблемы оказалась замена приведенного выше условия на следующее:

            if(variant!=Count-1) return;

Вот так вот... Два часа на поиск одной единственной строчки...

понедельник, 20 октября 2008 г.

Запись и чтение из файлов Excel при отсутствии установленного Excel

Получил на днях очередной бюллетень-молния Technet от Microsoft (кстати, интересная штука, кто еще не подписан - рекомендую. Такой же бюллетень есть и для MSDN). И были там две интересных ссылки: How Can I Write to Excel Without Using Excel? и How Can I Read from Excel Without Using Excel?

Собственно, идея очень простая - надо открыть OleDb-соединение и вперед, с песней :)

Берем вот такой .xls-файл:


Чтение данных делаем так:

            string fileName = @"test.xls";
            string sheetName = "Sheet$";
            string connString="Provider=Microsoft.Jet.OLEDB.4.0; Data Source = " +
                                       fileName +
                                       "; Extended Properties=Excel 8.0";
            string query = "Select * from [" + sheetName + "]";

            OleDbConnection conn = new OleDbConnection(connString);
            OleDbCommand cmd=new OleDbCommand(query, conn);
            conn.Open();

            OleDbDataReader reader = cmd.ExecuteReader();

            textBox1.Text = "";

            while (reader.Read())
            {
                textBox1.Text += System.Environment.NewLine;
                textBox1.Text += reader.GetString(0) + " ("+reader.FieldCount+")";
            }

            reader.Close();
            conn.Close();

Результат будет примерно таким:

А запись данных так:

            string fileName = @"test.xls";
            string sheetName = "Sheet$";
            string connString="Provider=Microsoft.Jet.OLEDB.4.0; Data Source = " +
                                       fileName +
                                       "; Extended Properties=Excel 8.0";
            string wquery = "Insert into [Sheet$] (Name,Data) Values (?,?)";

            OleDbConnection conn = new OleDbConnection(connString);
            OleDbCommand wcmd=new OleDbCommand(wquery, conn);
            conn.Open();

            OleDbParameter namep = wcmd.Parameters.Add("Name", OleDbType.VarChar, 80);
            OleDbParameter datap = wcmd.Parameters.Add("Data", OleDbType.UnsignedInt, 16);

            namep.Value = "aaa";
            datap.Value = 15;

            wcmd.ExecuteNonQuery();;

            conn.Close();

Результат, соответственно, такой:

Вот так вот всё просто. Я надеюсь, что найти где это можно применить сможете сами :)