October 17, 2012

std.uni; modülündeydi galiba o. Düşündüm ama program basamaklarını yeniden düzenler belki diye düşündüğümden ses edemedim.
Kütüphanelerin olanaklarından yararlanırken o kütüphaneyi bir kez daha kontrol edeceğimizden hem kendi bilgilerimizi hem de sunduklarımız güncelleme olanağına sahip oluruz gibime geliyor.

Ha bu arada ben std.stdio; harici bir kütüphaneyi projemde kullanmaktan kaçınıyorum sürekli. Bunun bir nedeni de dil halen geliştiriliyor olduğundan emekliye ayrılan işlevlerle baş edemeyecek olduğumu düşünmem. Onun yerine gereken işlevi kendim tasarlamaya ve onu kullanmaya çalışıyorum. Bir süre sonra sanırım buna da gerek olmayacak.

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

October 17, 2012

Bu durumda belki küçük harfe çevirmek için kendi yazdığımız şu iki işlevi (aslında 1 diğeri yardımcısı) kullanabiliriz:

char toLower(char c) {
   return isUpper(c) ? cast(char)(c + 32) : c;
}
bool isUpper(char c) {
   return (c > 64 && c < 90) ? true : false;
}

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

October 17, 2012

Konuyla bağlantılı olduğu için ayrıca std.stdio'daki writef()'i kullanırken Gruplama Düzen Belirteçi (http://ddili.org/forum/post/7929) ile ilgili başlıkta iki işlev yazmıştım. Burada enum ifadeleri çok akıllıca ve basit bir şekilde (cast'siz) ekrana yazıyorsunuz:

   void enumPrint(T)(T x) {
       write("{ ");
       foreach(i; T.min..T.max) writef("%s, ", i);
       T.max.writeln(" }");
   }

Çok çok basit değil mi? Ama Mert ağabey şimdi açıklama isteyeceğini bildiğimden bir de bu işleve açıklama katacağım...:)

   void enumYaz(T)(T x) {        // Herhangi bir türden (T)ype değer alabilir
       write("{ ");
       foreach(i; T.min..T.max)  // Türün ilk ve son değeri arasında gezer
       {
         writef("%s, ", i);      // Gezilen her değer biçimli şekilde yazılır
       }
       T.max.writeln(" }");      // Nihayetinde son değer yazılarak bitirilir
   }
   /* Ek Açıklama: Malumunuz programcılıkta neredeyse her şey 0'dan başlar ve
    *              bir şeyin sonu ifade edildiğinde aslında x - 1 demek olur.
    *              İşte bu yüzden son eleman yazılmayacağından biz bunu elle
    *              yaparak kısa bir şekilde pratik çözüm üretmiş oluyoruz...
    */

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

October 17, 2012

Ahaha.
Haklısın açıklama istiyorum elbette. Hatta Programda kullandığın File nesnesini işlevlerde neden açıp kapattığını anlatman yararlı olur diye bir mesaj yazacaktım ki senin bu mesajın geldi ve vazgeçtim.
Şöyley bir referans göstermek için istemiştim o açıklamayı:

Alıntı:

>
>
> void dosyayaYaz(string dosya_ismi, string notalar) {
>     File dosya;
>     dosya.open(dosya_ismi ~ ".dat", "w");
>     dosya.write(notalar);
>     dosya.close();
>   }
> ```

>
>
> Burada hemen bir notlamada bulunmak gerekli sanıyorum. Biz programımızda File yapısı kullanıyoruz. Bu yapı (Yapı olduğundan değer türü zaten) Aksini bildirsekte bildirmesekte dosyamız kapsamdan çıkarken otomatik olarak kapanıyor.
>
> Belki böyle bir açıklama eklemek yararlı olur diye düşünüyorum.
>
> Burada File nesnesi  dosyayı farklı erişim haklarıyla kullandığından dosyanın kapatılıp tekrar açılması gerekmekte Bilgi için: <http://ddili.org/ders/d/dosyalar.html>
>
> gibi, gibi
>

Diye yazıyordum ki...

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

Haklısın Mert ağabey, hatta Ali hocam da şunu diyeceğini zannediyorum:

"File nesnesini işlev içinde kurmak ve bunu yapının üyesi olarak kullanmamak daha doğrudur."

İşte programcılığın bu yanını seviyorum; bir şeyi binbir türde yapmak mümkün. Ancak aralarından hangisi daha iyi olduğunu seçmek de sanırım tecrübe ile alakalı bir durum. Yoksa bütün bunların hangisi daha iyi diye tartmaya kalksak ya kararsız kalırız ya da vaktimizi çok harcarız...:)

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

October 17, 2012

Tasarımın da belirleyici olduğu durumlar yok değil.
Alıntı:

>

"File nesnesini işlev içinde kurmak ve bunu yapının üyesi olarak kullanmamak daha doğrudur."

Ben de aynen senin kodladığın biçimde kullanıyorum File nesnesini. Bunun bir nedeni tasarımın gerekleri. Belki ileride değiştiririm ama şu ara öyle kullanmamın daha etkin olduğunu düşündüyorum sanırım. Zararlarını gördükçe tasarımda bazı kararlar alınması kaçınılmaz olacak ki asıl öğretici olan kısım da burada bana kalırsa.
Zaten Senin bol neşeli programının bir kaç adım sonrasında switch içerisindeki ifadeler birer sınıfa dönecek gibi görünüyor.
O zaman bu duruma daha farklı bir açıdan yaklaşmak isteyebileceksin sanıyorum.
Tamamen tasarımınla ilgili bir durum. Ancak bazen hatalı olanı da göstermek gerekiyor ki yanlışların sayısı azalabilsin. Sanıyorum sen de şu an bu noktayı kurguluyorsun. İyi de yapıyorsun çünkü beklentimiz bu yönde. Başka türlü nasıl daha öğretici olabiliriz ki değil mi ama?

Bol detay, bol açıklama, çözüm önerileri doğrultusunda başlangıcından itibaren adım adım geliştirilen program örnekleri çok yararlı oluyorlar.

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

October 17, 2012

Yine belirtmeden edemeyeceğim bir konu var ki...
Bu önerdiğim öğretici kod örnekleri aslında tam da senin kalemin Salih. Soruna farklı açılardan yaklaşabilme yeteneğin, çözümü basite indirgemen, sorgulaman, kurgulaman bu tarz öğretici bölümlerin geliştirilmesinde senin katkılarını olmazsa olmaz yapıyor.

Tek fazlan var o da karmaşık düşünebilme yeteneğin. Örneklemeleri basit ve açıklayıcı sunduğunda sanırım o yetin daha fazla artı değer katacak öğren(ret)me çabamıza.

Herşeyi de Ali Hocamızdan beklememiz lazım. O zaten gerektiği durumlarda bir parantez açıp gerekli katkıyı şıppadanak ekliyor çalışmalarımıza.

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

October 17, 2012

Alıntı (mert):

>

Ha bu arada ben std.stdio; harici bir kütüphaneyi projemde kullanmaktan kaçınıyorum sürekli. Bunun bir nedeni de dil halen geliştiriliyor olduğundan emekliye ayrılan işlevlerle baş edemeyecek olduğumu düşünmem.

Bence herkes elinden geldiğince tüm sınıfları kullanmayı düşünmeli. Çünkü bir çözümün en güvenli kodu gerçekten de orada. Mesela uzun süre std.conv'yi kullanmamaya gayret ettim. Sonra çok akıllı şablonlara sahip olduğunu görünce kendi küçücük çözümlerimi bir kenara bıraktım. Bunu da forumda dile getirdiğimi hatırlıyorum...:)

Hepsinden önemlisi bu tutum size zaman kazandıracak. Hatta std.stdio'nun de sürekli değiştiğini ve o kullanmadığımız bir çok sınıfa bağlı olduğunu düşünürsek ne kadar haklı olduğumu tahmin edebilirsiniz. Zaten emekliye ayrılması planlanan bir şey önceden kurulmuş çok akıllıca sistem ile duyuruluyor. Dolayısıyla hız ve güvenlik sağlayacak bir olanağı kullanmak çok iyi olsa gerek.

File yapısı olayına gelince...

Bu yapıyı az önce biraz inceledim. Gördüğüm kadarıyla içinde başka bir yapı var; bir de bu yapının işaretçisinin ve isminin tutulduğu üyeleri. Meğer biz bütün işlemleri bu işaretçi ve dolayısıyla diğer yapı içindeki FILE nesnesi üzerinden yapıyormuşuz. Herhalde bu da çekirdekte olan bir şey ve buna kapsülleme mi ne diyorlar...:)

Bizim örneğimizde ise sanırım kapsülleme gibi bir şey yapıyoruz. Bu terimlerden çok anlamıyorum ama basit mantıkla (functional programming) olayı kurduktan sonra işleri biraz daha düzene sokmak için yapı içine sardık. Adeta bir bayram hediyesi gibi paketledik...:D

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

October 17, 2012

diğer modülleri kullanmamaya çalışmam geçici bir durum. biraz pratik yapma hesabından gidiliyor o duruma :-)

Alıntı:

>

Herhalde bu da çekirdekte olan bir şey ve buna kapsülleme mi ne diyorlar...

O ne ola ki ? :-)))

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

October 17, 2012

Alıntı (acehreli):

>

Hatta, .max'ın özel olarak işlenmesinin gerekmesi ise bir talihsizlik. Yapacak bir şey de yok. enum'lar çok işe yarıyorlar ama böyle gariplikleri olmak zorunda.

Bence bu .min ve .max'lar sadece bir makro! Derleme anında bunların yerine karşılıkları aynen konuyor; biz tek tek koymayalım diye. Hatta makrodan da öte, işaret ettiği değiştiğinde onlarda değişiyor...

Alıntı (acehreli):

>

Notalar yerine Nota daha iyi bir isim olabilir mi acaba? Nota.Do "do notası" anlamına geliyor. Öte yandan Notalar.Do da "notalardan do" oluyor. :) Ben yine de Nota derdim.

Bence bunun bir önemi yok çünkü doğrudan kullanmıyoruz. Ama dil bilgisi olarak daha anlamlı olduğu konusunda hemfikiriz.

Alıntı (acehreli):

>

notayıKodla'ya da gerek yok: std.conv.to o işi de becerir: to!Notalar("Mi")

Hocam bunu denemiştim ve tekrar belirttiğin için üzerine asıldım...:)

Asıldım çünkü, sıkıntılı hatalar alıyordum. Ben de ilk iletimde belirttiğim gibi "beceremedim" dedim. Sonra bir tane try catch kümesi koyduğumda programın çökmesini engelleyebileceğimi düşündüm. Şimdi kod daha kısa oldu...

Alıntı (acehreli):

>

Kendim yazsam, aşağıdaki gibi bir durumda .open da kullanmazdım herhalde:

> void dosyayaYaz(string dosya_ismi, string notalar) {
>     File dosya(dosya_ismi ~ ".dat", "w");
>     dosya.write(notalar);
> }
> ```

