1’den 1000’e kadar olan sayılardan mükemmel sayı olanları ekrana yazdırın. Bunun için bir sayının mükemmel olup olmadığını dönen bir tane fonksiyon yazın.
*Bir sayının bölenlerinin toplamı kendine eşitse bu sayı mükemmel bir sayıdır. Örnek olarak 6 mükemmel bir sayıdır (1 + 2 + 3 = 6)
def mükemmel_mi(sayı = 1000):
toplam = 0
bölen = 1
mükemmel_sayılar = []
for v in range(1,sayı):
while (bölen < v):
if (v % bölen == 0):
toplam += bölen
bölen += 1
if (v == toplam):
mükemmel_sayılar.append(v)
return mükemmel_sayılar
print(mükemmel_mi())
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
def mukemmel_mi(liste):
for i in liste:
bolenler = []
for j in range(1, i):
if i % j == 0:
bolenler.append(j)
if sum(bolenler) == i:
yield i
for i in mukemmel_mi([j for j in range(1000) if j != 0]):
print(f"{i} mükemmel bir sayı.")
def mükemmel_mi(sayı = 1000):
toplam = 0
bölen = 1
mükemmel_sayılar = []
for v in range(1,sayı):
# Yukarıdaki for döngüsüne göre
# v = 1 olduğunda
# Aşağıdaki while döngüsü atlanır.
# Doğrudan mükemmel_sayılar return edilir.
# Ve return edilen şey boş bir listedir.
while (bölen < v):
if (v % bölen == 0):
toplam += bölen
bölen += 1
if (v == toplam):
mükemmel_sayılar.append(v)
return mükemmel_sayılar
print(mükemmel_mi())
Ayrıca bir for döngüsünde return'u for döngüsünün içinde kullanarak birden fazla değeri geri dönderemeyiz. Bu yüzden return'u for döngüsünün dışına almak lazım. for döngüsünün içinde bir değişkeni geri döndermek istiyorsak, ya döngü içindeyken onu bir listeye eklemeli, sonradan listeyi geri döndermeli ya da yield deyimi kullanılmalı. Bu arada bir önceki mesajımda yazdığım kodlar aşağıdaki gibi de yazılabilirdi.
# Argümanı liste değil de
# sayı olacak şekilde
# fonksiyonu yeniden düzenleyebilirsiniz.
def mukemmel_mi(liste):
mukemmel_sayilar = []
for i in liste:
# Listedeki her bir sayı için
# bir tane bolenler listesi oluşturulsun
bolenler = []
# Her bir sayı kendisine kadar olan sayılara
# kadar bir döngü içerisine sokulsun
for j in range(1, i):
# i değişkenini kendisine kadar olan j sayılarına bölelim (0 hariç)
# kalanı 0 veren j sayısını
# bolenler listesine ekleyelim.
if i % j == 0:
bolenler.append(j)
# Eğer bolenler listesindeki j sayılarının toplamı
# i değişkenine eşitse, i mükemmel bi sayıdır.
if sum(bolenler) == i:
# i, mükemmel bir sayıysa mukemmel_sayilar
# listesine eklensin.
mukemmel_sayilar.append(i)
# Son olarak döngü tamamlandığında
# mükemmel_sayilar'ı geri dönderelim.
return mukemmel_sayilar
liste = [j for j in range(1000) if j != 0]
print(mukemmel_mi(liste))
Aşağıdaki fonksiyon da yukarıdaki fonksiyon ile benzer sonuçlar üretir. Ama birinin argümanı list veri tipindeyken, diğerinin argümanı int veri tipindedir.
def mukemmel_mi(sayi):
mukemmel_sayilar = []
for i in range(1, sayi):
toplam = 0
for j in range(1, i):
if i % j == 0:
toplam += j
if toplam == i:
mukemmel_sayilar.append(i)
return mukemmel_sayilar
print(mukemmel_mi(1000))
yield deyimi kullanarak aşağıdaki gibi de yazılabilir:
def mukemmel_mi(sayi):
for i in range(1, sayi):
toplam = 0
for j in range(1, i):
if i % j == 0:
toplam += j
if toplam == i:
yield i
print(list(mukemmel_mi(1000)))
Sayenizde lambda, map, filter ile ilgilenmeye başladım.
Mesela aşağıdaki kodlar yazdığınız kodlarla aynı işlemleri yapıyor sadece yazım şekli biraz farklı:
mukemmel_mi = lambda sayi: list(filter(lambda x: sum(filter(lambda y: x % y == 0, range(1, x))) == x, range(1, sayi)))
print(mukemmel_mi(sayi=1000))
@gopenumbra d, sayi verisi gibi, bir lambda fonksiyonunun argümanı. Aynı şekilde yukarıdaki lambda fonksiyonundaki sayi, x ve y verileri de birer argüman.
lambda y: x % y == 0, bir lambda fonksiyonudur. y, bu fonksiyonun argümanı olup, x bu fonksiyonun argümanı değildir. Bu fonksiyon şu haliyle bir NameError hatası yükseltir. Ama kodun devamı sayesinde bu kısım bir anlam kazanır. Fonksiyon; bir x sayısının, değişen bir y sayısına bölündüğünde kalan 0'a eşit mi değil mi sorgusu yapar. Bu fonksiyondan True veya False değerlerinden birisi geri döndürülür.
filter(lambda y: x % y == 0, range(1, x)), ifadesi şu haliyle bir NameError hatası yükseltir. Ama kodun devamı sayesinde bu kısım çalışır bir hal alır.
Kısaca filter() fonksiyonu nasıl kullanılıyor ona bakalım:
Çağrılışı filter(fonksiyon, yinelenebilir_veri) şeklindedir. Fonksiyon, yinelenebilir veri tipinden aldığı her bir argüman ile bir koşulu denetler.
Örnek:
fonksiyon = lambda x: x % 2 == 0
liste = range(1, 10)
filtrelenmis_liste = list(filter(fonksiyon, liste))
print(filtrelenmis_liste)
# O halde yukarıdaki kodları şu şekilde düzenleyebiliriz:
filtrelenmis_liste = list(filter(lambda x: x % 2 == 0, range(1, 10)))
print(filtrelenmis_liste)
filter(lambda y: x % y == 0, range(1, x)) ifadesi ile; x, 1'den x'e kadar olan sayılara bölünür ve 0 kalanını veren y sayılar bulunur.
sum(filter(lambda y: x % y == 0, range(1, x))) ifadesinde, x hala tanımlanmamış bir haldedir. Yani sadece bu kod çalıştırılırsa NameError hatası yükseltilir. Kısaca sum() fonksiyonu nasıl kullanılıyor önce ona bakalım:
Çağrılışı sum(range(10)) şeklindedir. Fonksiyon, yinelenebilir verideki her bir sayıyı toplar ve toplamı geri döndürür.
sum(filter(lambda y: x % y == 0, range(1, x))) ifadesi ile, 1'den x'e kadar olan y sayılarından, x'i tam bölen sayılar bulunur ve toplanır.
lambda x: sum(filter(lambda y: x % y == 0, range(1, x))) == x, bir lambda fonksiyonudur. Burada, x değişebilen bir argüman olarak tanımlanır. Bu fonksiyon verilen bir x sayısının mükemmel olup olmadığını sorgular. x, mükemmel bir sayıysa, yani 0 kalanını veren bölenlerin (y sayılarının) toplamı x'e eşitse, True değeri yükseltilir.
filter(lambda x: sum(filter(lambda y: x % y == 0, range(1, x))) == x, range(1, sayi)). Burada sayi henüz tanımlanmamış başka bir fonksiyonun argümanıdır. Yani şu haliyle kodları çalıştırsak yine NameError hatası alırız. sayi'yi argüman olarak alacak olan fonksiyon mukemmel_mi fonksiyonudur. Filter fonksiyonu bu şekilde çağrılırsa hata oluşur. Ama burada yapılan işlemden bahsetmek gerekirse; 1'den sayi'ya kadar olan sayıların mükemmel sayı olup olmadığı sorgulanır. Ve True değeri veren sayılar filtrelenir.
Bu da mukemmel_mi fonksiyonu: mukemmel_mi = lambda sayi: list(filter(lambda x: sum(filter(lambda y: x % y == 0, range(1, x))) == x, range(1, sayi)))
Sizi tebrik ederim. Üşenmemiş o kadar anlatmışsınız üstüne bir de resim hazırlamışsınız. Aslında genelde beğenip geçerdim ama bu çabanız gerçekten takdire layık.
Fonksiyonun ismini ve parametre ismini ben de değişik kullanırdım.
Hmm, closure şöyle bir şeymiş:
def f(x):
def g(y):
return x + y
return g # Return a closure.
def h(x):
return lambda y: x + y # Return a closure.
# Assigning specific closures to variables.
a = f(1)
b = h(1)
# Using the closures stored in variables.
assert a(5) == 6
assert b(5) == 6
# Using closures without binding them to variables first.
assert f(1)(5) == 6 # f(1) is the closure.
assert h(1)(5) == 6 # h(1) is the closure.
Bu return şeklini biliyorum. “()” işaretleri olmadan return edilen fonksiyonun isminin closure olduğunu yeni öğreniyorum. Fonksiyon bezeyicilerinde kullanılan yapıya da closure deniliyor o halde, doğru mu?
def f(x):
def g(func):
def h():
return func() * x
return h
return g
@f(x=10)
def a():
return 5
print(a())
# Sonuç = 50
Genellikle tkinter’de lambda fonksiyonunu sıklıkla kullanmak durumunda kaldığımı söyleyebilirim.
Mesela bir widget’in command parametresine bir fonksiyon atanacak diyelim, fonksiyonu sadece isim olarak yazıyoruz.
widget.config(command=fonksiyon)
Ama bazen fonksiyonlara parametreler girmek gerekiyor, dolayısıyla command kısmına bir lambda fonksiyonu yazmak gerekiyor.
Eyvallah hocam çok saolun yazdığım kodları güzel düzenlemişsiniz list veri tipiyle yazdığınız algoritma çok hoşuma gitti bide sum parametresinide öğrenmiş oldum o çok mantıklıymış