Jump to page: 1 26  
Page
Thread overview
Şablonlar ile yığın sınıfı
Jul 03, 2012
zafer
Jul 04, 2012
Kadir Can
Jul 04, 2012
zafer
Jul 04, 2012
Kadir Can
Jul 04, 2012
Kadir Can
Jul 04, 2012
Salih Dinçer
Jul 04, 2012
Salih Dinçer
Jul 04, 2012
zafer
Jul 04, 2012
Kadir Can
Jul 04, 2012
zafer
Jul 05, 2012
Salih Dinçer
Jul 05, 2012
Kadir Can
Jul 05, 2012
Kadir Can
Jul 05, 2012
Salih Dinçer
Jul 05, 2012
Kadir Can
Jul 05, 2012
Salih Dinçer
Jul 05, 2012
zafer
Jul 06, 2012
Salih Dinçer
Jul 06, 2012
zafer
Jul 06, 2012
Salih Dinçer
Jul 06, 2012
zafer
Jul 05, 2012
Salih Dinçer
Jul 08, 2012
zafer
Jul 09, 2012
zafer
Jul 09, 2012
Salih Dinçer
Jul 09, 2012
zafer
Jul 09, 2012
zafer
Jul 09, 2012
Kadir Can
Jul 10, 2012
Salih Dinçer
Jul 10, 2012
zafer
Jul 10, 2012
Kadir Can
Jul 31, 2012
Salih Dinçer
Aug 01, 2012
Salih Dinçer
Aug 01, 2012
Salih Dinçer
Aug 01, 2012
Salih Dinçer
Aug 01, 2012
Salih Dinçer
Aug 02, 2012
zafer
Aug 02, 2012
Salih Dinçer
Aug 02, 2012
erdem
Aug 02, 2012
zafer
Aug 03, 2012
erdem
July 04, 2012

Bir süredir şablonlara karşı müthiş bir ilgi duyuyorum. Daha öncesinde hiç kullanmadım. İlk C++ ile tanıdım ama hepsi o kadar daha sonra C#'ın generic programlama (http://www.asp.net.tr/Makale/897-C--Generic--programlama-Giris-I.aspx) yaklaşımı ile biraz daha yakından ilgilenme fırsatım oldu. Şimdilerde ise D dilinin sağladığı olanak olarak ilgimi çekiyor. Özellikle şablonlar hakkında şuradaki yazıdan (http://www.bilisim-kulubu.com/sozluk/sozluk.php?e=generics) sonra daha yakından incelemeye ve öğrenmeye karar vardim.

Bu sebeple şablon olarak hazırlanmış bir yığın sınıfı yazmaya çalışıyorum. Gerçi tam kodlamayı yaptım dersaneye bir göz atayım dedim. Ali'nin yazdığı ve aynı mantıkta olan yiğin sınıfını gördüm. Eklesem mi diye düşünürken belki üzerinde farklı konularda bilgi paylaşımı olur düşüncesi ile kodu ekliyorum.

import std.stdio;
import std.exception;

class Yigin(T)
{
   private int konum;
   private T[] yigin;

   public this(int kapasite)
   {
       enforce(kapasite >=0, "Yigin buyuklugu negatif olamaz!");
       yigin.length = kapasite;
       konum = -1;
   }

   public void Push(T)(T deger)
   {
       if (konum == yigin.length)
       {
           throw new Exception("Yigin dolu");
       }

       konum++;
       yigin[konum] = deger;
   }

   public T Pop()
   {
       if (konum == -1)
       {
           throw new Exception("Yigin bos");
       }

       return yigin[konum--];
   }
}

void main()
{
   Yigin!(string) stack = new Yigin!(string)(10);

   stack.Push("ben");
   stack.Push("bir");
   stack.Push("D");
   stack.Push("Dili");
   stack.Push("yigin");
   stack.Push("sinifiyim");

   for (int i = 0; i < 6; ++i)
   {
       writeln("Deger : ", stack.Pop());
   }
}

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

July 04, 2012

Eline sağlık zafer, güzel kodlar.
Böyle bir yapıyla foreach kullanmak iyi olurdu.Son giren ilk çıkar(LIFO) yapısını koruyarak;


import std.stdio;
import std.exception;

class Yigin(T)
{
   private int konum;
   private T[] yigin;

   public this(int kapasite)
   {
       enforce(kapasite >=0, "Yigin buyuklugu negatif olamaz!");
       yigin.length = kapasite;
       konum = -1;
   }


   public void Push(T)(T deger)
   {
       if (konum == yigin.length)
       {
           throw new Exception("Yigin dolu");
       }

       konum++;
       yigin[konum] = deger;
   }

   public T Pop()
   {
       if (konum == -1)
       {
           throw new Exception("Yigin bos");
       }

       return yigin[konum--];
   }

   int opApply(int delegate(ref T) islemler)
   {
       int sonuc;
       for(int i = yigin.length - 1; i >= 0; --i){
           if( yigin[i] != null ){
              sonuc = islemler(yigin[i]);
           }
       }
       return sonuc;
   }
}

void main()
{
   Yigin!(string) stack = new Yigin!(string)(10);

   stack.Push("ben");
   stack.Push("bir");
   stack.Push("D");
   stack.Push("Dili");
   stack.Push("yigin");
   stack.Push("sinifiyim");

   foreach (eleman; stack)
   {
       writeln("Deger : ", eleman);
   }
}

Ayrıca tasarım açısından üye işlevlerde hata atma kısmı in bloklarına alınsa daha düzenli olabilir ama sanırım bu blokları kullanmayı pek sevmiyorsun. :)

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

July 04, 2012

Alıntı:

>

Ayrıca tasarım açısından üye işlevlerde hata atma kısmı in bloklarına alınsa daha düzenli olabilir ama sanırım bu blokları kullanmayı pek sevmiyorsun. :)

Koda bakmadim ancak hatalar icin enforce ve throw kullanildigina gore kullanici kaynakli hata olabilir. sozlesmeli programlama yaparsak dmdye verecegimiz komut ile bu hatalari bakmayi istemeden iptal edebiliriz. Onun icin inde olmamali.

foreach ise stack.Pop uye islevini kullanmak icin kullanmamis.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

July 04, 2012

Alıntı (Kadir Can):

>

Eline sağlık zafer, güzel kodlar.
Böyle bir yapıyla foreach kullanmak iyi olurdu.Son giren ilk çıkar(LIFO) yapısını koruyarak;

Teşekkürler Kadir, aslına bakarsan öncelikli amacım şablon sınıfına yoğunlaşmaktı. Bu sebeple diğer olanakları biraz göz ardı ettim.

Güvenlik konusunda ise (in blokları) bu konuda sunum yapmış birisi olarak :) çok abartılmamalı diye düşünüyorum. Eminim hepimizin evinin giriş kapısında iki veya üç kilit var ancak on tane kilit olan bir kapı ben hiç görmedim. Yinede yazdığın gibi belki sözleşmeli programlama ile ilgili bazı olanaklardan faydalanılabilir. Örneğin 'invariant' olanağını gerçeklemeye ne dersin ?

Ayrıca bu kodu eklerken bunun üzerine bir iki şey yazarız diye düşünmüştüm. Ancak Kadir'in opApply gerçeklemesi gerçekten çok hoşuma gitti. Eline sağlık Kadir çok güzel olmuş.

Ben opApply içindeki if kontolünden kurtulmak için kodu şöyle düzenlemeye çalıştım. Birde siz bakın nasıl olmuş, bir eksik veya hata var mı? Ne dersiniz ?

   int opApply(int delegate(ref T) islemler)
   {
       int sonuc;
       for(int i = konum; i >= 0; --i)
       {
           sonuc = islemler(yigin[i]);
       }
       return sonuc;
   }

Alıntı (canalpay):

>

foreach ise stack.Pop uye islevini kullanmak icin kullanmamis.

Can, aslında hem evet, hem hayır :) önce bende foreach düşündüm ama dediğim gibi hem şablon olanağına odaklandığım için, hemde kodlar mümkün olduğunca sade olsun diye for döngüsünü kullandım. for'u özlemişim bu arada uzun zamandır neredeyse hiç kullanmamıştım :)

Son olarak Kadir'den aldığım şevk ile bende foreach olanağını gerçeklemek için sınıf üzerinde aralık yapısını kodlamaya karar verdim. Biraz uğraştıktan sonra şöyle bişey oldu. Eğer hata yoksa ilk aralık gerçeklememi yazmış oldum :)

import std.stdio;
import std.exception;

class Yigin(T)
{
   private int konum;
   private int bas;

   private T[] yigin;

   public this(int kapasite)
   {
       enforce(kapasite >=0, "Yigin buyuklugu negatif olamaz!");
       yigin.length = kapasite;
       konum = -1;
   }