>

Hocam o şekilde tek satır çok leziz gözüküyor; ancak denediğimde hata verdi. Ama şu şekilde bir sıkıntı yok ve bundan sonra hep böyle kullanmayı düşünüyorum, teşekkürler...

auto veriler = File(this.dosya, "w");


Alıntı (acehreli):
> Bu amaç için fazla karmaşık olabilir; aklıma geldi diye yazıyorum: Dosyayı satır satır okumak için .byLine var. * toLower'ın yalnızca bazı alfabelerde doğru işleyebildiğini biliyoruz. Salih, senin gösterdiğin toLower ve toUpper ise yalnızca ASCII tablosunda geçerli.

Bu örnek için teşekkür ederim. Sanırım uygulama geliştikçe kullanabiliriz. Örneğin her satır bir şarkı notası olur ve oku işlevi alacağı parametre ile (index) şarkı seçimi yapılabilir. Ancak şu tek ayraç (delimiter) boşluk olduğu için readln() yeterli gözüküyor.

Alıntı (acehreli):
> File'ın yapının üyesi olup olmaması konusunda tahmin edilen görüşüm doğru. :) File, müzik kutusu kavramının bir parçası değildir. File, MüzikKutusu nesneleri oluşturulurken ve onun verileri yazılıp okunurken kullanılan bir araçtır. Şimdiye kadar anladığım kadarına bakarsak olsa olsa dosya ismi MüzikKutusu'nun üyesi olabilir... gibi geliyor... :) Eğer MüzikKutusu nesnelerinden çok sayıda olacaksa büyüklüklerinin bir de File kadar artmasını istemeyiz.

Holeyyy, doğru tahmin etmişim...:D

