Kendi Split Fonksiyonumu Yaptım

Karakter buluncaya kadar indisi arttırıp iterable’da arama yapıyor. Bulunca konumunu kaydedip kelime_baslangic’a atıyor ve bir sonraki döngüye geçiyor.
Sonraki döngüde space oluncaya dek kelime_boyutu arttırılıyor. kelime_baslangic:kelime_baslangic+kelime_boyutu olacak şekilde kelime ekleniyor.

metin = input("Metin: ") + " "
kelimeler = []
indis = 0
kelime_baslangic = 0
kelime_indis = 0
while indis < len(metin) - 1:
    if " " not in metin:
        kelimeler.append(metin[0:])
        break
    if metin[indis] == " ":
        indis += 1
    else:
        kelime_baslangic = indis
        kelime_indis = indis
        kelime_boyutu = 0
        while metin[kelime_indis] != " ":
            kelime_boyutu += 1
            kelime_indis += 1
            if metin[kelime_indis].isspace():
                kelimeler.append(metin[kelime_baslangic:kelime_baslangic + kelime_boyutu])
                indis += kelime_boyutu
                kelime_indis = 0
                kelime_boyutu = 0
                break
print(kelimeler)

İkinci örnek:

metin = bytearray(input("Metin: "),"utf-8","ignore")
indis = 0
kelimeler = []
while len(metin) > 0:
    for i in metin.decode():
        if i.isspace():
            kelimeler.append(metin[0:indis].decode())
            del metin[0:indis + 1]
            indis = 0
            break
        indis += 1
    if " " not in metin.decode():
        kelimeler.append(metin.decode())
        del metin[0:]
            
print(kelimeler)

Yukarıdaki ile prensip olarak aynı. Tek fark her boşluk karakterinde bytearray nesnesi sayesinde metni silip iterasyonu tekrarlaması.

Başka metotlarınız varsa lütfen yazın. Kolay gelsin.

1 Beğeni

Merhabalar,

Test/ornek yok mu?

Olsa hem dogru yaptiginizi dogrular, hem de kendi metodunu yazacak veya sizinkilerle oynayacak kisilere onayak olur.

def split(s):
	return s.split()

def test(beklenen, sonuc):
	print(f"Beklenen: {beklenen}")
	print(f"Sonuc   : {sonuc}")
	if beklenen != sonuc:
		print("*** OLMADI")

test(["bir", "iki"],       split("bir iki"))
test(["bir", "iki", "uc"], split("bir iki uc"))
test(["bir"],              split("bir"))
test([],                   split(""))
test(["bir"],              split(" bir"))
test(["bir"],              split("bir "))
test(["bir", "iki"],       split(" bir iki "))
1 Beğeni
metin = "bu bir deneme metnidir"
def kelime_ayirma(metin):
    metin += " "
    kelimeler = []
    indis = 0
    kelime_baslangic = 0
    kelime_indis = 0
    while indis < len(metin) - 1:
        if metin[indis] == " ":
            indis += 1
        else:
            kelime_baslangic = indis
            kelime_indis = indis
            kelime_boyutu = 0
            while metin[kelime_indis] != " ":
                kelime_boyutu += 1
                kelime_indis += 1
                if metin[kelime_indis].isspace():
                    kelimeler.append(metin[kelime_baslangic:kelime_baslangic + kelime_boyutu])
                    indis += kelime_boyutu
                    kelime_indis = 0
                    kelime_boyutu = 0
                    break
    return kelimeler

def test(mtn):
    a = mtn.split()
    b = kelime_ayirma(metin)
    print("Beklenen:",a)
    print("Sonuç:",b)
    if a != b:
        print("Başarısız.")
test(metin)

Umarım bu iş görür.

Super!

Bu arada unit (birim) test’lerinin yazilim gelistirmeye nasil yardimci olduklarini birebir gormus olduk.

1 Beğeni

Merhaba,

Son zamanlarda C++ ile ilgileniyorum ve C++'da aşağıdaki gibi bir split metodu kullanıyorum:

#include <vector>
#include <string>
#include <iostream>

template <typename T>
using lst = std::vector<T>;

using str = std::string;

void innerSplit(str cstr, str sep, lst<str>& splitted) {
    int first = 0;
    int last = cstr.find(sep);
    str item = cstr.substr(first, last);
    splitted.push_back(item);
    if (last == -1) { 
        return; 
    }
    return innerSplit(
        cstr.substr(last + sep.length(), cstr.length()), 
        sep, 
        splitted
    );
}

