бот поиска фраз на компьютере

 это интересная задача для программы или бота
Я понял, что нужно создать алгоритм, который:

Начинает поиск с рабочего стола (предполагаем, что это папка на компьютере, например, C:\Users\YourUser\Desktop на Windows).

Рекурсивно сканирует папки и подпапки в поисках файлов с расширением .txt.
Ищет уникальные фразы (я предполагаю, что под "фразами" имеются в виду предложения или строки текста, которые содержат введённую пользователем фразу — для простоты возьмём предложения, заканчивающиеся точкой, вопросительным или восклицательным знаком).

Собирает до 40 уникальных таких фраз (уникальность = отсутствие дубликатов в результатах).
Из найденных выводит случайно выбранные 3 фразы (или первые, если случайный выбор не нужен).
Я придумал простой и эффективный алгоритм на основе рекурсивного обхода файловой системы и обработки текста. Он не требует сложных библиотек, но для реализации на Python можно использовать встроенные модули вроде os и random. Вот пошаговое описание алгоритма:

Шаги алгоритма:
Получение ввода от пользователя: Запросить у пользователя фразу для поиска (например, через консоль или GUI). Пусть это будет строка search_phrase.

Определение стартовой папки: Установить путь к рабочему столу. На Windows это обычно os.path.expanduser("~/Desktop") (в Python). Если на другой ОС, адаптировать (например, /home/user/Desktop на Linux).

Рекурсивный обход папок:

Использовать функцию, которая обходит все подпапки (например, с помощью os.walk() в Python).

Для каждого файла проверить, заканчивается ли он на .txt (игнорируя регистр).
Если да, открыть файл и прочитать его содержимое как текст (предполагаем кодировку UTF-8 для поддержки русского языка).
Обработка текста файла:

Разделить текст на предложения (по символам ., !, ? — использовать регулярные выражения для точности, например, re.split(r'[.!?]', text)).
Для каждого предложения проверить, содержит ли оно search_phrase (игнорируя регистр, например, search_phrase.lower() in sentence.lower()).
Если содержит, добавить предложение в множество (set) для обеспечения уникальности. Продолжать до тех пор, пока не наберётся 40 уникальных фраз или не закончатся файлы.
Вывод результатов:

Если найдено менее 40 фраз, вывести все.
Из найденных выбрать 3 случайные фразы (используя случайный выбор) и вывести их.
Если фраз меньше 3, вывести все найденные.
Обработка ошибок: Игнорировать файлы, которые нельзя открыть (например, из-за прав доступа), и продолжить поиск.

Этот алгоритм эффективен для небольших объёмов данных (тысячи файлов), но для очень больших папок может быть медленным — в этом случае можно добавить многопоточность.

Пример реализации на Python
Вот простой скрипт на Python, который реализует этот алгоритм. Сохрани его как .py файл на рабочем столе и запусти (нужен Python 3.x). Он использует только встроенные модули



import os
import re
import random

def find_unique_phrases(search_phrase, start_path, max_phrases=40):
    unique_phrases = set()
   
    # Рекурсивный обход папок
    for root, dirs, files in os.walk(start_path):
        for file in files:
            if file.lower().endswith('.txt'):
                file_path = os.path.join(root, file)
                try:
                with open(file_path, 'r', encoding='utf-8') as f:
                text = f.read()
               
                # Разделить на предложения
                sentences = re.split(r'[.!?]', text)
               
                for sentence in sentences:
                sentence = sentence.strip()
                if sentence and search_phrase.lower() in sentence.lower():
                unique_phrases.add(sentence)
                if len(unique_phrases) >= max_phrases:
                break  # Прекратить, если набрали 40
                if len(unique_phrases) >= max_phrases:
                break
                except Exception as e:
                print(f"Ошибка при чтении {file_path}: {e}")
        if len(unique_phrases) >= max_phrases:
            break
   
    return list(unique_phrases)

