Forum: Duyurular RSS
Yığıt (sürüm2)
Stack v2
Sayfa:  1  2  sonraki 
Avatar
Salih Dinçer #1
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: Yığıt (sürüm2)
Merhaba,

Zafer'in başlattığı ve bir süre önce C++'daki olanağı görünce devam ettirdiğim basit bir yığıt yapısının son halini yayınlıyorum. Bilmiyorum, D'de aynı özelliklerde bir olanak var mı? Ama yoksa da koysalar ne iyi olurdu...:)

Çünkü birebir C++'daki ile aynı şekilde çalıştığı gibi (bunu çözdüğüm 5 örnekten ve referans verdiğim adreslerden anlayabilirsiniz) aralıklarla da çalışıyor. Üstelik ikinci bir bonus olarak clear() üye işlevini ekledim. Böylece 5 üye işlev aralık olanağı ile birlikte 8 üye işleve çıktı. Bilmiyorum başka şeye ihtiyaç var mı?
struct Stack(T) {
    private int konum;
    private T[] stack;
 
    public:
    void push(T)(T veri) @property
    {
        stack ~= veri;
        konum++;
    }
 
    T pop() @property
    {
        return stack[--konum];
    }
 
    ref T top() @property
    {
        return stack[konum - 1];
    }
    
    /*** BONUS ***/
    
    void clear() @property
    {
        stack = stack.init;
        if(stack.length) {
            throw new Exception("Stack is not empty!");
        } else konum = 0;
    } 
    
    void popFront() @property
    {
        --konum;
    }
    
    T front() const @property
    {
      return stack[konum - 1];
    }
    
    /*** BONUS ***/
    
    bool empty() const @property
    {
        return konum == 0;
    }
 
    int size() @property
    {
      return konum;
    }
}
 
import std.stdio; 
void main() {
    Stack!int mystack;
    int sum;
    
    foreach(i; 0..11) mystack.push(i);
    
    while (!mystack.empty()) {
        sum += mystack.top();
        mystack.pop();
    }
    sum.writeln(" Sum of the numbers..."); 
    // example #1: http://www.cplusplus.com/reference/stl/stack/empty/
 
 
    foreach(i; 0..5) mystack.push(i);
 
    write("Popping out elements...");
    while (!mystack.empty()) {
      mystack.top().write(" ");
      mystack.pop();
    }
    writeln();
    /* example #2: http://www.cplusplus.com/reference/stl/stack/pop/
     * example #3: http://www.cplusplus.com/reference/stl/stack/push/
     */
 
    "0. size: ".writeln(mystack.size());
    foreach(i; 0..5) mystack.push(i);
    "1. size: ".writeln(mystack.size());
    mystack.pop();
    "2. size: ".writeln(mystack.size());
    // example #4: http://www.cplusplus.com/reference/stl/stack/size/
 
    mystack.clear(); // BONUS...:)
 
    mystack.push(10);
    mystack.push(20);
    mystack.top() -= 5 ;
    "mystack.top() is now ".writeln(mystack.top);
    // example #5: http://www.cplusplus.com/reference/stl/stack/top/
    
    foreach(range; mystack) range.writeln(); // BONUS...:)
    writeln("-THE END-");
}
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Avatar
Salih Dinçer #2
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
İnsanoğlunun bir gözünü (dikkat iki gözünden bir tanesini!)
terazinin bir kefesine koymuşlar, diğer kesesine de dünyayı yine de göz ağır gelmiş... [Resim: http://www.clker.com/cliparts/R/t/4/Q/u/c/eye-can-see-the-world-th.png]

Hal böyleyken oldu mu sürüm 2.1...:)

Aslında aç gözlülük bir yana belki de boş boğazlılık. Hatta yaptığım boşuna bir kod yazmak/vakit harcamaktan öteye gidemez. Ancak en iyi test ortamının saha olduğu düşünülürse acaba bu yığıt yapısını sıralama algoritmaları dışında bir hesap makinesi gibi kullanırsak ne tür ihtiyaçlar doğlar:
  • İlk elemana erişme (Stack.first)
  • Son elemanın yedeğini alma (Stack.topBackup) "Belki de ismi popBackup olmalıydı?"