lst<str> split(str cstr, str sep) {
    lst<str> splitted;
    innerSplit(cstr, sep, splitted);
    return splitted;
}

int main() {
    str cstr = "hello world = merhaba dünya";
    str sep = " ";
    lst<str> splitted = split(cstr, sep);
    for (size_t i = 0; i < splitted.size(); i++) {
        std::cout << splitted[i] << std::endl;
    }
}

Yukarıdaki C++ kodlarını Python’a uyarlarsak, aşağı yukarı şöyle bir kod elde ederiz:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-


def innerSplit(string: str, sep: str, splitted: list[str]):
    try:
        last = string.index(sep)
    except ValueError:
        splitted += [string]
        return
    splitted += [string[:last]]
    string = string[last + len(sep): len(string)]
    return innerSplit(string, sep, splitted)


def split(string: str, sep: str) -> list[str]:
    splitted = []
    innerSplit(string, sep, splitted)
    return splitted
    
    
def main():
    cstr = "hello world = merhaba dünya";
    sep = " ";
    splitted = split(cstr, sep);
    for i in range(len(splitted)):
        print(splitted[i])

    
if __name__ == "__main__":
    main()

Umarım faydası olur.

1 Beğeni

Bu tekniğin adı fonksiyonel programlama mı? Öyleyse avantajı nedir?

Fonksiyonel programlama daha başka prensiplere dayanıyor. Burada öz-yineleme kullanıldı.

Sizin yazdığınız koda göre avantajları şunlar:

  • Kodun okunabilirliği sizin yazdığınız koddan daha fazla.

  • Fonksiyon herhangi bir ayıraç ile de çalışabilir.

1 Beğeni

O daha cok soyle:

def split_f(whole, sep):
	sindex = whole.find(sep)

	if sindex == -1:
		return [whole]
	else:
		left, right = whole[:sindex], whole[sindex + 1:]
		return [left] + split_f(right, sep)

Nereden anliyoruz? Cunku degisken kullanilmamis (tum degiskenlere bir kere yazildigi icin aslinda sabitler, ve atandiklari deger ile yer degistirebilirler:

def split_f2(whole, sep):
	if whole.find(sep) == -1:
		return [whole]
	else:
		left, right = whole[:whole.find(sep)], whole[whole.find(sep) + 1:]
		return [left] + split_f(right, sep)

hatta:

def split_f3(whole, sep):
	if whole.find(sep) == -1:
		return [whole]
	else:
		return [whole[:whole.find(sep)]] + split_f(whole[whole.find(sep) + 1:], sep)

) Ayrica tum fonksiyon bir ifade:

def split_f4(whole, sep):
	return [whole] if whole.find(sep) == -1 else [whole[:whole.find(sep)]] + split_f(whole[whole.find(sep) + 1:], sep)

hatta:

split_f5 = lambda whole, sep: [whole] if whole.find(sep) == -1 else [whole[:whole.find(sep)]] + split_f(whole[whole.find(sep) + 1:], sep)

Bu arada kod basit olsun diye tanimi degistirdim; bastaki, sondaki ve birbirine yapisik ayraclar bos eleman uretiyor. Bu, mesela CSV okumaya calisan kod icin daha mantikli:

split(,a,,) = [_, a, _, _]

Yeni testler (yeni mekanizmayla) soyle:

def test2(f, kaynak, beklenen):
	sonuc = f(kaynak)
	if beklenen != sonuc:
		print("--- Olmadi ---")
		print(f"Kaynak:   \"{kaynak}\"")
		print(f"Beklenen: {beklenen}")
		print(f"Sonuc:    {sonuc}")
		print("---")

def split(s): return split_f(s, ' ')

test2(split, "bir iki",    ["bir", "iki"])
test2(split, "bir iki uc", ["bir", "iki", "uc"])
test2(split, "bir",        ["bir"])
test2(split, "",           [""])

test2(split, " bir",      ["", "bir"])
test2(split, "bir ",      ["bir", ""])
test2(split, " bir iki ", ["", "bir", "iki", ""])

test2(split, "cok   bosluk",      ["cok", "", "", "bosluk"])
test2(split, "  cok    bosluk  ", ["", "", "cok", "", "", "", "bosluk", "", ""])
3 Beğeni