{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "cell-23-06-00",
   "metadata": {},
   "source": [
    "# 23-06 · Файлы и Tkinter\n",
    "\n",
    "Практика к разделу [«Домашний проект F: приложение «Заметки»»](../../site/chapters/glava-23/23-hw-06-zametki.html). Полный файл — `projects/tkinter/notes-app/notes_app.py`."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "setup-23-06",
   "metadata": {},
   "source": [
    "## Reproducible local environment\n",
    "\n",
    "These appendix projects live in the course repository, not in SafeSort:\n",
    "\n",
    "```bash\n",
    "git clone https://github.com/Cartesian-School/python-from-zero.git\n",
    "cd python-from-zero\n",
    "python3.14 -m venv .venv\n",
    "source .venv/bin/activate\n",
    "# Windows PowerShell: .venv\\Scripts\\Activate.ps1\n",
    "python -m pip install -U pip\n",
    "python -m pip install pytest pygame-ce jupyter ipykernel\n",
    "python -m ipykernel install --user --name course-py314 --display-name \"Course Python 3.14\"\n",
    "jupyter lab\n",
    "```\n",
    "\n",
    "Select **Course Python 3.14**. On Linux, Tkinter may also require the OS\n",
    "package `python3-tk`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "diagnostic-23-06",
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "from pathlib import Path\n",
    "\n",
    "print(sys.executable)\n",
    "print(Path.cwd())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-23-06-03",
   "metadata": {},
   "source": [
    "## Цель\n",
    "\n",
    "Проверить сохранение и загрузку заметки через чистые функции `sohranit_v_fajl()`/`zagruzit_iz_fajla()`, а также поведение при отсутствии сохранённого файла."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-23-06-04",
   "metadata": {},
   "source": [
    "## Example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cell-23-06-05",
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "import tempfile\n",
    "from pathlib import Path\n",
    "\n",
    "sys.path.insert(0, \"../../projects/tkinter/notes-app\")\n",
    "import notes_app as na\n",
    "\n",
    "katalog = tempfile.TemporaryDirectory()\n",
    "put_k_zametke = Path(katalog.name) / \"zametka.txt\"\n",
    "\n",
    "print(\"Файл существует до сохранения:\", put_k_zametke.exists())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-23-06-06",
   "metadata": {},
   "source": [
    "## Проверка результата — загрузка несуществующего файла поднимает понятную ошибку"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cell-23-06-07",
   "metadata": {},
   "outputs": [],
   "source": [
    "try:\n",
    "    na.zagruzit_iz_fajla(put_k_zametke)\n",
    "    fajl_najden = True\n",
    "except FileNotFoundError:\n",
    "    fajl_najden = False\n",
    "\n",
    "assert fajl_najden is False\n",
    "print(\"Верно: попытка загрузки без сохранённого файла поднимает FileNotFoundError, \"\n",
    "      \"а не падает трудночитаемой ошибкой позже.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-23-06-08",
   "metadata": {},
   "source": [
    "## Эксперимент — сохраняем и загружаем заметку"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cell-23-06-09",
   "metadata": {},
   "outputs": [],
   "source": [
    "tekst_zametki = \"Купить молоко\\nПозвонить маме\"\n",
    "na.sohranit_v_fajl(put_k_zametke, tekst_zametki)\n",
    "\n",
    "assert put_k_zametke.exists()\n",
    "assert put_k_zametke.read_text(encoding=\"utf-8\") == tekst_zametki\n",
    "print(\"Верно: sohranit_v_fajl() записывает переданный текст в файл в кодировке UTF-8.\")\n",
    "\n",
    "zagruzhennyj_tekst = na.zagruzit_iz_fajla(put_k_zametke)\n",
    "assert zagruzhennyj_tekst == tekst_zametki\n",
    "print(\"Верно: zagruzit_iz_fajla() возвращает ровно то, что было сохранено.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-23-06-10",
   "metadata": {},
   "source": [
    "## Starter\n",
    "\n",
    "Заполните отмеченное место. Неизменённый starter не проходит tests."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "task-23-06",
   "metadata": {
    "tags": [
     "exercise",
     "starter"
    ]
   },
   "outputs": [],
   "source": [
    "novyj_tekst = \"\"\"Список покупок:\n",
    "- хлеб\n",
    "- сыр\n",
    "- яблоки 🍎\"\"\"\n",
    "\n",
    "# TODO: save novyj_tekst through na.sohranit_v_fajl(...).\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-23-06-12",
   "metadata": {},
   "source": [
    "## Task\n",
    "\n",
    "Сохраните многострочный UTF-8 текст с кириллицей и emoji в `put_k_zametke`, затем прочитайте его обратно."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-23-06-13",
   "metadata": {},
   "source": [
    "## Tests\n",
    "\n",
    "Запустите после task cell: есть основной пример и хотя бы один крайний случай."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "tests-23-06",
   "metadata": {
    "tags": [
     "exercise-tests"
    ]
   },
   "outputs": [],
   "source": [
    "assert na.zagruzit_iz_fajla(put_k_zametke) == novyj_tekst\n",
    "assert \"🍎\" in na.zagruzit_iz_fajla(put_k_zametke)\n",
    "print(\"Tests passed\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-23-06-15",
   "metadata": {},
   "source": [
    "## Hint\n",
    "\n",
    "Передайте путь первым аргументом, текст вторым."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-23-06-16",
   "metadata": {},
   "source": [
    "## Solution\n",
    "\n",
    "<details><summary>Показать решение после собственной попытки</summary>\n",
    "\n",
    "```python\n",
    "novyj_tekst = \"\"\"Список покупок:\n",
    "- хлеб\n",
    "- сыр\n",
    "- яблоки 🍎\"\"\"\n",
    "na.sohranit_v_fajl(put_k_zametke, novyj_tekst)\n",
    "```\n",
    "\n",
    "</details>"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Cartesian Python 3.14",
   "language": "python",
   "name": "cartesian-python314"
  },
  "language_info": {
   "name": "python",
   "version": "3.14.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
