Python101 – Mantık İfadeleri (Boolean)

Bir örnekle başlayalım (yazmanız gerekmiyor):

a = 6
b = 7
c = 42
print(1, a == 6)
print(2, a == 7)
print(3, a == 6 and b == 7)
print(4, a == 7 and b == 7)
print(5, not a == 7 and b == 7)
print(6, a == 7 or b == 7)
print(7, a == 7 or b == 6)
print(8, not (a == 7 and b == 6))
print(9, not a == 7 and b == 6)

Bu kodun çıktısı aşağıdaki gibi:

1 True
2 False
3 True
4 False
5 True
6 True
7 False
8 True
9 False

Ne oldu? Yukarıdaki program bir sürü komik görünümlü print ifadesinden oluşuyor. Her satır bir sayı ve bir ifade yazdırıyor. Yazdırdığımız sayılar hangi ifadeyle uğraştığımızı takip etmeye yardımcı olacak, burası tamam. Peki her ifadenin nasıl True ya da False olarak tamamlandığına dikkat ettiniz mi?. Python’da false 0 ve true 1 olarak da yazılabilir. 

İnceleyelim:

print(1, a == 6)
print(2, a == 7)

ilk ifade doğru (a, 6’ya eşit), ikinci ifade ise yanlış olduğundan beklendiği gibi sırasıyla True ve False yazdırdı. Üçüncü ifade print(3, a == 6 and b == 7) biraz farklı. and işleci hem önceki ifade hem de sonraki ifade doğruysa, tüm ifadenin doğru olduğunu söyler, aksi takdirde tüm ifade yanlıştır. Dolayısıyla, bir sonraki satırda, print(4, a == 7 and b == 7), ifadenin bir kısmı yanlışsa her şeyin yanlış olduğunu görüyoruz. Bu davranış aşağıdaki gibi özetlenebilir: 

ifadesonuç
true and truetrue
true and falsefalse
false and truefalse
false and falsefalse

İlk ifade false ise Python tüm ifadenin yanlış olacağını bilir. Bu sebeple ikinci ifadeyi denetlemez. Bunu test etmek için False and print("Hi") ifadesi ile True and print("Hi") ifadesini çalıştırmayı deneyin. Bunun teknik ifades kısa devre değerlendirmesidir.

Bir sonraki satır, print(5, not a == 7 and b == 7), farkettiyseniz not ifadesini kullanıyor. not, ifadenin tam tersini verir. (Bu ifade print(5, a != 7 and b == 7) olarak da yeniden yazılabilirdi). Tabloya bakalım:

ifadesonuç
not truefalse
not falsetrue

Sonraki iki satır, print(6, a == 7 or b == 7) ve print(7, a == 7 or b == 6), or işlecini kullanır. İlk ifade true ise veya ikinci ifade doğruysa veya her ikisi de doğruysa işleç true döndürür. İkisi de doğru değilse, false döndürür. İşte tablo: 

ifadesonuç
true or truetrue
true or falsetrue
false or truetrue
false or falsefalse

İlk ifade doğruysa Python’un ikinci ifadeyi denetlemediğine dikkat edin. or işlecine göre ifadenin en az yarısı doğruysa, tümü doğru olacaktır. İlk bölüm doğru, bu nedenle ikinci bölüm yanlış veya doğru olabilir, ancak tüm ifade hala doğrudur. 

Sonraki iki satır print(8, not (a == 7 and b == 6)) ve print(9, not a == 7 and b == 6), parantezlerin ifadeleri gruplamak ve ifadenin bir bölümünün daha önce değerlendirilmeye zorlamak için kullanılabileceğini gösterir. Parantezlerin ifadeyi false’tan true’ya değiştirdiğine dikkat edin. Bu, not işlecinin parantezlerin yalnızca bölümü yerine tüm ifadeye uygulanmaya zorlanması nedeniyle oluştu. 

Boole ifadesi için bir başka örneğe bakalım:

list = ["Life", "The Universe", "Everything", "Jack", "Jill", "Life", "Jill"]

# listenin kopyasını yapalım
copy = list[:]
# kopyayı sıralayalım
copy.sort()
prev = copy[0]
del copy[0]

sayi = 0

# listeyi tarayalım 
while sayi < len(copy) and copy[sayi] != prev:
    prev = copy[count]
    sayi = sayi + 1

# Eğer istediğimiz öğe bulunmadıysa sayı < len olamaz
# while döngüsü sayı < len olduğu sürece devam edecek

if sayi < len(copy):
    print("İlk bulgu:", prev)

Çıktı:

