Amazon Mechanical Turk 101

February 17, 2007

"Beta" tipi alternatif web hizmetleri verme modası sürerken Amazon'un son hizmeti gerçekten ilgi çekici. :)

Amazon Mechanical Turk, resmi tanımı ile bir çeşit yapay yapay zeka.

Bilgisayarların çözmesi gerçekten zor olan, karmaşık desenler içinden anlamlı imgeler bulmak gibi görüntü işleme görevlerini bilirsiniz. Hatta bu tür uygulamalar web'de otomatik form doldurmayı engellemek gibi gündelik yaşamda da karşımıza çıkar. İnsanlar için saniyelik, basit işler olmasına rağmen bilgisayarların oldukça zamanını alan görüntü işleme ve buna benzeyen semantik görevleri yerine getirmek için sunulabilecek en basit çözüm herhalde bilgisayarları aradan kaldırıp insanları kullanmak olurdu... Ve oldu da..

Lafı dolandırmayı (belki de daha açıklayıcı olmak adına) ne kadar çok sevsem de basitçe Amazon'un yeni hizmeti ile artık web'de form doldururken karşınıza çıkan "insan olma" testlerini yaparak para kazanabileceğinizi söylesem iyi olacak.

Sistem basitçe şöyle çalışıyor :

  1. (Her zamanki gibi ne yazık ki) Üye oluyorsunuz. (ama beleş tabii)
  2. HIT (Human Intelligence Task ;) ) kategorinizi seçiyorsunuz. (Görüntü analizi, web sitesi semantik tanımlaması gibi)
  3. HIT'inizi gerçekleştiriyorsunuz. (Resim için örneğin rastgele gelen uydudan çekilmiş deniz fotoğrafında bir tekne mevcut mu? veya "Verilen bir web sitesini en iyi tanımlamak için hangi üç tümceyi kullanırsınız?" gibi)
  4. Bu gibi her iş karşılığı $0,07 gibi bir ücret kazanıyorsunuz.

Bağlamam gereken son konu sanırım "Turk" isminin nereden bu konuya karıştığı. Amazon buna cevabı da eksik bırakmamış. Anladığımız kadarıyla konu Avrupa tarihi ile de ilgili. 1976 yılında, Wolfgang von Kempele isimli Macar soylusu, aralarında Napolyon ve Benjamin Franklin (Amerika?) da bulunan bir çok kişiyi yenen tahtadan yapılmış bir otamat yapar. Bu dişli ve çarklar yardımıyla hareket eden manken, kaftan ve sarıkla giydirildiği için adına "Mekanik Türk" denir. Sonradan kuklanın içine saklanmış bir satranç ustası olduğu da ortaya çıkar tabi.

Bu bağlamda Amazon'un hizmetinde, kukladaki satranç ustaları kullanıcılar oluyor sanırım :).

Geçtiğimiz yıllarda (çok önce geçtik ama), Internet Explorer'ın Windows'a entegrasyonu üzerine bir çok tartışma ve davaya şahit olduk. Hatta Amerikan anti-tekel yasalarına göre Microsoft bölünecek, Windows'la ilgilenen departman ayrılacak, Office'le ilgilenen departman ayrılacak gibi söylentiler etrafta dolaşıyordu. Devam eden yıllarda bildiğim kadarıyla bu söylemler gerçekleşmedi. Hatta artık bir çok MS ürünün IE'dan fazlasıyla yararlandığını hepimiz biliyoruz.

Geçenlerde MSDN Help sisteminde bir makale okurken, gerekli araç çubuğu ikonuna tıklayarak yazı puntosunu büyülttüm. MSDN okumamı bitirdikten sonra web'de dolaşırken bir de baktım ki Internet Explorer'da puntoları büyük gösteriyor! Entegrasyon ve bileşenleri tekrar-kullanım mantığını anlayabilirim ama yapılandırma veya ayar dosyalarının uygulamaya özel olması gerekmez mi?

DataTable.Clone() Hakkında

February 15, 2007

Belki geç kalmış bir bilgi ama yakın zamanda başıma geldiği için dikkat çekmek istedim,

