Forum: Ders Arası RSS
Müzik Yapalım
Mert ağabey için...:)
Sayfa:  1  2  3  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ı: Müzik Yapalım
Şu şekilde notalarımız olsun:
  enum Notalar { Do = 1, Re, Mi, Fa, Sol, La, Si }
Onları şu şekilde okunduğu sırada ekrana yazabiliriz:
  foreach(nota; 1..8) {
    writef("%s\t", cast(Notalar)nota);
  }
Öyleyse bununla çok şey yapabiliriz. Örneğin klavyeden aralarında boşluklar olacak şekilde notaları istetiriz ve bunu bir dosyaya kaydedebiliriz. Bunlar D'de ekrana yazmak kadar kolay. Ancak zor olan şeyler de var! Örneğin "do re mi" dediğimizde yine yukarıdaki gibi ama bu sefer tersi şekilde "[ 1, 2, 3 ]" çıktısını almak. Ben bunu beceremedim. Ama gelin isterseniz nereye kadar gidebileceğimizi birlikte kodu geliştirerek görelim.

Bunun için aynı işi yapan iki kod vereceğim. Birisi başlangıç için temel olsun diye. Diğeri ise Mert ağabey için; işlevlerden oluşan bu temeli nasıl yapıya dönüştürdüğümüz birlikte şahit olmak için...
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ı
  import std.array, std.stdio, std.conv;
 
  enum Notalar { Do = 1, Re, Mi, Fa, Sol, La, Si } 
 
  string notayıKodla(string nota) {
    switch(nota) {
      case "do" : return "1";
      case "re" : return "2";
      case "mi" : return "3";
      case "fa" : return "4";
      case "sol": return "5";
      case "la" : return "6";
      case "si" : return "7";
      default   : return "0";
    }
  }
 
  void dosyayaYaz(string dosya_ismi, string notalar) {
    File dosya;
    dosya.open(dosya_ismi ~ ".dat", "w");
    dosya.write(notalar);
    dosya.close();
  }
 
  int[] dosyadanOku(string dosya_ismi) {
    File dosya;
    dosya.open(dosya_ismi ~ ".dat", "r");
    scope(exit) dosya.close();
    
    int[] sonuç;
    foreach(sayı; dosya.readln()) {
      sonuç ~= to!int(sayı) - 48;
    }
    return sonuç;
  }
 
void main() {
  // Notaları klavyeden oku
  string müzik_notası;
  readf(" %s\n", &müzik_notası);
 
  // Notaları sıkıştır (kodla)
  string müzik_verisi;
  foreach(nota; split(müzik_notası)) müzik_verisi ~= notayıKodla(nota);
 
  // Notaları dosyaya yaz
  string kayıt_dosyası = "ses";
  dosyayaYaz(kayıt_dosyası, müzik_verisi);
 
  // Notaları dosyadan oku ve biçimli şekilde ekrana yaz
  int[] veri_dosyası = dosyadanOku(kayıt_dosyası);
  foreach(nota; veri_dosyası) {
    writef("%s\t", cast(Notalar)nota);
  }
}
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Avatar
Salih Dinçer #3
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
  import std.array, std.stdio, std.conv;
  
  enum Notalar { Do = 1, Re, Mi, Fa, Sol, La, Si } 
 
  struct MüzikKutusu {
    int[] kodlar;
    string dosya;
    File veriler;
            
    this(string dosya_ismi) {
      dosya = dosya_ismi ~ ".dat";
    }
        
    private string kodla(string notalar) {
      string sonuç;
      
      foreach(nota; split(notalar)) {
        switch(nota) {
          case "do" : sonuç ~= "1"; break;
          case "re" : sonuç ~= "2"; break;
          case "mi" : sonuç ~= "3"; break;
          case "fa" : sonuç ~= "4"; break;
          case "sol": sonuç ~= "5"; break;
          case "la" : sonuç ~= "6"; break;
          case "si" : sonuç ~= "7"; break;
          default   : sonuç ~= "0";
        }
      }
      return sonuç;
    }
 
    public void kaydet(string notalar) @property {
      veriler.open(dosya, "w");
      veriler.write(kodla(notalar));
      veriler.close();
    }
 
    public void oku() @property {
      veriler.open(dosya, "r");
 
      foreach(sayı; veriler.readln()) {
        kodlar ~= to!int(sayı) - 48;
      }
      veriler.close();
    }
    
    public string toString() @property {
      auto sonuç = appender!string();
      
      foreach(nota; kodlar) {
        std.format.formattedWrite(sonuç, "%s\t", cast(Notalar)nota);
      }
      return sonuç.data;
    }
}
 
