May 05, 2011

goto ezelden beri sorun oluşturmuştur. Aşağıdaki bağlantıdan bir alıntı:

Alıntı:

>

D'de goto'yu kullanmak için hiçbir neden yoktur.

İç içe döngülerden veya switch deyimlerinden hangisinin etkileneceğini belirtmek için break ve continue deyimlerinde etiket belirtilebilir.

http://ddili.org/ders/d/etiketler.html

Ali

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

May 05, 2011

Alıntı (acehreli):

>

Alıntı (erdem):

>

bir bilgisayarda Commodore'dan da önceydi galiba böyle

Dikkat! Yaşın belli oluyor. :-p

Evet yaşlanıyoruz artık :) Hımm. Düşündüm de bu Commodore'lardan epey sonraymış. 90'lı yıllarda. Üzerinde windows ya da linux yoktu ama bir satranç programı ve müzik düzenleme yazılımı olduğunu hatırlıyorum.

Ama Commodore'ları da çok iyi hatırlıyorum. Commodore sanki tamamen oyun içindi. Sonra Amiga'larla da ne yaptığını anlamasak da bir bilgisayar dergisinde verilen program kodlarını yazıp çalıştırdığımızı hatırlıyorum. Bir de böyle editör, hata yakalayıcı falan da yoktu galiba. Bir sayfa kodu yazıp sonra hata olduğunda harf harf karşılaştırıp tekrar düzeltiyorduk.

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

May 05, 2011

Alıntı (erdem):

>

bir bilgisayarda Commodore'dan da önceydi galiba böyle

Dikkat! Yaşın belli oluyor. :-p

Ben Sinclair Spectrum'cuydum.

Ali

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

May 06, 2011

Tamamen test edemedim ancak son hali bu şekilde oldu. Artık html elemanlarını da ekleyebiliyor.

import std.string, std.stdio, std.conv;

string[] elemanlar;
XmlElement[] elements;
bool alteleman;


class XmlElement
{
   // ...
}

void parçala(string yazı) {
   if (yazı.length > 0) {
       // ilk < karakterini ara konumunu kaydet
       auto ilk = yazı.indexOf('<');

       // ikinci < karakterini ara konumunu kaydet
       auto ikinci = yazı[ilk + 1 .. $].indexOf('<') + ilk + 1;
       if (ikinci != 0) {

           if (ilk > 0) {  // sadece metin var
               auto metin = yazı[0 .. ilk];
               elemanlar ~= metin;
               yazı = yazı[ilk .. $];
               alteleman = false;
               parçala(yazı);

           } else if (yazı[ikinci + 1] == '/') {      // tek bir html elemanı var
               auto içerik = yazı[ilk + 3 .. ikinci];
               auto etiket = yazı[ilk + 1 .. 2];

               if (alteleman) {
                   assert(elements.length > 0);
                   auto gecici = new XmlElement(etiket, içerik);
                   elements[elements.length - 1].addElement(gecici);
               } else {
                   elements ~= new XmlElement(etiket, içerik);
               }


               if (elements.length > 0) {
                   auto kaçtane = elements.length;
                   auto son = kaçtane - 1;
               }

               yazı = yazı[ikinci + 4 .. $];
               alteleman = false;
               parçala(yazı);

           } else {
               auto içerik = yazı[3 .. ikinci];
               auto etiket = yazı[ilk + 1 .. 2];

               if (alteleman == false) {
                   elements ~= new XmlElement(etiket, içerik);
                   alteleman = true;

               } else {
                   assert(elements.length > 0);
                   auto gecici = new XmlElement(etiket, içerik);
                   elements[elements.length - 1].addElement(gecici);
               }

               auto kaçtane = elements.length;
               auto son = kaçtane - 1;
               yazı = yazı[ikinci .. $];
               parçala(yazı);

           }
       }
   }
}


void main()
{
   int etiketsayısı = 0;

   string[] elemanlar;

   auto yazı ="Deneme yaparken <b>matematiğe </b>benzer çok şeyler <b>olduğunu"
              "biliyoruz<b> ama bunların nasıl kullanılacağı</b></b>";
   parçala(yazı);

   writeln("kaç tane: ", elements.length);

   for (int i = 0; i < elements.length; ++i) {
       writeln(elements[i]);
   }

}

İçiçe geçmiş html ifadelerini doğru bir şekilde ayrıştıramadığını farkettim. Aslında Ayrıştırıcı isimli bir sınıf mı yazsak. Örneğin kendisine geçilen:


<a>deneme<b>deneme<c>deneme</c>deneme</b>deneme</a>

Şeklindeki bir ifadeyi kendiliğinden ayrıştırabilse.

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

May 07, 2011

Alıntı (erdem:1304428023):

>