Diyelim ki içinde veriler bulunan bir tabloyu çoğaltmak için DataTable.Clone() + ImportRow() yapmak istiyorsunuz, böyle bir durumda bu DataTable örneğine ait DefaultView (yani varsayılan DataView) e atanmış bir filtre (DataView.RowFilter) tanımlanmışsa bu filtrenin klonlanarak oluşturulmuş yeni DataTable'da yer almayacağını unutmamalısınız...

Örneğin : DataTable dtOrijinal = new DataTable(); ... dtOrijinal.DefaultView.RowFilter = "Isim = 'Ahmet'"; Console.WriteLine("Orijinal Filtre: " + dtOrijinal.DefaultView.RowFilter); ... DataTable dtClone = dtOrijinal.Clone(); Console.WriteLine("Klonun Filtresi: " + dtClone.DefaultView.RowFilter); şeklindeki bir kod parçacığı...

Orijinal Filtre: Isim = 'Ahmet' Klonun Filtresi:
şeklinde bir çıktı oluşturur.

Kısaca belirtmek gerekirse klonlar veriyi içermediği gibi filtreleri de içermiyor!

Ek olarak filtrelenmiş bir DataTable'ın satırları içinde dolaşırken filtre dışında kalan satırlara da ulaşırsınız. Dolayısıyla filtre edilmiş bir DataTable'daki verileri bir klona aktarırken satırları değil de DefaultView satırlarını dolaşmalısınız.

Örneğin sadece filtre kuralına uyan satırları import etmek istenen bir durumda aşağıdaki kod parçası istenen sonucu üretmez: foreach (DataRow dr in dtOrijinal.Rows) { this.dtClone.ImportRow(dr); } ...ama aşağıdaki kod parçası ile sadece filtre kuralıana uyan satırlar alınabilir: foreach (DataRowView drv in this.dtOrijinal.DefaultView) { this.dtClone.ImportRow(drv.Row); }

Ozan'a Selam

February 3, 2007

Web güncesi tutanlar arasına sevgili Ozan Günceler de katıldı. Bu noktada "Günceler'den günce tutmasını uzun zamandır bekliyorduk!" esprisi yapmamaktan kendimi alı koyamayacağım. :) Özellikle Active Directory üzerinde çalışan makinalar, LDAP gibi konuların .NET tarafından değerlendirilmesi ve yönetilmesi gibi kullanışlı konular üzerine girişler yapmayı düşünen Ozan'nın günlüğüne aynı Ejder'in ki gibi devamlılık dilerim. Yazılarını ilgiyle takip edeceğiz Ozan'cım. Hoşgeldin ;)

Bu konunun büyütüldüğünü ve aslında her aklı başında insan gibi hırsızlara karşı mal varlığını savunduğunu düşünebilirsiniz ve aslında bir yere kadar haklısınızdır da, ama Bill Gates'in korsan yazılımla savaşı gerçekten tarih öncesine dayanıyor ve insan merak etmeden duramıyor acaba gençliğinde korsan yazılımlar yüzünden açık kaynak kodlu yazılıma karşı kompleksler edinmiş midir?

Bu noktada yazılım geliştirerek hayatını kazanan biri olarak konu hakkındaki kişisel görüşüm hakkında ipucu vermem gerekiyor. Dolayısıyla korsan yazılıma karşı olduğumu hatırlatayım...

Homebrew Computer Club Newsletter

Yukarıdaki belge, Steve Wozniak gibi zamanın bilgisayar dahilerinin de üye olduğu Stanford Lineer Parçacık Hızlandırıcı çatısı altında faaliyet gösteren, insanların hobi elektroniği şeklinde ev yapımı bilgisayarlar üretip paylaştığı Homebrew Computer Club'ın haber bülteninde 1976 tarihinde yayınlanan Bill Gates imzalı bir mektup. İnsan bakıp tarih tekerrürden ibarettir demekten kendini alamıyor. :)

Ejder'e Selam

January 31, 2007

Merhabalar, uzun süredir çeşitli sebeplerle yaz(a)madığım günlüğüme hayırlı bir haberle geri döneyim istedim.

Eski çalışma arkadaşım ve dostum Ejder Kuvemli web günlüğü tutmaya başladı. Bence içerdiği değerli bilgilerle devamlı takip edilebilecek bir şeyler ortaya koyuyor.