   public void Push(T)(T deger)
   {
       if (konum == yigin.length)
       {
           throw new Exception("Yigin dolu");
       }

       konum++;
       yigin[konum] = deger;
   }

   public T Pop()
   {
       if (konum == -1)
       {
           throw new Exception("Yigin bos");
       }

       return yigin[konum--];
   }

   bool empty() const
   {
       // Aralıktaki eleman mevcudunu denetler.
       // true ise eleman bitmiştir.
       return (konum < 0);
   }

   void popFront()
   {
       // Bir sonrakine geçmek, mevcut eleman
       // sıramızda her defasında sondan bir tane
       // dışarı çıkarmak
       --konum;
   }

   string front() const
   {
       // ilgili konumdaki elemanı bize verir
       return yigin[konum];
   }
}

void main()
{
   Yigin!(string) stack = new Yigin!(string)(10);

   stack.Push("ben");
   stack.Push("bir");
   stack.Push("D");
   stack.Push("Dili");
   stack.Push("yigin");
   stack.Push("sinifiyim");

   foreach (kelime; stack)
   {
       writeln("Deger : ", kelime);
   }
}

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

July 04, 2012

Doyurucu bilgiler için teşekkürler.Özellikle veri yapılarında sıkıntım var, D.ershane bittikten sonra çalışmam gerek.
in ile ilgili bir sorum var, eğer hata düzeltilemeyecek seviyede değilse assert() veya enforce() yerine hata atmak daha faydalı sanırım.Peki, o zaman assert() ve enforce() kullanmak çok da mantıklı gelmiyor, çünkü madem hata atıp uyarıda bulunabileceksek, ayrıca o hataları yakalayıp sorunu programı kesmeden düzeltebileceksek programı bir anda bitirmenin gereği var mı?Çok zorunlu durumlar dışında hata atmak daha kullanışlı oluyor sanırım.
Açıkçası kafam karıştı.Belki de bu mesajdaki düşüncelerimle doğru olanı yakaladım.Siz ne düşünüyorsunuz?

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

July 04, 2012

Teşekkürler, işte şimdi her şey oturdu. :)
İlk alıntıda hata programın hemen sonlanmasını gerektirmeyecekse assert() ile tutmayacağımız bir hata atmak yerine tutacağımız hata atmanın( Orada enforce()'un da Exception türünden hata attığını gözden kaçırmışım.) daha faydalı olacağından bahsetmiştim.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

July 04, 2012

Çok güzel bir örnek...

Öyle ki bir elektronikçi olarak Zafer'i kıskandım şimdi! Çünkü benim yapmam gerekirdi...:)

Neyse önemli olan bu ilk giren son çıkar yapısını kodlamak ve kimin yaptığından çok D'de bunu temsil edebilmek. Gerçekten çok hoş ve sade bir örnek. Gerçi 'empty()' hiç kullanılmamış, örneğin şu şekilde de tüm işlevler kullanılmış olabilir:

   with(stack) {
       Push("start");
       Push("1"); Push("2"); Push("3");
       do {
           Pop.writeln;
       } while(!empty);
   }

Çıktısı:
'3
2
1
start
'
Bir de sade anlam yerine 'isEmpty()' olsa sanki daha anlamlı olacak. Çünkü ismine bakınca bunun ne işe yaradığı tam anlaşılmıyor ve biraz daha anlam katmak gerekiyor. Belki de tamamen Türkçe'ye çevirip push yerine yolla, pop yerine getir ve empty yerine de boş_mu kullanabiliriz, ne dersiniz?

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

July 04, 2012

Karışık olarak notlarım:

  • Yığın (veya bazen "yığıt"?) yapısı geleneksel olarak yalnızca üstteki elemana erişim sağladığı için foreach ile kullanılmasa da eksikliği çekilmez herhalde.

  • opApply() içinde islemler()'in döndürdüğü değere bakmayı unutuyorsunuz. O değer sıfırdan farklı ise bizim kullanıcımız kendi foreach döngüsü içindeyken 'break' demiş demektir. Ona saygı göstermeli ve sonuç sıfırdan farklı olduğunda biz de opApply()'dan çıkmalıyız.

  • Başkalarının da söylediği gibi, Zafer'in 'in' bloklarını kullanmıyor olması doğru. Aslında Push()'ta ve Pop()'ta da enforce kullanabilir. (Ama sunumunu yapmış birisi olarak istediği yöntemi de seçebilir. ;))

  • Benim de son zamanlarda farkına vardığım bir konu var: Topluluklarla aralıkları birbirlerinden ayrı tutmak gerek. Eğer Yığın bir topluluksa, foreach onun üzerinde değil, onun bir aralığı üzerinde ilerlemelidir. Yoksa ilerledikçe topluluğu tüketmiş oluruz.

Bunun örneğini biraz olsun dilimlerde görüyoruz. Dilim üzerinde foreach ile ilerlendiğinde asıl elemanlar kaybolmazlar, o dilimin eriştirdiği eleman adedi azalır. Oysa Yığın'da ilerlendikçe elemanlar asıl topluluktan eksiliyorlar.

Doğrusunu isterseniz Yığın gibi bir yapıda bunun bir çözümü de olmamalı. Eğer Yığın yukarıda dediğim gibi hep en üsttekine eriştiren bir topluluk ise zaten üzerinde ilerlemek tanım gereği eleman kaybettirmelidir.

Neyse... Bu son söylediğim madde aklımızda bir iz bıraksın yeter. Yığın için yapacak bir şey yok gibi...

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

July 04, 2012

Az önce aşağıdaki kodun istediğimiz zaman hata döndürmediğini, yukarıdaki bir sınıftan core.exception'a takılıp "Range violation" hatasını verdiğini farkettim:

   public void Push(T)(T deger)
   {
       if (konum == yigin.length)
       {
           throw new Exception("Yigin dolu");
       }

       konum++;
       yigin[konum] = deger;
   }

Yığın boş olduğunda sorun yok ve hatayı yakalayabiliyorum. Sanki büyük eşit (>=) yapılırsa sorun düzeliyor. Bir de buna şu şekilde try/catch kümesi eklersek harika olabilir.

   try {
       with(stack) do Pop.write(", "); while(!empty);
       stack.Pop.writeln; // boşalmış yığından hata döndürecek...
   }
   catch (Exception hata) {
       writeln("Sorun var:", hata);
   }

Dip Not: Yukarıda verdiğim kodu tek satırda kısalttığım için kusura bakmayın. Tekrar olmasın dedim bir de her zaman ki alışkanlığım işte...:)

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

