From 816c9f1cda082d869ec9d6f5964a71902d9a21ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B5=D0=B4=D0=BE=D0=B2=20=D0=95=D0=B3=D0=BE=D1=80?= =?UTF-8?q?=20=D0=A1=D0=B5=D1=80=D0=B3=D0=B5=D0=B5=D0=B2=D0=B8=D1=87?= Date: Mon, 18 May 2026 14:51:05 +0300 Subject: [PATCH] Add calendar implementation: models, storage, CLI --- __pycache__/models.cpython-312.pyc | Bin 0 -> 2058 bytes __pycache__/storage.cpython-312.pyc | Bin 0 -> 2914 bytes calendar_cli.py | 141 ++++++++++++++++++++++++++++ calendar_data.json | 8 ++ models.py | 35 +++++++ storage.py | 44 +++++++++ 6 files changed, 228 insertions(+) create mode 100644 __pycache__/models.cpython-312.pyc create mode 100644 __pycache__/storage.cpython-312.pyc create mode 100644 calendar_cli.py create mode 100644 calendar_data.json create mode 100644 models.py create mode 100644 storage.py diff --git a/__pycache__/models.cpython-312.pyc b/__pycache__/models.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..00053d74f097de04e24d67c40d2dc72e46df1750 GIT binary patch literal 2058 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 WH dict: + """Преобразует событие в словарь для JSON""" + return { + "title": self.title, + "date": self.date, + "time": self.time, + "description": self.description + } + + @classmethod + def from_dict(cls, data: dict) -> 'Event': + """Создаёт событие из словаря""" + return cls( + title=data["title"], + date=data["date"], + time=data.get("time", ""), + description=data.get("description", "") + ) + + def __str__(self) -> str: + time_str = f" в {self.time}" if self.time else "" + return f"{self.date}{time_str}: {self.title} - {self.description}" \ No newline at end of file diff --git a/storage.py b/storage.py new file mode 100644 index 0000000..1fed0c0 --- /dev/null +++ b/storage.py @@ -0,0 +1,44 @@ +import json +import os +from typing import List +from models import Event + +DATA_FILE = "calendar_data.json" + +def load_events() -> List[Event]: + """Загружает события из JSON файла""" + if not os.path.exists(DATA_FILE): + return [] + + try: + with open(DATA_FILE, 'r', encoding='utf-8') as f: + data = json.load(f) + return [Event.from_dict(item) for item in data] + except (json.JSONDecodeError, FileNotFoundError): + return [] + +def save_events(events: List[Event]) -> None: + """Сохраняет события в JSON файл""" + with open(DATA_FILE, 'w', encoding='utf-8') as f: + data = [event.to_dict() for event in events] + json.dump(data, f, ensure_ascii=False, indent=2) + +def add_event(event: Event) -> None: + """Добавляет новое событие""" + events = load_events() + events.append(event) + save_events(events) + +def remove_event(index: int) -> bool: + """Удаляет событие по индексу (начиная с 0)""" + events = load_events() + if 0 <= index < len(events): + del events[index] + save_events(events) + return True + return False + +def get_events_by_date(date: str) -> List[Event]: + """Возвращает события на конкретную дату""" + events = load_events() + return [e for e in events if e.date == date] \ No newline at end of file