🏠 Домашнее задание

⚡ Суть задания

Домашнее задание состоит из двух задач: фильтрация строк по ключевому слову и удаление дублирующихся строк с сохранением порядка.

Результат: две программы, которые корректно открывают файлы, обрабатывают отсутствие файла и создают выходные файлы по заданным шаблонам имен.

📋 Формулировка задания

Исходное задание из LMS:

  1. Фильтрация по ключевому слову
    Напишите программу, которая ищет в файле все строки, содержащие указанное пользователем слово, и сохраняет их в новый файл.
    Имя нового файла формируется как <keyword>_<original_filename>.
    Если файл не существует, программа должна вывести ошибку.
    Если совпадения не найдены, новый файл не создаётся.
    Используйте файл system_log.txt.
    Пример ввода:
    Введите имя файла для поиска: system_log.txt
    Введите ключевое слово: error
    Пример вывода:
    Строки, содержащие 'error', сохранены в error_system_log.txt.
  2. Поиск и удаление дубликатов
    Напишите программу, которая удаляет дублирующиеся строки из файла и сохраняет результат в новый файл.
    Имя нового файла формируется как unique_<original_filename>.
    Если файл не существует, программа должна вывести ошибку.
    Исходный порядок строк должен сохраниться.
    Если в файле нет дубликатов, создаётся точная копия файла.
    Используйте файл movies_to_watch.txt.
    Пример ввода:
    Введите имя файла: movies_to_watch.txt
    Пример вывода:
    Дубликаты удалены. Уникальные строки сохранены в unique_movies_to_watch.txt.

🔧 Шаг 0. Подготовка окружения

Перед началом работы над любым заданием курса нужно настроить окружение. Эти шаги одинаковы для всех уроков.

📁 Структура репозитория: мы используем один репозиторий для всех практических работ курса. Это удобнее, чем много отдельных репозиториев: общий .gitignore, единая история, легко переключаться между уроками.
1

Создайте (или откройте) рабочую папку

В VS Code нажмите Ctrl+K Ctrl+O → выберите или создайте папку python-fundamentals-practice. Это будет корень вашего учебного репозитория.

# Или в терминале VS Code (Ctrl + `):
mkdir python-fundamentals-practice
cd python-fundamentals-practice
2

Инициализируйте Git-репозиторий (один раз)

Если папка ещё не является git-репозиторием:

git init

# Создайте базовые файлы
echo "# Python Fundamentals — Практические работы" > README.md
echo "venv/" > .gitignore
echo "__pycache__/" >> .gitignore
echo "*.pyc" >> .gitignore
echo ".env" >> .gitignore
echo "*.log" >> .gitignore

git add README.md .gitignore
git commit -m "init: базовая структура репозитория"
3

Создайте папку для текущего урока

# Структура: lesson-XX/
mkdir -p lesson-52
cd lesson-52
4

Создайте виртуальное окружение (venv)

# Windows (PowerShell / CMD)
python -m venv venv
venv\Scripts\activate

# Mac / Linux
python3 -m venv venv
source venv/bin/activate

После активации в начале строки терминала появится (venv). Все дальнейшие команды выполняйте внутри venv.

5

Создайте ветку для задания

# Вернитесь в корень репозитория
cd ../..

# Создайте и переключитесь на ветку
git checkout -b lesson/52-file-basics

# Отправьте ветку на удалённый репозиторий (если настроен)
git push -u origin lesson/52-file-basics

Именование веток: lesson/XX-краткое-название. Это позволяет легко находить нужный урок.

🛠️ Шаги выполнения задания

Теперь, когда окружение готово, приступайте к решению.

1

Шаг 1: фильтрация по ключевому слову

Создайте файл filter_keyword.py и файл system_log.txt с тестовыми данными.

# system_log.txt (пример содержимого)
INFO: system started
ERROR: connection timeout
INFO: user logged in
ERROR: file not found
WARNING: low memory
# filter_keyword.py

def filter_by_keyword(filename, keyword):
    output_filename = f"{keyword}_{filename}"
    matches = []

    with open(filename, "r", encoding="utf-8") as file:
        for line in file:
            if keyword in line:
                matches.append(line)

    if matches:
        with open(output_filename, "w", encoding="utf-8") as file:
            file.writelines(matches)
        print(f"Строки, содержащие '{keyword}', сохранены в {output_filename}.")
    else:
        print(f"Совпадений для '{keyword}' не найдено.")


if __name__ == "__main__":
    filename = input("Введите имя файла для поиска: ")
    keyword = input("Введите ключевое слово: ")

    try:
        filter_by_keyword(filename, keyword)
    except FileNotFoundError:
        print(f"Ошибка: файл '{filename}' не найден.")