Evet, ben bunlara ihtiyaç duydum. Yaptığım ise basit bir Julian Date hesabıydı. Belki yedek almak çok şart değildi çünkü bunu o sırada bir yerel değişken ile yapabilirdik. Ancak yapı içindeki biraz daha işlevsel ve hatta tüm dizinin yedeğini alma gibi bir özellik ile daha işlevsel olabilir. Dedim ya göz ve terazi meselesi işte...:D
struct Stack(T) {
    private int konum;
    private T[] stack;
    T yedek;
 
    public:
    void push(T)(T veri) @property
    {
        stack ~= veri;
        konum++;
    }
 
    T pop() @property
    {
        return stack[--konum];
    }
 
    ref T top() @property
    {
        return stack[konum - 1];
    }
    
    /*** BONUS ***/
    
    ref T first() @property
    {
        return stack[0];
    }
    
    T topBackup(bool refresh = true) {
        if(refresh) yedek = pop;
        return yedek;  
    }
    void clear() @property
    {
        stack = stack.init;
        if(stack.length) {
            throw new Exception("Stack is not empty!");
        } else konum = 0;
    } 
    
    void popFront() @property
    {
        --konum;
    }
    
    T front() const @property
    {
      return stack[konum - 1];
    }
    
    /*** BONUS ***/
    
    bool empty() const @property
    {
        return konum == 0;
    }
 
    int size() @property
    {
      return konum;
    }
}
 
double julian(int year, int month, int day) {
    // convert Gregorian date to Julian day
    // Ref: Astronomical Algorithms by Jean Meeus
        if (month <= 2) {
            year -= 1;
            month += 12;
        }
 
        double a = floor(year / 100.0);
        double b = 2 - a + floor(a / 4.0);
 
        return floor(365.25 * (year + 4716)) +
               floor(30.6001 * (month + 1)) + day + b - 1524.5;
    }
    
import std.math, std.stdio;
void main() {
  Stack!double julianDate;
  enum { day = 15, month = 9, year = 2012 };
  double sum = 0;
 
  //sum = julian(year, month, day); /*
  with(julianDate) { // Memory Calculator
    push(day); push(month);
  
    if(top <= 2) {
        top += 12;
        push(year - 1);
    } else push(year);
        
    push(2-floor(top/100.0) + floor(top/400.0));
    first += pop - 1524.5;
    top = floor(365.25 * (top + 4716));
    topBackup();
    top = floor(++top * 30.6001);
    push(topBackup(false));
    do sum +=pop; while(!empty);
  }//*/
  writefln("%.1f", sum);
}
Başarılar...
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
acehreli (Moderatör) #3
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #1
Güzel. :)

  • top'ın ayrıca şablon olmasının nedeni, topluluğun T'sinden başka türlerden elemanlar da ekleyebilmek, değil mi? Örneğin bir Stack!long'a bir int eklenebiliyor.

  • Acaba top'ın 'const' olanı da iyi olur mu? Böylece top, 'const Stack!long' ile uğraşılan bir durumda da çağrılabilir. Örneğin bir işlevin 'ref const Stack!long' aldığını düşün. O işlevin içinde top'ı çağırabiliyor musun?

  • BONUS açıklamalarından iki tane var. :) Yalnızca iki tanesi mi bonus, yoksa bütün o bölümler mi?

  • clear() konusunda aklıma bir şey geldi: Acaba çağıranlar üyelerin sonlandırıcılarının da işletilmelerini beklerler mi? Örneğin içinde 10 adet BenimYapım olan bir Stack!BenimYapım topluluğu olsa, clear() deyince 10 adet sonlandırıcı hemen işletilmeli mi? (Bunun yanıtını bilmiyorum.) Acaba bu Stack eski elemanların yerleri ancak tekrar kullanılırsa mı o sonlandırıcıları işletiyor? (Denemedim. :))

Ali
Avatar
Salih Dinçer #4
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
acehreli:
* top'ın ayrıca şablon olmasının nedeni, topluluğun T'sinden başka türlerden elemanlar da ekleyebilmek, değil mi? Örneğin bir Stack!long'a bir int eklenebiliyor.

Açıkçası onu oraya kim koydu bilmiyorum, hiç dikkat etmemiştim ama faydalıysa dursun o zaman...:)

acehreli:
* Acaba top'ın 'const' olanı da iyi olur mu? Böylece top, 'const Stack!long' ile uğraşılan bir durumda da çağrılabilir. Örneğin bir işlevin 'ref const Stack!long' aldığını düşün. O işlevin içinde top'ı çağırabiliyor musun?

Bence const olmamalı. Çünkü bu durumda işaret ettiği değişkenin içeriği değiştirilemez öyle değil mi?