# Основная часть
if __name__ == "__main__":
    search_phrase = input("Введите фразу для поиска: ")
    desktop_path = os.path.expanduser("~/Desktop")  # Адаптировать под ОС, если нужно
   
    phrases = find_unique_phrases(search_phrase, desktop_path)
   
    if not phrases:
        print("Фразы не найдены.")
    else:
        # Выбрать 3 случайные (или первые, если меньше)
        selected = random.sample(phrases, min(3, len(phrases)))
        print("Найденные фразы:")
        for phrase in selected:
            print(f"- {phrase}")



Как использовать:
Запусти скрипт.
Введи фразу (например, "привет")
Программа просканирует все .txt файлы на рабочем столе и подпапках,
найдёт до 40 уникальных предложений с этой фразой и выведет 3 случайные.
Если нужно доработать (например, сделать GUI, добавить фильтры или оптимизировать), дай знать — я могу помочь! Если это не то, что имел в виду, уточни детали.


 ищем фразы которые на 10-20% похожи на фразу ввода

 Обновлённый алгоритм поиска похожих фраз в текстовых файлах
 Я понял, что нужно изменить поиск: вместо точного совпадения подстроки теперь ищем фразы (предложения), которые похожи на введённую фразу на 10-20%. Это добавляет интересный поворот — теперь это не точный матч, а семантическая/лексическая схожесть.

Что значит "10-20% похожести"?
Это субъективно, поэтому я выбрал простую и надёжную метрику: Jaccard similarity (коэффициент Жаккара) на основе слов.
Разбиваем вводную фразу и каждое предложение на уникальные слова (игнорируя регистр и знаки препинания).
Jaccard = (количество общих слов) / (количество уникальных слов в объединении двух множеств).
Если Jaccard в диапазоне [0.1, 0.2] (т.е. 10-20%), то считаем фразу похожей.
Почему Jaccard? Он простой, не требует внешних библиотек и хорошо работает для коротких текстов. Если нужно что-то посложнее (например, расстояние Левенштейна или эмбеддинги с ИИ), дай знать — но это усложнит код.
Уникальность по-прежнему через set (по тексту предложения).
Остальное остаётся: сканируем .txt на рабочем столе и подпапках, собираем до 40 уникальных, выводим 3 случайные.
Обновлённые шаги алгоритма:
Получение ввода: Запросить фразу для поиска.

Подготовка вводной фразы: Разбить на слова, очистить от знаков препинания, привести к нижнему регистру, взять уникальные слова в set.

Рекурсивный обход: Как раньше, с os.walk().

Обработка текста:

Разделить на предложения (по . ! ?).
Для каждого предложения: разбить на слова, вычислить Jaccard с вводной фразой.
Если 0.1 ; Jaccard ; 0.2 и предложение не пустое, добавить в set уникальных фраз.
Остановить на 40 уникальных.
Вывод: 3 случайные из найденных.

Обработка ошибок: Как раньше.

Этот подход найдёт фразы, которые делят 10-20% слов с вводной (например, если ввод "красный дом в лесу", то подойдут предложения вроде "зелёный лес полон тайн" — если пересечение ~15%).

Обновлённый пример реализации на Python
Вот доработанный скрипт. Я добавил функцию для Jaccard без доп. библиотек. Сохрани как .py и запусти.


import os
import re
import random
import string

def jaccard_similarity(set1, set2):
    """Вычисляет Jaccard similarity между двумя множествами слов."""
    if not set1 or not set2:
        return 0.0
    intersection = len(set1.intersection(set2))
    union = len(set1.union(set2))
    return intersection / union if union > 0 else 0.0

def clean_words(text):
    """Очищает текст от знаков препинания и приводит к нижнему регистру."""
    translator = str.maketrans('', '', string.punctuation)
    words = re.findall(r'\b\w+\b', text.lower().translate(translator))
    return set(words)  # Уникальные слова