void main() {
  auto müzik = MüzikKutusu("ses");
   
  // Notaları klavyeden oku
  string müzik_notası;
  readf(" %s\n", &müzik_notası);
 
  // Notaları dosyaya kodlayarak yaz
  müzik.kaydet(müzik_notası);
 
  // Notaları dosyadan oku
  müzik.oku();
  
  // Biçimli şekilde ekrana yaz
  müzik.writeln();
}
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Avatar
Salih Dinçer #4
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Fark ettiniz mi; iki örnek hemen hemen aynı biçimde yazılmış ve benzer kodlama kullanılmış ama ikincisinde main() içindeki yük alınarak yapı içine taşınmış. İlginçtir satır sayısı ve dosya boyutu hafiflememiş, artmıştır...:)

Ancak birden fazla File nesnesine ve notaların yazıldığı dizilere ihtiyaç duyulmamış. Sadece kodlar isminde tek bir dizi yeterli görünmüştür. Sizce hangi kod daha okunaklı ve daha ne tür geliştirmeler yapabiliriz?
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Avatar
mert #5
Üye Ara 2010 tarihinden beri · 194 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #1
Şu şekilde notalarımız olsun:

  enum Notalar { Do = 1, Re, Mi, Fa, Sol, La, Si }

Onları şu şekilde okunduğu sırada ekrana yazabiliriz:

  foreach(nota; 1..8) {
    writef("%s\t", cast(Notalar)nota);
  }

Salih,
Eğer bu program kod örneklerine girecekse;
standartlara uyacaksak  foreach döngüsünden sonra paranteze gelmeden bir boşluk,
ve açıklamaların yazılması gerekecek.

foreach(nota; 1..8)

Buraya nasıl gelindiğini ve tür dönüşümüne bir referans verilmesi gibi..
Bahsettiğim yalınlıkla ilgili meseleye girmiş olduk böylece :-)
mert
Avatar
mert #6
Üye Ara 2010 tarihinden beri · 194 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #3
Konu adı: Referans
Şurada Ali Hocamın bir açıklaması bulunmakta http://ddili.org/forum/post/3767 Kısaca:
Bundan sonraki adım, DarbeTipi'ni enum yapmak yerine Darbe diye bir sınıf sıradüzeni kurmak olabilir. Nesne yönelimli programlamaya tam sadık olanlar için switch deyimi bir işarettir: o deyimin görüldüğü yere bir sıradüzen gelebilir. :)

Darbenin etkisi, sınıfları olmayan C'de switch ile yazılmak zorundadır. (Aslında işlev göstergeleriyle C'de de nesne yönelimli programlama yapılır ama çetrefillidir.) D gibi dillerde ise aşağıdaki gibi de olabilir. (Not: enum ve switch yasak değildir. :) Bir işaret olarak görülebileceğini söylemek istiyorum.)

Diye belirtmiş ki tam olarak benim anlatmak istediğim açıklamaya referans oluyor.

Ders arası bölümünde olmasını arzu ettiğim ve yararlı olacağına inandığım örnekler böyle açıklamaları da barındırmalı ki daha rahat kavranılsın.

Nasıl geliştirebiliriz sorusu orada yanıta da dönüşüyor.

Şimdi senin koduna dönersek; Ben bu aşamaya gelene kadar sanıyorum bir kaç ara kod daha vermenin iyi olacağını düşünürdüm. Önce tasarımı anlatırdım nereden başlayıp nereye gitmek istediğimi bildirirdim. Programım için kullandığım modüllerden nasıl faydalandığımı açıklardım ( ki sen bunu her zaman unutmadan ekliyorsun güzel ve yararlı :-) Elimden geldiğince kullandığım olanakları açıklamayı ihmal etmezdim gibi gibi. Çünkü kod örneği vermekten çok derslerin anlaşılmasına katkımız olsun derdindeyiz diye düşünürdüm.
Salih'çiğim aman söylediklerim yanlış anlaşılmasın. Ben sadece dün belirttiğim eksikliği nasıl giderebileceğimiz konusunda sesli sesli düşünüyorum. Yoksa kodların gayet güzel anlaşılır ve yeterli.


         
case "do" : sonuç ~= "1"; break;
          case "re" : sonuç ~= "2"; break;
          case "mi" : sonuç ~= "3"; break;
          case "fa" : sonuç ~= "4"; break;
          case "sol": sonuç ~= "5"; break;
          case "la" : sonuç ~= "6"; break;
          case "si" : sonuç ~= "7"; break;
          default   : sonuç ~= "0";