Benim aklıma şu tür bir çözüm geldi. Bir Yazıcı nesnemiz olur '' etiketine rastladığı zaman özellikler koyu yazmayı aç ya da '' etiketine geldiği zaman özellikler gizli yazmayı kapat diyebilir.

Sorunun çözüm yöntemini baştan sona değiştirdim ve ilk aklıma gelen yöntemle yapmaya çalıştım.

import std.stdio, std.string;

struct Metin
{
   string yazı_;
   static bool koyu_;
   bool büyük_;
   bool köşeli_;
   bool gizli_;

   this(string yazı)
   {
       if (!koyu_ && !gizli_ && !köşeli_ && !büyük_)
           yazı_ ~= yazı;

       else if (koyu_) {
           foreach (dchar harf; yazı) {
               writeln(harf);
               yazı_ ~= harf;
               yazı_ ~= harf;

           }
       }

   }
}

Metin[] elemanlar;


void çıkış(string mesaj)
{
   writeln(mesaj);
}

void ayrıştır (string yazı)
{
   // dizi içeriğini karakter karakter yaz
   for (int i = 0; i != yazı.length; ++i) {
       writeln(i, " ", yazı[i], " ");
   }

   if (yazı.length <= 0) çıkış("dizinin işlenmesi tamamlandı");

   // ilk < karakterini bul
   auto ilk = yazı.indexOf('<');
   writeln("ilk karakter: ", ilk);

   // yazının başında sadece metin var
   if (ilk > 0) {
       // metin kısmı ekle
       elemanlar ~= Metin(yazı[0 .. ilk]);
       // eklenen kısmı yazıdan çıkart
       yazı = yazı[ilk .. $];
       // son durumu göster
       writeln("yazının son hali: ", yazı);
       // tekrar başa dön
       ayrıştır(yazı);

   } else if (ilk == 0) {
       // en başta bir etiket var mı
       switch (yazı[0 .. 3]) {
       case "<b>":
       {
           elemanlar[elemanlar.length - 1].koyu_ = true;
           // yazının en başını kısalt
           yazı = yazı[3 .. $];
           writeln("Yazının son hali", yazı);
           writeln("koyu yaptım");
           ayrıştır(yazı);
           break;
       }

       default:
           çıkış("Programda bir hata oluştu");

           break;

       }
   }
}

void main()
{
   auto yazı = "Deneme yaparken<b>matematiğe</b>";
   ayrıştır(yazı);

   writeln(elemanlar[0].yazı_);
   writeln(elemanlar[1].yazı_);

}

Yalnız gördüğüm bir eksik metin yapısına niteliklerin açılma sırasını da eklemeliyiz galiba. Örneğin '0:Koyu 1:Köşeli 'ya da '0:Büyük 1:Gizli' gibi..

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

May 07, 2011

Son hali de bu şekilde olmuş oldu:

import std.stdio, std.string;

static int sayac = 0;
auto metin = Metin();

struct Metin
{
   string yazı;
   string[int] nitelikler;
   int niteliksayısı = 0;

   this(string yazı)
   {
      this.yazı = yazı;
   }

   void ekle (string eklenen)
   {
       if (nitelikler.length == 0)
           yazı ~= eklenen;
       else if (nitelikler.length == 1) {
           switch (nitelikler[0]) {
           case "koyu":
               foreach (dchar harf; eklenen) {
                   yazı ~= harf;
                   yazı ~= harf;
               }
               break;
           default:
               break;
           }
       }
   }

   string toString() const
   {
       return format("%s", yazı);
   }
}

void ayrıştır (string yazı)
{
   // dizi içeriğini karakter karakter yaz
   for (int i = 0; i != yazı.length; ++i) {
       writeln(i, " ", yazı[i], " ");
   }

   if (yazı.length <= 0) çıkış("dizinin işlenmesi tamamlandı");

   // ilk < karakterini bul
   auto ilk = yazı.indexOf('<');
   writeln("ilk karakter: ", ilk);

   // yazının başında sadece metin var
   if (ilk > 0) {
       // metin kısmı ekle
       metin.ekle (yazı[0 .. ilk]);
       // eklenen kısmı yazıdan çıkart
       yazı = yazı[ilk .. $];
       // son durumu göster
       writeln("yazının son hali: ", yazı);
       writeln("metinin son hali: ", metin.yazı);

       // tekrar başa dön
       ayrıştır(yazı);

   } else if (ilk == 0) {
       // en başta bir etiket var mı
       if (yazı[0 .. 3] == "<b>") {
           // koyu özelliğini aç
           metin.nitelikler = [sayac:"koyu"];
           // yazının en başını kısalt
           yazı = yazı[3 .. $];
           writeln("Yazının son hali: ", yazı);
           writeln("koyu yaptım");
           ayrıştır(yazı);
       } else if (yazı[0 .. 3] == "<u>") {
           // yazının en başını kısalt
           yazı = yazı[3 .. $];
           writeln("Yazının son hali: ", yazı);
           writeln("büyük yaptım");
           ayrıştır(yazı);

       }

       if (yazı[0 .. 4] == "</b>") {
           // yazının en başını kısalt
           yazı = yazı[4 .. $];
           writeln("Yazının son hali: ", yazı);
           writeln("</b> etiketini attım");
           metin.nitelikler.remove(metin.nitelikler.length - 1);
       }

   }
}