Kendisine benim aksine devamlılık diliyorum. Günlüğüne buradan ulaşabilirsiniz.

Evet Visual Studio 2005 hakkında yazdıklarımı tekrar okuyunca durumu dengelemek gerektiğini düşündüm :). Sonuçta kıyaslayınca VS hala çok başarılı ama bazı hataları olacak tabi ;). Neyse yine VS'yi çekiştirmeden konumuz JBuilder'a geçelim :).

  • VS2005 ile gelen (bak yine!) main()'in ayrı bir Program.cs gibi bir dosyada olması zaten uzun süredir Java'cıların standart şekliydi. JBuilder'da da bu bağlamda bir MyApplication.java bir de MyFame.java gibi iki dosya oluşturur. MyFrame.java'da JFrame veya Frame'den türeyen sınıfın kaynak kodu bulunurken, tahmin edilebileceği gibi MyApplication.java'da bu frame'i SwingUtilities.invokeLater() ile veya direk show() diyerek mesaj döngüsünü başlatan main()'in kaynak kodu bulunur. Bu şekilde herşey sağlıklı giderken siz eski .NET alışkanlığı ile gelip Frame'in içine kendini invoke eden main()'yazarsanız o zaman JBuilder işleri biraz karıştırıyor... Frame'in kod görünümünden tasarım görünümüne geçerken bir anda içi boş başlıksız ve daha kötüsü windowClosing() WindowEvent'i (siz gerekli kodu yazmış olsanız bile) handle edilmemiş bir hayalet pencere beliriyor. Bu pencereyi (neyseki) iconify edip işinize devam ettikten sonra her kod görünümünden tasarım görünümüne geçişte yeni bir hayalet pencere beliriyor. :) Dolayısıyla görev çubuğunuz dolunca JBuilder'ı kapatıp tekrar açmanız gerekiyor... Aslında hiç kasmadan o main()'i oradan çıkarmak en iyisi ama yine de bu bir bug...
  • Uzun süre inaktivitede mesala gorev çubuğuna indirip bir süre geçtkten sonra tekrar kendine gelmesi uzun süre alabiliyor hatta gelemeyebiliyor. Program muadili Oracle JDeveloper gibi Java ile yazıldığı için ve sağ alt köşede heap bellek miktari ile GarbageCollector simgesini görünce insan JBuilder'ın kendini topladığını düşünüyor :).

Her ne kadar piyasadaki (Java IDE leri dahil) en sağlam IDE'lerden biri olduğunu düşünsem de Visual Studio'nun yeni sürümü, eski sürüm Visual Studio 2003'e göre kesinlikle daha az stabil. Etrafımdaki bir çok kişi C# editörünün background compiling ile daha başarılı hale geldiğini söylese de genel IDE deneyimi olarak daha az verim alındığını düşünüyorum. Şimdiye kadar beni en çok rahatsız eden kusurları sıralamak gerekirse :

  • Hiding Panel'lerin hide etmemesi, daha çok sol tarafta bulunan "Solution Explorer" ve "Properties" panellerinde karşılaştığım bu sorun beni gerçekten çileden çıkarıyor. Sabitleme raptiyesi basılı değilken panel kendiliğinden kayarak hide etmesi gerekirken donup öylece kodunuzun üzerinde kalıyor. Paneli sabitleyip (raptiyeye tıklayarak) tekrar auto-hide moduna sokmak (raptiye ye bir daha tıklayarak) zorunda kalıyorsunuz. Brrr!
  • IDE'nin Bir anda kapanması, uzun süredir bir tik haline gelen CTRL+S hareketim yüzünden şimdiye kadar bir veri kaybına yol açmadı ama gerçekten rahatsız edici.
  • Toolbox'ın resetlenmesi, özellikle önceki maddede söylediğim olaydan sonra gereçekleşen ve 3rd party component kurulumları ile gelen tabların, (componentleri uninstall edip tekrar kurmaya üşenme sonucu) dandik versiyonlarının oluşturulması için gerekli .dll(ler)i bulup refere edilmesini gerektiren gerçekten rahatsız edici bir şey. Tek kaybettiğiniz 3rd party controllerin kısayolları değil ama kendi türemiş veya UserControl'lerinizin kısa yolları da ki bu bir tane daha madde demek bz. aşağı :)
  • Diyelim ki bir sebepten dolayı Toolbox'ınız resetlendi (!), veya yeni bir UserControl yaptınız ve bunu Toolbox'ınıza koymak istiyorsunuz. Eğer UserControl'ünüz programınızın .exe'sinin olduğu projede ise Toolbox'dan "Choose Items..." deyip kendi projenizi yine kendi projenize "Browse..." diyerek refere etmeniz gerekiyor. Ve bu işlemde gayet çalışıyor :). Yalnız ugulamayı derlerken warning almanız olası. Çünkü UserControl'ü kullandığınız yerde derleyici iki tane referansla karşılaşıyor biri yerel assemble içindeki diğeri ise refere edilmiş. Dolayısıyla birini seçiyor (hangisini diye sormayın :)). Bunu daha sonra o referası silerek düzeltebiliyorsunuz ama UserControl, Toolbox'ınızda kalmaya devam ediyor... evet kabul ediyorum uzundu...
  • Form'dan türeyen (yada designer.cs ve resx alt dosyalarına sahip diyelim) .cs dosyalarınızı kopyalayıp isimlendirirken dikkatli olun!

