Найти - Пользователи
Полная версия: Проверка спама в электронном письме или фильтрацию запрещенных слов в сообщении
Начало » Python для экспертов » Проверка спама в электронном письме или фильтрацию запрещенных слов в сообщении
1
Alduin
Рассмотрим задание на проверку спама в электронном письме или фильтрацию запрещенных слов в сообщении.

Пусть функция is_spam_words принимает строку (параметр text), проверяет ее на содержимое запрещенных слов из списка (параметр spam_words), и возвращает результат проверки: True, если есть хоть одно слово из списка, и False, если в тексте стоп-слов не обнаружено .

Слова в параметре text могут быть в произвольном регистре, а значит функция is_spam_words при поиске запрещенных слов регистра независима и весь текст должен сводиться к нижнему регистру. Для упрощения будем считать, что в строке есть только одно запрещенное слово.

Предусмотреть третий параметр space_around, который по умолчанию равен False. Он будет отвечать за то, что функция будет искать отдельное слово или нет. Слово считается, что стоит отдельно, если слева от слова находится символ пробела или оно расположено в начале текста, а справа от слова находится пробел или символ точки.

К примеру, в тексте мы ищем слово “лох”. Так в слове “Молох” вызов и результат будет следующим:

print(is_spam_words(“Молох”, )) # True
print(is_spam_words(“Молох”, , True)) # False
То есть во втором случае слово не отдельно и является частью другого.

В этом примере функция вернет True в обоих случаях.

print(is_spam_words(“Ты лох.”, )) # True
print(is_spam_words(“Ты лох.”, , True)) # True


НУжна помощь!
Как доделать последнюю часть?

 def is_spam_words(text, spam_words, space_around=False):
    #print(text.lower()) # Молох бог ужасен.
    print(spam_words) # ['лох']
    print("".join(spam_words))
    if space_around: # if space_around not False
        if text.lower().split(): # if list not empty
            for i in text.lower().split():
                if "".join(spam_words) in i:
                    return True
                else: 
                    return False
    else: # so to find word as part other word 
        pass
                    
py.user.next
Внутри функции не должно быть никаких print(), там только return True или return False должно быть.

Alduin
Как доделать последнюю часть?
У тебя и первая часть не сделана.

А вообще, этот флажок space_around может быть проверен через индекс символа в строке. А для этого тебе надо получать индекс начала слова и индекс конца слова.

Набросок
  
>>> def f(text, word):
...     text_length = len(text)
...     word_length = len(word)
...     index = text.find(word)
...     if (index >= 0
...         and (index == 0
...              or text[index - 1] == ' ')
...         and (index + word_length >= text_length
...              or text[index + word_length] == ' ')):
...         print(word)
... 
>>> f('abc def ghi', 'abc')
abc
>>> f('abc def ghi', 'ghi')
ghi
>>> f('abc def ghi', 'def')
def
>>> f('abc def ghi', 'a')
>>> f('abc def ghi', 'c')
>>> f('abc def ghi', 'g')
>>> f('abc def ghi', 'i')
>>>
Alduin
Можно в принципе но тут смысл задания сделать через третий параметр без него к сожалению никак.
Alduin
А что в первой части не так ?
Alduin
Просто читалось когда писал вроде бы логично
py.user.next
Alduin
Можно в принципе но тут смысл задания сделать через третий параметр без него к сожалению никак.
Вот этот код, который я тебе написал, - набросок - он как раз и делает эту проверку, которую третий параметр включает. Так что разбери его хорошо, пойми его, как он сделан, а потом у себя добавишь аналогичную проверку. Там тебе сначала нужно будет только уменьшить регистр у текста и у слова, прежде чем этот поиск проводить.
Alduin
Ну у меня была еще вот такая реализация но тут также ошибка

 def is_spam_words(text, spam_words, space_around=False):
    t = text.casefold()
    ts = t.split()
    tf = t.find("лох")
    l_list = ["лох","лох.","лох,"]
    if space_around==False:
        if tf > 0:
            return True
            space_around=True
        else:
            return False
    if space_around==True:
        for i in ts:
            print(i)
            if i in l_list:
                return True
            else:
                return False
Alduin
Функция вернула неверный результат с тремя параметрами: False. Должно быть is_spam_words('Ты хорош, но выглядишь как лох.', , True) == True
py.user.next
Подумал, что не напишешь ты её вообще. Так что я сделал юнит-тесты и написал её.
  
>>> def is_spam_words(text, spam_words, space_around=False):
...     text_lower = text.lower()
...     for word in spam_words:
...         if not word:
...             continue
...         word_lower = word.lower()
...         if not space_around:
...             if word_lower in text_lower:
...                 return True
...         else:
...             text_lower_length = len(text_lower)
...             word_lower_length = len(word_lower)
...             index = text_lower.find(word_lower)
...             if (index >= 0
...                 and (index == 0
...                      or text_lower[index - 1] in (' '))
...                 and (index + word_lower_length >= text_lower_length
...                      or text_lower[index + word_lower_length] in (' ', '.'))):
...                 return True
...     return False
... 
>>> is_spam_words('Молох', ['лох'])
True
>>> is_spam_words('Молох', ['лох'], True)
False
>>>
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB