Program if'i atlayıp hep else'e gidiyor

import json
import difflib

data = json.load(open((“data.json”)))

def dictionary(word):
word = word.lower()

if (word in data):
    return data[word]
elif (len(difflib.get_close_matches(word,data.keys(),cutoff=0.7))>0):

  answer=input("Did you mean {} ?  :".format(difflib.get_close_matches(word,data.keys(),cutoff=0.7)))
   answer = answer.capitalize()
    for answer in data:
        if answer == data.keys:
            return data[answer]

        else:
            return "Error!!"


else:
    return "Error!!"

word = input("Enter word: ")
print(dictionary(word))

Bir sözlük oluşturmaya çalışıyorum. Mesela “rain” yerine “rainn” yazıldı sözlük raine benzeyen ifadeleri gösteriyor ve kullanıcı kastetmek istediğini seçiyor. Sonra sözlük o kelimeyi data dosyasında arıyacak eğer bulursa gösterecek ama çalışmıyor. Def fonksiyonu içinde “if answer==data.keys” bloğuna hiç girmeden bir altındaki else bloğuna giriyor. Sorunu nasıl çözebilirim?

Kod yazılışında hata yok ama buraya yazdığımda satırlar kayıyor.

data.keys nedir? print ile çıktısını alıp buraya yazabilir misiniz?
Sanki bir string ifadeyi bir liste veya sözlük ile karşılaştırıyorsunuz gibi görünüyor.

if answer in data.keys():
    return data[answer]
else:
    return "Error!!"

“laundry machine”: [“A machine, usually automatic, which washes clothes etc.”], “clothes washer”: [“A machine, usually automatic, which washes clothes etc.”],…

gibi ifadelerin olduğu bir ingilizce sözlük

Sanırım şöyle bir şey elde etmek istiyorsunuz,

def fonksiyon():
    answer = input("answer: ")

    data = {"laundry machine": ["A machine, usually automatic, which washes clothes etc."],
            "clothes washer": ["A machine, usually automatic, which washes clothes etc."]}

    for key in data:
        if answer == key:
            return data[key]
    
    return "Error!!"

print(fonksiyon())

Örnek kullanım:

answer: laundry machine
['A machine, usually automatic, which washes clothes etc.']

-Bir sözlük {key: item} olarak oluşur. Bizler de for key in data: şeklindeki bir kullanım ile sözlük içerisindeki key'leri döngü içerisinde kullanabiliriz. sözlük[key] ise bize o key'e ait item'i verecektir.

json dosyası elimde olmadığı için örnek olarak sizin paylaşımınızdan yola çıkarak data’yı kendim oluşturmak durumunda kaldım.

1 Beğeni

Böyle yapıyorsunuz ama sizin data’daki elemanlar büyük harfle başlamıyor gibi, bunu neden yazmıştınız?

döngü değişkeninin ismini de answer yaptığınız için kullanıcının girdiğini tutan answer kaybolmuş oluyor… for kelime in data gibi answer’dan farklı bir isim vermek isteyebilirsiniz.

Burada answer’ı bir fonksiyonla karşılaştırıyorsunuz:

>>> data.keys
<function dict.keys>

ve bu da normal şartlarda hiçbir zaman True döndürmüyor, if es geçiliyor.

Buradaki else ile çok hızlı pes etmiş oluyorsunuz; data’da ne var ne yok gezdikten ve ancak answer’a karşı bir eşleşme bulamadıktan sonra "Error!!" döndürmeniz gerekmez mi?

Velhasıl şöyle düzenleyebilirsiniz:

answer = input("...")
# `data`'daki her kelime için...
for kelime in data:
    # `answer` bu `kelime`ye eşit mi?
    if answer == kelime:
        # öyleyse `data`'daki karşılığı döndürürüz
        return data[answer]
    # değilse for devam ediyor

# burası for'un bittiği yer; buraya geldiyse `data`da bir eşleşme yoktur
return "Error!!"

Ama sayın Gok_Mavisi_Anka’nın ilk yanıtında belirttiği ve sizin de if word in data diye ilk başta yaptığınız gibi verilen bir değerin sözlükte olup olmadığına in ile bakabiliriz:

answer = input("...")
if answer in data:
    return data[answer]
else:
    return "Error!!"

veya “ternary” ile:

answer = input("...")
return data[answer] if answer in data else "Error!!"

Buna bir alternatif de try/except olabilir:

try:
    return data[answer]
except KeyError:
    return "Error!!"

Burada ilk olarak direkt data[answer]'a ulaşılmaya çalışıyoruz (deniyoruz): eğer varsa o döndürülüyor; yoksa KeyError ortaya çıkıyor, onu yakalıyoruz ve "Error!!" döndürüyoruz. Bu arada "Error!!" döndürmek yerine kendiniz bir hata da yükseltebilirsiniz daha uygun görürseniz. Örneğin return “Error!!” yerine raise ValueError("Girdiğiniz değer uygun değil") gibi.


Ek olarak

difflib.get_close_matches(word, data.keys(), cutoff=0.7)

ifadesini iki kere kullanıyorsunuz; 2 > 1 olduğundan bunu bir değişkene atamak isteyebilirsiniz. DRY’ın yanında get_close_matches’ın pahalı bir işlem olabileceğini de düşünebiliriz. İlk if’te direkt return olduğu için devamını elif ile değil de yine if ile getirip araya bunu yazabiliriz:

if word in data:
    return data[word]

yakin_eslesmeler = difflib.get_close_matches(word, data.keys(), cutoff=0.7)

# bir listenin uzunluğunun 0'dan büyük olup olmadığına bakmaktansa
# kendisini direkt if'e tabi tutmak tercih edilir 
if yakin_eslesmeler:
    # f-string ile okunabilirliği artırmaya çalışıyoruz
    answer = input(f"Did you mean {yakin_eslesmeler}?")
    ...
else:
   return "Error!!"
3 Beğeni