четверг, 19 июня 2014 г.

Доклад с Moscow Data Science Meetup

Публикую доклад, с которым выступал на  Moscow Data Science Meetup.
Затронул темы того, как можно применить математическую статистику в задачах web-аналитики.
Первая часть доклада посвящена предсказанию значений метрик в будущем. Объясняю что такое модель SARIMA и как ее использовать.
Во второй части говорю о том, как правильно применять статистические тесты и где их использовать нельзя.

пятница, 18 марта 2011 г.

Imagine Cup в Москве



Завтра в Москве пройдет региональный этап международного конкурса Imagine Cup 2011. В этом году в нем будет участвовать целых две команды от моего вуза (а еще точнее от моего факультета).
Собственно вот ссылка на хабр: http://habrahabr.ru/company/microsoft/blog/115284/

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

вторник, 9 ноября 2010 г.

Редактор графов на C#



В ходе написания одного из курсовиков, мной был создан визуальный редактор графов, исходниками которого я и хочу поделиться.
До начала работы я провел допрос гугла, с целью найти нечто подобное в уже готовом виде. Но, к сожалению, ничего приемлемого на .Net не нашел. И это притом, что на C++ или Java таких вещей множество. Своим приложением я, надеюсь, смогу устранить данный пробел.

Итак, моя библиотека состоит из двух частей: GraphModel и VisualGraphModel.

GraphModel представляет собой простейшую реализацию графа. Позволяет добавлять и удалять вершины и дуги, а также выполнять такие операции, как поиск вершины по имени, нахождение минимального пути между 2 вершинами и т.д. Полностью все доступные операции вы сможете найти в интерфейсе IGraph. Думаю, там все будет понятно.

VisualGraphModel - библиотека, включающая 2 компонента для Windows Forms: VisualGraphComponent и EditGraph. Я рекомендую пользоваться вторым, т.к. это уже готовое решение. VisualGraphComponent - заготовка, представляющее поле для отрисовки фигур.

Сама библиотека реализует все возможности предыдущей + добавляет ряд функций для рисования фигур и взаимодействием с пользователем.

Вот общая схема классов:



Реакция на действия пользователя реализована через механизм посредника и состояний. (Состояния устанавливаются как посредником, так и другими состояниями).

Сама отрисовка происходит через GDI+.

Для использования компонента в своем приложении следует сделать так:

Подключите библиотеки GraphModel.dll и VisualGraphModel.dll

Подключите след. пространства имен:

using org.zavyalov.VisualGraphModel.Abstract;
using org.zavyalov.VisualGraphModel.Concrete;
using org.zavyalov.VisualGraphModel.Coordinates;
using org.zavyalov.GraphModel.Concrete;


Добавьте компонент EditGraph в свой проект.

Далее в классе формы советую определить два объекта

VisualGraph vg ;
Mediator mediator;


В конструкторе формы пропишите след. код:

vg = this.editGraph1.vg;
mediator = this.editGraph1.mediator;


Где editGraph1 - имя компонента.

Все, компонент может использоваться.

В частности можно получить матрицу смежности:

ConnectivityMatrix connectMatrix = vg.GetConnectivityMatrix();


Сам объект класс ConnectivityMatrix включает 2 поля: int[,] matrix - саму матрицу и Vertex[] vertexs - массив вершин, с помощью которого можно определить индекс той или иной вершины в матрице смежности.

Редактировать граф можно также и из кода:

VisualVertex a1 = VisualVertex.Create();
a1.name = "V1";
CoordinatesVertex c = new CoordinatesVertex();
c.from = new PointF(100, 100);
a1.setCoordinates(c);
vg.AddVertex(a1);

VisualVertex a2 = VisualVertex.Create();
a2.name = "V2";
CoordinatesVertex c2 = new CoordinatesVertex();
c2.from = new PointF(130, 30);
a2.setCoordinates(c2);
vg.AddVertex(a2);

VisualPair p1 = VisualPair.Create(a1, a2);
p1.value = 13;
vg.AddPair(p1);


Результат будет таким:


Надеюсь, что мое приложение поможет вам сэкономить приличное количество времени.

А вот и сама библиотека, вместе с примером.

среда, 28 июля 2010 г.

ASP.NET MVC 2. Ошибка компиляции, или почему иногда не стоит надеяться на отладчик

Вчера во время компиляции моего проекта (ASP.NET MVC 2)возникла ошибка компиляции, а именно
CS0115: 'ASP.views_user_index_aspx.GetTypeHashCode()': не найден метод, пригодный для переопределения
Честно признаться, ошибки подобные этой происходят довольно часто (вначале, я думал именно так) и легко отлавливаются либо цепким взглядом разработчика, либо отладчиком.



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

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

