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

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

Yeni Deascifier

anonim

15 senedir İngilizce klavye ile yazıyorum, ve fena alıştım. F klavyeye de, Türkçeleştirilmiş Q klavyeye bile alışacak vaktim ve isteğim yok. Eh dedim ben de, biraz beyin ve Perl kaslarımı çalıştırayım, ve şu işe kalıcı bir çözüm bulayım. Benim değişmeye niyetim yok, teknoloji bana yardım etsin.

Perl Öğreniyoruz - 3

cayfer

2. bölümün sonunda bu hafta "listeler"den söz edeceğimi söylemiştim.

Listeler (arrays) Perl'in çok güçlü olduğu konulardan birisidir. Perl'de bir listeden söz ederken değişken adının başına bir @ işareti koymalısınız. (Hatırlıyorsanız sayıl (scalar) değişkenlerin adı $ işareti ile başlardı).

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 ;-)

Perl, Divx, altyazı ve başının çaresine bakabilmek üzerine

sundance

Uzun zamandır izlemek istediğim, The Hustler'ı seyretmek için sonunda zaman bulabildim. Paul Newman'ın 1962'de başrolünü oynadığı bu film, yıllar sonra Color of Money'e de konu olacak Fast Eddie Felson'ın hikayesini anlatıyordu. Dahası Unix Junkie makalemde bahsettiğim insan modelinin belki de en iyi örneklerinden biriydi.

Fakat küçük bir problem vardı, filmindeki hiçbir dialoğu kaçırmamak için altyazıya ihtiyaç duyuyordum, fakat benim elimdeki film iki cd olmasına rağmen bulabildiğim yegane ingilizce altyazı üç cdlikti.

Durumdan vazife çıkartmaya zaten hazır bir FM sakini olarak, sıvadım kolları ve küçük bir perl betiki yazdım bu işi yapması için. Film hatırladığımdan bile güzeldi, ama böyle bir durumda bir beş, on dakika içinde problemi çözebilmek daha bile keyifliydi, GNU/Linux kullanıyor olmak keyifliydi :)