ResolveUrl i ResolveClientUrl

by Piotrosz 26. March 2009
ResolveUrl i ResolveClientUrl pozwalają na zamianę ścieżek względnych na bezwzględne (ResolveUrl) i bezwzględnych na względne (ResolveClientUrl). Przykład:
public partial class Default3 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Debug.WriteLine(ResolveUrl("../22.gif"));
        Debug.WriteLine(ResolveUrl("~/22.gif"));

        Debug.WriteLine(ResolveClientUrl("../22.gif"));
        Debug.WriteLine(ResolveClientUrl("~/22.gif"));

	// Wynik w Output Window:	

        // /WebSite1/22.gif
        // /WebSite1/22.gif
        // ../22.gif
        // ../22.gif
    }
}

Wzorce projektowe: Strategia

by Piotrosz 24. March 2009
Jak zwykle luźny i niezobowiązujący opis kolejnego wzorca. Tym razsem Strategii.
Wzorzec ten stosuje się, gdy w aplikacji zachodzi potrzeba wybrania jakiegoś sposobu wykonania zadania. Sposób ten (algorytm) jest wybierany w trakcie wykonywania programu. Algorytm może zależeć od wyboru użytkownika, platformy, na której jest wykonywany program, środowiska, etc. Pod uwagę można brać na przykład szybkość i dokładność wykonania zadania.
Występuje tu interfejs, który jak wiadomo definiuje kontrakt. Klasy implementujące ten interfejs zawierają szczegóły różnych sposobów rozwiązania problemu (różne algorytmy, strategie rozwiązania problemu).
Następnie jest kontekst, który przechowuje instancję strategii. Klient może dokonać wyboru strategii, poprzez stworzenie instancji klasy kontekstu, bez potrzeby znajomości szczegółów implementacji tych strategii. Jest to korzystne, bo implementacja algorytmu jest oddzielona od klienta (są luźno powiązane). Taki projekt może być też z łatwością rozszerzony, tzn. kolejny algorytm może być bardzo łatwo dodany.
Przykład. Różne sposoby określania jakości wykonania gitary akustycznej:
Najpierw interfejs:
namespace StrategyExample
{
    interface IStrategy
    {
        int EvaluateQuality(Guitar g);
    }
}
Mój algorytm oceny jakości gitary na podstawie różnych parametrów:
namespace StrategyExample
{
    class PiotrAlgorithm : IStrategy
    {
        public int EvaluateQuality(Guitar g)
        {
            // Czy gryf jest prosty?
            // Czy progi są prawidłowo nabite?
            // Oceniam z jakich materiałów jest wykonany instrument
            // Czy słoje są równoległe go gryfu?
            // etc.
            // Zwracam cokolwiek bo chodzi tylko o prezentacje struktury wzorca
            return 666; 
        }
    }
}
Inna osoba może sobie dodać inne algorytmy poprzez implementacje interfejsu IStrategy.
Następnie mamy kontekst, który przechowuje strategię:
namespace StrategyExample
{
    class Context
    {
        private IStrategy strategy;

        public Context(IStrategy s)
        {
            this.strategy = s;
        }

        public void Update(IStrategy s)
        {
            this.strategy = s;
        }

        public int Test(Guitar g)
        {
            return strategy.EvaluateQuality(g);
        }
    }
}
W programie można zdecydować o wyborze konkretnego algorytmu na przykład uzależniając to od wyboru użytkownika:
namespace StrategyExample
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Jakiej strategii chcesz użyć, A czy B?");
            ConsoleKeyInfo ki = Console.ReadKey();

            Guitar g = new Guitar();

            IStrategy s;
            if (ki.KeyChar == 'A')
            {
                s = new PiotrAlgorithm();
            }
            else
            {
                throw new NotImplementedException("Ten algorytm nie został jeszcze zaimplementowany.");
            }

            Context c = new Context(s);
            int Quality = c.Test(g);
            Console.WriteLine("\nWynik oceny to: {0}", Quality);
        }
    }
}

Fraktale Julii i Mandelbrota

by Piotrosz 18. March 2009
Programik w C#, który potrafi stworzyć zbiór Julii i Mandelbrota i zapisać wynik w pliku graficznym. Można za jego pomocą przekonać się na czym polega różnica między tymi typami fraktali. Świetna zabawa, polecam:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;

