Forum: Projeler KelimeMatik RSS
Kelime döngüsünün oluşturulması
zafer #1
Üye Tem 2009 tarihinden beri · 706 mesaj · Konum: Ankara
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: Kelime döngüsünün oluşturulması
Merhaba,

KelimeMatik projesinin egzersiz kısmını hazırlıyorum. Buradaki durum şu şekilde çalışıyor. Giriş yapan kullanıcı egzersiz hazırla ekranına geçtikten sonra "Egzersiz Başlat" dügmesine basarak yeni bir egzersiz başlatıyor. Bu esnada biz arkaplanda egzersiz sınıfı üzerinden kullanılacak kelime listesini alıp global olarak tanımlanan "kelimeListesi" dizisine aktarıyoruz. sonra "kelimeNo" isimli değişkenimizi sıfırlayıp kelimeListesi dizisindeki ilk elemanı alıp ekrana basıyoruz. Tüm bu işlemler "Egzersiz Başlat" dügmesine bastıgımız zaman olup bitecek.

Ardından kullanıcı cevabı yazıp "Cevapla" düğmesine bastıgında cevabı kontrol ediyor, ardından "kelimeNo" değerini bir arttırıp "kelimeListesi" dizisinden sonraki kelimeli alıp ekrana basıyoruz. Hızlıca böyle birşeyler düşündüm ama sanki daha iyi çözümler olabilir gibi geliyor. Bu çözümden pek emin değilim, bu konuda fikri olan var mı?
https://github.com/zafer06 - depo
acehreli (Moderatör) #2
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4533 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Doğru geliyor. Yalnızca globalde kuşkuluyum. Verilerin global olmaları engellenebilir mi?

Ali
zafer #3
Üye Tem 2009 tarihinden beri · 706 mesaj · Konum: Ankara
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Aslında engellenebilir ama bu sefer iki defa liste almak gerekiyor.

Yani şöyle, kullanıcı "Egzersiz Başlat" düğmesine tıklayınca soru listesini alıp ilk soruyu ekrana basıyoruz. Daha sonra cevabı yazınca bu sefer "Cavapla" düğmesine basıyor haliyle burada listeyi yeniden ele alıp bir sonraki soruyu bulup ekrana basmak gerekiyor. Bende iki defa liste almamak için "Egzersiz Başlat" düğmesine basılınca global kelimeListesini dolduruyorum ve ilk soruyu ekrana basıyorum ardından her "Cevapla" düğmesine basılınca listede bir sonraki soruya ilerliyorum.

Yani globalden vazgeçersek iki defa liste almak zorunda kalırız iki defa xml dosyası okumak demek bu da. Bilemiyorum durum ortada sen ne dersin?
https://github.com/zafer06 - depo
acehreli (Moderatör) #4
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4533 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
İkna olmadım. Belki de gtk'nin ayrıntılarını bilmediğim için böyle düşünüyorum ama iki farklı düğmenin işlenmesi sırasında aynı veriler kullanılamıyor mu?

Liste bir kere hazırlandıktan sonra önce Egzersiz Başlat tarafından sonra da Cevapla tarafından kullanılsa?

Ali
acehreli (Moderatör) #5
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4533 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Bir yolunu buldum: addOnClicked() delegate aldığı için kolay. Aşağıdaki delegate düğmeye her basıldığında yerel bir değişkenin değerini arttırıyor ve çıkışa yazdırıyor:

import std.stdio
/* ... */
                int yerelDeğer;
                btnYeniKullaniciEkle.addOnClicked(
                    (Button) {
                        ++yerelDeğer;
                        writeln(yerelDeğer);
                    });

Yerel değişken yerine herhangi başka değişken de kullanılabilir. Eminim başka yöntemler de bulunabilir.

Ali
zafer #6
Üye Tem 2009 tarihinden beri · 706 mesaj · Konum: Ankara
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Evet oldu :). Ali sen harikasın biraz farklı bir kodlama oldu ama çalıştı ve kelimeListesi ve kelimeNo değişkenleri artık yerel oldular.

Kodlar şöyle oldu.