İlk bulgu: Jill

Bu program, eşleşme bulmaya çalışırken while sayi< len(copy) and copy[sayi] is not equal to prev ifadesine bakar. Eğer sayı, öğe sayısından büyükse veya bir eşleşme bulunursa, and ifadesi artık doğru olmaz ve döngüden çıkılır. Bir eşleşme bulunarak çıkıldığından emin olmak için ise en sonda bir if ifadesi ile bunu denetliyoruz. 

Burada and ile ilgili diğer bir noktaya da bakalım. Eğer tablodaki üçüncü satıra bakarsanız “False and False” olduğunu göreceksiniz. Eğer sayi >= len(copy) (başka bir deyişle sayi < len(copy) yanlışsa) o zaman copy[sayi] ifadesine bakılmaz. Bunun nedeni, ilk ifade yanlışsa, haliyle, iki ifadenin de doğru olamayacağını Python’un bilmesi. Bu kısa devre olarak bilinir ve bir ifadenin ikinci yarısı sorun oluşturacaksa veya hataya neden olacaksa yararlı olacaktır.

Boole ifadeleri, aynı anda iki veya daha fazla farklı şeyi denetlemeniz gerektiğinde de kullanılabilir.

Boole Operators hakkında bir not

Programlamaya yeni başlayanlar için yaygın bir hata da, Python yorumlayıcısının bu ifadeleri okuma şeklinden kaynaklanan boole işleçlerinin çalışma şeklinin yanlış anlaşılmasıdır. Örneğin, başlangıçta “ve ” ve “veya” deyimleri hakkında bilgi edindikten sonra, x == ('a' or 'b') ifadesinin x değişkenini a veya b‘den birine eşdeğer olup olmadığını denetleyeceği düşünülebilir. Ama durum böyle değil. Neden bahsettiğimizi görmek için etkileşimli bir oturum başlatın ve aşağıdaki ifadeleri girin: 

>>> 'a' == ('a' or 'b')
>>> 'b' == ('a' or 'b')
>>> 'a' == ('a' and 'b')
>>> 'b' == ('a' and 'b')

Ve çıktı:

>>> 'a' == ('a' or 'b')
True
>>> 'b' == ('a' or 'b')
False
>>> 'a' == ('a' and 'b')
False 
>>> 'b' == ('a' and 'b')
True

Bu noktada, and ve or operatörleri bozukmuş gibi görünüyor. İlk iki ifade için 'a'‘nın a ve b‘ye eşdeğer olması ama b’nin olmaması mantıklı değil. Ayrıca b‘nin a ve b‘ye eşit olması da mantıklı değil. Aslında boole operatörleriyle Python’un ne yaptığını inceledikten sonra bu sonuçların tam olarak istediğimiz şeyi yaptığını göreceğiz.

Python yorumlayıcısı bir or ifadesine baktığında, öncelikle ilk ifadeyi alır ve doğru olup olmadığını kontrol eder. İlk ifade doğruysa, Python ikinci deyimi denetlemeden bu nesnenin değerini döndürür. Bunun nedeni, yukarıda da bahsettiğimiz gibi, değerlerden biri doğruysa her şeyin doğru olmasıdır; programın ikinci ifade ile uğraşmasına gerek yoktur. Öte yandan, ilk değer false ise Python ikinci yarıyı denetler ve bu değeri döndürür. İkinci yarı, ilk yarı yanlış olduğunda tüm ifadenin gerçek değerini belirler. Yorumlayıcının bu “tembelliği” “kısa devre” olarak adlandırılır ve birçok programlama dilinde boole ifadelerini değerlendirmenin yaygın bir yoludur.

Benzer şekilde, bir and ifadesi için Python, doğruluk değeri değerlendirmesini hızlandırmak için kısa devre tekniği kullanır. İlk ifade yanlışsa, her şey yanlış olmalıdır, bu nedenle bu değeri döndürür. Aksi takdirde, ilk değer doğruysa, ikinciyi denetler ve bu değeri döndürür. 

Bu noktada dikkat edilmesi gereken bir şey, boole ifadesi bir True veya False değer döndürdür, ancak Python belirli bir doğruluk değerine sahip olmak için bir dizi farklı şeyi dikkate alır. Herhangi bir x nesnesinin doğruluk değerini denetlemek için, bool(x) işlevini kullanabilirsiniz. Aşağıda, çeşitli nesnelerin doğruluk değerlerinin örneklerini içeren bir tablo bulunuyor:

