def suzgec(n):
return n >= 70
print(*filter(suzgec, notlar.values()))
olarak çıktı aldığımda sözlük değerlerini tek tek suzgec fonksiyonunda girerek >70 olan değerleri ekrana basıyor. Buraya kadar problem yok. Ama aşağıdaki gibi bir fonksiyon tanımlarsam filter() fonsiyonu, sözlük değerlerinin karşılığı olan harf değerlerini girmiyor. Yani :
def not_durum(n):
if n in range(0,50): return 'F'
if n in range(50, 70): return 'D'
if n in range(70, 80): return 'C'
if n in range(80, 90): return 'B'
if n in range(90, 101): return 'A
print(*filter(not_durum, notlar.values()))
çıktısı sözlük değerlerini sayı olarak ekrana basıyor:
60 50 45 87 99 98 51 100 66 80
filter() fonksiyonu, tanımladığım son fonksiyon için neden istediğim harf notları ekrana vermiyor?
https://docs.python.org/2/library/functions.html#filter
Buradaki kaynağı incelediğimde filter fonksiyonu, verilen fonksiyondan çıkan verinin bool değeri ile ilgileniyor. Buna göre filtreleme yapıyor. İlk örnekte 70 ve üstü için True olduğu için 70 ve üstü olan notları çıktı olarak veriyor.
İkinci örnekte ise not_durum fonksiyonundan çıkan veriler string. bool(‘F’) gibi bir kod True değerini verecektir. Bu nedenle sözlük değerleri ekrana basılmaktadır. (PC başında olmadığım için deneme yapamadım.)
Çünkü harf bastırılması ile ilgili bir işlem tanımlanmamış.
def not_durum(n):
if n in range(0,50): return 'F'
if n in range(50, 70): return 'D'
if n in range(70, 80): return 'C'
if n in range(80, 90): return 'B'
if n in range(90, 101): return 'A
Yukarıdaki fonksiyon filter ile kullanıldığında şöyle bir fonksiyon gibi davranıyor.
def not_durum(n):
return n
notlar.values()'u bu n’e göre sıralıyorsunuz. Ve harfleri bastırmıyor. return kısmına harf yerine başka birşey yazsanız onları da bastırmaz. Dolayısıyla harf bastırmak istiyorsanız, onun için ayrı bir fonksiyon tanımlamanız lazım. İsterseniz aşağıdaki kodları bir inceleyin.
notlar = {
'Ahmet': 60,
'Sinan': 50,
'Mehmet': 45,
'Ceren': 87,
'Selen': 99,
'Cem': 98,
'Can': 51,
'Kezban': 100,
'Hakan': 66,
'Mahmut': 80
}
def suzgec():
"""def f(n):
return n
return [i for i in filter(f, notlar.values())]"""
# suzgec() fonksiyonunun içine sadece aşağıdakini de yazabiliriz.
return notlar.values()
# Bir üst satırdaki return'un geri dönderdiği değerler ile,
# yukarıdaki f(n) fonksiyonunun geri dönderdiği değerler aynıdır.
# Çünkü notlar.values()'un tamamı üzerinde işlem yapılıyor.
def harfe_cevir():
for i in suzgec():
# for i in notlar.values():
# Yukarıdaki suzgec() fonksiyonuna gerek de yok aslında.
if i in range(0, 50):
yield "F"
elif i in range(50, 70):
yield "D"
elif i in range(70, 80):
yield "C"
elif i in range(80, 90):
yield "B"
elif i in range(90, 100):
yield "A"
if __name__ == "__main__":
sonuc = harfe_cevir()
print(*sonuc)
Acaba harfe_cevir fonksiyonundaki yield ifadelerini mi anlamadınız?
Mesela aşağıdaki kodla, bütün i’leri kullanamayız. Sadece ilk i değeri kullanılır.
def f(n):
for i in range(n):
return i
Bütün i’leri kullanabilmek için iki farklı yazım şekli var.
Birincisi:
def f(n):
return [i for i in range(n)]
print(*f(10))
İkincisinde ise yield kullanılır:
def f(n):
for i in range(n):
yield i
print(*f(10))
yield, aşağıdaki gibi de kullanılır:
def f():
for i in range(10):
yield i
if __name__ == "__main__":
x = f()
# print(x.__next__())
print(next(x)) # 0
# print(x.__next__())
print(next(x)) # 1
Yield ile ilgili lütfen aşağıdaki örneği de inceleyin.
def f():
yield "hello"
yield 1
yield [i for i in range(10)]
x = f()
print(next(x)) # hello'yu bastırır.
print(next(x)) # 1'i bastırır.
print(next(x)) # [i for i in range(10)]'u bastırır.
# Şayet bir kez daha print(next(x)) yazarsak bu kez hata alırız
print(next(x)) # StopIteration
def not_durum(n):
if n in range(0,50): return 'F'
if n in range(50, 70): return 'D'
if n in range(70, 80): return 'C'
if n in range(80, 90): return 'B'
if n in range(90, 101):return 'A'
print(not_durum(55)) #yazınca D yazıyor.
print(*filter(not_durum, notlar.values()))
burada sözlük değerlerini tek tek neden girmiyor. Demişsiniz ki
“Çünkü harf bastırılması ile ilgili bir işlem tanımlanmamış.”
Ben de not_durum() fonksiyonun içinde print(‘harf’) kodunu yazdım.
Bu sefer de aynı harften iki tane yazmaya başladı. retun’u silsem print (*filter()…) print fonksiyonu None hatası verecek. Sonra siz sınıflara falan girmişsiniz. Sonra olay çorba oldu. Dediğim gibi toparlamam gerek.
return “C” yerine print(“C”) yazarsanız bu sefer harfleri bastırır. Her not için bastırır. Yani notlar isimli sözlüğün içinde 3 tane 90 ile 101 arasında not alan kişi var. Dolayısıyla 3 tane A bastırılır. Ayrıca sınıflarla ilgili bir çalışma yapmadım.
Sizin yazdığınız kodlar:
notlar = {
'Ahmet': 60,
'Sinan': 50,
'Mehmet': 45,
'Ceren': 87,
'Selen': 99,
'Cem': 98,
'Can': 51,
'Kezban': 100,
'Hakan': 66,
'Mahmut': 80
}
def not_durum(n):
if n in range(0, 50): print('F')
if n in range(50, 70): print('D')
if n in range(70, 80): print('C')
if n in range(80, 90): print('B')
if n in range(90, 101): print('A')
print(*filter(not_durum, notlar.values()))
Benim yazdığım da sizinkine benzer bir işlem yapıyor, sadece yol biraz farklı:
notlar = {
'Ahmet': 60,
'Sinan': 50,
'Mehmet': 45,
'Ceren': 87,
'Selen': 99,
'Cem': 98,
'Can': 51,
'Kezban': 100,
'Hakan': 66,
'Mahmut': 80
}
def harfe_cevir():
for i in notlar.values():
if i in range(0, 50):
yield "F"
elif i in range(50, 70):
yield "D"
elif i in range(70, 80):
yield "C"
elif i in range(80, 90):
yield "B"
elif i in range(90, 101):
yield "A"
sonuc = harfe_cevir()
print(*sonuc)
Yazıyor. Çünkü print’le kullandım
Yani gömülü bir len() fonksiyonu gibi çalışmıyor. Öyle çalışması için return lazım. O zaman da baştaki sorun hasıl oluyor.
Dediğim gibi daha konuyu bitirmedim. Aşağıdaki yazdığınız sınıflara giriyor sandım. Bilmiyorum. if __name__ == "__main__":
yapısını da bilmiyorum henüz. Kitapta gömülü fonksiyonlar konusu filter() de kaldım.
print(not_durum(55)) yerine not_durum(55) yazın. Çünkü zaten not_durum() fonksiyonunun içinde print() var, not_durum’u çağırdığınızda 55’e karşılık gelen harf notu bastırılacak.
Onu anlıyorum zaten sebebini. Ama ben yazdığım bir fonksiyonun Python’daki gömülü fonksiyonlar gibi çalışmasını istediğimden return kullanıyorum. Yani şimdilik bu kadar biliyorum.
Yapmak istediğinizi anlamaya çalışıyorum. Sizin yazdığınız kodlardaki filter() fonksiyonu ekrana harf bastırılmasına engel oluyor. Yani belki biraz kurcalanırsa, onunla da yapılır ama şimdiki haliyle print(“C”) yerine return “C” yazarsanız, rakamları geri döndermiş olursunuz.
Sizin yapmak istediğinize benzer bir şeyi başka bir yöntemle yapabiliriz:
notlar = {
'Ahmet': 60,
'Sinan': 50,
'Mehmet': 45,
'Ceren': 87,
'Selen': 99,
'Cem': 98,
'Can': 51,
'Kezban': 100,
'Hakan': 66,
'Mahmut': 80}
def harfe_cevir():
listeye_al = [[] for _ in "FDCBA"]
for i in notlar.values():
if i in range(0, 50):
listeye_al[0].append("F")
elif i in range(50, 70):
listeye_al[1].append("D")
elif i in range(70, 80):
listeye_al[2].append("C")
elif i in range(80, 90):
listeye_al[3].append("B")
elif i in range(90, 101):
listeye_al[4].append("A")
return [j for i in listeye_al for j in i]
sonuc = harfe_cevir()
print(*sonuc)
Bu da istediğiniz gibi olmadı sanırım. Siz hem not_durum(55) yazınca harfi return etmesini, hem de o sözlükteki notların da harf karşılıklarını return etmesini, daha sonra print() ile ekrana bastırılabilir olmalarını istiyorsunuz değil mi? Yani şu yapı korunsun. Ve aynı zamanda notlar’a da uygulanabilsin.
def not_durum(n):
if n in range(0, 50):
return "F"
elif n in range(50, 70):
return "D"
elif n in range(70, 80):
return "C"
elif n in range(80, 90):
return "B"
elif n in range(90, 101):
return "A"
notlar = {
'Ahmet': 60,
'Sinan': 50,
'Mehmet': 45,
'Ceren': 87,
'Selen': 99,
'Cem': 98,
'Can': 51,
'Kezban': 100,
'Hakan': 66,
'Mahmut': 80
}
def not_durum(n):
"""Bu fonksiyon gömülü bir fonksiyon gibi kullanılabilir."""
if n in range(0, 50):
return "F"
elif n in range(50, 70):
return "D"
elif n in range(70, 80):
return "C"
elif n in range(80, 90):
return "B"
elif n in range(90, 101):
return "A"
def veri_gruplari_icin_not_durumu(veriler):
"""Yukarıdaki not_durum fonksiyonunu;
liste, demet gibi veri tipleri içindeki
her sayı verisi için çağırır ve sonucu liste olarak
geri gönderir.
Bu da gömülü bir fonksiyon gibi kullanılabilir."""
return [not_durum(n=i) for i in veriler]
print(*veri_gruplari_icin_not_durumu(veriler=notlar.values()))
# Örneğin veri grubu aşağıdaki gibi gruplar da olabilir.
# print(*veri_gruplari_icin_not_durumu(veriler=[i for i in range(10)]))
# print(*veri_gruplari_icin_not_durumu(veriler=(11, 45, 88)))
print(not_durum(55))