Perl Öğreniyoruz - 4

0
cayfer
Daha önceki bölümler:
1. bölüm
2. bölüm
3. bölüm
Bu hafta konumuzda çağrışımlı listeler var, Haftaya "regexp"ler! Bu arada merak ettiğim birşey var: Acaba bu Perl tefrikasından yararlanan var mı?

Çağrışımlı Listeler

C programcılarını biraz üzelim isterseniz! Listelerde (array) indekslerin sıfırdan başlayan ardışık tamsayılar olması gerektiğini düşünenler yanılıyor. Perl listelerinde indeks olarak alfabetik diziler hatta eksi sayılar kullanabilirsiniz. Tek yapmanız gereken indeksleri "[" ve "]" arasında değil "{" ve "}" arasında yazmanız ve listenin tümünden söz ederken %liste notasyonunu kullanmak olacaktır.

Örneğin, web sitenizin aylık ziyaretçi istatistiklerini çıkaran bir programın içinde

    $ziyaret{'Ocak'} = $ziyaret{'Ocak'} + 1;
gibi bir deyim kullanabilirsiniz. İndeksi "Ocak" olan liste elemanının değerini bir arttırmak için bundan daha kullanışlı nasıl bir yapı olabilirdi ki?

Çağrışımlı lisstelerin yararını ve kullanımını en kolay bir örnek problemle anlatabilirim:

Diyelim ki bir basit metin dosyasında her sözcüğün kaç kez geçtiğini saymanız gerekiyor. Örneğin "bir kere bir iki, bir kere iki iki eder" gibi bir satır içeren dosya üzerinde çalıştığında, programımız
bir - 3
kere - 2
iki - 3
eder - 1
gibi bir çıktı üretmelidir.

Bu işi yapan Perl kodu şöyle birşey olabilir:

      #!/usr/local/perl
      while ( $satir = <> ) {
         @sozcukler = split (/W/, $satir);
         foreach $sozcuk (@sozcukler) {
           $sayac{$sozcuk}++;
         }
      }
      foreach $sozcuk ( sort( keys(%sayac) ) ) {
          print "$sozcuk - $sayac{$sozcuk}
";
      }
      exit;
Şimdi bu programı satır satır bir gözden geçrirelim:

#!/usr/local/perl
Bu satırım amacını biliyor olmalısınız. Gene de hatırlatmakta yarar var: UNIX kabuk programına bu satırın ardındaki satırların /usr/local/ dizinindeki "perl" isimli program tarafından yorumlanması gerektiğini bildiriyor.

 while ( $satir = <> ) {
Hmmm.. bu satır biraz ilginç! "<>" dosyasından okuyabildiği sürece satır okuyacak ve her defasında okuduğu satırı "$satir" değişkenine atayacak. Bu kadarı belli de <> dosyası hangi dosya, nerede duruyor, neden bir "open" deyimiyle açılmadı?

Perl ile kod yazdığınızı unutuyorsunuz herhalde! Dosyayı açmadıysanız Perl sizin için açacaktır. Açılacak dosyanın adını kodun içinde belirtmediğinize göre, bunu programı çalıştırırken komut satırından vereceksiniz demektir. Güzel di mi? Evet, "elmas operatörü" (diamond operator) denen <> operatörü, Perl kodunu çalıştırırken komut satırında vereceğiniz dosyadan okumak için kullanılır.

@sozcukler = split (/W/, $satir);
Bir ilginç satır daha... Deneyimli programcılar hemen bu komutu okumayı başaracaktır: $satir değişkenindeki karakter dizisi "birşeylere göre" parçalanıp her bir parça @sozcukler listesine bir eleman olarak atanacak. İyi de bu "birşeyler" de ne? Henüz regexp'leri (regular expressions) anlatmadım. O yüzden bu "birşeyleri" "sozcük içinde yer alamayacak karakterler" olarak okuyunuz. Yani "/W/" --> "Sözcük içinde yar alamayacak karakterler".

Boşluklar, virgüller, diğer noktalama işaretleri, tab karakterleri vs hepsi sözcük içinde yer alamayacak karakterler olduğu için $satır karakter dizisi mükemmel bir şekilde sözcüklere parçalanacak ve her bir parça da @sozcukler listesine birer eleman olarak yerleştirilecektir. Satırın ilk sözcüğü $sozcukler[0]'a, ikinci sözcüğü $sozcukler[1]'in içine, vs.

Bu noktada Türkçe'ye özgü karakterlerin sorun çıkaracağını ve ne yazık ki "ğ", "ş" gibi karakterlerin "sözcük içinde yer alamayacak karakter" olarak değerlendirileceğini belirtmek isterim. Bunun sorumlusu kim biliyor musunuz? Türk Standartları Enstitüsü. Uzun yıllar önce karakter kümelerinin uluslararası standartlara oturtulması toplantılarına "yurt dışı seyahat sırası gelen" ama ingilizce bilmeyen ve bilgisayar bilimlerinden anlamayan bürokratların "gezsinler ve alışveriş yapsınlar diye" gönderilmesi nedeniyle tren kaçmıştı. 5-6 yıl sonra bir fırsat daha yakalamıştık, o toplantılara da ödenek olmadığı gerekçesiyle kimse gönderilmedi. İşte şimdi bu zavallı tavırların meyvelerini topluyoruz.

Neyse..

foreach $sozcuk (@sozcukler) {
@sozcukler listesinin herbir elemanını sırayla "$sozcuk" değişkenine alır ve döngüyü tekrarlar.
$sayac{$sozcuk}++;
%sayac çağrışımlı listesinin $sozcuk'üncü elamanını bir arttıtıyor! Örneğin $sozcuk değişkeninde "eder" varsa, %sayac listesinin "eder" indeksli elemanını bir arttıracaktır. Dİkkat ederseniz %sayac listesinin tek bir elemanından, yani "eder"inci elemanından söz ederken "$sayac" dedik (ilk karakteri "$"). Normal bir liste değil de çağrışımlı bir listeden söz ettiğimizi de indeksi "{" ve "}" karakterleri arasında yazarak belli ettik.

Bir numara daha çektik aslında bu satırda...
$sozcuk değişkenine ilk kez "bir" sözcüğü geldiğinde bir arttırmaya çalışacağımız $sayac{'bir'} henüz tanımsız. Tanımsız bir değeri bir arttırmak sorun çıkarmayacak mı? Hayır, çıkarmayacak! Unutmayın Perl kullanıyoruz. Herşey programcılar için! Madem programcı bir değerin bir arttırılmasını istiyor, Perl bunu yerine getirecektir. Eğer tanımsız bir değeri bir arttırmak istiyorsa önce o değeri tanımlı kılacak, sonra ilk değer olarak sıfır atayacak sonra da bir arttıracaktır.

foreach $sozcuk ( sort( keys(%sayac) ) ) {
Tüm satırlar okunduğuna ve tüm sözcüklerin kaçar kez tekrarlandığı da sayıldığına göre artık elde ettiğimiz sonuçları görüntüleyebiliriz.

Şimdi %sayac çağrışımlı listesi içinde dosyamızdaki sözcük çeşidi kadar eleman var. Elemanların indeksleri de sözcüklerin kendisi. Listenin herhangi bir indeksli elemanında da o sözcüğün kaç kez geçtiğinin sayısı var.

Bir başka deyişle

$sayac{'bir'}  --> 3
$sayac{'kere'} --> 2
$sayac{'iki'}  --> 3
$sayac{'eder'} --> 1
İndeksleri ardışık doğal tamsayılar olan bir listeyi dolaşmak kolay! İndeksin sıfırdan başladığı, bir sonrakinin de bir olduğu belli. Oysa çağrışımlı listelerde durum bu kodar kolay değil. İndeksler herhangi bir kümeye ait olmadıkları için akla gelen her değeri alabilirler. Dolu bir çağrışımlı listenin tüm elemanlarını dolaşmak istediğinizde keys( ) fonksiyonu kullanmalısınız. Bu fonksiyon parametresi olarak verilen çağrışımlı listenin tüm indeksklerini normal bir listeye doldurup geri gönderir.

Yani

@indeksler = keys(%sayac);
diye bir komut verirseniz, @indeksler listesi
$indeksler[0] = "bir",
$indeksler[1] = "kere",
$indeksler[2] = "iki",
$indeksler[3] = "eder"
şeklinde doldurulur. Bu anahtarlar listesinin hangi sırayla doldurulacağını önceden kestiremezsiniz. Tamamen anahtar (indeks) değerlerine bağlıdır. Bu listeye makul bir sırada erişmek isterseniz ayrıca "sort( )" fonksiyonuyla sıralayabilirsiniz.

keys( ) fonksiyonunun bir çağrışımlı listenin anahtarlarını toparlayıp vermesi gibi values( ) fonksiyonu da bir çağrışımlı listenin değerlerini derleyip geri gönderir.

Yukardaki örnek için

keys(%sayac)   --> ("bir", "iki", "kere", "eder);
values(%sayac) --> (3,     3,     2,      1)
listeleri alınabilir.

Çağrışımlı listelere eleman eklemek kolaydır. İndeksini ve listeye eklenmesi istediğiniz değeri

     $liste{'indeks'} = $deger; 
benzeri bir deyimle istediğiniz zaman ekleyebilirsiniz.

Eleman çıkarıp atmak içinse "delete($liste{'indeks'});" deyimini kullanmalısınız.

Görüşler

0
FZ
Hocam, öncelikle çağrışımlı listeler konusunu anlattığınız ve diziyi örneklerle zenginleştirdiğiniz için teşekkürler. C kurallarına alışık pek çok programcı için evet, çağrışımlı listeler epey garip ve fantastik ama göze güzel görünen yapılar ;-) Tabii mesela bu tip bir liste yapısının kullanılmasına izin veren dilleri geliştirenleri de ayrıca takdir etmek lazım, başlıbaşına bir iş!

Bir de acaba birileri bu yazı dizisinden faydalanıyor mu demişsiniz, hemen şuna dikkat çekmek isterim ki mesela regexp konusuna girdiğinizde, bundan sadece Perl programcıları değil, JavaScript, VBScript gibi regexp'in kullanıldığı programlama dillerinde sistem geliştirenler de faydalanacaktır.

Yani demem o ki pekçok kişi yazılarınızı takip ettikleri takdirde Perl ile program yazmaya kalkmasalar bile işlerine yarayacak fikirleri, bilgileri edinecekler, belki de birtakım kalıpların dışına çıkabilme becerisini kazanacak ya da en azından 'vay canına demek böyle de bir şey bu şekilde yapılabiliyormuş' diyecektir (bunu buraya yazarlar mı orası ayrı konu ;-)

Yazmaya ve paylaşmaya devam!
0
anonim
Valla şahsen benim bildiğim bir çok kişi, yaw ne güzel oldu şeklinde yaklaşıyor. FM okurlarında (genel IT sektörümüzde mi yoksa) bir miktar yazmaya karşı çekingenlikten olsa gerek, tepkiler genelde sözel veriliyor. O yüzden siz hiç dert etmeyin, çok güzel bir yazı dizisi oluşturdunuz elinize sağlık ve inanın takip edenleriniz var.
0
Anduril
Can Uğur AYFER hocam FM Forumlarında İlanlar kısmındaki sizle ilgili yazıyı okursanız sevinirim. Artık daha dikkatli davranırsınız kitaplarınızı yayınlarken. Kolay gelsin sağolun.
Görüş belirtmek için giriş yapın...

İlgili Yazılar

`Diğerleri(miz) için Flash´

butch

Perl::Flash ın beta sürümünün hazır olduğu Slashdot da duyuruldu. Artık Perl kullanarak Flash animasyonları yapılabilecek. Proje hakkında geniş bilgi burada...

Perl Öğreniyoruz - 5

cayfer

1. bölüm 2. bölüm 3. bölüm 4. bölüm
regexp'ler (Regular Expressions)Sözlüğe bakınca
regular: düzenli, muntazam, kurallı, kurallara uygun ve düzenli
expression: deyim, ifade, tabir, anlatım ve dışavurum
karşılıklarını buldum. Bence ingilizce Regular Expression sözcükleri de bu bölümde anlatacağım konuyu tam olarak anlatamıyor; çünkü aslında kavram adını ABD'li matematikçi Kleen'in Düzenli Kümeler Cebiri (Algebra of Regular Sets) üzerindeki çalışmalarından alıyor.

Nokia Cep Telefonlarını Perl ile Programlayın

FZ

Meşhur cep telefonu üreticisi Nokia, Series 60 cihazlarının Perl ile programlanabilmesi için gerekli çalışmayı başlattığını açıkladı.

Sanırım artık ciddi ciddi cep telefonu programlamayı düşünmekte fayda var, nihayet bu aletleri programlamak ``eğlenceli´´ hale gelmek üzere ;-)

Kaynaklar:

- http://slashdot.org/article.pl?sid=04/01/17/1435206

- http://theregister.co.uk/content/64/34943.html

Perl Öğreniyoruz - 1

butch

Haydi millet toplanın. Perl öğrenmeye başlıyoruz :) Bundan sonra düzenli olarak bu köşede Can Uğur Ayfer tarafından hazırlanan Perl Öğreniyoruz makaleleri yayınlanacak. Bu makalelerde, klasik yöntemle, basit problemleri adım adım çözerek beraberce Perl öğreneceğiz. Buyrun ilk derse...

(Can Uğur Ayfer, Kim Korkar Unix`den, Perl ve MySQL ile Cgi Programlama gibi kitapların yazarı, 1973 yılından beri ülkemizde bilgisayar sektörünün duayenlerinden birisidir. Halen aktif olarak çalışmakta öğrenmeye, öğretmeye aynı coşku ile devam etmektedir. Kendisine sonsuz teşekkürler)

Anti-Spam E-Posta Adresi Oluşturma (Şifreli IP Adresiyle)

FZ

Bugün Perl Rahipleri tapınağında okuduğum ve spam e-posta konusu ile ilgili bu önemli makaleyi ve Perl kodunu sizinle paylaşmak istedim.

Eğer bir şekilde web sayfanızda e-posta adresinizi yayınlamak istiyorsanız yukarıdaki makaledeki Perl betiğini (script) kullanarak oluşturacağınız dinamik bir e-mail adresinin içine o anda sizin e-posta adresinizi çekmeye çalışan robota ya da spamciye dair bilgileri gömebiliyorsunuz. Nasıl yani diyenler okumaya devam edebilir ;-)