acehreli:
* BONUS açıklamalarından iki tane var. :) Yalnızca iki tanesi mi bonus, yoksa bütün o bölümler mi?

BONUS'ların sayısı arttığı için o bölgenin başını ve sonun ifade etmek istemiştim...

acehreli:
* clear() konusunda aklıma bir şey geldi: Acaba çağıranlar üyelerin sonlandırıcılarının da işletilmelerini beklerler mi? Örneğin içinde 10 adet BenimYapım olan bir Stack!BenimYapım topluluğu olsa, clear() deyince 10 adet sonlandırıcı hemen işletilmeli mi? (Bunun yanıtını bilmiyorum.) Acaba bu Stack eski elemanların yerleri ancak tekrar kullanılırsa mı o sonlandırıcıları işletiyor? (Denemedim. :))

Buradaki temizleme işlemi çok işlevsel değil ama gerekirse class yaparak daha mı akıllıca yapılsa emin değilim. Ama o zaman, (zannedersem) top() üye işlevi bir değişken gibi çağrılamıyordu diye hatırlıyorum. Tabi sınıf olmanın with içinde bir avantajı daha var. İsimsiz olarak küme içinde çalışan bir nesne meydana getirilebiliyor. Sanırım diğer türlü önce dışarıda meydana getirmek gerekiyor ya da benim eksik bildiğim bir şeyler var...:D
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
acehreli (Moderatör) #5
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Salih Dinçer:
acehreli:
bir işlevin 'ref const Stack!long' aldığını düşün. O işlevin içinde top'ı çağırabiliyor musun?

Bence const olmamalı. Çünkü bu durumda işaret ettiği değişkenin içeriği değiştirilemez öyle değil mi?

İşlevi yazan const almak istemiş çünkü bizim nesnemizi değiştirmeyeceği sözünü vermiş. Örneğin üsttekiniYazdır() gibi bir işlevin const olarak alması uygundur çünkü yazdıran bir işlevin yığıtta değişiklik yapması saçma olurdu.

Yalnızca bu kavrama odaklanan basit örnek:

import std.stdio;
 
struct Yığıt
{
    int eleman;
 
    ref int top()
    {
        return eleman;
    }
}
 
void üsttekiniYazdır(const ref Yığıt yığıt)
{
    writeln("Üstteki çok güzelmiş: ", yığıt.top());
}
 
void main()
{
    Yığıt yığıt;
    üsttekiniYazdır(yığıt);
}

O program derlenemez:

Error: function deneme.Yığıt.top () is not callable using argument types () const

C++'taki gibi olan çözümü, const olan ve olmayan iki top() tanımlamaktır:

    ref int top()
    {
        return eleman;
    }
 
    ref const(int) top() const
    {
        return eleman;
    }

Şimdi derlenir.

Aslında int gibi bir tür ise const olanın dönüş türü hiç ref de olmayabilir:

    int top() const
    {
        return eleman;
    }

Tabii eğer top() yoluyla erişim de sağlıyorsak, bu işi @property yoluyla da halledebiliriz:

import std.stdio;
 
struct Yığıt
{
    int eleman;
 
    // Değerini döndürür
    int top() const @property
    {
        return eleman;
    }
 
    // Elemana yeni değer atar; artık hiçbir şey döndürmüyor
    void top(int değer) @property
    {
        eleman = değer;
    }
}
 
void üsttekiniYazdır(const ref Yığıt yığıt)
{
    writeln("Üstteki çok güzelmiş: ", yığıt.top());
}
 
void main()
{
    Yığıt yığıt;
    yığıt.top = 42;            // <-- Bekleneceği gibi bu da çalışır
    üsttekiniYazdır(yığıt);
}

Ali
Avatar
Salih Dinçer #6
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Bu iletiyi yeni görüyorum!

Herhalde tatile çıktığımdandır...:D

Bu durumda iki top() işlevi ile sürüm 2.2'ye geçebiliriz...:)
/*
  yığıt2.d (27.09.2012)
  sürüm: 2.2
  yazanlar: Ali Çehreli, Erdem Öncel, Salih Dinçer, Zafer Çelenk
*/
struct Stack(T) {
    private int konum;
    private T[] stack;
    T yedek;
 
    public:
    void push(T)(T veri) @property
    {
        stack ~= veri;
        konum++;
    }
 
    T pop() @property
    {
        return stack[--konum];
    }
 
