Автономная словарная программа: найдите как похожие слова, так и слова, начинающиеся одинаково - PullRequest
1 голос
/ 28 февраля 2020

Я написал эту автономную словарную программу. Я хочу, когда пользователь нажимает клавишу, эта программа go в базу данных и находит слово, близкое к слову, введенному пользователем до сих пор. Или когда пользователь полностью ввел слово и слово было в базе данных, программа отобразит его с его значениями.

В этой части все идет хорошо. Тогда я хочу, например, когда пользователь ввел слово «а», программа показывает все слова в базе данных, которые начинаются с «а».

Вот пример моей проблемы: Когда мы вводим «а» все слова и значения, начинающиеся с «а» должны отображаться. Но программа показывает что-то вроде этого:

screenshot

А вот часть моей базы данных в формате json:

{"apple": ["Apple", "apple", "Sib", "Apfel", "Des pommes"], "average": ["Average", "average", "Miangin", "Durchschnitt", "Des pommes"], "acknowledge": ["Acknowledge", "acknowledge", "Tasdigh Kardan", "Zu bestatigen", "Pour reconnaître"], "book": ["Book", "book", "Ketab", "Buch", "Livre"], "banana": ["Banana", "banana", "Mouz", "Bananen", "Bananes"], "beach grass": ["Beach Grass", "beach grass", "Chamane Sahel", "Strandhafer", "herbe de plage"], "cat": ["Cat", "cat", "Gorbe", "Katzen", "chatte"], "certificate": ["Certificate", "certificate", "Govahi Name", "Zertifikat", "certificat"], "declaration of conformity": ["Declaration Of Conformity", "declaration of conformity", "Elamie Entebagh", "Konformitatserklarung", "déclaration de conformité"], "database": ["Database", "database", "Paygah Dade", "Datenbank", "base de données"], "dear colleagues": ["Dear Colleagues", "dear colleagues", "Hamkarane Aziz", "Liebe Mitarbeiterinnen und Mitarbeiter", "Chers collègues"]}

В этом словаре у нас есть английское sh, персидское, французское и немецкое значения для каждого слова.

Вы можете увидеть мой код ниже:

import json
import msvcrt
import os 
from difflib import get_close_matches

DataBase = json.load(open("DataBase.json"))

def getMeaning(w):

    w = w.lower()
    n = len(w)

    if w in DataBase:
        return DataBase[w]

    elif len(get_close_matches(w,DataBase.keys(),1,0.3)) > 0:
        close_match = get_close_matches(w,DataBase.keys(),1,0.3)[0]
        print("Not Found!\nCheck The Close Match:\n")
        return DataBase[close_match]

    else:
        print ("Not Found!\n")
        res = [value for key, value in DataBase.items()]
        for i in res:
            for j in i:
                if w in j[0:n].lower(): 
                     print(j)
        return ''

word = '' 
while True:
    if msvcrt.kbhit():
        temp = msvcrt.getwch()
        word += temp
        os.system('cls')
        print(word)
        print("\n")
        meaning = getMeaning(word)
        for item in meaning:
            print(item)

Обратите внимание, что вы должны запустить эту программу в CMD, чтобы работать правильно, из-за msvcrt.kbhit().

Ответы [ 2 ]

1 голос
/ 28 февраля 2020

В get_close_matches необязательный аргумент cutoff - это число с плавающей точкой в ​​диапазоне [0, 1].
Возможности, которые не набирают хотя бы значения, аналогичного слову, игнорируются.

Так что мне просто нужно изменить cutoff из get_close_matches с 0.3 на 0.8.
Это решает мою проблему.

    elif len(get_close_matches(w,DataBase.keys(),1,0.8)) > 0:
        close_match = get_close_matches(w,DataBase.keys(),1,0.8)[0]
        print("Not Found!\nCheck The Close Match:\n")
        return DataBase[close_match]
1 голос
/ 28 февраля 2020

Если кто-то вводит a, вы звоните getMeaning, что, в свою очередь, вызывает get_close_matches. Затем вы проверяете, имеет ли этот вызов ненулевое возвращаемое значение, и если это так, вы делаете return DataBase[close_match]. На этом getMeaning заканчивается.

Вы никогда не достигнете else -части getMeaning, если get_close_matches даст результаты. На скриншоте вашего вопроса мы видим результаты пользовательского ввода a, которые имеют смысл, как это, так как get_close_matches находит cat аналогично a.

Независимо от этого, вы должны использовать startswith, если вы хотите проверить, начинается ли строка с другой строки. Кроме того, вам не нужно elif или else после того, как предыдущий if или elif имеет return, и я изменил имена в соответствии с PEP 8 разделом Описательные стили именования .

Вот возможное решение, использующее фильтр, который принимает близкое совпадение, только если буквы такие же, как в word:

from difflib import get_close_matches

database = {"apple": ["Apple", "apple", "Sib", "Apfel", "Des pommes"], "average": ["Average", "average", "Miangin", "Durchschnitt", "Des pommes"], "acknowledge": ["Acknowledge", "acknowledge", "Tasdigh Kardan", "Zu bestatigen", "Pour reconnaître"], "book": ["Book", "book", "Ketab", "Buch", "Livre"], "banana": ["Banana", "banana", "Mouz", "Bananen", "Bananes"], "beach grass": ["Beach Grass", "beach grass", "Chamane Sahel", "Strandhafer", "herbe de plage"], "cat": ["Cat", "cat", "Gorbe", "Katzen", "chatte"], "certificate": ["Certificate", "certificate", "Govahi Name", "Zertifikat", "certificat"], "declaration of conformity": ["Declaration Of Conformity", "declaration of conformity", "Elamie Entebagh", "Konformitatserklarung", "déclaration de conformité"], "database": ["Database", "database", "Paygah Dade", "Datenbank", "base de données"], "dear colleagues": ["Dear Colleagues", "dear colleagues", "Hamkarane Aziz", "Liebe Mitarbeiterinnen und Mitarbeiter", "Chers collègues"]}

def get_meaning(word):

    # Make word case-insensitive
    word = word.lower()

    # Check if word already in database
    if word in database:
        return {word: database[word]}

    # Find possible close matches
    close_matches = get_close_matches(word, database.keys(), 1, 0.3)
    # Filter matches: keep only those which contain the same letters
    close_matches = [
        close_match
        for close_match in close_matches
        if set(close_match) == set(word)
    ]
    # Return close matches if any left
    if close_matches:
        return {
            close_match: database[close_match]
            for close_match in close_matches
        }

    # Return all dictionary entries which start with the word
    return {
        entry: database[entry]
        for entry in database
        if entry.startswith(word)
    }

Теперь a не производит cat больше:

>>> get_meaning("a")
{'apple': ['Apple', 'apple', 'Sib', 'Apfel', 'Des pommes'], 'average': ['Average', 'average', 'Miangin', 'Durchschnitt', 'Des pommes'], 'acknowledge': ['Acknowledge', 'acknowledge', 'Tasdigh Kardan', 'Zu bestatigen', 'Pour reconnaître']}

Но applle все равно распознается как apple:

>>> get_meaning("applle")
{'apple': ['Apple', 'apple', 'Sib', 'Apfel', 'Des pommes']}

В качестве альтернативы, вы можете изменить аргумент cutoff вашего вызова на get_close_matches для разных результатов.

...