27 Ocak 2010 Çarşamba

Microsoft Expression Blend 3 SketchFlow İncelemesi

Microsoft geçen aylarda Expression ürünü piyasaya sürdü, veya ben yeni tanıştım :) Sizde tanışmak isterseniz buradan resmi sitesine erişebilirsiniz.

Çalıştığım şirket Expression içerisinde olan SketchFlow kullanımını incelememi istedi, bende inceleme sonuçlarını sizlerle paylaşmak istedim. Burada sadece Blend için bir SketchFlow projesi üzerine inceleme yaptım. WPF değil, "Silverlight 3 SketchFlow Application" projesi oluşturdum ve buradaki eğitim videolarını kullandım. Jeremy Osborn adlı birisi anlatımı yapıyor. 2009 Haziran ayında kaydedilmiş, henüz ürün betayken. Eğitim video sayfasında "Download the assets, step-by-step guide, and video package (127MB)" linkinden tüm ilgili videoları ve örnek kodları tek seferde indirebilirsiniz.

SketchFlow projelerinin amacı, özellikle web projelerinde, sayfa tasarımlarının en başta, tahta veya kağıt üzerinde çizilmesi yerine bilgisayar ortamında yapılmasına imkan vermek. Kağıda çizerek "abi bu olmuş mu" demek yerine, biraz daha çaba göstererek SketchFlow projesi oluşturursak bize ne avantajlar sağlıyor önce buradan başlayalım.

SketchFlow kullanıldığında, isteğinize göre el çizimine benzer şirin kontroller veya daha ciddi duran, web kontrolleri kullanma imkanınız var. Buradaki tercihimiz, ürünü kullanım amacımıza göre değişebilir. Örneğin şirket içinde kendi geliştirme akışımızda ürünü kullanacaksak, çok ciddi ekranlara ihtiyacımız yok, amacı net ortaya koyan ekranlar yeterli olabilir. Amacımız müşterilere yönelik bir sunum yapmak ise, -örneğin bir demo sunumu- animasyonlar ile süslenmiş ve ciddi tasarlanmış ekranlar seçilebilir.

Bu ürünü istediğimiz gibi kullanmakta özgürüz ancak ürün müşteri sunumları için tasarlanmış değil. Genede kullanılabilir, sadece müşterilere bu demonun amacının ne olduğu çok itina ile izah edilmeli :)

Teknik konulara girersek, SketchFlow'un en büyük özelliği çok basit bir şekilde sayfa hareketlerinin tanımlanmasını sağlaması. Bir sayfa eklediğimizde, sıradaki sayfanın ne/neler olacağını, nasıl bir akış ile ilerleneceğini ayarlamak gerçekten çok basit ve kullandığımız yazılım (IDE) bu konuda işlevsel. Sayfalarda UserControl ve ComponentScreen olarak kontroller tanımlayabilir ve bunları istediğimiz tüm sayfalara sürükle-bırak yöntemi ile ekleyebiliyoruz.

Butonlara geldiğimizde şu nokta önemli, butonun tek bir işlevi olmalı, bir kontrolün yapacağı işlem başka kontrole bağımlı olmamalı. Yani eğer butona ilk basıldığında şu olsun, sonrasında tekrar basılırsa bu olsun derseniz script kullanmanız gerekecek. Veya şu checkbox seçiliyse butona basıldığında bu olsun derseniz gene aynı şekilde script kullanmanız gerekecek. Script kullanma durumlarını ben incelemedim ve videolarda bu kısım geçmiyor, bir tek yerde script kullanılması gerekli ama bu bizim konumuz dışında şeklinde bir uyarı vardı. Kısacası script kullanımı kolay mıdır, zor mudur benim bir bilgim yok.

Sayfalarımızı basit tasarladığımızda, duruma göre davranan kontrollerden kaçındığımız durumlarda, SketchFlow bize çok büyük zaman kazandırabiliyor. Hem kısa zamanda güzel görsel bir sonuç elde ediliyor hemde aşağıda açıklayacağım farklı imkanlardan faydalanmamızı sağlıyor.