def find_similar_phrases(search_phrase, start_path, min_sim=0.1, max_sim=0.2, max_phrases=40):
    search_words = clean_words(search_phrase)
    if not search_words:
        print("Вводная фраза не содержит слов для поиска.")
        return []
   
    unique_phrases = set()
   
    # Рекурсивный обход папок
    for root, dirs, files in os.walk(start_path):
        for file in files:
            if file.lower().endswith('.txt'):
                file_path = os.path.join(root, file)
                try:
                with open(file_path, 'r', encoding='utf-8') as f:
                text = f.read()
               
                # Разделить на предложения
                sentences = re.split(r'[.!?]+', text)
               
                for sentence in sentences:
                sentence = sentence.strip()
                if len(sentence) > 10:  # Игнорируем слишком короткие
                sentence_words = clean_words(sentence)
                similarity = jaccard_similarity(search_words, sentence_words)
               
                if min_sim <= similarity <= max_sim:
                unique_phrases.add(sentence)
                if len(unique_phrases) >= max_phrases:
                break  # Прекратить, если набрали 40
                if len(unique_phrases) >= max_phrases:
                break
                except Exception as e:
                print(f"Ошибка при чтении {file_path}: {e}")
        if len(unique_phrases) >= max_phrases:
            break
   
    return list(unique_phrases)

# Основная часть
if __name__ == "__main__":
    search_phrase = input("Введите фразу для поиска (похожести 10-20%): ")
    desktop_path = os.path.expanduser("~/Desktop")  # Адаптировать под ОС, если нужно
   
    phrases = find_similar_phrases(search_phrase, desktop_path)
   
    if not phrases:
        print("Похожие фразы не найдены.")
    else:
        print(f"Найдено {len(phrases)} похожих фраз (10-20% сходства).")
        # Выбрать 3 случайные (или все, если меньше)
        selected = random.sample(phrases, min(3, len(phrases)))
        print("Выбранные примеры:")
        for phrase in selected:
            print(f"- {phrase}")



Как использовать:
Запусти скрипт.
Введи фразу (например, "солнечный день в парке").
Программа найдёт предложения, где ~10-20% слов совпадают (например, "дождливый вечер у реки" может подойти, если пересечение "день/в/парке" ~15%).

Вывод: 3 случайные из до 40 найденных.
Возможные улучшения:
Точность схожести: Если Jaccard не подходит, можно использовать расстояние Левенштейна (для символов) — добавлю, если скажешь.
Минимум длины: Добавил фильтр на предложения >10 символов, чтобы избежать мусора.

Процент: Если "10-20%" имел в виду что-то другое (например, по символам или семантике с ИИ), уточни — могу интегрировать библиотеку вроде difflib (встроенная) или даже Hugging Face для эмбеддингов.
Тестирование: Создай тестовые .txt файлы на столе, чтобы проверить.







import os
import re
import random
import string

def jaccard_similarity(set1, set2):
    """Вычисляет Jaccard similarity между двумя множествами слов."""
    if not set1 or not set2:
        return 0.0
    intersection = len(set1.intersection(set2))
    union = len(set1.union(set2))
    return intersection / union if union > 0 else 0.0

def clean_words(text):
    """Очищает текст от знаков препинания и приводит к нижнему регистру."""
    translator = str.maketrans('', '', string.punctuation)
    words = re.findall(r'\b\w+\b', text.lower().translate(translator))
    return set(words)  # Уникальные слова