.Net Framework 2.0 da C# ile object tipi bir nesneyi alıp bunu integer bir değere dönüştürürken acaba hangisi daha performanslıdır :

object deger = 1492; int.Parse(deger.ToString()); // Bu mudur? Convert.ToInt32(deger); // Yoksa bu mu? Lutz'un Reflector'ü ile mscorlib.dll'i açıp kodları incelediğimizde kesin yargıya ulaşamıyoruz. En iyisi gözlerimizle görmek diyerek konu hakkında minik bir uygulama yazdım.

Tester Uygulaması

public partial class Form1 : Form   
{   
object kurban = 1492;   
int sonuc;      

private void btnConvertTo_Click(object sender, 
    EventArgs e)   
{   
    for (int i = 0; i < 9000000; i++)   
    {   
        sonuc = Convert.ToInt32(kurban);   
    }   
    MessageBox.Show("Bitti!");   
}      

private void btnIntParse_Click(object sender, 
    EventArgs e)   
{   
    for (int i = 0; i < 9000000; i++)   
    {   
        sonuc = int.Parse(kurban.ToString());   
    }   
    MessageBox.Show("Bitti!");   
}  

}
Sonuçlara baktığımızda "ToString + int.Parse" butonuna tıkladığımızda 6sn sonra "Bitti!" mesajını görürken, "Convert.ToInt32" butonu 1sn içinde bize "Bitti!" mesajını gösterebiliyor.

Sizce hangisi daha performanslı?

WSOD Örneği Visual Studio .NET 2003'ten Visual Studio 2005'e geçenler yeni bir hata mesajı ile tanıştı. Bu mesaja MS çalışanları tarafından "Blue Screen of Death"e bir gönderme olarak "White Screen of Death" adı takılmış ama kullanıcılar hatanın "fatal" sonuçlar doğurmadığı ve rastgele gelebilmesi ihtimali üzerine bunu hayal kırıklığını temsil eden "White Screen of Darn" şeklinde yeniden adlandırmış. WSoD'ı Windows projelerinde bir formun design görünümünü açıldığında beyaz pencere üzerine hata mesajı, stack trace ve kırmızı bir çarpı şeklinde ortaya çıkıyor. Hatayı verilen mesajdan daha iyi belirlemenin ve engellemenin yolu bir codeproject makalesinde açıklanmış. Ama önerilen yöntem runtime'da olması gereken pencere görünümünü design time da doğru olarak görünmemesi ile sonuçlanabiliyor, kısacası WYSIWYG düşünüşüne biraz aykırı bir çözüm. (Ctor'da "if(this.DesignMode) return;" gibi bir kod tavsiye ediliyor.) Neden böyle bir hata mesajının VS 2003'te olmadığı ama VS 2005'e konulduğu vede doğasını Raghavendra Prabhu'nun MSDN blogundan okuyabilirsiniz.