void çıkış(string mesaj)
{
   writeln(mesaj);

}

void main()
{
   auto yazı = "Deneme yaparken<b>matematiğe</b>";
   ayrıştır(yazı);

   writeln(metin);
}

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

May 07, 2011

Doğru işlediğini biraz da birim testlerinden duymak isteriz. ;)

Bir kaç not ekledim:

/*
* [Ali] Global değişkenler eninde sonunda sorun doğururlar. Taze örnek (C++
* ama farketmez): bizim firmada iki farklı grup daha geçen hafta global
* değişkenlerin ilklenme ve sonlanma sıralarının tanımlanmamış olmasının
* neden olduğu hatalarla uğraştılar.
*/

/*
* [Ali] Bu herhalde eskinden kalmış olmalı. Değeri programda hiç
* değişmiyor. Ne olursa olsun, kullanıldığı yere yakın tanımlanmalı. Örneğin
* belki de yalnızca ayrıştır() tarafından kullanılıyordur.
*/
static int sayac = 0;

/*
* [Ali] Bu daha büyük bir sorun. En azından ileride gerekse, programda
* belirli bir anda ancak tek metin ayrıştırılabilir. ayrıştır()'ı çağıranlar
* bunun global olduğunu bilmek zorundadırlar ve hemen kopyalamaları gerekir.
*
* ayrıştır() gibi işlevlerin kendi işleri için kullandıkları global veya
* static değişkenler onları 'non-reentrant' (iki kere çağrılamayan)
* yapar. ayrıştır() için öyle bir sorun düşünemiyorum ama globallerden
* kaçınmak gerektiği için sözü uzatıyorum. :)
*
* Çözüm: metin, ayrıştır() tarafından döndürülmelidir:
*
*    Metin ayrıştır(string yazı) { ... }
*/
auto metin = Metin();

// [Ali] ...

               foreach (dchar harf; eklenen) {
                   /*
                    * [Ali] Buradan "koyu" yazının her zaman için iki harfle
                    * gösterildiğini anlıyoruz. Ama eğer çıkış biriminin ne
                    * olduğunu biliyorsak zaten Metin diye bir türe gerek
                    * bile yoktur. Girişi baştan sonra okuyarak bir string
                    * üretebiliriz.
                    *
                    * Oysa Metin türü yalnızca metni tarif etse, ondan sonra
                    * ona "kendini konsola gönder", "kendini dosyaya gönder",
                    * vs. diyebiliriz.
                    *
                    * Yani Metin'in gücü, metin düzenini tarif etmesinde
                    * duruyor.
                    */
                   yazı ~= harf;
                   yazı ~= harf;

// [Ali] ...

   string toString() const
   {
       /* [Ali] Bu da zamanla basitleşmiş olmalı; yoksa bu haliyle doğrudan
        * yazı da döndürülebilir. */
       return format("%s", yazı);
   }
}

void ayrıştır (string yazı)
{
   /*
    * [Ali] İstediğin bu olmayabilir ama aklımda taze olduğu için
    * hatırlatıyorum.
    *
    * Aralıklar dersinde çok yeni yazdığım gibi, eğer std.array * eklenirse
    * ve yazı bir InputRange olarak kullanılırsa, UTF kod birimleri değil,
    * harfler görünür. Gerekenler:
    *
    * 1) import std.array;
    *
    * 2) InputRange olarak kullanmak; yani
    *
    * 2a) ya for yerine foreach,
    *
    * 2b) ya da for döngüsünde yazı.empty, yazı.front, ve yazı.popFront()
    *     diye InputRange işlevleri kullanmak
    *
    * (Dikkat: o işlem sırasında yazı tükenebilir. :D Onun için bir dilim
    * tüketmemiz gerekebilir.)
    */
   // dizi içeriğini karakter karakter yaz
   for (int i = 0; i != yazı.length; ++i) {
       writeln(i, " ", yazı[i], " ");
   }

   /* [Ali] Önemsiz ayrıntı: length'in türü işaretsiz olduğu için sıfırdan
    * küçük olamaz. */
   if (yazı.length <= 0) çıkış("dizinin işlenmesi tamamlandı");

Ali

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

1 2 3
Next ›   Last »