def find_similar_phrases(search_phrase, start_path, min_sim=0.1, max_sim=0.2, max_phrases=40):
    search_words = clean_words(search_phrase)
    if not search_words:
        print("Вводная фраза не содержит слов для поиска.")
        return []
   
    unique_phrases = set()
   
    # Рекурсивный обход папок
    for root, dirs, files in os.walk(start_path):
        for file in files:
            if file.lower().endswith('.txt'):
                file_path = os.path.join(root, file)
                try:
                with open(file_path, 'r', encoding='utf-8') as f:
                text = f.read()
               
                # Разделить на предложения
                sentences = re.split(r'[.!?]+', text)
               
                for sentence in sentences:
                sentence = sentence.strip()
                if len(sentence) > 10:  # Игнорируем слишком короткие
                sentence_words = clean_words(sentence)
                similarity = jaccard_similarity(search_words, sentence_words)
               
                if min_sim <= similarity <= max_sim:
                unique_phrases.add(sentence)
                if len(unique_phrases) >= max_phrases:
                break  # Прекратить, если набрали 40
                if len(unique_phrases) >= max_phrases:
                break
                except Exception as e:
                print(f"Ошибка при чтении {file_path}: {e}")
        if len(unique_phrases) >= max_phrases:
            break
   
    return list(unique_phrases)

# Основная часть
if __name__ == "__main__":
    search_phrase = input("поиск: ")
    desktop_path = os.path.expanduser("~/Desktop")  # Адаптировать под ОС, если нужно
   
    phrases = find_similar_phrases(search_phrase, desktop_path)
   
    if not phrases:
        print("Похожие фразы не найдены.")
    else:
        print(f"Найдено {len(phrases)} похожих фраз (10-20% сходства).")
        # Выбрать 3 случайные (или все, если меньше)
        selected = random.sample(phrases, min(3, len(phrases)))
        print("Выбранные примеры:")
        for phrase in selected:
            print(f"- {phrase}")





    ред. edit   **





import os
import re
import random
import string

def jaccard_similarity(set1, set2):
    """Вычисляет Jaccard similarity между двумя множествами слов."""
    if not set1 or not set2:
        return 0.0
    intersection = len(set1.intersection(set2))
    union = len(set1.union(set2))
    return intersection / union if union > 0 else 0.0

def clean_words(text):
    """Очищает текст от знаков препинания и приводит к нижнему регистру."""
    translator = str.maketrans('', '', string.punctuation)
    words = re.findall(r'\b\w+\b', text.lower().translate(translator))
    return set(words)  # Уникальные слова

def find_similar_phrases(search_phrase, start_path, min_sim=0.1, max_sim=0.2, max_phrases=40):
    search_words = clean_words(search_phrase)
    if not search_words:
        return []
   
    unique_phrases = set()
   
    # Рекурсивный обход папок
    for root, dirs, files in os.walk(start_path):
        for file in files:
            if file.lower().endswith('.txt'):
                file_path = os.path.join(root, file)
                text = None
                try:
                with open(file_path, 'r', encoding='utf-8') as f:
                text = f.read()
                except UnicodeDecodeError:
                try:
                with open(file_path, 'r', encoding='cp1251') as f:  # Попытка с Windows-1251
                text = f.read()
                except UnicodeDecodeError:
                continue  # Пропустить файл, если не удаётся прочитать
               
                if text:
                # Разделить на предложения
                sentences = re.split(r'[.!?]+', text)
               
                for sentence in sentences:
                sentence = sentence.strip()
                if len(sentence) > 10:  # Игнорируем слишком короткие
                sentence_words = clean_words(sentence)
                similarity = jaccard_similarity(search_words, sentence_words)
               
                if min_sim <= similarity <= max_sim:
                unique_phrases.add(sentence)
                if len(unique_phrases) >= max_phrases:
                break
                if len(unique_phrases) >= max_phrases:
                break
        if len(unique_phrases) >= max_phrases:
            break
   
    return list(unique_phrases)

# Основная часть с упрощённым циклом
if __name__ == "__main__":
    desktop_path = os.path.expanduser("~/Desktop")
   
    while True:
        search_phrase = input("поиск: ")
       
        phrases = find_similar_phrases(search_phrase, desktop_path)
       
        if phrases:
            # Выбрать 3 случайные (или все, если меньше)
            selected = random.sample(phrases, min(3, len(phrases)))
            for phrase in selected:
                print(phrase)
        # Иначе ничего не выводим, просто ждём следующий ввод


Рецензии