Şimdi bir örnek; ben konsoldan "Re" girdiğimde çıktıyı tür dönüşümü olarak alıyorum ve hemen aklıma takılan soruyu soruyorum:
Programcımız burada neyi hedeflemektedir. Acaba:
 case "re","Re" : sonuç ~= "2"; break;
Biçiminde bir düzenleme gerekiyor mu?
mert
Avatar
Salih Dinçer #7
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #4
mert:
Salih,
Eğer bu program kod örneklerine girecekse;
standartlara uyacaksak  foreach döngüsünden sonra paranteze gelmeden bir boşluk,
ve açıklamaların yazılması gerekecek.

Yani şunu demek istiyor olabilir misin?

foreach() içinde iki parametre ve bunlardan ikincisinde iki sayı arasında iki nokta görürseniz bunun bir aralığı ifade ettiğini düşünmelisiniz. Tıpkı dizi ile yapılan şu uygulama gibi:
// foreach(i; 1..8) i.writeln; /*
auto int[] birDizi = [  1, 2, 3, 4, 5, 6, 7 ];
foreach(i; birDizi) {
  i.writeln;
}//*/ 
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Bu mesaj Salih Dinçer tarafından değiştirildi; zaman: 2012-10-17, 06:46.
Avatar
mert #8
Üye Ara 2010 tarihinden beri · 194 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
foreach() içinde iki parametre ve bunlardan ikincisinde iki sayı arasında iki nokta görürseniz bunun bir aralığı ifade ettiğini düşünmelisiniz. Tıpkı dizi ile yapılan şu uygulama gibi:

Budur...
mert
Avatar
mert #9
Üye Ara 2010 tarihinden beri · 194 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
 foreach (i; 1..8) i.writeln; // foreach birkarakterboşluk(/* ifadeler */) { .....// } 

Gayet hoş. Ben de en basit haliyle bir kahraman karakteri yaratmaya çalışıyorum. İşlev yüklemelere de örnek olsun dizilere de referans versin akışına göre yapı, daha sonra class ve arayüzünü kuyllansın mantığında ilerliyorum. Bakalım ortaya nasıl bir şey çıkacak :-)
mert
Avatar
Salih Dinçer #10
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #6
mert:
Şimdi bir örnek; ben konsoldan "Re" girdiğimde çıktıyı tür dönüşümü olarak alıyorum ve hemen aklıma takılan soruyu soruyorum:
Programcımız burada neyi hedeflemektedir. Acaba:
 case "re","Re" : sonuç ~= "2"; break;
Biçiminde bir düzenleme gerekiyor mu?
Bunu yazarken düşünmüştüm ama özellikle eklemedim. Bu vesileyle olası bir sorunun çözümünü de gösterdiğin için ayrıca teşekkür ediyorum. Hatta Caps Lock açık unutulduğu zaman ise tüm yazılanlar büyük olacağı için dönüş değeri her zaman bol sıfırlı (0000000 ..) olacak, yani default: ...:)

Bu arada ben daha farklı bir çözüm düşünüyordum. Sanırım yine std.string sınıfında olmalı ....

Unutmadan araya sıkıştırayım: (önceki konudaki alıntının bağlantısı)
Salih Dinçer:
...Hatta yanılmıyorsam std.string sınıfında olan split() işlevi ile çok daha akıllı bir şey yapabilirdik. Yine de dilim olayın göstermeyi ve bu konularda olabildiğince örnek çözmeyi tercih ederim.
Meğer split() işlevi std.array içerisideymiş. Sürekli bir şeyler deprecated olduğu için karıştırıyorum. Sanırım ileride std.string diye bir şey kalmayacak...:)

... bir string ifadeyi küçük harfe çeviren toLower() işlevi vardı. İşte bunu döngü içinde bir kere kullanarak her şeyi daha basitleştirebiliriz. Ne dersiniz?

Sevgiler, saygılar...
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Bu mesaj 2 defa değişti; son değiştiren: Salih Dinçer; zaman: 2012-10-17, 07:20.
Avatar
mert #11
Üye Ara 2010 tarihinden beri · 194 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
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.
mert
Avatar
Salih Dinçer #12
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
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;
}
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Bu mesaj 2 defa değişti; son değiştiren: Salih Dinçer; zaman: 2012-10-17, 08:02.
Avatar
Salih Dinçer #13
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Konuyla bağlantılı olduğu için ayrıca std.stdio'daki writef()'i kullanırken Gruplama Düzen Belirteçi 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...
     */
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Avatar
mert #14
Üye Ara 2010 tarihinden beri · 194 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
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ı:


 
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...
mert
Avatar
Salih Dinçer #15
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
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...:)
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  3  sonraki 
Forum: Ders Arası 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-19, 19:49:18 (UTC -08:00)