namespace JuliaAndMandelbrot
{
    class Program
    {
        static void Main(string[] args)
        {
            // Tworzenie zbioru Julii
            //Complex C = new Complex(-0.234, 0.332);
            //JuliaSet Js = new JuliaSet();
            //Area JuliaArea = new Area(-1.0, 1.0, -1.0, 1.0);
            //List Set = Js.Create(C, 0.003, 1000, -1.0, 1.0, 300);
            //SaveImage("Julia.png");

            MandelbrotSet Ms = new MandelbrotSet();
            Area ManArea = new Area(-2.0, 0.6, -1.0, 1.0);
            Ms.Create(new Complex(0, 0), 0.003, 100, ManArea, 4);
            SaveImage(Ms.Set, "Mandelbrot.png", 300);
        }

        static void SaveImage(List Set, string FileName, int Scale)
        {
            float MinX = 0, MaxX = 0, MinY = 0, MaxY = 0;
            foreach (Complex c in Set)
            {
                MinX = (float)Math.Min(MinX, c.Re);
                MaxX = (float)Math.Max(MaxX, c.Re);
                MinY = (float)Math.Min(MinY, c.Im);
                MaxY = (float)Math.Max(MaxY, c.Im);
            }
            int Width = Scale*Convert.ToInt32(MaxX - MinX);
            int Height = Scale*Convert.ToInt32(MaxY - MinY);
            Bitmap b = new Bitmap(Width, Height);
            Graphics g = Graphics.FromImage(b);
            g.Clear(Color.White);
            Pen p = new Pen(Color.Black, 1);

            float x, y;
            foreach (Complex c in Set)
            {
                x = (float) ((c.Re / (MaxX - MinX)) * Width);
                y = (float) ((c.Im / (MaxY )- MinY) * Height);
                g.DrawLine(p, x, y, x + 1, y);
            }
            b.Save(FileName, ImageFormat.Png);
            b.Dispose();
            g.Dispose();
        }
    }

    // Klasa pomocnicza
    public class Area
    {
        public Area() 
        {
            this.MinX = this.MaxX = this.MinY = this.MaxY = 0;
        }
        public Area(double MinX, double MaxX, double MinY, double MaxY)
        {
            this.MinX = MinX;
            this.MaxX = MaxX;
            this.MinY = MinY;
            this.MaxY = MaxY;
        }

        public double MinX;
        public double MaxX;
        public double MinY;
        public double MaxY;
    }


    public class FractalBase
    {
        protected int i;
        protected List _Set;
        public List Set
        {
            get { return this._Set; }
        }

        protected FractalBase()
        {
            this._Set = new List();
        }

        public virtual void Create(Complex C, double Delta, int Iterations, Area area, double Level)
        {}

        public void ToFile(string Path)
        {
            StreamWriter w = File.CreateText(Path);
            foreach (Complex c in _Set)
                w.WriteLine("{0};{1};", c.Re, c.Im);
            w.Close();
        }
    } // end class

    public class JuliaSet : FractalBase
    {
        private Complex _Z;

        public JuliaSet() : base()
        {
            this._Z = new Complex();
        }

        public override void Create(Complex C, double Delta, int Iterations, Area area, double Level)
        {
            double real, imag;
            for (real = area.MinX; real < area.MaxX; real += Delta)
                for (imag = area.MinY; imag < area.MaxY; imag += Delta)
                {
                    _Z.Re = real;
                    _Z.Im = imag;
                    for (i = 0; i < Iterations; i++)
                    {
                        _Z = _Z * _Z + C;
                        if (_Z.GetModulus() > Level)
                        {
                           _Set.Add(new Complex(real, imag)); 
                            break;
                        }
                    }
                }
        }
    } // end class

    public class MandelbrotSet : FractalBase
    {
        private Complex _C;
        private Complex _Z;

        public MandelbrotSet() : base()
        {
            _C = new Complex();
            _Z = new Complex();
        }

        public override void Create(Complex Z, double Delta, int Iterations, Area area, double Level)
        {
            double real, imag;
            for (real = area.MinX; real < area.MaxX; real += Delta)
                for (imag = area.MinY; imag < area.MaxY; imag += Delta)
                {
                    _C.Re = real;
                    _C.Im = imag;
                    _Z.Re = Z.Re;
                    _Z.Im = Z.Im;
                    for (i = 0; i < Iterations; i++)
			        {
                        _Z = _Z * _Z + _C;
                        if(_Z.GetModulus() > Level)
                        {
                            this._Set.Add(new Complex(real, imag));
                            break;
                        }
			        }
                }
        }
    } // end class
}
Skorzystałem z klasy Complex autorstwa Bena Houstona, którą znalazłem gdzieś na sieci
Complex.cs.zip
Przykładowe obrazki:
Zbiór Julii:



Żuczek Mandelbrota nieudany (błąd w programie):
I udany:

Wielolinijkowa zmienna string