    ref T top() const @property
    {
        return stack[konum - 1];
    }
    
    /*** BONUS ***/
 
    void top(T)(T value) @property
    {
        stack[konum - 1] = value;
    }
    
    ref T first() @property
    {
        return stack[0];
    }
    
    T topBackup(bool refresh = true) {
        if(refresh) yedek = pop;
        return yedek;  
    }
    void clear() @property
    {
        stack = stack.init;
        if(stack.length) {
            throw new Exception("Stack is not empty!");
        } else konum = 0;
    } 
    
    void popFront() @property
    {
        --konum;
    }
    
    T front() const @property
    {
      return stack[konum - 1];
    }
    
    /*** BONUS ***/
    
    bool empty() const @property
    {
        return konum == 0;
    }
 
    int size() @property
    {
      return konum;
    }
}
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Avatar
Salih Dinçer #7
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Opsss!

Aşağıdaki uygulamayı yurkarıdaki 2.2 sürümü ile denediğimde hatalar alıyorum!
double julian(int year, int month, int day) {
    // convert Gregorian date to Julian day
    // Ref: Astronomical Algorithms by Jean Meeus
        if (month <= 2) {
            year -= 1;
            month += 12;
        }
 
        double a = floor(year / 100.0);
        double b = 2 - a + floor(a / 4.0);
 
        return floor(365.25 * (year + 4716)) +
               floor(30.6001 * (month + 1)) + day + b - 1524.5;
}
import std.math, std.stdio;
void main() {
  Stack!double julianDate;
  enum { day = 15, month = 9, year = 2012 };
  double sum = 0;
 
  //sum = julian(year, month, day); /*
  with(julianDate) { // Memory Calculator
    push(day); push(month);
  
    if(top <= 2) {
        top += 12;
        push(year - 1);
    } else push(year);
        
    push(2-floor(top/100.0) + floor(top/400.0));
    first += pop - 1524.5;
    top = floor(365.25 * (top + 4716));
    topBackup();
    top = floor(++top * 30.6001);
    push(topBackup(false));
    do sum +=pop; while(!empty);
  }//*/
  assert (sum == julian(year, month, day));
  writefln("%.1f", sum);
}
yığıt2.d(25): Error: cast(double)this.stack[cast(ulong)(this.konum - 1)] is not an lvalue
yığıt2.d(30): Error: template yığıt2.Stack!(double).Stack.top(T) conflicts with function yığıt2.Stack!(double).Stack.top at yığıt2.d(23)
yığıt2.d(90): Error: template instance yığıt2.Stack!(double) error instantiating
İlk hata dışında kalanları (conflicts & instantiating) halletmesi kolay gibi çünkü bunlar şablon hataları. İşlev şablonunu kaldırdığımda bu hatalar gidiyor; yapının işlevselliği de...:(

Tabi diğer hatayı halledemediğimi belirtmeliyim. Bunu halletsek bile şablon kullanmak, farklı veri türlerine göre yığıt oluşturabileceğimiz için iyi gözüküyor. Bu durumda sürüm 2.1'e geri dönüyoruz...:)
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
acehreli (Moderatör) #8
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Kodu dmd 2.060 ile şu değişikliklerle derleyebildim:

    /* [Ali] Sondaki 'const' belirtecine bakılırsa bu işlev bu Stack!T
     * nesnesinde değişiklik yapmayacağı sözünü veriyor. O yüzden 'ref T'
     * döndürmesi olanaksızdır. Döndürebilse, çağıranlar elemanı o referans
     * üzerinden değiştirilebilirler ve böylece işlevin sözü bozulmuş olur.
     *
     * O yüzden bu işlevin 'ref const(T)' döndürmesi gerekir:
     */
    ref const(T) top() const @property
    {
        return stack[konum - 1];
    }
 
    /* [Ali] Programda top()'ın döndürdüğü referansa gerçekten atama
     * yapılacaksa o zaman bir de const olmayan top gerekiyor. Ne işlev const
     * olmalı, ne de döndürdüğü referans:
     */
    ref T top() @property
    {
        return stack[konum - 1];
    }
 
    /*** BONUS ***/
 
    /* [Ali] Bunu şablon olmaktan çıkarttım. Yoksa koddaki 'top=x' gibi
     * kullanımlarda bir üstteki top()'ın mı yoksa bunun mu çağrılacağı
     * karışıyordu.
     *
     * Biraz düşününce mantıklı ama bu şablon olmayınca neden karışmıyor;
     * ondan emin değilim. */
    void top(T value) @property
    {
        stack[konum - 1] = value;
    }
 
// ...
 
  /* [Ali] Sondaki noktalı virgülü kaldırdım çünkü:
   *     Warning: use '{ }' for an empty statement, not a ';'
   */
  enum { day = 15, month = 9, year = 2012 }//; 

Ali
acehreli (Moderatör) #9
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #7
Salih Dinçer:
Bu durumda sürüm 2.1'e geri dönüyoruz...:)

Sürümlerin öncelikle testlerini geçmeleri gerekmez mi? ;)