private void EgzersizBaslat_Click(Button btn)
    {
        int kelimeNo = 0;
        
        Egzersiz calisma = new Egzersiz("/home/zafer/DProjeler/KelimeMatik/data/en-tr.xml");
        
        Kelime[] kelimeListesi = calisma.VerEgzersizSoruListesi();
        
        lblSoru.setMarkup("<span foreground='black' font='20' font_weight='bold'>" ~ kelimeListesi[kelimeNo].soru ~ "</span>");
        
        btnEgzersizBaslat.setSensitive(false);
        
        btnCevap.addOnClicked((Button) 
        {
            ++kelimeNo;
            if (kelimeNo < kelimeListesi.length)
            {
                lblSoru.setMarkup("<span foreground='black' font='20' font_weight='bold'>" ~ kelimeListesi[kelimeNo].soru ~ "</span>");
            }
            else
            {
                btnEgzersizBaslat.setSensitive(true);    
            }
        });
    }

Buradaki bir durum EgzersizBaslat_Click metodu çalışmadan bizim buton çalışmıyor ama bunun şimdilk bizim için bir sorun olduğunu düşünmüyorum. Başka ne fikirlerin var Ali denemek için sabırsızlanmaya başladım. Birde buradaki temsilci (delegate) olayı daha geniş bir şekilde anlatırmısın. Bu işlmleri bu şekilde kullanmamıza olanak sağlayan nedir?
https://github.com/zafer06 - depo
acehreli (Moderatör) #7
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4533 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
zafer:
Birde buradaki temsilci (delegate) olayı daha geniş bir şekilde anlatırmısın. Bu işlmleri bu şekilde kullanmamıza olanak sağlayan nedir?

Bu konu işlevlerden başlayarak uzun uzun anlatılabilir. İsimsiz işlevlerin yararına değinilir, onların davranışlarının değiştirilebilmelerinin parametrelerle nasıl yapılabildiği gösterilir ve temsilcilere gelinebilir. Şu sıralarada zaman bulamıyorum. :)

Temsilci yerine başka ne kullanılabileceğini gösterebilirim. Ama önce belgeleri okurken yeniden hatırladığım bir bilgiyi vereceğim. Hani üye işlevler belirli bir nesne üzerinde işlerler ya... Yani aslında üye işlevin bir de gizli bir 'this' göstergesi olur ve üye işlev o göstergenin gösterdiği nesne üzerinde işler.

İşte temsilciler de aynı sistemi kullanıyorlar. Hatta perde arkasında aynı üye işlev gibi gerçekleştiriliyorlar. Temsilciler bir sınıf (veya yapı) türü olmadıklarından onlar üye işlev değiller ve üzerlerinde işledikleri nesne yok. Derleyicinin bu durumun üstesinden gelmek için yaptığı şu: temsilcinin oluşturulduğu ortamdaki bütün değişkenleri sanki bir nesnenin üyeleriymiş gibi saklıyor. O ortamı gösteren gösterge 'this' yerine geçiyor. (Daha teknik olarak, temsilcinin oluşturulduğu 'stack frame'i gösteren bir gösterge saklıyor.)

Temsilcinin işlevi de o 'this' göstergesi ile işleyen bir üye işlev gibi kullanılıyor.

Sonuç olarak bizim için canlı tutulmuş olan yerel değişkenler üzerinde işleyen isimsiz bir işlev ediniyoruz. O isimsiz işlev (yani 'delegate') ilerideki bir zamanda işletilirken bu ortamı kullanabiliyor.

Bütün bunlardan da anlaşılacağı gibi, "yerel değişkenler"+"temsilci" kullanmak yerine başlı başına bir tür ve onun üye değişkenlerini de kullanabiliriz. (Zaten temsilcileri bulunmayan C++98 gibi dillerde de öyle yapılmak zorundadır.)

Bunun örneğini sonra göstereceğim. Hatırlarsam... :)

Ali
acehreli (Moderatör) #8
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4533 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
acehreli on 2011-12-09, 12:12:
Hani üye işlevler belirli bir nesne üzerinde işlerler ya... Yani aslında üye işlevin bir de gizli bir 'this' göstergesi olur ve üye işlev o göstergenin gösterdiği nesne üzerinde işler.

O söylediğim, C++ programcılarına çok yakın bir kavramdır. D'de de üye işlevler içinde 'this' diye bir kavram var. (Hem yapılarda hem sınıflarda.) O da aynen C++'ta olduğu gibi "şu anda üzerinde işlemekte olduğumuz nesne" anlamına geliyor. Bunu zaten D'nin kurucu işlevlerinde de görürüz:

import std.stdio;
 
class Sınıf
{
    int i;
 