Попробовал создать новый проект и постепенно вносить в него мой код. Успешно подключил IoC (при отладке вылезало исключение именно от него, но это, конечно, просто внешние проявления), скопировал библиотеку, реализующую репозиторий для работы с БД, скопировал код из контроллеров в новый контроллер по умолчанию. Пока все работает. Переименовал класс и файл из HomeController в UserController. Возникла ошибка, похожая на изначальную.

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

В конечном счете, решил создать новое представление для метода, на который жаловался компилятор (ASP.views_user_index_aspx.GetTypeHashCode()')
И тут я заметил, что в этом представлении есть одно отличие (за исключением того, что он пустой, конечно) от моего рабочего (т.е. нерабочего варианта)

В новом представлении было так

Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage"

А в старом вот так:

Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewUserControl"

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

четверг, 22 июля 2010 г.

Настройка шаблона IoC в ASP.NET MVC с использованием Castle Windsor

На днях у меня возникла необходимость настроить шаблон инверсии управления(IoC) в ASP.NET MVC 2. В первой версии с этим никаких проблем не возникло, поскольку в сети есть куча информации на данную тему (хотя бы книга Стивена Сандерсона). Но во второй версии, которая и идет в VS 2010, изменился интерфейс IControllerFactory, вследствие чего реализация собственного класса фабрики контроллеров требует изменение старого кода. Покопавшись в сети, я удивился тому, как мало информации на сей счет. В результате пришлось около часа просматривать забугорные форумы (в русскоязычных источниках, конечно, ничего не было). Даже на официальных сайтах Castle Windsor и ASP.NET про это ни слова (хотя, может, я и google искать не умеем). В результате наткнулся на блог Ali Bastani и его статью "Setting Up IoC in ASP.NET MVC using Castle Windsor". Сама статья почти полностью основана на книге Стивена Сандерсона "Pro ASP.NET MVC framework" (ASP.NET MVC Framework для профессионалов). Но в добавок ко всему содержит так же и модификацию класса фабрики контроллеров. Частичный перевод этой статьи с добавлением нескольких своих замечаний я и хочу привести ниже.

Аннотация: эта статья содержит информация, необходимую для настройки шаблона инверсии управления (IoC) в приложениях ASP.NET MVC, используя Castle Windsor.

В этой статья я расскажу вам обо всех шагах необходимых для того, чтобы вы могли создать собственную фабрику контроллеров для реализации IoC в вашем приложении. Более подробную информацию об IoC и том, зачем использовать его, вы можете найти здесь http://www.mikesdotnetting.com/Article/117/Dependency-Injection-and-Inversion-of-Control-with-ASP.NET -MVC
Я узнал о том, как использовать Windsor для реализации IoC в выдающейся книге Стивена Сандерсона "Pro ASP.NET MVC framework" (ASP.NET MVC Framework для профессионалов).
...
Последнюю версию Castle Windsor можно взять с его официального сайта.

И так, сначала добавим ссылки в наш проект на след. сборки: "Castle.Core.dll", "Castle.MicroKernel.dll", "Castle.Windsor.dll"



Далее создадим класс фабрики контроллеров. В корневой папке проекта создадим файл WindsorControllerFactory.cs. В него запишем след. код:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Castle.Windsor;
using Castle.Windsor.Configuration.Interpreters;
using Castle.Core.Resource;
using System.Reflection;
using Castle.Core;
using System.Web.Routing;

namespace Mvc2Application6
{
public class WindsorControllerFactory : DefaultControllerFactory
{
WindsorContainer container;
// The constructor:
// 1. Sets up a new IoC container
// 2. Registers all components specified in web.config
// 3. Registers all controller types as components
public WindsorControllerFactory()
{
// Instantiate a container, taking configuration from web.config
container = new WindsorContainer(
new XmlInterpreter(new ConfigResource("castle"))
);
// Also register all the controller types as transient
var controllerTypes =
from t in Assembly.GetExecutingAssembly().GetTypes()
where typeof(IController).IsAssignableFrom(t)
select t;
foreach (Type t in controllerTypes)
container.AddComponentWithLifestyle /* Либо используйте AddComponentLifeStyle для второй версии */
(t.FullName, t,LifestyleType.Transient);
}

// Constructs the controller instance needed to service each request this part is Updated to be compatible with MVC 2
protected override IController
GetControllerInstance
(RequestContext requestContext, Type controllerType)
{
return (IController)container.Resolve(controllerType);
}
/*
* For MVC 1 use this
protected override IController GetControllerInstance(Type controllerType)
{
return (IController)container.Resolve(controllerType);
}*/
}
}

Этот код реализует интерфейс IControllerFactory (это след. хотя бы из того, что он наследует класс DefaultControllerFactory). Далее нам осталось внести след. изменения в Web.config:






//содержимое


Лучше сделать это сразу перед system.web (здесь это показано)

Далее в configSections добавить след. строку (если узел configSections еще не создан, то его след. создать внутри configuration)



Теперь необходимо указать ASP.NET использовать новую фабрику контроллеров, делается это добавлением строки


ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory());