July 04, 2012

Alıntı (Kadir Can):

>

eğer hata düzeltilemeyecek seviyede değilse assert() veya enforce() yerine hata atmak daha faydalı sanırım.

Oradaki birden fazla olumsuz anlam benim anlamamı güçleştiriyor. :) Ayrıca hem assert() hem de enforce() hata attıkları için onların "yerine hata atmak" demen kafamı karıştırıyor.

Alıntı:

>

Peki, o zaman assert() ve enforce() kullanmak çok da mantıklı gelmiyor, çünkü madem hata atıp uyarıda bulunabileceksek, ayrıca o hataları yakalayıp sorunu programı kesmeden düzeltebileceksek programı bir anda bitirmenin gereği var mı?

Eğer patlayan assert() ise evet, programı hemen sonlandırmak gerekir çünkü programladığımızı sandığımız mantığın dışında hareket etmektedir. İşte bu yüzden assert() Assert veya ondan türemiş olan bir hata atar. Assert'ün veya ondan türemiş olan bir hatanın yakalanması ise hiç önerilmez. Hatta D bu tür bir hata atıldığında yığıtın temizliği konusunda da hiçbir garanti getirmez. Durum çok kötüdür ve bu yüzden işlemlerin hemen sonlanmaları şarttır.

Eğer patlayan enforce() ise, zaten programı sonlandırmıyoruz; bir hata atıyoruz. Bizi çağıran düzeylerdeki bir kod o hatayı yakalayabilir ve gereken önlemi alabilir. Zaten enforce()'un etkisi şundan başka bir şey değil:

if (!koşul) {
   throw new Exception(/* ... */);
}

Görüldüğü gibi, enforce() Exception türünde bir hata atar. Assert'ün tersine, bu tür hatalar yakalanabilirler.

Benim izlediğim ilkeler:

in bloğunda assert'ler: Bu programın, modülün, sınıfın, vs. mantığı ile ilgili olan doğruları denetlemek için.

İşlev içinde enforce'lar: Bu işlevi çağıran kullanıcıların gönderdikleri parametreleri denetlemek için.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

« First   ‹ Prev
1 2 3 4 5 6