    this(int i)
    {
        this.i = i;
    }
 
    void bilgi()
    {
        writefln("bilgi() %s adresindeki nesne üzerinde çağrıldı", &this);
        writefln("Bu nesnenin i üyesinin değeri şu: %s", this.i);
    }
}
 
void main()
{
    auto nesne = new Sınıf(42);
    nesne.bilgi();
}

Bir çıktısı:

bilgi() 7FFF33D8CF28 adresindeki nesne üzerinde çağrıldı
Bu nesnenin i üyesinin değeri şu: 42


Yukarıda hem kurucu içinde hem de bilgi() içinde this kullanılıyor. İşte, nesnenin üyelerinin ve nesnenin üzerindeki işlemin bir araya gelerek çağrılması olayı D'de temsilcilerin gerçekleştirilmesinin aynısıymış.

Bunun örneğini sonra göstereceğim. Hatırlarsam... :)

Hatırladım! :-p Button ve addOnClicked() ile temsilci kullanımını basit bir örnekle göstereceğim. Yukarıda söylediğimin örneği olarak &işlemciNesne.özelİşlem kullanımına bakın:

import std.stdio;
 
/* Button gibi kullanılan bir sınıf */
class Düğme
{
    /* Koda açıklık getirmek için tanımlanmış bir takma isim */
    alias string delegate(Düğme) İşlemci;
 
    /* Her Düğme nesnesinin işlemcileri var. Düğmeye basıldığında teker teker
     * bunlar işletilecekler. */
    İşlemci[] işlemler;
 
    /* addOnClicked()'in benzeri olan bir işlev. Tek yaptığı, kendisine
     * verilen işlemi basitçe işlemciler dizisine ekliyor. Daha sonradan
     * düğmeye basıldığında işletecek. */
    void ekle(İşlemci işlem)
    {
        işlemler ~= işlem;
    }
 
    /* Düğmeye basılmış. Bütün işlemleri teker teker işletiyor. Bu basit
     * örnekte yalnızca onların sonuçlarını bir diziye yerleştirip diziyi
     * yazdırıyoruz. */
    void bas()
    {
        string[] sonuç;
 
        foreach (işlem; işlemler) {
            sonuç ~= işlem(this);
        }
 
        writeln(sonuç);
    }
}
 
/* Burada asıl göstermek istediğim bu: Kendisi bir temsilci olmasa da, üye
 * işlev temsilci gibi kullanılmaya uygun: Düğme alıyor ve string
 * döndürüyor. Uygun. */
class İşlemciSınıf
{
    string özelİşlem(Düğme düğme)
    {
        return "selam";
    }
}
 
void main()
{
    /* Daha sonradan basılacak olan bir düğme. */
    auto düğme = new Düğme;
 
    /* addOnClicked()'te olduğu gibi iki tane temsilci ekleyelim. */
    düğme.ekle(
        (Düğme) {
            return "merhaba";
        });
 
    /* Değişiklik olsun diye farklı bir düzende. */
    düğme.ekle((Düğme) { return "hello"; });
 
    /* Önemli olan yer burası. delegate türünde olmayan bir nesnenin üzerinde
     * çağrılan bir üye işlev, temsilci gibi kullanılıyor. Önemli: özelİşlem()
     * burada çağrılmıyor. O daha sonra bas() içindeyken tam da bu nesne
     * üzerinde işletilecek. */
    auto işlemciNesne = new İşlemciSınıf;
    düğme.ekle(&işlemciNesne.özelİşlem);
 
    /* ... arada başka işlemler olabilir ... */
 
    /* Kullanıcı sonunda düğmeye basıyor ve pencere sistemi bizim düğmenin
     * bas() işlevini çağırıyor. */
    düğme.bas();
}

Sonuçta iki temsilci ve tek "nesne"+"üye işlev" çağrıları şu çıktıyı üretiyorlar:

["merhaba", "hello", "selam"]


Ali
zafer #9
Üye Tem 2009 tarihinden beri · 706 mesaj · Konum: Ankara
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Ali güzel ve detaylı açıklama için çok teşekkürler. Hepsini tam olarak anladım desem doğru olmaz ama kesinlikle ufkumu çok genişletti ve özellikle arka planda dönen olguları farketmemi sağladı. Eline sağlık diyorum.
https://github.com/zafer06 - depo
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:
Forum: Projeler KelimeMatik 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-12-11, 01:29:08 (UTC -08:00)