Animasyon konusuna da değinmek isterim, daha önce hiç animasyon ile uğraşmamış bir kişi olarak Silverlight SketchFlow projelerindeki animasyon imkanları gerçekten çok hoşuma gitti. Butona tıklandığında neler olacak, göstermek isterseniz, bunu inanılmaz kolay bir şekilde yapabiliyorsunuz. İşte bu yetenek, özellikle müşterileri görsel olarak etkileyecek bir sunumda çok faydalı olacaktır. Bu iş için tasarımcı ayıramayan şirketlerde; ön satış, satış hatta teknik ekipler bile etkileyici animasyonlar hazırlayabilirler.

Peki projemizi bitirdik, şimdi ne olacak.
Öncelikle karşımıza beklediğimiz şekilde bir web sitesi çıkmayacak. Silverlight SketchFlow projelerini "package" oluşturarak çalışır hale getirebiliyorsunuz. SketchFlow Player aracılığı ile sayfları gezebiliyorsunuz, bu player İnternet Explorer ile veya farklı bir browser ile, silverlight yüklü bir bilgisayarda açılabiliyor. Burada önemli nokta şurada, browser ile açabiliyor olmamız, elimizde web sayfaları olduğu anlamına gelmiyor. Basitçe player sayfaları gezme imkanını bize sunuyor. Player yoksa gezecek birşeyimiz de yok :)

Player sadece sayfları gezme imkanı vermiyor, altta map ile tüm sayfaları ve birbirlerine bağlantılarını bize gösterebiliyor. Sayfa sayımız arttıkça bu bağlantıları incelememiz zorlaşıyor, yani bu map kızmını akış çıkarmak için kullanmak pek olası değil. Sayfayı gezerken yan tarafta, o sayfanın etkileşimde olduğu diğer sayfaları ve o sayfa içerisindeki eventlerin neler olduğunu görebiliyoruz. Blend içerisinde bu işlemin adı event değil, sanırım behavior terimi kullanılıyor.

Player ile yapılan sayfaları gezen kişiler, ekran ile ilgili yorum, öneri ve isteklerini player aracılığı ile kaydedebiliyor. Bu çok uygun geri dönüşler alınmasına imkan sağlıyor. İzleyen kişi ekrana çizim yaparak müdahale edebiliyor, bu çizimler bizim projemizi bozmuyor. Çizim yanında yan tarafa not ekleyebiliyor, veya bazı yazıları "highlight" edebiliyor. Sonrasıda bunu bir "feedback" olarak kaydediyor ve projeyi yapana gönderiyor. Burada sadece feedback dosyasının gönderidiğini ve projenin tamamının gönderilmediği önemli. Projeyi yapan kişi, feedback dosyasını açtığında, kim-nerede-ne zaman-ne yorum yapmış, ekranda neresi için öneri/istekte bulunduş detaylıca görebiliyor. Bu kısım müşterilerle olan iletişimlerde de sayfalarda mutabık kalınması konusunda son derece verimli olarak kullanılabilir.

Projenin sonunda "Export to Microsoft Word" dediğimizde, projemizdeki her sayfa için bir screenshot barındıran bir çıktı elde ediyoruz. Bu word dosyasında, içerik bilgileri dahi var, kendi anlatımımızı gereken yerlere eklediğimizde elimizde harika bir doküman oluşmuş oluyor.

Sonuç olarak, bu ürün ile amacımız, karşımızdaki kim olursa olsun, onlara bir izlenim verebilmek. Detaylara girmeden, basitçe, mümkünse animasyonlar kullanarak, know-how'ımız nedir, neler yapabiliriz, fonksiyon setimiz nedir, gibi bilgileri muhattabımıza aktarmak.
Bana göre, sunumu yapılan veya tasarlanan gerçek sistemde, müşteri için 15 bilgi alacaksak, bunların tamamını sunuma koymaya gerek yok, 2-3 tanesini yazmamız yeterli olacaktır. Burada amacımız karşımızdakine müşteri bilgilerini tutarız fikrini verebilmek. İleriki aşamalarda, hangi bilgileri tutulmalıya kadar geldiğimizde gereken alanları ekleyebilir, karşı taraftan yeni alanlar için feedback alabiliriz.

20 Ocak 2010 Çarşamba

SQL'deki Bazı Fonksiyonlar : NTILE()

NTILE msdn
Açıkçası NTILE fonskiyonuna bugüne kadar hiç işim düşmedi, ancak geçmişte böyle bir fonksiyona ihtiyacı olan kişiler varsa, onlar için hayat kurtarıcı olduğuna eminim.

Bu yazımı da okumadan önce, SQL 2005 ile gelen yeni sıra numarası fonksiyonlarının temeli olan ROW_NUMBER() fonksiyonu ile ilgili yazımı okumanızda fayda var.

NTILE() fonksiyonu, diğer sıralama fonksiyonlarından farklı olarak bir parametre ile çalışır. Parametresi NULL veya 0 olamaz. Bu parametre, dönen satırları kaç parçada gruplamak istedimiz bilgisini içerir.

Örneğin dönen 13 satırımız varsa, parametre olarak da 1 gönderirsek, her satırın sıralama değeri 1 olacaktır. Parametre olarak 13 gönderirsek sıralama değerleri, 1 den başlayacak ve 13 e kadar gidecektir. Sıralama numarasını verirken kullanılacak olan değerler OVER() içerisindeki ORDER BY kolonu ile sıralanacaktır.

Peki 13 satırı 5 grup ile sırala dersek hesaplama nasıl olacaktır?

13/5 = 2,x = 3 yani ilk grup 3 elemandan oluşacak.
10/4 = 2,x = 3, ilk 3 satır yukarıda gruplandı, 10 satır ve 4 grup kaldı geriye, 2. grupta 3 satırdan oluşacak
7/3 = 2,x = 3
4/2 = 2
2/1 = 2

Sonuç olarak NTILE(5) fonksiyonu, 13 satırımıza aşağıdaki gibi sıra numarası verecektir.

1
1
1
2
2
2
3
3
3
4
4
5
5

NTILE(5) OVER(PARTITION BY "KOLONA" ORDER BY "KOLONB") şeklinde kullanıldığı durumda, tüm satırları, KOLONA'ya göre gruplayacak ve sonrasında, her grubu kendi içerisinde KOLONB'ye göre sıralayacak ve her grubu 5 iç gruba bölecek şekilde sıralama numarasını dağıtacaktır.

Başlarda biraz karmaşık gelse de, kullandıkça mantığa alışılacaktır diye düşünüyorum, dediğim gibi benim bu fonksiyona şimdiye kadar işim düşmedi. MSDN sayfasındaki örnekler gayet güzel, AdventureWorks örnek veritabanını indirerek kendi makinanızda denemeniz faydalı olacaktır. Özellikle PARTITION BY ve ORDER BY alanlarını değiştirerek mantığı kafanızda oturtmanızda fayda var.
Ben ilk denemelerimde pek beklediğim şekilde sonuçlar alamamıştım, mantığı kafamda oturtana kadar biraz şaşı bak şaşır modunda dönen dataset'leri incelemiştim :)

15 Ocak 2010 Cuma

SQL'deki Bazı Fonksiyonlar : RANK() ve DENSE_RANK()

RANK() msdn 
DENSE_RANK() msdn

Bu yazımı okumadan önce, ROW_NUMBER() ile ilgili yazımı okumanızda fayda olacaktır. Mantığı aynı olduğu için aynı detaylara daha fazla girmeyeceğim.

Sıralama ve gruplama fonskiyonlarından birisi de RANK() fonksiyonudur. Bu fonksiyon aslında ROW_NUMBER() ne yapıyorsa aynısını yapar, tek bir farkla. Eğer ORDER BY durumunda kullanılan değer, farklı satırlar için aynıysa, ROW_NUMBER() fonksiyonu sıra numarasını arttırmaya devam eder. Hangisine ilk sırayı verir derseniz, bence diskteki fiziksel sıralamada önde olana ilk sırayı veriyor olabilir, yani Clustered Index'e göre ilk geleni veya son geleni alabilir (ASC ise ilk DESC ise son). Bu kısımdan emin değilim, açıkçası tam olarak nasıl olduğuna pek işim düşmedi.

