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. ]