Ali
Avatar
Salih Dinçer #10
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Teşekkürler, gördüğüm kadarıyla bütün bunları top() işlevinin her türlü kullanımı için yapıyoruz. Ayrıca bir benzeri olan first() işlevine de uyarladığımızda işlev sayısı 2'den 6'ya çıkıyor. Çünkü son düzenlemede bir tane daha ekledik...:)

Tamam, belki derlenirken derleyici bu 3 işlevden birini seçiyor (bu arada her ikisi veya üçü kullanıldığında da object koda dahil oluyor mu? Sanırım oluyor ve bunu işlevleri farklı isimlendirerek (adreslere yerleştirerek) yapıyor!) ama git gide basitlikten uzaklaşıyoruz gibime geldi. Hatta espri yoluyla terazi, dünya ve göz misaliyle bir nevi kendimi eleştirdiğim sırada kendimi frenleyip ileriye gitmemeliydim. Bence tek işlevli (const olmadan) kullanım için yeterli ama tarihte downgrade olan ilk yazılım olmamak için 2.2 için şu düzenlemeye gidebiliriz:
class Stack(T) {
    private int konum;
    private T[] stack;
    T yedek;
    :    :    :
}
 
import std.math, std.stdio;
 
void main() {
  enum { day = 15, month = 9, year = 2012 }
  double sum = 0;
 
  with( new Stack!double ) {
    :    :    :
  }
}
Böylece with() ile isimsiz nesne (anonymous object) oluşturabiliyoruz...
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
acehreli (Moderatör) #11
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Salih Dinçer:
bir benzeri olan first() işlevine de uyarladığımızda işlev sayısı 2'den 6'ya çıkıyor.

inout anahtar sözcüğü tam da bu sorun için gelmişti. Değişebilen, const, ve immutable yerine geçerek işlev sayısını üçte birine indirir. (Ama gerçekleştirimi hâlâ tam değil).

import std.stdio;
 
struct Foo(T)
{
    T i;
 
    ref inout(T) foo() inout
    {
        return i;
    }
}
 
void main()
{
    auto d = Foo!int();
    const c = Foo!int();
    immutable i = immutable(Foo!int)();
 
    writeln(typeid(d.foo()));
    writeln(typeid(c.foo()));
    writeln(typeid(i.foo()));
}

Yine de bizim ihtiyacımızı karşılıyor. foo() işlevi üç farklı değişebilme özelliğine sahip Foo!int üzerinde çağrılabiliyor ve uygun türde değer döndürüyor. Çıktısı:

int
const(int)
immutable(int)



üçü kullanıldığında da object koda dahil oluyor mu? Sanırım oluyor ve bunu işlevleri farklı isimlendirerek (adreslere yerleştirerek) yapıyor!)

Doğru.

git gide basitlikten uzaklaşıyoruz gibime geldi.