by Piotrosz 13. March 2009
class Program
{
    static void Main(string[] args)
    {
        string Multiline = @"Czuję w sobie moc piekelną,
                            jad śmiertelny stu skorpionów,
                            w twardych żyłach mego cielska
                            miąższ kosmicznych salcesonów.";

        Console.WriteLine(Multiline);

        // Wynik działania:
        //Czuję w sobie moc piekelną,
        //                    jad śmiertelny stu skorpionów,
        //                    w twardych żyłach mego cielska
        //                    miąższ kosmicznych salcesonów.
    }
}
Znaczek @ przed wartością typu string powoduje, że kompilator traktuje dosłownie znaki takie jak \n\r czy \.
Gdy nie ma małpy, to trzeba napisać: "\\n\\r\\" zamiast @"\n\r\".

Tags: ,

C#

XmlNode Value vs. InnerText

by Piotrosz 9. March 2009
Jaka jest różnica między właściwościami InnerText i Value obiektu XmlNode?
Załóżmy, że mamy taki dokument XML:
<?xml version="1.0" encoding="utf-8" ?>

  wartosc

Poniższy przykład obrazuje tę różnicę:
class Program
{
    static void Main(string[] args)
    {
        XmlDocument XmlDoc = new XmlDocument();
        XmlDoc.Load("test.xml");
        XmlNode node = XmlDoc.SelectSingleNode("/root/element");

        Console.WriteLine("node.Value = {0}", node.Value);
        Console.WriteLine("node.FirstChild.Value = {0}", node.FirstChild.Value);
        Console.WriteLine("node.InnerText = {0}", node.InnerText);

        // Wynik działania:
        //node.Value =
        //node.FirstChild.Value = wartosc
        //node.InnerText = wartosc
    }
}
A więc element tekstowy jest traktowany jako dziecko danego węzła. W takim przypadku node.FirstChild.Value == node.InnerText.

Tags: , ,

C# | XML

Wyrażenia regularne - ściągawka

by Piotrosz 8. March 2009

Ściągawka z wyrażeń regularnych

^ Początek ciągu e.g. ^abc dopasuje abcd, ale nie aabc
$ Koniec ciągu, e.g do abc$ pasuje xxxabc, ale nie abcxx
[abc] Oznacza: a lub b lub c
[^] Wewnątrz kwantyfikatora ([]) daszek oznacza negację e.g. [^\w] oznacza wszystkie nie-słowa, a[^qwerty] - neguje wszystkie znaki wewnątrz nawiasu kwadratowego
\w+ Dopasowuje każdą grupę znaków, które składają się na słowa
\W Znak niebędący literą ani cyfrą, odpowiednik [^a-zA-Z0-9_]
\S Znak niebędący znakiem białym, odpowiednik [^\f\n\r\t\v]
\s Znak biały (np. spacja, tab), odpowiednik [\f\n\r\t\v]
\D Znak niebędący cyfrą, odpowiednik [^0-9]
\d Dowolna cyfra, odpowiednik [0-9]
[a-z] Dowolna litera z zakresu od a do z
[A-Z] Dowolna wielka litera z zakresu od A do Z
x|y Dopasowuje x lub y, e.g. kot|s pasuje do kot i kos, (he|gie)niek pasuje do heniek i gieniek To samo co [xy]
\d Dowolna cyfra, odpowiednik [0-9]
\d{5} Pięć cyfr (przykład), możliwe są też takie przykładowe zastosowania nawiasu: {0,}, {1,}, {1, 6}
. Dowolny 1 znak (oprócz znaku końca linii), e.g. a.b
* Dowolna ilość znaków po jakimś znaku (także zero), odpowiednik {0,} e.g. a (bc)*
+ Jeden znak lub więcej po jakimś znaku zo+ pasuje do zo oraz zoo, ale nie do z, odpowiednik {1,}
? Jeden znak, ale opcjonalnie (czyli jeden lub zero), odpowiednik {0,1}, e.g. abc? pasuje do abc lub abcd, ale nie do abccc
\b Word boundary e.g. car\b pasuje do tttcar, ale nie do carksjlj
\B Non word boundary e.g. car\B pasuje do cardsss, ale nie do sssscar
\< Odpowiednik \b na początku słowa (flavor specific)
/> Odpowiednik \b na końcu słowa (flavor specific)
\numer Backreference np. \1, \2, \3, ... na przykład \w\1 znajduje podwojone słowa
\k<name> Named Backrefence
(?<name>pattern) Nazwanie wyrażenia

Zastępowanie tekstu:

$numer Zastępuje ostatni podciąg dopasowany przez wyrażenie o numerze numer
${nazwa_wyrazenia} Zastępuje ostatni podciąg dopasowany przez nazwane wyrażenie (<? nazwa_wyrazenia>)
$$ Zastępuje pojedynczy znak $
$& Zastępuje kopię dopasowanego ciągu
$` Zastępuje cały ciąg wejściowy poprzedzający dopasowanie
$' Zastępuje cały ciąg wejściowy za dopasowaniem
$+ Zastępuje ostatnią dopasowaną grupę
$_ Zastępuje cały ciąg wejściowy

Przykłady

Wyszukanie wszystkich ciągów złożonych z litery q nie poprzedzonej literą q (czyli dowolnym znakiem niebędącym literą u):

q[^u]

Dopasowanie dowolnego słowa w nawiasach (znaki ( oraz ) są znakami specjalnymi i dlatego trzeba zastosować backslash):

\([a-zA-Z]+\)

Dowolna nazwa pliku z rozszerzeniem .php i dwoma parametrami przekazywanymi poprzez GET (poprzez query string):

\w\.php?[&=\w]{2}

Godzina w formacie 12:33 am (uwaga na spację przed (am|pm)):

(1[012]|[1-9]):[0-5][0-9] (am|pm)

Adres e-mail:

^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$

Tag HTML:

<([A-Z][A-Z0-9]*)\b[^>]*>(.*?)</\1>

Adres IP:

\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0 -9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b

Powtarzające się litery (przykład z named backreference):

(?<znak>\w)\k<znak>

Powtarzające się słowa (przykład z named backreference):

(?<słowo>\s\w+)\k<słowo> Dopasuje ba ba, ale też ba baxxx.

Ulepszona wersja: (?<słowo>\s\w+)\k<słowo>\b dopasuje tylko oddzielne powtarzające się słowa (e.g. do domu).

Regex w C# .NET

Programik konsolowy do testowania różnych wyrażeń regularnych. Jako parametry wywołania należy podać ciąg znaków i wyrażenie regularne:
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace RegularExpressions
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            if (args.Length == 2)
            {
                if (Regex.IsMatch(args[1], args[2]))
                {
                    Console.WriteLine("Matches");
                }
                else
                {
                    Console.WriteLine("Does not match");
                }
            }
        }
    }
}

Filtrowanie (parsowanie) tekstu:

 // dumping, extracting from file
 private static List<string> RegexFind(string contents)
 {
    List<string> result = new List<string>();
    Regex r = new Regex(@"'(linkphp\.php\?[&=\w]{2,})'");
    Match m;
    for (m = r.Match(contents); m.Success; m = m.NextMatch())
    {
        result.Add(m.Groups[1].ToString());
    }
    return result;
 }

Zastępowanie wyrażeń w tekście. Poniższy przykład zastępuje daty w formacie dd/MM/yyyy na datę w formacie dd-MM-yyyy:

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace RegexReplacingText
{
    class Program
    {
        static void Main(string[] args)
        {
            string DtFrom = "12/22/2008";
            Console.WriteLine(ReplaceDate(DtFrom));
        }

        private static string ReplaceDate(string input)
        {
            return Regex.Replace(input, @"\b(?<miesiac>\d{1,2})/(?<dzien>\d{1,2})/(?

<rok>\d{1,4})\b", "${dzien}-${miesiac}-${rok}");
        }
    }
}
Usuwanie tagów HTML z tekstu (HTML tags stripping):
public static string StripHtmlTags(string input)
{
    return Regex.Replace(input, "<.*?>", string.Empty);
}
Wyrażenie tutaj jest uproszczone, ale działa w większości przypadków.

Funkcje Left oraz Right w C#

by Piotrosz 6. March 2009
Odpowiedniki funkcji Left oraz Right z Visual Basica czy SQL:
class Program
{
    public static string Left(string Value, int Length)
    {
        return (Value.Length > Length) ? Value.Substring(0, Length) : Value;
    }

    public static string Right(string Value, int Length)
    {
        return (Value.Length > Length) ? Value.Substring(Value.Length - Length, Length) : Value;
    }

    static void Main(string[] args)
    {
        for (int i = 0; i < 15; i++)
            Console.WriteLine(Left("1234567890", i));

        Console.WriteLine();

        for (int i = 0; i < 15; i++)
            Console.WriteLine(Right("1234567890", i));

        // Wynik działania:
        //
        //1
        //12
        //123
        //1234
        //12345
        //123456
        //1234567
        //12345678
        //123456789
        //1234567890
        //1234567890
        //1234567890
        //1234567890
        //1234567890
        //
        //
        //0
        //90
        //890
        //7890
        //67890
        //567890
        //4567890
        //34567890
        //234567890
        //1234567890
        //1234567890
        //1234567890
        //1234567890
        //1234567890
    }
}

Powered by BlogEngine.NET 1.5.0.7
Theme by Mads Kristensen