В метод Application_Start(), находящегося в файле Global.asax.

Допустим, вы используете интерфейс IUserRepository


namespace Models.Abstract

{

public interface IUserRepository

{

IQueryable Users { get; }

}

}

И существует реализация этого интерфейса:

namespace Model.Concrete
{
public class SqlUserRepository : IUserRepository
{
private Table current;
public SqlUserRepository(String connectionString)
{
current = (new DataContext(connectionString)).GetTable();
}
public IQueryable Users
{
get { return current; }
}
}
}

Теперь, можно использовать данный интерфейс так:

public class UsersController : Controller
{
public IUserRepository myUser;
public UsersController(IUserRepository userRepository)
{

this.myUser = userRepository;
}

public ViewResult List()
{
return View(userRepository.Users.ToList());
}

}

Необходимо зарегистрировать интерфейс и его реализацию в CastleWindsor



service="Model.Abstract.IUserRepository, Model"
type="Model.Concrete.SqlUserRepository, Model"
lifestyle="PerWebRequest">

Server=.\SQLEXPRESS;DataBase=SportStore;Trusted_Connection=yes;





Теперь осталось зарегистрировать стиль поведения объекта PerRequestLifestyle в httpModules (если в web.config еще нет узла httpModules, то его следует объявить внутри system.web)



Ну, вот и все. Теперь CastleWindsor установлен и готов к использованию.

четверг, 8 июля 2010 г.

ZXing. Используем в C# приложениях



Недавно у меня возникла потребность реализовать в одном из своих приложений возможность работы с QR-кодами. После однодневного поиска соответствующей библиотеки мой выбор остановился на ZXing (об этом я писал здесь). В первую очередь, мне требовалась полная поддержка .Net и желательно на C#, что собственно и реализует указанный проект. Сразу хочу сказать, что в использовании библиотека проста до неприличия, но все же, касаемо C#, возникли некоторые трудности, связанные с отсутствием (притом полным) примеров на данном языке. В силу чего у меня и появилась мысль написать данную статью, чтобы сберечь время таким же, как и я разработчикам. Итак, прочтя эту заметку до конца, я думаю, вы легко сможете встроить ZXing в свой проект. Но обо всем по порядку.
Проект поддерживает следующие форматы:
• UPC-A and UPC-E
• EAN-8 and EAN-13
• Code 39
• Code 93
• Code 128
• QR Code
• ITF
• Codabar
• RSS-14 (all variants)
• Data Matrix ('alpha' quality)
• PDF 417 ('alpha' quality)

Проверить качество распознования можно отсюда. Это онлайн декодер, реализованный на ASP.

Скачать последнюю версию ZXing можно отсюда. Хотя сразу оговорюсь, что она нам не понадобится, поскольку поддержки C# в ней нет (в текущей версии 1.5). Впрочем, скачать портированную версию опять же можно с сайта разработчиков из SVN репозиториев. Так что, вероятно, официальная поддержка C# появится в ближайшее время. Оттуда советую взять и документацию. Несмотря на то, что она реализована в версии только для Java, большинство описанных классов совпадает и с шарповской версией, значит, она и здесь будет очень полезна.

Открыв данную версию можно заметить, что отсутствуют многие пространства имен, например отвечающие за работу с Android, но это и понятно. Они нам и не нужны. Рассматривать все классы подробно не вижу смысла, поскольку за меня это уже сделано в документации. В целом, нам потребуются только несколько из них: Reader (в простарнстве имен com.google.zxing) – интерфейс, содержащий объявление всего 2 функций: decode(BinaryBitmap image) и reset();MultiFormatReader - класс, реализующий Reader (если бы мы хотели декодировать только QR формат, то взяли бы QRCodeReader); BinaryBitmap – если коротко, то это класс для внутреннего представления изображения, данный класс наследует от абстрактного Binarizer, который в свою очередь от также абстрактного LuminanceSource. Таким образом нам придется как-то преобразовать изображение из класса Bitmap в LuminanceSource. Сделать это можно, если найти производные от LuminanceSource. В документации говориться сразу о нескольких таких, но в версии для С# ни одного из них не оказалось. Зато появился класс RGBLuminanceSource, он то нам и нужен (но при желании вы, конечно, можете и сами реализовать подобный класс). У него есть несколько конструкторов, самым подходящим для моего приложения оказался RGBLuminanceSource(System.Drawing.Bitmap, int, int).

Итого получаем:

