{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "cell-23-05-00",
   "metadata": {},
   "source": [
    "# 23-05 · Преобразование температуры\n",
    "\n",
    "Практика к разделу [«Домашний проект E: приложение для преобразования температуры»](../../site/chapters/glava-23/23-hw-05-temperatura.html). Полный файл — `projects/tkinter/temperature-converter/temperature_converter.py`."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "setup-23-05",
   "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-05",
   "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-05-03",
   "metadata": {},
   "source": [
    "## Цель\n",
    "\n",
    "Проверить формулы перевода на известных опорных точках и убедиться, что `preobrazovat()` отклоняет физически невозможные значения."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-23-05-04",
   "metadata": {},
   "source": [
    "## Example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cell-23-05-05",
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "\n",
    "sys.path.insert(0, \"../../projects/tkinter/temperature-converter\")\n",
    "import temperature_converter as tc\n",
    "\n",
    "print(tc.preobrazovat(0, \"C\"))\n",
    "print(tc.preobrazovat(100, \"C\"))\n",
    "print(tc.preobrazovat(32, \"F\"))\n",
    "print(tc.preobrazovat(0, \"K\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-23-05-06",
   "metadata": {},
   "source": [
    "## Проверка результата"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cell-23-05-07",
   "metadata": {},
   "outputs": [],
   "source": [
    "r = tc.preobrazovat(0, \"C\")\n",
    "assert abs(r[\"F\"] - 32) < 1e-9\n",
    "assert abs(r[\"K\"] - 273.15) < 1e-9\n",
    "\n",
    "r = tc.preobrazovat(100, \"C\")\n",
    "assert abs(r[\"F\"] - 212) < 1e-9\n",
    "\n",
    "r = tc.preobrazovat(32, \"F\")\n",
    "assert abs(r[\"C\"] - 0) < 1e-9\n",
    "\n",
    "r = tc.preobrazovat(0, \"K\")\n",
    "assert abs(r[\"C\"] - (-273.15)) < 1e-9\n",
    "\n",
    "print(\"Верно: 0 °C = 32 °F = 273.15 K, 100 °C = 212 °F, 0 K = -273.15 °C.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-23-05-08",
   "metadata": {},
   "source": [
    "## Эксперимент — ниже абсолютного нуля такой температуры не существует"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cell-23-05-09",
   "metadata": {
    "tags": [
     "raises-exception"
    ]
   },
   "outputs": [],
   "source": [
    "tc.preobrazovat(-274, \"C\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-23-05-10",
   "metadata": {},
   "source": [
    "## Как это выглядит в коде\n",
    "\n",
    "Вызов выше завершился трассировкой `ValueError` — так и задумано: `preobrazovat()` не пытается тихо «исправить» физически невозможное значение, а поднимает понятную ошибку. Настоящий обработчик кнопки внутри `main()` перехватывает именно этот `ValueError` и показывает пользователю фразу «Такой температуры не существует — ниже абсолютного нуля» вместо падения программы."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cell-23-05-11",
   "metadata": {},
   "outputs": [],
   "source": [
    "try:\n",
    "    tc.preobrazovat(-460, \"F\")   # ниже -459.67°F — тоже ниже абсолютного нуля\n",
    "except ValueError as oshibka:\n",
    "    poymano = True\n",
    "    tekst_oshibki = str(oshibka)\n",
    "else:\n",
    "    poymano = False\n",
    "\n",
    "assert poymano is True\n",
    "assert \"абсолютного нуля\" in tekst_oshibki\n",
    "print(\"Верно: значение ниже абсолютного нуля в градусах Фаренгейта тоже отклоняется.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-23-05-12",
   "metadata": {},
   "source": [
    "## Starter\n",
    "\n",
    "Заполните отмеченное место. Неизменённый starter не проходит tests."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "task-23-05",
   "metadata": {
    "tags": [
     "exercise",
     "starter"
    ]
   },
   "outputs": [],
   "source": [
    "assert tc.preobrazovat(0, \"K\")[\"C\"] == -273.15\n",
    "\n",
    "otkloneno_nizhe_nulya = None\n",
    "# TODO: call preobrazovat(-0.01, \"K\") inside try/except ValueError.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-23-05-14",
   "metadata": {},
   "source": [
    "## Task\n",
    "\n",
    "Проверьте границу шкалы: `0 K` допустим, `-0.01 K` вызывает `ValueError`. Запишите факт отказа в `otkloneno_nizhe_nulya`."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-23-05-15",
   "metadata": {},
   "source": [
    "## Tests\n",
    "\n",
    "Запустите после task cell: есть основной пример и хотя бы один крайний случай."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "tests-23-05",
   "metadata": {
    "tags": [
     "exercise-tests"
    ]
   },
   "outputs": [],
   "source": [
    "assert otkloneno_nizhe_nulya is True\n",
    "assert tc.preobrazovat(0, \"K\")[\"K\"] == 0\n",
    "print(\"Tests passed\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-23-05-17",
   "metadata": {},
   "source": [
    "## Hint\n",
    "\n",
    "Установите флаг в `False` перед вызовом и в `True` только внутри `except ValueError`."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-23-05-18",
   "metadata": {},
   "source": [
    "## Solution\n",
    "\n",
    "<details><summary>Показать решение после собственной попытки</summary>\n",
    "\n",
    "```python\n",
    "assert tc.preobrazovat(0, \"K\")[\"C\"] == -273.15\n",
    "\n",
    "otkloneno_nizhe_nulya = False\n",
    "try:\n",
    "    tc.preobrazovat(-0.01, \"K\")\n",
    "except ValueError:\n",
    "    otkloneno_nizhe_nulya = True\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
}
