{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "964da491",
   "metadata": {},
   "source": [
    "# 06-02 · Движение вперёд и назад\n",
    "\n",
    "Практика к разделу [«Движение вперёд и назад»](../../site/chapters/glava-06/06-02-dvizhenie-vpered-nazad.html)\n",
    "(Глава 6 · Turtle, книга «Python с нуля», Cartesian School)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "40c17d13",
   "metadata": {},
   "source": [
    "## Цель\n",
    "\n",
    "Научиться управлять черепашкой Turtle: `forward`, `backward`, `right`, `left` —\n",
    "и на практике почувствовать разницу между **движением** и **поворотом**."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c6d22cb9",
   "metadata": {},
   "source": [
    "## Что нужно знать\n",
    "\n",
    "Этот ноутбук — лаборатория к уже прочитанному разделу теории. Если вы попали сюда\n",
    "впервые, коротко: у черепашки есть позиция и курс (направление). `forward`/`backward`\n",
    "двигают её по прямой, `left`/`right` только поворачивают курс."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "693d95ec",
   "metadata": {},
   "source": [
    "## Краткое напоминание\n",
    "\n",
    "- `artist.forward(n)` / `artist.fd(n)` — вперёд на `n` пикселей\n",
    "- `artist.backward(n)` / `artist.bk(n)` / `artist.back(n)` — назад на `n` пикселей\n",
    "- `artist.left(угол)` / `artist.lt(угол)` — повернуть против часовой стрелки\n",
    "- `artist.right(угол)` / `artist.rt(угол)` — повернуть по часовой стрелке\n",
    "\n",
    "**Особенность работы в Jupyter:** окно Turtle открывается один раз на весь ноутбук —\n",
    "мы создаём `screen` и `artist` в следующей ячейке. Перед каждым новым рисунком\n",
    "вызываем `artist.reset()`, чтобы очистить холст и вернуть черепашку в начало\n",
    "координат; закрываем окно командой `screen.bye()` только в самой последней ячейке.\n",
    "(Технически создать и закрыть отдельное окно Turtle в каждой ячейке невозможно —\n",
    "модуль `turtle` не рассчитан на это внутри одного процесса.)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "189328bf",
   "metadata": {},
   "source": [
    "## Настройка (выполнить один раз)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "643261e0",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-14T20:52:20.932841Z",
     "iopub.status.busy": "2026-08-14T20:52:20.932720Z",
     "iopub.status.idle": "2026-08-14T20:52:21.093681Z",
     "shell.execute_reply": "2026-08-14T20:52:21.093218Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Окно Turtle готово. Позиция: (0.00,0.00) | курс: 0.0\n"
     ]
    }
   ],
   "source": [
    "import turtle\n",
    "\n",
    "screen = turtle.Screen()\n",
    "artist = turtle.Turtle()\n",
    "print(\"Окно Turtle готово. Позиция:\", artist.position(), \"| курс:\", artist.heading())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8bd957fa",
   "metadata": {},
   "source": [
    "## Рабочий пример"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "559236fc",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-14T20:52:21.094693Z",
     "iopub.status.busy": "2026-08-14T20:52:21.094577Z",
     "iopub.status.idle": "2026-08-14T20:52:21.428378Z",
     "shell.execute_reply": "2026-08-14T20:52:21.427931Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Позиция: (120.00,80.00)\n",
      "Курс: 90.0\n"
     ]
    }
   ],
   "source": [
    "artist.reset()\n",
    "\n",
    "# едем вперёд на 120 пикселей\n",
    "artist.forward(120)\n",
    "\n",
    "# поворачиваем на 90 градусов против часовой стрелки\n",
    "artist.left(90)\n",
    "\n",
    "# едем вперёд ещё раз — получаем букву «Г»\n",
    "artist.forward(80)\n",
    "\n",
    "print(\"Позиция:\", artist.position())\n",
    "print(\"Курс:\", artist.heading())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "021e1f96",
   "metadata": {},
   "source": [
    "## Эксперимент 1\n",
    "\n",
    "Измените расстояние `120` на `250` и угол `90` на `45`. Перед запуском попробуйте\n",
    "предсказать: в какую сторону теперь «смотрит» черепашка после поворота?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "7f7085bb",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-14T20:52:21.429406Z",
     "iopub.status.busy": "2026-08-14T20:52:21.429289Z",
     "iopub.status.idle": "2026-08-14T20:52:21.815854Z",
     "shell.execute_reply": "2026-08-14T20:52:21.815382Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Курс после поворота: 45.0 градусов\n"
     ]
    }
   ],
   "source": [
    "artist.reset()\n",
    "\n",
    "artist.forward(250)   # было 120\n",
    "artist.left(45)       # было 90\n",
    "artist.forward(80)\n",
    "\n",
    "print(\"Курс после поворота:\", artist.heading(), \"градусов\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4f39b29a",
   "metadata": {},
   "source": [
    "## Эксперимент 2\n",
    "\n",
    "Добавьте третью пару команд `left(90)` и `forward(120)` в конец программы. Какая\n",
    "фигура получится?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "98ccfe06",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-14T20:52:21.816903Z",
     "iopub.status.busy": "2026-08-14T20:52:21.816787Z",
     "iopub.status.idle": "2026-08-14T20:52:22.396102Z",
     "shell.execute_reply": "2026-08-14T20:52:22.395696Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Позиция: (0.00,80.00)\n",
      "Курс: 180.0\n"
     ]
    }
   ],
   "source": [
    "artist.reset()\n",
    "\n",
    "artist.forward(120)\n",
    "artist.left(90)\n",
    "artist.forward(80)\n",
    "artist.left(90)        # новый поворот\n",
    "artist.forward(120)    # новая сторона\n",
    "\n",
    "print(\"Позиция:\", artist.position())\n",
    "print(\"Курс:\", artist.heading())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8195e683",
   "metadata": {},
   "source": [
    "## Задание ★ Базовая практика\n",
    "\n",
    "Используя только `forward`, `backward`, `left` и `right`, нарисуйте букву «Т» одной\n",
    "непрерывной линией пера: сначала верхнюю перекладину, потом ножку вниз от её середины.\n",
    "\n",
    "Один из вариантов решения — ниже. Попробуйте написать свой вариант **до** того, как\n",
    "запускать эту ячейку."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "00d417c2",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-14T20:52:22.398477Z",
     "iopub.status.busy": "2026-08-14T20:52:22.398292Z",
     "iopub.status.idle": "2026-08-14T20:52:22.798653Z",
     "shell.execute_reply": "2026-08-14T20:52:22.798173Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Позиция: (0.00,-100.00)\n",
      "Курс: 270.0\n"
     ]
    }
   ],
   "source": [
    "artist.reset()\n",
    "\n",
    "# верхняя перекладина: сначала правая половина, потом через центр — левая\n",
    "artist.forward(40)\n",
    "artist.backward(80)\n",
    "artist.forward(40)  # возвращаемся точно в центр перекладины\n",
    "\n",
    "# ножка буквы «Т» — вниз от центра перекладины\n",
    "artist.right(90)\n",
    "artist.forward(100)\n",
    "\n",
    "print(\"Позиция:\", artist.position())\n",
    "print(\"Курс:\", artist.heading())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2c77357e",
   "metadata": {},
   "source": [
    "## Проверка результата\n",
    "\n",
    "После выполнения ячейки с заданием черепашка должна закончить движение в точке\n",
    "`(0.0, -100.0)` с курсом `270°` (смотрит вниз) — низ ножки буквы «Т».\n",
    "\n",
    "Следующая ячейка повторяет решение и автоматически проверяет конечное состояние."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "e523f39a",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-14T20:52:22.799716Z",
     "iopub.status.busy": "2026-08-14T20:52:22.799605Z",
     "iopub.status.idle": "2026-08-14T20:52:23.198230Z",
     "shell.execute_reply": "2026-08-14T20:52:23.197711Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Проверка пройдена: буква «Т» нарисована корректно.\n"
     ]
    }
   ],
   "source": [
    "artist.reset()\n",
    "\n",
    "artist.forward(40)\n",
    "artist.backward(80)\n",
    "artist.forward(40)\n",
    "artist.right(90)\n",
    "artist.forward(100)\n",
    "\n",
    "x, y = artist.position()\n",
    "assert round(x, 1) == 0.0, f\"Неожиданная координата x: {x}\"\n",
    "assert round(y, 1) == -100.0, f\"Неожиданная координата y: {y}\"\n",
    "assert artist.heading() == 270.0, f\"Неожиданный курс: {artist.heading()}\"\n",
    "\n",
    "print(\"Проверка пройдена: буква «Т» нарисована корректно.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9671d153",
   "metadata": {},
   "source": [
    "## Типичная ошибка\n",
    "\n",
    "Начинающие часто путают `right()`/`left()` с движением — кажется, что черепашка\n",
    "должна сместиться в сторону. На самом деле эти команды **только поворачивают** курс\n",
    "и не двигают черепашку ни на пиксель. Ниже — программа с этой ошибкой: вместо буквы\n",
    "«Г» получается просто прямая линия длиной 200, потому что поворот «потерялся» между\n",
    "двумя одинаковыми движениями вперёд."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "6574b240",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-14T20:52:23.199134Z",
     "iopub.status.busy": "2026-08-14T20:52:23.199030Z",
     "iopub.status.idle": "2026-08-14T20:52:23.409252Z",
     "shell.execute_reply": "2026-08-14T20:52:23.408797Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Курс (не изменился!): 0.0\n",
      "Черепашка проехала прямо, а не буквой «Г»: (200.00,0.00)\n"
     ]
    }
   ],
   "source": [
    "artist.reset()\n",
    "\n",
    "artist.forward(120)\n",
    "# ошибка: забыли повернуть здесь\n",
    "artist.forward(80)\n",
    "\n",
    "print(\"Курс (не изменился!):\", artist.heading())\n",
    "print(\"Черепашка проехала прямо, а не буквой «Г»:\", artist.position())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "81709aae",
   "metadata": {},
   "source": [
    "## Исправление\n",
    "\n",
    "Добавляем пропущенный поворот между двумя движениями:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "5cec8f52",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-14T20:52:23.410413Z",
     "iopub.status.busy": "2026-08-14T20:52:23.410295Z",
     "iopub.status.idle": "2026-08-14T20:52:23.744348Z",
     "shell.execute_reply": "2026-08-14T20:52:23.743809Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Курс после исправления: 90.0\n",
      "Позиция: (120.00,80.00)\n"
     ]
    }
   ],
   "source": [
    "artist.reset()\n",
    "\n",
    "artist.forward(120)\n",
    "artist.left(90)   # добавили поворот\n",
    "artist.forward(80)\n",
    "\n",
    "print(\"Курс после исправления:\", artist.heading())\n",
    "print(\"Позиция:\", artist.position())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "15440492",
   "metadata": {},
   "source": [
    "## Самостоятельная практика\n",
    "\n",
    "Нарисуйте лестницу из трёх одинаковых «ступенек» (вперёд-поворот-вперёд-поворот,\n",
    "повторить трижды). Пока не изучены циклы (глава 10), просто повторите нужный блок\n",
    "команд вручную три раза подряд."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "16bbaf7f",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-14T20:52:23.745342Z",
     "iopub.status.busy": "2026-08-14T20:52:23.745226Z",
     "iopub.status.idle": "2026-08-14T20:52:24.101664Z",
     "shell.execute_reply": "2026-08-14T20:52:24.101159Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Позиция после одной ступеньки: (40.00,40.00)\n"
     ]
    }
   ],
   "source": [
    "artist.reset()\n",
    "\n",
    "# одна ступенька — допишите ещё две по тому же образцу\n",
    "artist.forward(40)\n",
    "artist.left(90)\n",
    "artist.forward(40)\n",
    "artist.right(90)\n",
    "\n",
    "print(\"Позиция после одной ступеньки:\", artist.position())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "22fbc318",
   "metadata": {},
   "source": [
    "## Дополнительная задача ★★★\n",
    "\n",
    "Нарисуйте пятиконечную звезду одной линией, используя только `forward` и один и тот\n",
    "же угол поворота между всеми пятью движениями. Подсказка: сумма внешних углов\n",
    "многоугольника всегда равна 360° — для пятиконечной звезды этот угол равен 144°."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "dba437f9",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-14T20:52:24.102596Z",
     "iopub.status.busy": "2026-08-14T20:52:24.102486Z",
     "iopub.status.idle": "2026-08-14T20:52:25.738185Z",
     "shell.execute_reply": "2026-08-14T20:52:25.737784Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Звезда нарисована. Финальная позиция: (-0.00,-0.00)\n"
     ]
    }
   ],
   "source": [
    "artist.reset()\n",
    "\n",
    "for _ in range(5):\n",
    "    artist.forward(150)\n",
    "    artist.right(144)\n",
    "\n",
    "print(\"Звезда нарисована. Финальная позиция:\", artist.position())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fd90d269",
   "metadata": {},
   "source": [
    "## Завершение (выполнить один раз, в самом конце)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "de57dcdb",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-14T20:52:25.739454Z",
     "iopub.status.busy": "2026-08-14T20:52:25.739287Z",
     "iopub.status.idle": "2026-08-14T20:52:25.743120Z",
     "shell.execute_reply": "2026-08-14T20:52:25.742430Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Окно Turtle закрыто.\n"
     ]
    }
   ],
   "source": [
    "screen.bye()\n",
    "print(\"Окно Turtle закрыто.\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Cartesian Python 3.14",
   "language": "python",
   "name": "cartesian-python314"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.14.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
