Python fonksiyon tanımı ve balon sıralaması

Bir arkadaşımın python ödevini çözerken buldum kendimi bugün. Son 10 yılımı yazılım alanında geçirdiğim için baya basit bir problemdi. Fakat bilmeyen insan tabi zorlanıyor. Ödev teknik olarak balon sıralaması (bubble sort) uygulaması fakat olaya biraz renk katmışlar. Problem aşağıdaki gibi;

Pay ve paydası iki elemanlı bir liste olarak verilen kesirli sayıların bulunduğu listeyi küçükten büyüğe doğru sıralayan Python kodu yazınız. Size verilen liste, kendi içinde pay ve paydaların bulunduğu listeleri içermektedir.

Örnek:

[[1, 2], [4, 6], [134, 1024], [8, 23]]

listesi kesirli sayılarını ifade etmektedir. Bu listenin sıralanmış hali ise:

[[134, 1024], [8, 23], [1, 2], [4, 6]]

Sıralama işlemini gerçekleştirmek için, kesirliSayiSirala() isminde bir fonksiyon yazınız. Bu fonksiyon, sıralanması gereken kesirli sayıları bir liste halinde parametre olarak almalı, sıralama işlemini yapmalı ve sonucu ekrana liste olarak yazmalıdır. Bu sıralamayı Balon Sıralama (Bubble Sort) algoritmasını kullanarak yapmalısınız.

Önemli Not: Sıralama yaparken ondalıklı sayı karşılaştırılmasına izin verilmemektedir. Sayıları karşılaştırmak için aşağıdaki basit yöntemi kullanabilirsiniz.

a/b < c/d ancak ve ancak a*d/b*d < c*b/d*b eşitsizliği sağlandığında doğrudur. Payda eşitleme yani.

Yine wikipedia’dan arak bir imaj ile kafamızda canlandırmaya çalışalım nedir bu bubble sort.

Bir indeksi alıp diğer indeks ile karşılaştırıyoruz. Ve bunun sonucu eğer ikinci index ilk indeksten küçükse yerlerini değiştiriyoruz ve bu işlemi yeri değişecek eleman kalmayana kadar tekrarlıyoruz. Tekrar deyince benim aklıma direk looplar geliyor.

Önce python’da bir fonksiyon nasıl tanımlanır ona bakalım.

def fonksiyon(parametre1,parametre2,...):

def: İngilizce “define” kelimesinin kısaltılmışı sonra fonksiyon ismi geliyor. Parantez içinde de bu fonksiyonun alabileceği parametreler var. Milyon tane parametre alabilir (abarttım tabi o kadar RAM yoktur dünyada) fakat bizim fonksiyon bir tane alacak. Son olarak iki nokta üst üste ile tanımlamamızı bitiriyoruz.

Hani değişecek eleman kalmadı dedik ya, bu da benim aklıma mesela direk “for loop” yerine “while loop” getiriyor.

Ve genelde while loopları sonlandırabilmek için bir bayrağa (flag) ihtiyacımız var. Buna islem_bitti diyelim.

def kesirliSayiSirala(liste):
    islem_bitti = False
    while not sorted:
    # matık buraya gelecek.
    return liste

Şimdi mantığı düşünelim. Bir indeksi alıp o indeksten daha sonraki indekste olan elemanlarla karşılaştırmamız gerekiyor. İlk başta biraz kafa karıştırıcı fakat insan düşününce sanki şöyle bir şey aklına gelebilir.

for indeks in range(len(liste)):

sonra payda eşitleme mantığına ihtiyacımız var.

for index in range(len(liste) - index):
    eleman1 = liste[index]
    eleman2 = liste[index + 1]
    if (eleman1[0]*eleman2[1])/(eleman1[1]*eleman2[1]) > (eleman2[0]*eleman1[1])/(eleman2[1]*eleman1[1]):
        # elemanların yerini değiştir

Bir dizedeki elemanları değiştirirken ara bir değişken kaçınılmaz tabi. O yüzden gecici diye bir değişken tanımak gerekli. Ve ayrıca islem_bitti bayrağını “false” yapmalıyız. Çünkü iki elemanın yerini değiştirdik. Değişen eleman yeni pozisyonunun öncesindeki elemandan da küçük olabilir.

def kesirliSayiSirala(liste):
    islem_bitti = False
    indeks = 0
    while not islem_bitti:
        islem_bitti = True
        indeks += 1 # indeksin solunda kalan elemanlar sıralanmış durumda zaten.
        for indeks in range(len(liste) - indeks):
            eleman1 = liste[indeks]
            eleman2 = liste[indeks + 1]
            if (eleman1[0]*eleman2[1])/(eleman1[1]*eleman2[1]) > (eleman2[0]*eleman1[1])/(eleman2[1]*eleman1[1]):
                gecici = liste[indeks]
                liste[indeks] = liste[indeks + 1]
                liste[indeks + 1] = gecici
                islem_bitti = False
    return liste

Koşturalım bakalım.

Hop index out of range. Çünkü indeksi her while loopun ardından bir arttırıyoruz. Bunun nedeni ise solda kalan elemanları zaten sıraladık ( Wikipedia’dan çalıntı animasyonu düşünün) Fakat bu işlem listenin uzunluğunun dışına çıkamıza yola açıyor.

O yüzden for loop şartlarını değiştirmek gerekiyor. Listenin uzunluğundan bulunduğumuz indeksi çıkarsak yeter.

def kesirliSayiSirala(liste):
    islem_bitti = False
    indeks = 0
    while not islem_bitti:
        islem_bitti = True
        indeks += 1
        for indeks in range(len(liste) - indeks):
            eleman1 = liste[indeks]
            eleman2 = liste[indeks + 1]
            if (eleman1[0]*eleman2[1])/(eleman1[1]*eleman2[1]) > (eleman2[0]*eleman1[1])/(eleman2[1]*eleman1[1]):
                gecici = liste[indeks]
                liste[indeks] = liste[indeks + 1]
                liste[indeks + 1] = gecici
                islem_bitti = False
    return liste




result = kesirliSayiSirala([[1, 2], [4, 6], [134, 1024], [8, 23]])
print(result)

Sonuç pek sıralanmışa benzemiyor.

Kodumuza tekrar göz attığımızda, elemanları bölerken tam sayı üzerinden işlem yapıyoruz. Bu da if şartımızı 0 < 0 olarak çalıştırıyor. Bunları kesirli sayı cinsinden ifade etmemiz gerekli. float’a biçimlendirsek yeter. Allahtan python yorumlayıcı zeki alet. Payı biçimlendirince anlıyor cevabın kesirli olduğunu

if (float(eleman1[0]*eleman2[1])/(eleman1[1]*eleman2[1])) > (float(eleman2[0]*eleman1[1])/(eleman2[1]*eleman1[1])):

 

 

 

 

 

 

 

 

 

Leave a Reply