1372826956:AAFe2Py65GSQkfGiRnXuOQ-eD9yXcwMv988

AutoLISP Dersleri #9-Veri Yapıları

sekil-01

AutoLISP’te tüm veri yapıları listedirler. AutoLISP’te her şey şayet bir fonksiyon değilse, listedir; şayet liste ise, bir veri yapısıdır.

Liste bir boyutlu bir diziden başka bir şey değildir. Şayet listelerin listesine sahipseniz, iki boyutlu diziniz var demektir. İki boyutlu bir listenin bir başka iki boyutlu listenin içinde olması bile mümkündür. Sizin bunu ne olarak adlandırdığınızı bilmiyorum; ama ben bunu baş belası olarak adlandırıyorum. Şayet listelerinizi çok derinlere içe gömerseniz, işler kontrolünüzden çıkabilir. Sizin de tahmin edebileceğiniz gibi, AutoLISP listelerle çalışmak için, ön tanımlı birçok fonksiyona sahiptir.

Liste Fonksiyonları:


append (append veri …)(append ‘(1 2) ‘(3 4)) ; (1 2 3 4) olarak döner

append fonksiyonu verilen listeleri alır ve bunları tek bir listede birleştirir.

apply (apply işlem list)(apply ‘+ ‘(1 2 3) ; 6 olarak döner

apply fonksiyonu listedeki öğeleri fonksiyonun parametreleri olarak kullanarak “işlem” kısmında tanımlanan fonksiyonu çalıştırır.

assoc (assoc öğe liste)(assoc 1 ‘((1 “Sertan”)(2 “Türkan”)(3 “Autocadbeyni))); (1 “Sertan”) olarak döner

assoc fonksiyonu “öğe” kısmında verilenleri anahtar kelime olarak kullanarak ilişkiler listesini araştırır ve ilişkili girişleri geri döndürür.

car (car list)

(car ‘(1 2 3 4)) ;1 olarak döner

Listedeki birinci öğeyi geri döndürür.

cdr (cdr list)

(cdr ‘(1 2 3 4)) ; (2 3 4) olarak döner

cdr fonksiyonu listenin ilk elemanı hariç tüm elemanlarını geri döndürür.

cons (cons öğe liste)

(cons 0 ‘(1 2 3)) ;(0 1 2 3 4) olarak döner

cons fonksiyonu verilen “öğeyi”  listenin yeni birinci elemanı yaparak listeyi geri döndürür.

foreach (foreach isim liste tanım)

(foreach n ‘(1 2 3 4) (+ n 1)) ;(2 3 4 5) olarak döner

foreach fonksiyonu listenin her elemanını sırayla “isim” kısmında verilen değişkene atar ve “tanım” kısmında verilen işlemi uygulayarak sonucu geri döndürür.

last (last liste …)

(last 1 2 3 4) ;4 olarak döner

last fonksiyonu listenin son elemanını geri döndürür.

list (liste…)

(list 1 2 3 4) ;(1 2 3 4) olarak döner

list fonksiyonu verilen sayılardan bir liste yaratır.

mapcar (“işlem” liste-1 … liste-n)

(mapcar ‘* ‘(1 2 3) ‘(4 5 6) ;(4 10 18) olarak döner

mapcar fonksiyonu verilen listelerin elemanlarına “işlem” kısmında tanımlanan işlemi uygulayarak sonucu geri döndürür.

member (eleman liste)

(member 2 ‘(1 2 3)) ; (2 3) olarak döner

member fonksiyonu verilen listede “eleman” kısmında tanımlanan öğeyi arar ve o elemandan başlayarak listenim kalanını geri döndürür.

nth (nth n liste)

(nth 2 ‘(1 2 3 4)) ;2 olarak döner

Verilen listenin “n” kısmında tanımlanan öğesini geri döndürür.

reverse (reverse liste)

(reverse ‘(1 2 3)) ;(3 2 1) olarak döner

reverse fonksiyonu verilen listenin elemanlarını ters sırasıyla geri döndürür.

subst (subst yeniöğe eskiöğe liste)

(subst 5 2 ‘(1 2 3 4)) ;(1 5 3 4) olarak döner

subst fonksiyonu verilen listeyi listedeki ” eskiöğe” kısmında tanımlanan elemanı “yeniöğe” kısmında tanımlanan elemanla değiştirerek geri döndürür.

Yukarıdaki örneklerden sizin de gördüğünüz gibi, ön tanımlı fonksiyonları kullanarak listelerde istediğinizi yapabilirsiniz.

Diziler


Bir AutoLISP listesi diğer herhangi bir programlama dilindeki tek boyutlu diziden daha eksik bir şey değildir. Listeleri listelemeye başladığımız zaman, ben listeleri diziler olarak referanslayacağım. Şimdilik bir liste ile nasıl başa çıkılacağını öğrenmeniz yeterlidir.

Tek-boyutlu Listeler


Tek-boyutlu Listeleri Yaratma

CONS, APPEND ve LIST fonksiyonları liste yaratan temel fonksiyonlardır. Bu fonksiyonların herhangi bir tanesi setq fonksiyonu ile birleştirilerek listeler yaratılabilmektedir. Aşağıdaki örneklerde de göreceğiniz üzere, liste yaratmak için, QUOTE fonksiyonu da kullanılabilmektedir.

Öğelerin statik listesini yaratmak istediğiniz zaman, LIST ve QUOTE fonksiyonlarını kullanabilirsiniz. Bu fonksiyonlar listenin neleri içereceğinin bilindiği durumlarda yaratılan listelerdir. Ayrıca dinamik listeler yaratmak için, LIST fonksiyonu diğer lisp fonksiyonları ile birlikte de kullanılabilmektedir.

(setq liste_ismi

(list 1 2 3))

; (1 2 3) olarak döner

Şayet şimdi liste_ismi listesini kontrol edersek, bu listenin (1 2 3) listesine bağlandığını görürüz. Liste AutoLISP’in temel depolama aracıdır. AutoLISP’de göreceğimiz her yapı bir listeden başka bir şey değil ve her liste de bir boyutlu diziden başka bir şey değildir. Yukarıdaki liste QUOTE fonksiyonu kullanılarak da yaratılabilirdi.

(setq liste_ismi (quote (1 2 3)))

(setq liste_ismi ‘(1 2 3))

Yukarıdaki yöntemlerin her ikisi de kullanılmaktadır. Son örnek, listenizin neleri içermesini istediğinizi tam olarak bildiğiniz durumlarda muhtemelen en kolay liste yaratma yöntemidir.

CONS ve APPEND fonksiyonları dinamik listeler yaratmak için kullanılmaktadır. Bu listeler listenizin neleri içermesini istediğinizi tam olarak bilmediğiniz durumlarda yaratılan listelerdir. CONS komutu temel liste oluşturucusu olup; verilen bir listenin önüne öğeler ekleyerek yeni listeler yaratır.

(setq liste_ismi

(cons item liste_ismi))

Yukarıdaki örnek CONS fonksiyonu kullanılarak liste yaratmayı göstermektedir. APPEND fonksiyonu verilen listeleri alacak ve bunları tek bir liste olarak birleştirecektir. APPEND fonksiyonu ile ilgili olarak unutmamanız gereken tek şey fonksiyona aktarılacak olan öğelerin listeler olma zorunluluğudur.

(setq liste_ismi

(append ‘(1 2 3) ‘(4 5 6)))

;(1 2 3 4 5 6) olarak döner

Sizin de gördüğünüz üzere, buraya kadar listeleri yaratma işlemi kolay anlaşılır bir işlemdir. İlerde, daha kolay olan listelere nasıl ulaşabileceğimizi öğreneceğiz.

Tek-boyutlu Listelere Ulaşma

Listelerden değerler toplamak (elde etmek) için, kullanabileceğimiz birçok fonksiyon vardır. CAR ve CDR fonksiyonları bir listeden veriler elde etmenin en popüler iki yoludur. Şayet CAR fonksiyonunu kullanırsak, listenin birinci öğesini elde ederiz.

(car ‘(4 5 6)) ;4 olarak döner

CDR fonksiyonu listenin ikinci öğesinden başlayarak geri kalan tüm öğeleri geri döndürür.

(cdr ‘(4 5 6)) ;(5 6) olarak döner

Bu iki fonksiyon dört derece derinliğe kadar birbirlerinin içerisine gömülebilmektedir. Bu şayet bir listeden sadece ikinci öğeyi elde etmek isterseniz, bu iki fonksiyonu birleştirebileceğiniz anlamına gelir.

(cadr ‘(4 5 6)) ;5 olarak döner

Şayet listenin üçüncü öğesini elde etmek istersek, bunu CDR CDR CAR fonksiyonlarının birleştirilmesi ile oluşturulmuş CADDR fonksiyonunu kullanarak elde ederiz.

(caddr ‘(4 5 6)) ;6 olarak döner

Listeden bu yolla veri elde etme işlemine ilk baktığınız zaman, bu yöntem çok uzun ve meşakkatli gelebilir; fakat bu fonksiyonların kullanılması bazen çok faydalıdır. Bu fonksiyonların faydalarını görmek için, bir noktanın X, Y ve Z koordinat değerlerinin bir liste olduğunu hatırlamanız yeterlidir. İlerde ilişkisel listeleri tartışırken bu fonksiyonları hatırlayın. LAST fonksiyonu bir listeden listenin son öğesini elde etmek için kullanılabilmektedir. Şayet listedeki son öğenin ne olduğunu biliyorsanız, kullanacağınız fonksiyon budur.

MEMEBER fonksiyonu bir öğenin listede bulunup bulunmadığını söyler. MEMEBER fonksiyonunu genellikle SUBST fonksiyonunu kullanmadan önce kullanırsınız. Bir listedeki elemanı bir başka öğe ile değiştirmeden önce o elemanın listede bulunup bulunmadığını bilmek zorundasınızdır. İşte bu MEMEBER fonksiyonu öğenin verilen listenin bir elemanı olup olmadığını söyleyecektir. NTH fonksiyonu listenin belirli bir konumundaki veriyi elde etmek için, kullanılır. NTH fonksiyonu listenin gitmek istediğiniz konumunu (sırasını) bildiğiniz zaman çok kullanışlıdır.

(nth 3 ‘(2 3 4 5 6)) ;4 olarak döner

NTH fonksiyonunun kullanımı oldukça kolaydır. NTH fonksiyonu listenin içerisinde adım adım ilerlemesi için normalde bir endeks ile birlikte kullanılır. Listeyi belirli bir değer için aradığımız zaman, NTH fonksiyonunu bir endeks ile birlikte kullanırız.

(while ;While

(and(nth Ndx liste_ismi) ;listede

;hala öğeler vardır

(/= (nth Ndx liste_ismi) aranan_öğe)) ;ve bunlar bizim

;aradığımız öğe değildirler.

(= Ndx (+ Ndx 1))) ;arttırma endeksi

Yukarıdaki kod örneği şu iki durudan bir tanesi gerçekleşene dek verilen listede araştırma yapmaya devam edecektir:

  • Aranan şey bulunmuştur.
  • Listenin sonuna gelinmiştir.

Yukarıdaki kodu çalıştırmadan önce yapmanız gereken tek şey, Ndx, liste_ismi ve aranan_öğe değişkenlerini başlatmaktır.

If Şayet ilgilendiğiniz liste bir “ilişkisel” liste ise, bu listeye ulaşmak için, ASSOC fonksiyonunu kullanmalısınız. ASSOC fonksiyonu verilen listeyi belirli bir anahtar öğe için araştırır ve listenin o anahtar öğeyi içerip içermediğini geri döndürür. Şayet değişkenleri ve bu değişkenlerin değerlerini bir listede depolamak istiyorsanız, bunları depolamak için, bir ilişkisel liste kullanmanız gerekecektir.

İlişkisel liste aşağıdaki örnekte görüldüğü gibi oluşturulur:

(setq liste_ismi

(list

(1 “Bu”) (2 “bir”) (3 “ilişkisel”) (4 “liste”) (5 “dir”))))

Artık listeden verileri elde etmek için, sayısal anahtarlarınız vardır. Listedeki verilere ulaşmak için, çoğu zaman cadr fonksiyonunu kullanacaksınız. Şayet kullanmazsanız, aşağıdaki örnekte neler olduğunu görebilirsiniz:

(assoc 1 liste_ismi) ;(1 “Bu”) olarak döner

(assoc 2 liste_ismi) ;(2 “bir”) olarak döner

(cadr (assoc 3 liste_ismi)) ;”ilişkisel” olarak döner

(cadr (assoc 4 liste_ismi)) ;”liste” olarak döner

(cadr (assoc 5 liste_ismi)) ;”dir” olarak döner

Örneklerden de görüldüğü üzere,  ASSOC fonksiyonunun kendisi tek başına çok fazla faydalı olmayıp; şayet CADR fonksiyonu ile birlikte kullanılırsa, ihtiyacınız olan verileri elde edebilirsiniz.

Tek-boyutlu Listeleri Değiştirme

APPLY fonksiyonu verilen listeleri fonksiyonun argümanı olarak kullanan bir fonksiyondur. Bu fonksiyon bir liste içerisinde kaydetmiş olduğunuz sayıların toplamını hesaplamada faydalıdır.

(apply ‘+ (23 12 -10)) ; 25 olarak döner

APPLY fonksiyonu herhangi bir fonksiyon ile kullanılabilir; bu fonksiyon verilen listenin içerisindeki öğeleri sırasıyla soldan sağa doğru parametre olarak fonksiyona aktarır.

FOREACH fonksiyonu bir listede toplu değişiklikler yapmak için, kullanılır. Fonksiyon listedeki her öğe üzerinde çalışır ve her öğede aynı değişiklikleri yapar. Şimdi örnek olarak bazı kullanıcı veri girişlerini bir listede topladığımızı ve kullanıcının verdiği cevapları belirli bir sabit ile kontrol etmek istediğimizi farz edelim. Bunu yapmak için, yapmamız gereken ilk şey kontrol olarak kullanılacak olan dizgeyi büyük harf olarak tanımlayabilelim diye tüm cevapları büyük harfe çevirmek olmalıdır. Aşağıdaki kod tüm cevapları büyük harfe nasıl çevireceğinizi göstermektedir:

(foreach n cevap_listesi (strcase n))

Bu kod listeyi her öğesi büyük harfe çevrilmiş olarak geri döndürecektir.

Size bahsetmek istediğim bir sonraki fonksiyon listeleriniz içerisinde kullanacağınız SUBST fonksiyonudur. SUBST fonksiyonu listeleriniz içerisindeki verileri değiştirmek için kullanılır. SUBST fonksiyonu listedeki bir veri öğesini bir başka veri öğesi ile değiştirir. Tanımından da anlaşıldığı üzere bu fonksiyon oldukça açıktır.

Tek-boyutlu Listeleri Kullanma

MAPCAR fonksiyonu bir veya daha fazla sayıda listeden öğeleri parametreler olarak bir fonksiyona geçirir. MAPCAR fonksiyonu fonksiyona gönderilen eski listenin sonucunu yeni bir liste olarak geri döndürür. Bu fonksiyon “x” ve “y” koordinatlarını içeren bir listeden yeni bir nokta listeleri yaratırken çok kullanışlıdır.

(setq point_list (mapcar ‘list x_list y_list))

Çok-boyutlu Diziler

Listeleri kullanan dizileri yaratmak için de aynı fonksiyonları kullanabiliriz. Çünkü dizi bir listeden farklı bir şey değildir.  Bazen liste kavramını kullanmak yerine dizi kavramını kullanmak çok daha kolaydır. Dizi daha yapısal bir öğe iken, liste öğelerin uzun dizgeleri olma eğilimindedir.

Dizinin içerisine ne koyduğumuzu bildiğimiz zaman, diziyi düzenlemek için, tırnak işareti kullanacağız. Sabit verilerin dizisi böyle bir dizidir ve aşağıdaki liste, böyle bir dizinin nasıl düzenleneceğini göstermektedir. Bu bazı popüler matkap ebatları için, “Burgu”ların çap listesi ve “Burgu matkaplarının” çaplarıdır.

(setq Büyük_Burgu_Listesi’

(((“İsim” “#3”) (“Burgu” 0.099) (“Matkap” 0.0785))

((“İsim” “#4”) (“Burgu” 0.112) (“Matkap” 0.0890))

((“İsim” “#5”) (“Burgu” 0.125) (“Matkap” 0.1015))

((“İsim” “#6”) (“Burgu” 0.138) (“Matkap” 0.1065))

((“İsim” “#8”) (“Burgu” 0.164) (“Matkap” 0.1360))

((“İsim” “#10”) (“Burgu” 0.1875) (“Matkap” 0.1495))

((“İsim” “1/4”) (“Burgu” 0.2500) (“Matkap” 0.2010))

((“İsim” “5/16”)(“Burgu” 0.3125) (“Matkap” 0.2570))

((“İsim” “3/8”) (“Burgu” 0.375) (“Matkap” 0.3125))

((“İsim” “1/2”) (“Burgu” 0.500) (“Matkap” 0.4219))

((“İsim” “5/8”) (“Burgu” 0.625) (“Matkap” 0.5469))

((“İsim” “3/4”) (“Burgu” 0.750) (“Matkap” 0.6563))

((“İsim” “M3”) (“Burgu” 0.11811024) (“Matkap” 0.09842520))

((“İsim” “M4”) (“Burgu” 0.15748032) (“Matkap” 0.12992126))

((“İsim” “M5”) (“Burgu” 0.19685039) (“Matkap” 0.16535433))

((“İsim” “M6”) (“Burgu” 0.23622047) (“Matkap” 0.19685039))

((“İsim” “M8”) (“Burgu” 0.31496063) (“Matkap” 0.26574803))

((“İsim” “M10”) (“Burgu” 0.39370079) (“Matkap” 0.33464567))

((“İsim” “M12”) (“Burgu” 0.47244094) (“Matkap” 0.40354331))

((“İsim” “M16”) (“Burgu” 0.62992126) (“Matkap” 0.55118110))

((“İsim” “M20”) (“Burgu” 0.78740157) (“Matkap” 0.68897638))))

Yukarıdaki listeyi bu formda oluşturmak listenin okunabilirliğini ve bu liste ile çalışmayı kolaylaştıracaktır. Yukarıdaki yerleşim formu dizideki her listenin kolayca görünmesini sağlayacak ve diziye ulaşım yordamımı yazacağım zaman, dizinin ne kadar derin olduğunu kolaylıkla görebileceğim.

Çağıran fonksiyonum için liste geri döndüren tam bir fonksiyon yapmak için, aşağıdaki kodu ekleyeceğim. Bunun gibi bir burgu listesini elde ederek programın boyunca tüm Büyük_Burgu_Listesini hafızada tutmama gerek yoktur. Sadece ihtiyacım olan verileri elde edebilir ve geri kalan verileri elde etmeyi fonksiyona bırakabilirim.

(defun get_Burgu_list ( Matkap /BüyükBurguListesiTapNdxTapList )(setq BüyükBurguListesi ;yukarıda görünen kod;buraya gelir)(setq TapNdx 0TapList (car BüyükBurguListesi))(while(/= TapSize (cadr (assoc “İsim” TapList)))(setq TapList (nth TapNdx BüyükBurguListesi))(setq TapNdx (+ TapNdx 1)))(car (list TapList)))

Kodu yukarıda gösterdiğim şekilde yapılandırarak sadece ihtiyacımız olan verileri elde ederiz ve programımız tarafından kullanılmayacak olan veriler hiç yaratılmamış olurlar. Günümüzde RAM blokları yüksek kapasiteli ve ucuzlamış olsalar da, iyi programlama yapmaya dikkat etmeliyiz.

Hakkında Sertan Türkan

AutoCAD Beyni

Bunu da Kontrol edin

Revitte Altlıklar “Underlay” Hakkında

Revit’te koordinasyon ve inşaat için farklı kotlardaki bileşenlerin ilişkisini anlamanız gerektiğinde Altlıklar “Underlays” yararlıdırlar. Video: …

Bir cevap yazın

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Yardıma mı ihtiyacınız var? Chat with us
Bir görüşme başlatmak için lütfen önce gizlilik politikamızı kabul edin.