Alıntı (acehreli):
> Deneyim konusunda çok haklısınız. Daha önce de konuştuk: Ne kadar yazılsa ve söylense de insanın kendi yaşayarak ve yanılarak öğrenmesi gibisi yok Evet, bunları Salih bir yazı dizisi gibi yazsın ama her zaman için kodları basit tarafından alsın.

An itibariyle ikilemdeyim! Basit seviyorum ama basit artık benim için çok sıkıcı olmaya başladı. Ama hala karmaşık şeylerden hoşlanmıyorum. Yani orta karar bir şeye ihtiyacım var. Ama her zaman satır sayısı az olan şeylerden hoşlandığımı yinelemeliyim.

Alıntı (acehreli):
> Evet, File C'den beri bildiğimiz FILE* türünü sarmalar. (Encapsulation'ın karşılığı olarak "sarma" demiştik. Kitapta da öyle geçiyor; bence devam... ;))
Evet, ben de bunu demek istemiştim. Aslında OOP'da çok fazla terim yok gibi ama karıştırıyorum hep...

Bu arada Ali hocamın yukarıdaki katkılarıyla enum büyük harf oldu (çünkü do rezerve edilmiş bir anahtar sözcük olduğu için kullanamıyoruz) ve struct şu hale geldi:

import std.array, std.stdio, std.conv, std.uni;

enum Notalar { DO = 1, RE, MI, FA, SOL, LA, SI }

struct MüzikKutusu {
int[] kodlar;
string dosya;

this(string dosya_ismi) {
dosya = dosya_ismi ~ ".dat";
}

private auto kodla(string notalar) {
int[] sonuç;

 foreach(nota; split(notalar)) {
   string NOTA;
   foreach(c; nota) NOTA ~= toUpper(c);

   try {
     sonuç ~= to!Notalar(NOTA);
   } catch {
     continue;
   }
 }
 return sonuç;

}

public void kaydet(string notalar) @property {
auto veriler = File(this.dosya, "w");

 foreach(nota; kodla(notalar)) {
   veriler.write(nota);
 }

}

public void oku() @property {
auto veriler = File(this.dosya, "r");

 foreach(sayı; veriler.readln()) {
   kodlar ~= to!int(sayı) - 48;
 }

}

public string toString() @property {
auto sonuç = appender!string();

 foreach(nota; kodlar) {
   std.format.formattedWrite(sonuç,
        "%s\t", cast(Notalar)nota);
 }
 return sonuç.data;

}
}


Bunu önceki 'main()' ile sorunsuzca kullanabiliyorsunuz. Ancak her şey biraz daha kısa gözüksün ve az tuşa basalım diye vazgeçemediğim 'with()''li sürümü de paylaşayım. Maksat lahmacun yanında (yani MüzikKutusu için) ortaya yeşillik...:D

Alıntı:
>
>
>

void main() {
string müzik_notası;
readf(" %s\n", &müzik_notası);

with(MüzikKutusu("ses")) {
kaydet(müzik_notası);
oku();
toString.writeln();
}
}

>

Küçük bir özet geçersek bu örneğimizde şu olanakların hepsini kullandık:

  • readf() ile girişten veri aldık
  • with() sayesinde yapımız ile bütünleştik...:)
  • ~ işleçinin her iki anlamıyla da kullandık (üçüncüsü bool mantığında değil)
  • split() ile sözcükleri bir string[] dizgesine böldük
  • toUpper() ile sözcükleri büyük harfe çevirerek %100 uyumluluk sağladık (Türkçe karakterler hariç)
  • to!Notalar ve enum ile veriler arasında kolay eşleşme sağladık (eşleme tabloları sıralama sıkıntısı yapardı!)
  • try catch sayesinde hatalı nota girildiğinde yazılımın çökmesini engelledik ve
  • continue ile bunları süzdük; önemsemedik...
  • File yapısını doğrudan kurarak kullandık
  • Veriyi okurken 48 sihirli sabiti ile karşılaştık (irdelenmesi gereken bir konu!)
  • appender() ile üstün veri işleme olanağına adım attık (kapsamlı bir mevzu...)
  • formattedWrite() sayesinde enum'un dizge karşılığına sorunsuzca elde ettik!

Ne kadar çok şey elde etmişiz ve belki dikkatimden kaçanlar da vardır...:)

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