Şimdi aynı sorgumuzu RANK() ile çalıştırırsak, göreceğimiz tek fark, ORDER BY için kullanılan değerin aynı olması durumunda, bu kayıtların tamamına aynı sıralama numarası verileceğidir. Eş kayıtların aynı numarayı almasından sonra, sıradaki kayıt ise bir sonraki numara ile devam edecektir. Mesela : 1,2,3,3,3,4,5,5,6,7,8,9........

Gene aynı sorgumuzu DENSE_RANK() ile çalıştırırsak göreceğimiz tek fark, eş sayıların sırasından sonra gelen yeni sayının, kaldığı yerden değil, gerçek sırasından devam edeceğidir. Yani bazı sıra numaraları atlanmış olacaktır. Anlatması biraz zor olduğu için direk yukarıdaki örneğe geçiyorum, hemen anlaşılacaktır. 1,2,3,3,3,6,7,7,9,10,11,12........



SQL'deki Bazı Fonksiyonlar : ROW_NUMBER()


ROW_NUMBER() msdn 
Eksikliği MSSQL'de çok uzun zaman hissedilmiş bir fonksiyondur. SQL 2005 ile aramıza katılmıştır kendisi. Basitçe, sorgumuzdaki satırların, sıra numarasını döner diyebilir. ROW_NUMBER() fonksiyonunun çalışabilmesi için OVER ile kullanılması şarttır. OVER'ın anlamı, fonksiyona, dönen datasetin, neye göre gruplanıp, neye göre sıralanacağı bilgisini aktarmaktır. ROW_NUMBER() fonksiyonu bize kaydın, dönen verilerin içerisindeki sıralamasını verecektir, orjinal tablodaki sırasını vermeyecektir, bu ilk başlarda kafamızda durumlar canlandırırken sıkça yapabileceğimiz bir hatadır. Gerçekten ihtiyacımız bu ise, tablodaki tüm kayıtları alarak ve tablodaki Primary Key ile uygun sırada sıralama yaparak (ASC, DESC) fiziksel sıralama bilgisine ulaşabiliriz.

ORDER BY ile kullanımı 
SELECT ROW_NUMBER() OVER(ORDER BY KOLON1), *
FROM TABLO 
WHERE ...
ORDER BY KOLON2

Bu şekildeki bir sorgu, WHERE şartlarımıza uygun olarak dönen kayıtları KOLON1'e göre ASC olarak sıralayacak, ilk sıradaki kayda 1 vererek ve her satırda 1 arttırarak bize satır sıra numarasını dönecektir. Buradaki sıralama kayıtların dataset içerisindeki sıralaması değildir. Yani dönen dataset içerisindeki kayıtlar KOLON2'ye göre sıralanmış olacaktır. Bu kısım başlarda biraz karışık gelebilir, özet olarak; eğer KOLON1 ve KOLON2 farklı şekilde sıralanıyorsa, yukarıdaki sorgudaki satır sayıları sıralı olarak listelenmeyecektir.


PARTITION BY ve ORDER BY ile kullanımı
SELECT ROW_NUMBER() OVER(PARTITION BY KOLON3 ORDER BY KOLON1), * 
FROM TABLO 
WHERE ...
ORDER BY KOLON2

Yukarıdaki sorgunun şu sırayla çalıştığını hayal edelim, WHERE şartlarımıza uyan kayıtlar, KOLON2' e göre sıralı olarak bize döner, ROW_NUMBER() alanı şu anda null'dır, bu kayıtlara orjinaldataset gibi bir isim verelim :) Kayıtların tamamı elde edildikten sonra, datasetimiz içerisindeki kayıtlar KOLON3'e göre gruplanır, her bir grup için kendi içerisinde KOLON1'e göre bir sıralama yapılır. Bu sıralama 1'den başlar ve 1 artarak ilerler. Her grubun kendi içerisinde sıralandığı unutulmamalıdır, yani grup sayısı kadar 1 değerine sahip ROW_NUMBER() olacaktır. Bu şekilde elde edilen satır sayıları ile orjinaldataset üzerindeki null olan ROW_NUMBER() alanı güncellenir ve elimizde son hali ile kayıtlarımız oluşmuş olur.