Problem basitlikten uzaklaştıkça kod da basitlikten uzaklaşabilir. D bu konuda benim bildiğim dillerden daha yardımcı. (Andrei'nin sunumlarındaki min() ve max() saydamını hatırlayın (veya bulun). C++'taki onlarca işlev yerine tek işlev yazılabildiğini ve buna rağmen C++'takilerinden daha kullanışlı olduğunu göreceksiniz.)

Hatta espri yoluyla terazi, dünya ve göz misaliyle bir nevi kendimi eleştirdiğim sırada

Eleştiri mi içeriyormuş? :) Bir itirafım var: Ben o tür anlatımlardan hemen hemen hiçbir zaman bir anlam çıkartamıyorum. :blush: Edebi yanımı geliştirmem gerek... :(

Ali
Avatar
Salih Dinçer #12
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #9
Opss!

Ali hocamın iki işlevini de dahil ettiğimde işler ciddi şekilde karıştı! Öncelikle matematiksel hesap yapan uygulama yanlış hesaplamaya başladı ki assertion failure hatası vermemesi için o satırı gizledim ve 27 Eylül 2012 için şu sonuç ile bir de hata aldım:

75195263.5
core.exception.RangeError@yığıt2(32): Range violation

Normalde 2456185.5 değerini almalıydım. Demek ki top() işlevi istediğimiz gibi her satırda çalışmıyor. Sondaki hata ise üsttekiniYazdır() işlevini çağırdığım satır ki şu şekilde kullandım:
import std.math, std.stdio;
 
void üsttekiniYazdır(T)(const ref Stack!T yığıt)
{
  writeln("Üstteki çok güzelmiş: ", yığıt.top());
}
void main() {
  enum { day = 15, month = 9, year = 2012 }
  double sum = 0;
 
  auto yığıt = new Stack!double;
  with(yığıt) {
    :    :    :
  }
  //assert(sum == julian(year, month, day));
  writefln("%.1f", sum);
  üsttekiniYazdır(yığıt);
acehreli:
Salih Dinçer:
Bu durumda sürüm 2.1'e geri dönüyoruz...:)

Sürümlerin öncelikle testlerini geçmeleri gerekmez mi? ;)
Gerekirdi...:)

Bu arada son değişiklikler ile DMD 2.059 da derlemekte...
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
acehreli (Moderatör) #13
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Sen bir yandan o hatanın kaynağını bulurken ;) ben de unuttuğum bir şeyi söyleyeyim: topBackup()'ı görünce burnuma kötü kokular geldi. :) (http://en.wikipedia.org/wiki/Code_smell).

O işlevi Türkçe olarak nasıl anlatırsın? Eğer anlatımı basit değilse bir sorun var demektir. Tabii ki işlevin içeriğinden bahsetmiyorum. İşlevin işi nedir ve diğer üye işlevlerle bir arada kullanımı nasıldır? Bence basit değil.

Ali

Not: Bu, benim önceki değerli arttırma işlecine (post-increment) olan alerjimle de ilgili. Çünkü onun da tarifi uzundur: değişkenin değerini arttır ama önceki değerini üret. Arttırma işleci ise basittir: değişkeni değerini arttır.
Avatar
Salih Dinçer #14
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #12
Cuma akşamı bereketine iki düzeltme daha!

Öncelikle kendi hatalarımı düzelteyim: :D :D :D
  • Biz bugünün tarihini değil kodu ilk yazdığım 15 Eylül 2012 tarihini hesaplatıyoruz,
  • Yanlış hesaplamasının sebebi herhalde yanlışlıkla with() içini değiştirmiş olmam olabilir ki bulamadım ama CTRL+Z ile çözdüm...

Var olan üçüncü bir hata var ki o da dizi elemanlarına erişirken kullandığım konum değişkeni! Meğer, işlem sonucunu ekrana yazdırırken konum değeri -1 oluyormuş. Bu da range violation hatasına sebebiyet veriyormuş. Bunu şu üç satır ile anladım:
  yığıt.push(0);
  yığıt.stack.writeln;
  üsttekiniYazdır(yığıt);
Çıktısı:
[-1522.5, 306, 2.4574e+06, -13, 2.4574e+06, 0]
Üstteki çok güzelmiş: -1522.5


Sanırım burada 4. bir hata daha var! O da konum değeri -1 ise run-time hatası vermeyip T.init göndermemesi. Belki throw new ile hata da attırabiliriz.

Ayrıca dizideki elemanlara erişimi sonsuza (GC temizleyene) kadar erişimi iptal etmek için stack.length'i konum'un değerine göre de düşürebiliriz. Gerçi bu sınıf bir kütüphane içine girdiğinde private özellikleri çalışacağından diziye yukarıdaki gibi erişemeyeceğiz.
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Avatar
Salih Dinçer #15
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #13
acehreli:
O işlevi Türkçe olarak nasıl anlatırsın? Eğer anlatımı basit değilse bir sorun var demektir.
Sanırım tüm sınıfı (artık sınıf oldu...) Türkçeleştirmek gerekirse (-ki bunu düşünüyorum o yüzden "konum" ve "yedek" gibi iki Türkçe ifadeyi koruyorum) topBackup() işlevi yerine üsttekiniYedekle() veya sondakiniYedekle() verebiliriz...
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Sayfa:  1  2  sonraki 
Forum: Duyurular RSS
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-21, 13:08:06 (UTC -08:00)