TrueFalse
TrueFalse
10
Sıfır dışındaki sayılar‘None’ dizesi
Boş olmayan dizelerBoş dizeler
Boş olmayan listeleriBoş listeler
Boş olmayan sözlüklerBoş sözlükler

 

Şimdi bu boole ifadelerini daha önce test ettiğimizde elde ettiğimiz şaşırtıcı sonuçları anlamak mümkün. Bu koddan geçerken yorumlayıcının “ne gördüğüne” bir göz atalım:

İlk durum:

>>> 'a' == ('a' or 'b')  # Önce paranteze bakar ve "('a' or 'b')" ifadesini denetler
                         # 'a' boş olmayan bir dize olduğu için True
                         # Bu ilk ifadeyi döndürür: 'a'
>>> 'a' == 'a'           # 'a' dizesi 'a' dizesine eşit, dolayısıyla ifade True
True

İkinci durum:

>>> 'b' == ('a' or 'b')  # Önce paranteze bakar ve "('a' or 'b')" ifadesini denetler
                         # 'a' boş olmayan bir dize olduğu için True
                         # Bu ilk ifadeyi döndürür: 'a'
>>> 'b' == 'a'           # 'b' dizesi 'a' dizesine eşit değil, dolayısıyla ifade False
False 

Üçüncü durum:

>>> 'a' == ('a' and 'b')   # Önce paranteze bakar ve "('a' and 'b')" ifadesini denetler
                           # 'a' boş olmayan bir dize olduğu için True, ikinci ifadeye bakar
                           # 'b' boş olmayan bir dize olduğu için True
                           # İkinci ifadeyi tüm ifadenin sonucu olarak döndürür: 'b'
>>> 'a' == 'b'             # 'a' dizesi 'b' dizesine eşit değil, dolayısıyla ifade False
False

Dördüncü vaka:

>>> 'b' == ('a' and 'b')   # Önce paranteze bakar ve "('a' and 'b')" ifadesini denetler
                           # 'a' boş olmayan bir dize olduğu için True, ikinci ifadeye bakar
                           # 'b' boş olmayan bir dize olduğu için True
                           # İkinci ifadeyi tüm ifadenin sonucu olarak döndürür: 'b'
>>> 'b' == 'b'             # 'b' dizesi 'b' dizesine eşit, dolayısıyla ifade True
True 

Yani Python görünüşte sahte sonuçlar verdiğinde aslında işini yapıyordu. Daha önce de belirtildiği gibi, önemli olan boole ifadenizin değerlendirildiğinde hangi değeri döndüreceğini tanımaktır. Bu her zaman açık olmayabilir.

İlk ifadelere geri dönersek, aşağıdaki gibi yazdığımızda istediğimiz şekilde davranırlar:

>>> 'a' == 'a' or 'a' == 'b' 
True
>>> 'b' == 'a' or 'b' == 'b' 
True
>>> 'a' == 'a' and 'a' == 'b' 
False
>>> 'b' == 'a' and 'b' == 'b' 
False

Bu karşılaştırmalar değerlendirildiğinde, doğruluk değerlerini dizeler ile değil, Doğru veya Yanlış olarak döndürürler. Bu nedenle uygun sonuçları alırız.

Örnekler

password1.py

## Bu program kullanıcıdan bir kullanıcı adı ve şifre ister
# Sonra da bilgileri kontrol ederek kullanıcının gerekli izni olup olmadığına bakar

name = input("Kullanıcı adı? ")
password = input("Şifre? ")
if name == "Josh" and password == "Friday":
    print("Hoşgeldin Josh")
elif name == "Fred" and password == "Rock":
    print("Hoşgeldin Fred")
else:
    print("Seni tanımıyorum.")

Örnek çalıştırmalar

Kullanıcı adı? Josh
Şifre? Friday
Hoşgeldin Josh
Kullanıcı adı? Bill
Şifre? Money
Seni tanımıyorum.

Alıştırmalar

Kullanıcı adınızı tahmin eden bir program yazın, ancak program bitene kadar kullanıcının yalnızca 3 hakkı olsun.

Çözüm:

print("Try to guess my name!")
count = 1
name = "guilherme"
guess = input("What is my name? ")
while count < 3 and guess.lower() != name:    # .lower allows things like Guilherme to still match
    print("You are wrong!")
    guess = input("What is my name? ")
    count = count + 1

if guess.lower() != name:
    print("You are wrong!") # this message isn't printed in the third chance, so we print it now
    print("You ran out of chances.")
else:
    print("Yes! My name is", name + "!")

Bir yorum yapın

E-posta hesabınız yayımlanmayacak.

To top