poniedziałek, 5 marca 2012

Metoda wypełniająca dla testów

Problem jaki napotykam w trakcie testowania aplikacji jest ciągłe wypełnianie tych samych pól, tymi samymi danymi. Aby zautomatyzować dany proces wystarczy dodać metodę wypełniającą.
Do metody wypełniającej dane (np. w formularzu) dodaje się atrybut Conditional("DEBUG"). Jeżeli flaga DEBUG nie jest ustawiona to metoda jest omijana w produkcyjnej binarce. Do tej metody dodatkowo dodaje warunek czy debugger jest podłączony. Debugger możne być podłączony w trybie Debug oraz Release. Dobrę praktyką jest dodanie informacji do okna Output z jakiej metody zostało dokonane wypełnienie, pisanie nazw tych metod z prefiksem "DEBUG_" oraz ustawienie dostępności na private.
Poniższy kod przedstawia ten mechanizm:
[Conditional("DEBUG")]
private void DEBUG_YourFillingMethod() //hack: Debug
{ 
    if (Debugger.IsAttached)
    { 
        Debugger.Log(0, this.ToString(), System.Reflection.MethodBase.GetCurrentMethod().Name);
        //todo: your filling code
    } 
} 


Dla aplikacji ASP.NET można zastosować HttpContext.Current.IsDebuggingEnabled.

Mario + Portal = Mari0


Kto nie pamięta gry Mario. Sympatyczny hydraulik z wąsikiem :) Jeszcze mi się łezka kręci jak wspominam kiedy na komunie dostałem pegasusa z tą grą. Najlepsza gra wszech czasów.
Gra Portal powstała w 2007 i została uznana z innowacyjną z powodu tworzenia portali na płaskich powierzchniach, które pozwalają na swobodne podróżowanie. Portal jest grą logiczną z perspektywy first person shooter.



Z połączenia tych dwóch gier powstał Mari0.



Oprócz portali bardzo mi się podoba, że w przyszłości będzie możliwość zagrania z drugą osobą przez internet.


Powodzenia przy uwalnianiu księżniczki!!! :)

Wzorzec stanu dla stron

W tym poście chciałbym przedstawić moją implementację State Pattern dla stron internetowych w ASP.NET. Zakładam, że każda strona ma dokładnie jeden stan. Wzorcem chciałbym rozwiązać podany scenariusz: Uruchamiamy stronę startową (Page 1). Z tej strony chcemy przejść do strony Page 3. Przejście jest uzależnione od spełnienia warunku (Condition). Jeżeli warunek nie jest spełniony to przechodzimy do strony Page 2, a w przeciwnym przypadku przechodzimy do strony Page 3. Również ze strony Page 2 można przejść do Page 3. Schemat działania stron przedstawiony jest poniżej:

Graficzna implementacja wzorca stanu dla stron jest zawarta w poniższym schemacie:
Klasa PageContext zawiera różne stany oraz parametry z danej strony. Klasa abstrakcyjna PageState deklaruje metodę Handle(), która jest definiowana przez konkretny stan. Klasa bazowa zawiera nazwę pliku ze stroną (np. Page1.aspx) w polu PageName. W każdej ze stron (Page*.aspx) zdefiniowane jest zdarzenie odpowiadające za zmianę stanu (przejście do innej strony). Dla strony Page1.aspx definicja wygląda następująco:
        protected void GoToNextPage(object sender, EventArgs ea)
        {
            var thisContext = new PageContext(new PageState1()) 
                                { IsChecked =  Condition1.Checked};
            thisContext.Request();
            this.Response.Redirect(thisContext.State.PageName);
        }
Klasa PageContext ma zdefiniowaną metodę Request(), która dla danego stanu wywołuje metodę Handle(). Cały przykład można pobrać z tego pliku:

poniedziałek, 27 lutego 2012

Googlowanie polskich wyjątków w .NET

Inteligentna platforma .NET jest tak niesamowita, że wszystkie wyjątki potrafi przetłumaczyć na język domyślny systemu operacyjnego. Niestety dla mnie jest to mały problem, gdyż znalezienie w Internecie rozwiązania problemu opisanego w języku polski jest ciężkie. Jedne ze sposobów rozwiązana tego problemu można było przeczytać na blogu jednego z twórców dotnetomaniaka. Ja chciałbym przedstawić 2 serwisy, które rozwiązują podany problem. Są to Unlocalize oraz FindErr.NET. Na tych 2 stronach możesz wpisać polski komunikat i znajdziesz angielski odpowiednik tego komunikatu. Ja bardziej preferuje Unlocalize, gdyż ma przyjemniejszy interfejs :)

Przy okazji. Czy słyszałeś taki zwrot jak "GOOGLE IT IN BING" ??


Najlepsze jest to Bing indeksuje g+, a google jeszcze nie - lol

Jak przyspieszyć kodowanie cz.2



Już wcześniej pisałem o jednym ze sposobów przyspieszenia pisana kodu, a tym razem powiem więcej o Zen-Coding. Jest to silnik umożliwiający automatyczne generowanie kodu używanego w językach bazujących na SGML. Zapisując nazwy i specjalne symbole można w prosty sposób wygenerować wiele linijek kodu. Możliwości Zen-Codingu przedstawia poniższy filmik:



Jest dodatek do Visual Studio, a opis można znaleźć pod tym adresem.
Resharpera też można wzbogacić poprzez plugin. Lista innych programów jest przedstawiona na stronie Wikipedii

Sieć bayesowska w .NET

Sieć bayesowska jest zaawansowaną probabilistyczną metodą odkrywania wiedzy i wnioskowania. Przedstawia ona zależności pomiędzy zdarzeniami bazując na wzorze Bayesa oraz rachunku prawdopodobieństwa. Umożliwia reprezentację probabilistycznych zależności przyczynowych między dowolnymi atrybutami (zdarzeniami). W praktyce sieć bayesowska jest reprezentowana przez skierowany graf acykliczny. Największą korzyścią sieci bayesowskiej jest czytelna i intuicyjna graficzna reprezentacja wiedzy o bezpośrednio zachodzących zależnościach.

Poniżej przedstawiony jest przykład modelu graficznego sieci. Mokra trawa(atrybut WetGrass) jest bezpośrednio uzależniona od dwóch czynników: czy został załączony zraszacz (Sprinkler) oraz od tego czy padał deszcz (Rain). Te dwa czynniki są uzależnione od pochmurności ( atrybut Cloudy). Zgodnie z relacją przechodnią, mokra trawa jest pośrednio zależna od pochmurności. Każdy z atrybutów ma dwie opcje: może zajść lub nie może zajść (T i F). Dla każdej kombinacji przedstawione jest prawdopodobieństwo wystąpienia takiego zdarzenia.


Dajmy na to, że chcemy obliczyć z jakim prawdopodobieństwem padał deszcz (Rain(R)=T) przy zaistnieniu (zaobserwowaniu) mokrej trawy (atrybut WetGrass(W)= T). Czyli mamy do czynienia z prawdopodobieństwem warunkowym P(R|W=T).
Do implementacji takiego modelu z pomocą przychodzi nam projekt o naziwe Infer.NET. Służy on m.in. do wnioskowania dla bayesowskiego modelu graficznego. Implementacja przedstawiona jest poniżej:
#region implementacja modelu
     //pochmurnie
     Variable<bool> cloudy = Variable.Bernoulli(0.5);

     // spryskiwacz 
     Variable<bool> sprinkler = Variable.New<bool>();
     using (Variable.If(cloudy))
            sprinkler.SetTo(Variable.Bernoulli(0.1));

     using (Variable.IfNot(cloudy)) 
            sprinkler.SetTo(Variable.Bernoulli(0.5));

     // deszcz
     Variable<bool> rain = Variable.New<bool>();
     using (Variable.If(cloudy)) 
               rain.SetTo(Variable.Bernoulli(0.8));

     using (Variable.IfNot(cloudy)) 
               rain.SetTo(Variable.Bernoulli(0.2));

    // mokra trawa
    Variable<bool> wetGrass = Variable.New<bool>();
    using (Variable.If(sprinkler))
    {
           using (Variable.If(rain)) 
                  wetGrass.SetTo(Variable.Bernoulli(0.99));

           using (Variable.IfNot(rain)) 
                  wetGrass.SetTo(Variable.Bernoulli(0.9));
    }
    using (Variable.IfNot(sprinkler))
    {
           using (Variable.If(rain)) 
                  wetGrass.SetTo(Variable.Bernoulli(0.9));

           using (Variable.IfNot(rain)) 
                  wetGrass.SetTo(Variable.Bernoulli(0.0));
    }
#endregion

#region wnioskowanie
wetGrass.ObservedValue = true;  //mokra trawa
InferenceEngine ie = new InferenceEngine();
ie.ShowProgress = false;
Console.WriteLine("P(deszcz | trawa jest mokra)=" 
        + ie.Infer(rain));

Console.WriteLine("P(spryskiwacz | trawa jest mokra)=" 
        + ie.Infer(sprinkler));

cloudy.ObservedValue = false; //nie jest pochmurnie
Console.WriteLine("P(deszcz | trawa jest mokra,  nie jest pochmurnie)="
       + ie.Infer(rain));

Console.WriteLine("P(spryskiwacz | trawa jest mokra, nie jest pochmurnie)="
       + ie.Infer(sprinkler));
#endregion


W 60 linijkach mamy zaimplementowany cały model graficzny oraz mechanizm wnioskujący. Dla potrzeb publikacji zamieściłem zdjęcie z okienkiem całej aplikacji oraz prawdopodobieństwa dla paru innych warunków.



Implementacja podanego przykładu można znaleźć pod adresem Bayesian Networks na Codeplex. Więcej o samej sieci bayesowskiej jest na wykładzie pt. Introduction To Bayesian Inference.

Generator listy w c#

Chciałbym przedstawić krótki kod jaki używam do tworzenia listy obiektów.

   public class Generator
    {
        public static IEnumerable<T> Generate<T>(Func<T> func)
        {
            while (true)
            {
                yield return func();
            }
        }
        public static IEnumerable<T> Generate<T>(Func<int, T> func)
        {
            int index = 0;
            while (true)
            {
                yield return func(index);
                index++;
            }
        }
    }

Dzięki temu możemy w łatwy sposób stworzyć listę 10 elementów z losowymi i ponumerowanymi liczbami.
Random r = new Random();
var listWithRandomElements = Generator.Generate(()=> r.Next(10))
   .Take(10);

var listWithNumberedElements = Generator.Generate(i => i)
    .Take(10);