Общий принцип работы программы
Общий принцип работы программы
Это консольное приложение‑органайзер для задач. Данные сохраняются в файле tasks.json, что обеспечивает их сохранность между запусками. Программа построена на принципах ООП: логика разделена на классы с чётким назначением.
Разбор кода по частям
1. Импорты
pythonimport json import os from datetime import datetime from typing importList, Dict, Optional
- json — для сериализации объектов Python в формат JSON и обратно (сохранение/загрузка задач).
- os — проверка существования файла tasks.json перед загрузкой (os.path.exists).
- datetime — работа с датами и временем (фиксация моментов создания и завершения задач).
- typing — аннотации типов (List, Dict, Optional) для улучшения читаемости кода и поддержки со стороны IDE.
2. Класс Task
Описывает одну задачу.
Атрибуты:
- id — уникальный идентификатор (генерируется функцией id(self)).
- title — заголовок задачи (обязательное поле).
- description — подробное описание (опционально, по умолчанию пустая строка).
- created_at — дата и время создания задачи (datetime.now()).
- completed — флаг выполнения (True/False, изначально False).
- completed_at — время завершения задачи (None до выполнения).
Методы:
- __init__() — конструктор: инициализирует задачу с переданными параметрами.
- complete() — отмечает задачу как выполненную: устанавливает completed = True и фиксирует completed_at = datetime.now().
- to_dict() — преобразует объект Task в словарь для сохранения в JSON. Даты конвертируются в строковый формат ISO (isoformat()).
- @classmethod from_dict() — создаёт объект Task из словаря (при загрузке из файла). Даты восстанавливаются из строк (datetime.fromisoformat).
- __str__() — форматирует строку для вывода в консоль: отображает статус (✓/○), заголовок и ID задачи.
3. Класс TaskManager
Управляет коллекцией задач.
Атрибуты:
- storage_file — имя файла для сохранения (tasks.json по умолчанию).
- tasks — список объектов Task (изначально пустой).
Методы:
- __init__() — инициализирует менеджер: создаёт пустой список задач и вызывает load_tasks() для загрузки данных из файла (если он существует).
- add_task() — создаёт новую задачу (Task), добавляет её в список tasks, сохраняет изменения в файл (save_tasks()), возвращает созданный объект.
- get_task() — ищет задачу по ID в списке tasks. Если находит — возвращает объект, иначе — None.
- complete_task() — находит задачу по ID (get_task()), вызывает у неё метод complete(), сохраняет изменения (save_tasks()). Возвращает True при успехе, False — если задача не найдена.
- list_tasks() — возвращает список задач. Если show_completed = True — все задачи, иначе — только активные (незавершённые).
- save_tasks() — сохраняет все задачи в файл tasks.json. Для каждой задачи вызывается to_dict(), результат записывается через json.dump с форматированием (indent=2) и кодировкой UTF‑8 (ensure_ascii=False для поддержки кириллицы).
- load_tasks() — загружает задачи из файла tasks.json (если он существует). Для каждого элемента в JSON‑массиве вызывается Task.from_dict(), результаты добавляются в список tasks.
- delete_task() — находит задачу по ID (get_task()), удаляет её из списка tasks (remove()), сохраняет изменения (save_tasks()). Возвращает True при успехе, False — если задача не найдена.
4. Функция main()
Точка входа в программу. Реализует CLI‑интерфейс (командная строка).
Логика работы:
- Создаёт экземпляр TaskManager.
- Запускает бесконечный цикл (while True) с меню действий.
- Обрабатывает выбор пользователя:1. Добавить задачу — запрашивает заголовок и описание, вызывает add_task(), выводит информацию о созданной задаче.2. Показать задачи — спрашивает, показывать ли завершённые задачи, вызывает list_tasks(), выводит список (или сообщение «Задач нет»).3. Отметить как выполненную — запрашивает ID, вызывает complete_task(), обрабатывает ошибки (неверный ID — ValueError, задача не найдена).4. Удалить задачу — запрашивает ID, вызывает delete_task(), обрабатывает ошибки.5. Выход — выводит «До свидания!» и прерывает цикл (break).Иное — сообщает «Неверный выбор. Попробуйте снова».
- Обрабатывает исключения (try‑except): при вводе нечислового ID (int(input())) перехватывает ValueError и выводит сообщение.
5. Конструкция if __name__ == "__main__":
Гарантирует, что main() запустится только при прямом запуске скрипта, а не при импорте как модуля. Это стандартная практика в Python для разделения кода на переиспользуемые части и исполняемые скрипты.
Последовательность работы программы
- Запуск: выполняется скрипт, вызывается main(), создаётся экземпляр TaskManager.
- Загрузка данных: менеджер пытается загрузить задачи из tasks.json. Если файла нет — начинает с пустого списка.
- Отображение меню: пользователю показывается список действий (1–5).
- Взаимодействие: пользователь выбирает действие, вводит данные, программа выполняет соответствующую логику.
- Сохранение: после каждого изменения (добавление, выполнение, удаление) данные сохраняются в tasks.json.
- Выход: при выборе пункта 5 программа завершается, файл tasks.json содержит актуальное состояние всех задач.
Формат файла tasks.json
Пример содержимого после добавления и выполнения задачи:
json[{"id":123456789,"title":"Купить продукты","description":"Молоко, хлеб, яблоки","created_at":"2023-10-05T14:30:00","completed":true,"completed_at":"2023-10-05T15:15:22"}]
Преимущества формата:
- человекочитаемость;
- совместимость с другими системами (веб‑интерфейсы, мобильные приложения);
- простота парсинга и модификации.
Ключевые преимущества реализации
- Персистентность: данные сохраняются между запусками программы.
- Простота: нет внешних зависимостей, работает «из коробки».
- Расширяемость: легко добавить категории, приоритеты, сроки выполнения.
- Наглядность: понятный CLI‑интерфейс без лишних элементов.
- Обучение: демонстрирует ООП, работу с файлами, обработку ошибок, аннотации типов.