Reader reader = new com.google.zxing.MultiFormatReader();
Bitmap image1 = new Bitmap(selectFile.FileName, true);
LuminanceSource source = new RGBLuminanceSource(image1, image1.Width, image1.Height);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));

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

Result result = reader.decode(bitmap);

Где Result – класс ответственный за представление результата декодирования. Можно просмотреть его как в битовом виде, узнать формат кода и прочее. Нас интересует текстовое представление, поэтому делаем так.

textBox1.Text = result.Text;

Вот собственно и все. Осталось только обработать исключения. В версии для Java их в 2 раза больше. В частности, существуют ChecksumException, FormatException, NotFoundException, являющиеся унаследованными от ReaderException. В версии для C# их нет. Остались только ReaderException, WriterException и ReedSolomonException, к тому же, на сколько я понял, ReedSolomonException является внутренним и на уровень пользовательского кода не допускается, но все-таки лучше перехватить и его.

P.S. Конечно, в данной статье я описал только декодирование изображения, но вы легко можете убедиться, что создание кода ничуть не сложнее.

Вот пример работающего приложения.

среда, 7 июля 2010 г.

QR - коды и обзор основных библиотек работы с ними



Недавно наткнулся в сети на эту тему. Раньше я что-то слышал про дополнительную реальность, но считал это делом будущего. А между тем, двоичные коды уже вовсю применяются в Азии, да и у нас они имеют большую перспективу. Более подробно с данной тематикой можно ознакомиться на Wikipedia и на habrahabr.

Если коротко, то QR - коды - это разновидность двух-мерных шрихкодов, позволяющих кодировать относительно большой объем информации. Например, это может быть ссылка на сайт, текст, контакт в записной книжке и т.д. Считать этот код можно, используя даже обычную камеру мобильного телефона (единственное условие - камера должна иметь достаточное разрешение). Благодаря чему, теперь больше нет необходимости вводить вручную в телефон ссылки на сайты и данные контакта, достаточно просто сфотографировать двоичный код и все. Кстати, сервис по представлению ссылок в виде QR- кода недавно стал предоставлять и Google. Впрочем, таких проектов множество: qrcoder.ru - позволяет закодировать текст, ссылку, визитную карточку или sms-сообщение; mojiq.kazina.com - позволяет создавать "красивые" QR-коды, вставляя в них произвольный текст.

Гораздо меньше проектов по распознаванию и декодированию данных сообщений. В той же википедии можно найти сравнительный обзор существующих декодеров, а также ссылки на их онлайн версии. Лично я могу выделить след. проекты:
QuickMark - пожалуй, лучший на данный момент декодер. Поддерживает QR-коды и DataMatrix. Выпущены версии под Symbian, Windows XP (Vista/7) и Windows Mobile. Недостаток - проект отнюдь не свободный и требует денежку за использование.
Google ZXing - о нем скажу более подробно чуть ниже, а здесь хотелось бы отметить широкий выбор поддерживаемых платформ и кодов, а также бесплатность использования (в том числе и для коммерческих целей).

Конечно, проектов декодеров гораздо больше, но эта статья не претендует на полноту (в отличии от указанной статьи в википедии).
Перейду теперь к обзору основных библиотек разработки собственных приложений в этой области.

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

Open Source QRCode Library - это первая библиотека, попавшаяся мне на глаза. Проект абсолютно свободный, но отнюдь не самый лучший. Написан на C#, что мне в нем сильно приглянулось, но все же имеет ряд недостатков. Самый главный из них - низкий процент успешных распознаваний. Даже практически идеальные снимки кодов он или вообще не распознает или распознает после хитрых манипуляций (например, в одном из случаев потребовалось обрезать картинку почти до одного QR-кода и уменьшить! разрешение снимка). Не рекомендовал бы эту библиотеку к реальному применению.

www.aipsys.com - лучше, чем предыдущее решение, но имеет ряд недостатков - поддерживается малое число платформ (только Windows), представляется в виде динамической библиотеки, ActiveX и ASP компонент. Поддерживает языки C++ и Делфи. Ни о какой прямой поддержки Java или C# и речи не идет.

Google ZXing - самое лучшее, на мой взгляд, решение для использования в своем приложении. Здесь и широкая поддержка платформ ( в том числе Android и IPhone), множество поддерживаемых языков - Java (ME версия), C#, С++(через портирование) и другие. Бибилиотека распространяется по лицензии Apache License, Version 2.0, что означает возможность использования кода как в свободных, так и в коммерческих проектах. Библиотека хорошо документирована. На данный момент доступна версия 1.5 (к слову, в ней нет версии для C#, но она есть в SVN репозитории). Честно признаться, проект ZXing мне сразу приглянулся, а потому в ближайшее время я собираюсь написать статью с разбором основных возможностей этой библиотеки.

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