Проверка в VS Code:

  1. Убедитесь, что venv активирован.
  2. Запустите: python filter_keyword.py
  3. Введите system_log.txt и ERROR.
  4. Убедитесь, что создан файл ERROR_system_log.txt с двумя строками.
2

Шаг 2: удаление дубликатов

Создайте файл remove_duplicates.py и файл movies_to_watch.txt с тестовыми данными.

# movies_to_watch.txt (пример содержимого)
Inception
The Matrix
Inception
Interstellar
The Matrix
The Dark Knight
# remove_duplicates.py

def remove_duplicates(filename):
    output_filename = f"unique_{filename}"
    seen = set()
    unique_lines = []

    with open(filename, "r", encoding="utf-8") as file:
        for line in file:
            if line not in seen:
                seen.add(line)
                unique_lines.append(line)

    with open(output_filename, "w", encoding="utf-8") as file:
        file.writelines(unique_lines)

    print(f"Дубликаты удалены. Уникальные строки сохранены в {output_filename}.")


if __name__ == "__main__":
    filename = input("Введите имя файла: ")

    try:
        remove_duplicates(filename)
    except FileNotFoundError:
        print(f"Ошибка: файл '{filename}' не найден.")

Проверка в VS Code:

  1. Запустите: python remove_duplicates.py
  2. Введите movies_to_watch.txt.
  3. Откройте unique_movies_to_watch.txt и убедитесь, что дубликаты удалены, а порядок уникальных строк сохранён.

✅ Полное решение

Ниже приведены обе задачи в одном файле. Совет: попробуйте выполнить задание самостоятельно, прежде чем смотреть ответ.

# homework_52.py

def filter_by_keyword(filename, keyword):
    output_filename = f"{keyword}_{filename}"
    matches = []

    with open(filename, "r", encoding="utf-8") as file:
        for line in file:
            if keyword in line:
                matches.append(line)

    if matches:
        with open(output_filename, "w", encoding="utf-8") as file:
            file.writelines(matches)
        print(f"Строки, содержащие '{keyword}', сохранены в {output_filename}.")
    else:
        print(f"Совпадений для '{keyword}' не найдено.")


def remove_duplicates(filename):
    output_filename = f"unique_{filename}"
    seen = set()
    unique_lines = []

    with open(filename, "r", encoding="utf-8") as file:
        for line in file:
            if line not in seen:
                seen.add(line)
                unique_lines.append(line)

    with open(output_filename, "w", encoding="utf-8") as file:
        file.writelines(unique_lines)

    print(f"Дубликаты удалены. Уникальные строки сохранены в {output_filename}.")


if __name__ == "__main__":
    # Задача 1
    filename = input("Введите имя файла для поиска: ")
    keyword = input("Введите ключевое слово: ")

    try:
        filter_by_keyword(filename, keyword)
    except FileNotFoundError:
        print(f"Ошибка: файл '{filename}' не найден.")

    # Задача 2
    filename = input("\nВведите имя файла: ")

    try:
        remove_duplicates(filename)
    except FileNotFoundError:
        print(f"Ошибка: файл '{filename}' не найден.")

🧪 Как проверить решение

  1. Активируйте venv: venv\Scripts\activate (Windows) или source venv/bin/activate (Mac/Linux).
  2. Создайте тестовые файлы system_log.txt и movies_to_watch.txt.
  3. Запустите файл: python homework_52.py.
  4. Проверьте сценарии:
    • Фильтрация: совпадения сохраняются в файл <keyword>_<original>.
    • Если совпадений нет, выводится сообщение и новый файл не создаётся.
    • Удаление дубликатов: создаётся файл unique_<original> с сохранением порядка.
    • Если исходный файл не найден, выводится сообщение об ошибке.

🐛 Отладка в VS Code

Если что-то не работает:

  1. Поставьте точку останова (breakpoint) на строке с open(filename, ...).
  2. Нажмите F5 или выберите «Run → Start Debugging».
  3. На панели Debug следите за значениями переменных filename, keyword, matches, seen.
  4. Если файл не найден, проверьте, что вы запускаете скрипт из той папки, где лежат файлы.

💾 Сохранение работы

# Добавьте файлы урока
git add lesson-52/

# Сделайте коммит с осмысленным сообщением
git commit -m "lesson-52: основы работы с файлами"

# Отправьте на GitHub / GitLab
git push

💡 Советы и типичные ошибки

  • Всегда указывайте encoding="utf-8" при работе с текстовыми файлами.
  • Используйте with open(...), чтобы гарантировать закрытие файла.
  • Проверяйте, что выходной файл не создаётся, если совпадений нет.
  • Для удаления дубликатов сохраняйте исходный порядок строк с помощью множества и списка.
  • Не коммитьте папку venv/ и временные файлы — они указаны в .gitignore.