{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<table align=right>\n",
    "    <tr>\n",
    "        <td align=center>\n",
    "            <font size=4>Технология программирования и практикум на ЭВМ</font> \n",
    "        </td>\n",
    "        <td align=right>\n",
    "<img src=\"logoMM.png\" align=right width=120>\n",
    "        </td>\n",
    "    </tr>\n",
    "    </table>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true
   },
   "source": [
    "## Повторяем пройденное"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Задание 1. Написать программу, решающую уравнение вида\n",
    "$$ax^2 + bx + c = 0$$\n",
    "для любых значений коэффициентов $a$, $b$, $c$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = float(input('a = '))\n",
    "b = float(input('b = '))\n",
    "c = float(input('c = '))\n",
    "\n",
    "if a!=0:      # квадратное уравнение\n",
    "    d = b**2 - 4*a*c    \n",
    "    if d > 0:\n",
    "        x1 = (-b + d**0.5)/(2*a)\n",
    "        x2 = (-b - d**0.5)/(2*a)\n",
    "        print(f'{x1 = } { x2= }')\n",
    "    elif d == 0:\n",
    "        x = -b/(2*a)\n",
    "        print(f'{x = }')\n",
    "    else:\n",
    "        print('Нет решений')    \n",
    "elif b!=0:    # линейное уравнение        \n",
    "    x = -c/b\n",
    "    print(f'{x = }')\n",
    "elif c!=0:    # неверное равенство c=0   \n",
    "    print('Нет решений')\n",
    "else:         # тождество 0=0           \n",
    "    print('x - любое число')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"helix.png\" align=right width=300>\n",
    "\n",
    "# Циклы\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Цикл `while`\n",
    "\n",
    "Вспомним вот эту задачу \n",
    "\n",
    "---\n",
    "**Integer8**. Дано двузначное число. Вывести число, полученное при перестановке цифр исходного числа.\n",
    "\n",
    "---\n",
    "и ее решение\n",
    "```python\n",
    "n = int(input(\"двузначное число: \"))\n",
    "e = n%10\n",
    "d = n//10\n",
    "print(10*e + d)\n",
    "```\n",
    "\n",
    "Немного подумав и удлинив код, можно записать решение и для трехзначных чисел. И даже для четырехзначных. А для 150-значных? 😱🤷‍♂️\n",
    "\n",
    "На помощь приходят **циклы**. Они дают возможность выполнить одну и ту же последовательность действий много раз. \n",
    "\n",
    "Как много? Столько, столько требуется (если, конечно, программа написана правильно). \n",
    "\n",
    "---\n",
    "\n",
    "Цикл while (\"***пока***\") позволяет выполнять последовательность одинаковых действий, пока проверяемое условие истинно.\n",
    "\n",
    "Чуть позже решим задачу типа **Integer8** для числа с любым количеством десятичных цифр. А пока еще картинка и задачи попроще.\n",
    "\n",
    "<img src=\"while_scheme.png\" align=right width=300>\n",
    "\n",
    "Синтаксис цикла `while` в простейшем случае выглядит так: \n",
    "```python\n",
    "# предыдущий код\n",
    "while условие:\n",
    "    действие 1\n",
    "    действие 1\n",
    "    ...\n",
    "    действие N\n",
    "# код после цикла    \n",
    "```\n",
    "При выполнении цикла `while` сначала проверяется истинность или ложность условия. Если условие истинно, то выполняется цепочка действий (*тело цикла* или одна *итерация*), после чего условие проверяется снова и снова выполняется эта цепочка. Так продолжается до тех пор, пока условие будет истинно. Как только условие станет ложно, работа цикла завершится и управление передастся следующей инструкции после цикла. \n",
    "\n",
    "Если условие ложно в самом начале, то цикл не начинается, управление сразу передается на следующую команду после тела цикла `while`. \n",
    "\n",
    "---\n",
    "\n",
    "В качестве примера рассмотрим задачу:  \n",
    "Дано натуральное число $m$. Вычислить $m^2$, не используя символ `*`. \n",
    "\n",
    "Умножения придется заменить сложением:\n",
    "$$ m^2 = \\underbrace{m + m + \\ldots + m}_{m \\ слагаемых}$$\n",
    "\n",
    "На каждом шаге цикла нужно увеличивать сумму, а также уменьшать оставшееся количество итераций."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "m:  8\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "m^2 = 64\n"
     ]
    }
   ],
   "source": [
    "m = int(input(\"m: \"))\n",
    "iters_left = m      # количество оставшихся итераций\n",
    "answer = 0          # переменная для накопления суммы\n",
    "while iters_left>0:\n",
    "    answer += m\n",
    "    iters_left -= 1\n",
    "print(f'm^2 = {answer}')    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Устные упражнения:  определите результат работы программы"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n",
      "Вне цикла\n",
      "6\n"
     ]
    }
   ],
   "source": [
    "# Пример 1. Что выведет программа?\n",
    "\n",
    "num = 0\n",
    "while num <= 5:\n",
    "    print (num)\n",
    "    num += 1\n",
    "\n",
    "print (\"Вне цикла\")\n",
    "print (num)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "ename": "KeyboardInterrupt",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mKeyboardInterrupt\u001b[0m                         Traceback (most recent call last)",
      "Cell \u001b[1;32mIn[3], line 6\u001b[0m\n\u001b[0;32m      4\u001b[0m number_of_apples \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m2\u001b[39m\n\u001b[0;32m      5\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m number_of_loops \u001b[38;5;241m<\u001b[39m \u001b[38;5;241m10\u001b[39m:\n\u001b[1;32m----> 6\u001b[0m     \u001b[43mnumber_of_apples\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m2\u001b[39;49m\n\u001b[0;32m      7\u001b[0m     number_of_apples \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m number_of_loops\n\u001b[0;32m      8\u001b[0m     number_of_loops \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1\u001b[39m\n",
      "\u001b[1;31mKeyboardInterrupt\u001b[0m: "
     ]
    }
   ],
   "source": [
    "# Пример 2. Что выведет программа?\n",
    "\n",
    "number_of_loops = 0\n",
    "number_of_apples = 2\n",
    "while number_of_loops < 10:\n",
    "    number_of_apples *= 2\n",
    "    number_of_apples += number_of_loops\n",
    "    number_of_loops -= 1\n",
    "print (\"Количество яблок: \", number_of_apples)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-862897"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "number_of_loops"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "9\n",
      "8\n",
      "7\n",
      "6\n",
      "5\n",
      "4\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "# Пример 3. Что выведет программа?\n",
    "\n",
    "num = 10\n",
    "while num > 3:\n",
    "    num -= 1\n",
    "    print (num) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "В языке Питон, как и во многих других языках, есть специальная команда, позволяющая прервать выполнение итераций цикла и сразу перейти к командам, расположенным после тела цикла. Это команда `break`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10\n",
      "9\n",
      "8\n",
      "7\n",
      "Прерываем цикл\n",
      "После цикла\n"
     ]
    }
   ],
   "source": [
    "# Пример 4. Что выведет программа?\n",
    "\n",
    "num = 10\n",
    "while True:\n",
    "    if num < 7:\n",
    "        print ('Прерываем цикл')\n",
    "        break\n",
    "    print (num)\n",
    "    num -= 1\n",
    "print ('После цикла')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Пример 5. Что выведет программа?\n",
    "\n",
    "num = 100\n",
    "while not False:\n",
    "    if num < 0:\n",
    "        break\n",
    "print ('num is:', num)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Порешаем задачи\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**While4**. Дано целое число $n$ (> 0). Если оно является степенью числа 3, то вывести `True`, если не является — вывести `False`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "целое число:  51537752073201133103646112976562127270210752200199\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "# Решение\n",
    "n = int(input(\"целое число: \"))\n",
    "m = n\n",
    "# вариант 1\n",
    "while n%3 == 0:\n",
    "    n //= 3\n",
    "print(n==1)\n",
    "\n",
    "# вариант 2\n",
    "p = 1\n",
    "while p<m:\n",
    "    p *= 3\n",
    "print(p==m)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "515377520732011331036461129765621272702107522001"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "3**100 "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Integer8** (усложненный вариант). Дано натуральное число. Вывести число, полученное при перестановке цифр исходного числа в обратном порядке.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "натуральное число:  564\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "465\n"
     ]
    }
   ],
   "source": [
    "# Решение\n",
    "n = int(input(\"натуральное число: \"))\n",
    "s = 0\n",
    "while n>0:\n",
    "    s = s*10 + n%10\n",
    "    n //= 10\n",
    "print(s)    \n",
    "   \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**While22**. Дано целое число $n$ (> 1). Если оно является простым, т. е. не имеет положительных делителей, кроме 1 и самого себя, то вывести `True`, иначе вывести `False`. \n",
    "\n",
    "*Работу программы можно проверить на числах 9973, 9999901 и 2147483647, которые являются простыми*."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "натуральное число:  9999901\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n"
     ]
    }
   ],
   "source": [
    "# Решение 1\n",
    "n = int(input(\"натуральное число: \"))\n",
    "k = 2\n",
    "while n%k != 0:\n",
    "    k += 1\n",
    "print(k==n)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "натуральное число:  2147483647\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n"
     ]
    }
   ],
   "source": [
    "# Решение 2\n",
    "n = int(input(\"натуральное число: \"))\n",
    "k = 2\n",
    "root = int(n**0.5) + 1\n",
    "while n%k!=0 and k<root:\n",
    "    k += 1\n",
    "print(k==root)    \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**While24**. Дано целое число $n$ (> 1). Последовательность чисел Фибоначчи $F_k$ определяется следующим образом: \n",
    "$$\n",
    "F_1 = 1, \\  F_2 = 1,  F_k = F_{k-2} + F_{k−1},  \\  k = 3, 4, \\ldots.\n",
    "$$\n",
    "Проверить, является ли число $n$ числом Фибоначчи. Если является, то вывести `True`, если нет — вывести `False`. \n",
    "\n",
    "*Например, 17711 -  число Фибоначчи*\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "натуральное число:  17712\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n"
     ]
    }
   ],
   "source": [
    "# Решение\n",
    "n = int(input(\"натуральное число: \"))\n",
    "a, b = 1, 1\n",
    "while b < n:\n",
    "    a, b = b, a+b\n",
    "print(b==n)  \n",
    "   \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"color:blue;\">\n",
    "\n",
    "***Для самостоятельного чтения***\n",
    "\n",
    "«**Стандартное отклонение**» (pythontutor.ru)   \n",
    "Дана последовательность натуральных чисел $x_1$, $x_2$, ..., $x_n$. *Стандартным отклонением* называется величина\n",
    "$$\n",
    "\\sigma =\\sqrt{\\frac{(x_1-s)^2+(x_2-s)^2+\\ldots+(x_n-s)^2}{n-1}}\n",
    "$$\n",
    "где $s=\\frac{x_1+x_2+…+x_n}{n}$ — среднее арифметическое последовательности.\n",
    "\n",
    "Определите стандартное отклонение для данной последовательности натуральных чисел, завершающейся числом 0.\n",
    "\n",
    "\n",
    "\n",
    "---\n",
    "\n",
    "**Комментарий к решению**.  \n",
    "На первый взгляд, задачу нельзя решить, не сохраняя все значения переменных $x_k$, потому что для вычисления, например, $(x_1-s)$ нужно знать $s$, то есть сначала нужно ввести все числа, а потом вернуться к $x_1$.\n",
    "\n",
    "Решить задачу помогает школьная алгебра и знание формулы \n",
    "$$(a-b)^2 = a^2-2ab+b^2.$$\n",
    "Действительно,\n",
    "$$\n",
    "(x_1-s)^2+(x_2-s)^2+\\ldots+(x_n-s)^2 = \n",
    "$$\n",
    "$$\n",
    "=x_1^2-2x_1s+s^2 + x_2^2-2x_2s+s^2 +\\ldots x_n^2-2x_ns+s^2=\n",
    "$$\n",
    "$$\n",
    "= \\sum_{i=1}^n{x_i^2} - 2\\sum_{i=1}^n{x_i}s+ns^2 = \n",
    "$$\n",
    "$$\n",
    "= \\sum_{i=1}^n{x_i^2} - \\frac{2}{n}\\left(\\sum_{i=1}^n{x_i}\\right)^2 + \n",
    "\\frac{1}{n}\\left(\\sum_{i=1}^n{x_i}\\right)^2 = \n",
    "$$\n",
    "$$\n",
    "= \\sum_{i=1}^n{x_i^2} - \\frac{1}{n}\\left(\\sum_{i=1}^n{x_i}\\right)^2.\n",
    "$$\n",
    "\n",
    "Таким образом, в процессе ввода необходимо накапливать значение суммы вводимых чисел и суммы их квадратов."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# Решение\n",
    "summ = 0\n",
    "summ2 = 0\n",
    "n = 0\n",
    "x = int(input('x: '))\n",
    "while x != 0:\n",
    "    summ += x\n",
    "    summ2 += x**2\n",
    "    n += 1\n",
    "    x = int(input('x: '))\n",
    "sigma = ((summ2-summ**2/n)/(n-1))**0.5\n",
    "print(sigma)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Цикл `for`\n",
    "\n",
    "Цикл `for`, также называемый циклом с параметром, позволяет выполнить заранее известное количество итераций. Параметр цикла, или *счетчик*, $-$ это переменная, указываемая в цикле `for`. В нем также задается множество (диапазон) значений, по которому будет пробегать эта переменная. \n",
    "```python\n",
    "# ... какой-то код до цикла\n",
    "for параметр_цикла in множество_значений:\n",
    "    действие 1\n",
    "    действие 2\n",
    "    ...\n",
    "    действие N\n",
    "# ... код после цикла  \n",
    "```\n",
    "    \n",
    "Множество значений может быть задано, например, списком, строкой или диапазоном. Начнем с последнего $-$ очень распространенного и полезного объекта `range()`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 3 4 5 6 7 8 9 "
     ]
    }
   ],
   "source": [
    "# меняйте параметры функции range, \n",
    "#         чтобы лучше понять, как она работает\n",
    "for i in  range(1,10): # [1, 10)\n",
    "    print(i, end=' ')    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 2 3 4 5 6 7 8 9 "
     ]
    }
   ],
   "source": [
    "for i in range(0,10):\n",
    "    print(i, end=' ')    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "9"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "i"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 2 3 4 5 6 7 8 9 "
     ]
    }
   ],
   "source": [
    "for i in range(10):\n",
    "    print(i, end=' ')    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 2 4 6 8 "
     ]
    }
   ],
   "source": [
    "for i in range(0,10,2):\n",
    "    print(i, end=' ')    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(0,10,-1):\n",
    "    print(i)    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10 9 8 7 6 5 4 3 2 1 "
     ]
    }
   ],
   "source": [
    "for i in range(10,0,-1): #[10, 0)\n",
    "    print(i, end=' ')    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "range(0, 10)"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "range(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# range умеет проверять\n",
    "1500 in range(1000)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Примеры других вариантов задания множества значений параметра цикла."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Цвета российского флага:\n",
      "Цвет 1 - белый\n",
      "Цвет 2 - синий\n",
      "Цвет 3 - красный\n"
     ]
    }
   ],
   "source": [
    "# \"перечисление\" (список или кортеж)\n",
    "print('Цвета российского флага:')\n",
    "i = 1\n",
    "for color in 'белый', 'синий', 'красный':\n",
    "    print(f'Цвет {i} - {color}')\n",
    "    i += 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1-й цвет радуги - это красный\n",
      "2-й цвет радуги - это оранжевый\n",
      "3-й цвет радуги - это желтый\n",
      "4-й цвет радуги - это зеленый\n",
      "5-й цвет радуги - это голубой\n",
      "6-й цвет радуги - это синий\n",
      "7-й цвет радуги - это фиолетовый\n"
     ]
    }
   ],
   "source": [
    "# В этом примере ниже cимвол \"\\\" позволил разорвать\n",
    "# слишком длинную строку (для удобства чтения)\n",
    "# После этого символа в строке не должно быть ничего, \n",
    "#       даже пробела\n",
    "\n",
    "i = 1\n",
    "for цвет in 'красный','оранжевый',  \\\n",
    "            'желтый', 'зеленый', 'голубой', \\\n",
    "            'синий', 'фиолетовый':\n",
    "    print(f'{i}-й цвет радуги - это {цвет}')\n",
    "    i += 1\n",
    "\n",
    "# И да, Python разрешает русские имена переменных.\n",
    "# Но не стоит этим злоупотреблять!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Название 1-го цвета радуги начинается с буквы К\n",
      "Название 2-го цвета радуги начинается с буквы О\n",
      "Название 3-го цвета радуги начинается с буквы Ж\n",
      "Название 4-го цвета радуги начинается с буквы З\n",
      "Название 5-го цвета радуги начинается с буквы Г\n",
      "Название 6-го цвета радуги начинается с буквы С\n",
      "Название 7-го цвета радуги начинается с буквы Ф\n"
     ]
    }
   ],
   "source": [
    "# Цикл по символам строки\n",
    "i = 1\n",
    "for letter in 'КОЖЗГСФ':\n",
    "    print(f'Название {i}-го цвета радуги начинается с буквы', \n",
    "          letter)\n",
    "    i += 1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Решаем задачи"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Давно обещанное**. С использованием модуля `time` выясните, наконец, какой из двух вариантов обмена значений двух переменных работает быстрее:\n",
    "```python\n",
    "c = a\n",
    "a = b\n",
    "b = c\n",
    "```\n",
    "или\n",
    "```python\n",
    "a, b = b, a\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.9297525882720947\n",
      "0.7110157012939453\n"
     ]
    }
   ],
   "source": [
    "from time import time\n",
    "n = 10**7\n",
    "a = 10.4\n",
    "b = 20\n",
    "# 1 способ\n",
    "start = time()\n",
    "for i in range(n):\n",
    "    c = a\n",
    "    a = b\n",
    "    b = c\n",
    "finish = time()\n",
    "print(finish-start)\n",
    "\n",
    "# 2 cпособ\n",
    "start = time()\n",
    "for i in range(n):\n",
    "    a, b = b, a\n",
    "finish = time()\n",
    "print(finish-start)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**For7**. Даны два целых числа $a$ и $b$ ($a < b$). Найти сумму всех целых чисел от $a$ до $b$ включительно."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "введите целое число a  5\n",
      "введите целое число b  10\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "45\n",
      "45\n"
     ]
    }
   ],
   "source": [
    "a = int(input(\"введите целое число a \"))\n",
    "b = int(input(\"введите целое число b \"))\n",
    "# Решение с использованием цикла\n",
    "s = 0\n",
    "for i in range(a, b+1):  \n",
    "    s += i\n",
    "print(s)    \n",
    "\n",
    "# Эффективное решение\n",
    "print(sum(range(a, b+1)))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "49999995000000 0.7131147384643555\n",
      "49999995000000 0.08888554573059082\n"
     ]
    }
   ],
   "source": [
    "# сравнение\n",
    "from time import time\n",
    "n = 10**7\n",
    "start = time()\n",
    "s = 0\n",
    "for x in range(n):\n",
    "    s += x\n",
    "finish = time()\n",
    "print(s, finish-start)\n",
    "\n",
    "# Эффективное решение\n",
    "start = time()\n",
    "s = sum(range(n))\n",
    "finish = time()\n",
    "print(s, finish-start)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "❓❓❓ Почему при решении задачи «**Стандартное отклонение**» не пользовались функцией `sum` ?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**For19**. Дано целое число $n$ (> 0). Найти произведение\n",
    "$$ n! = 1·2·…·n\n",
    "$$\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "введите целое n(>0):  6\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "720\n"
     ]
    }
   ],
   "source": [
    "# Решение\n",
    "n = int(input(\"введите целое n(>0): \"))\n",
    "p = 1\n",
    "for i in range(1, n+1):\n",
    "    p *= i\n",
    "print(p)    \n",
    "   \n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "720\n",
      "720\n"
     ]
    }
   ],
   "source": [
    "import math\n",
    "print(math.prod(range(1,n+1)))\n",
    "\n",
    "print(math.factorial(n))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**For17**. Дано вещественное число $x$ и целое число $n$ (> 0). Используя один цикл (и не используя операцию возведения в степень), найти сумму \n",
    "$$\n",
    "1 + x + x^2 + x^3 + … + x^n.\n",
    "$$\n",
    "\n",
    "<font color='#0000FF'>\n",
    "    \n",
    "**дополнительно**: а почему в этой задаче действительно  важно не использовать возведение в степень?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "x:  0.1345\n",
      "введите целое n(>0):  20\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.1554015020219528\n",
      "1.1554015020219528\n"
     ]
    }
   ],
   "source": [
    "# Решение\n",
    "x = float(input('x: '))\n",
    "n = int(input(\"введите целое n(>0): \"))\n",
    "s = 1\n",
    "p = 1\n",
    "for i in range(1, n+1):\n",
    "    p *= x\n",
    "    s += p\n",
    "print(s)\n",
    "\n",
    "# неэффективное короткое решение\n",
    "t = 1\n",
    "for i in range(1, n+1):\n",
    "    t += x**i\n",
    "print(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.0"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "0.9**10000\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**For24**. Дано вещественное число $x$ и целое число $n$ (> 0). Найти значение выражения \n",
    "$$\n",
    "1 − \\frac{x^2}{2!} + \\frac{x^4}{4!} − … + (−1)^n\\frac{x^{2n}}{(2n)!}\n",
    "$$\n",
    "Полученное число является приближенным значением функции $\\cos$ в точке $x$. \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "введите x:  100\n",
      "введите целое n(>0):  10000\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "s = -1.0389369201271959e+26\n",
      "cos(100.0) = 0.8623188722876839\n"
     ]
    }
   ],
   "source": [
    "# Решение\n",
    "x = float(input(\"введите x: \"))\n",
    "n = int(input(\"введите целое n(>0): \"))\n",
    "s = 0\n",
    "p = 1\n",
    "d = 1\n",
    "for i in range(n+1):\n",
    "    p *= d\n",
    "    s += p\n",
    "    d = -x*x/(2*i+1)/(2*i+2)    \n",
    "print(f'{s = }')\n",
    "from math import cos\n",
    "print(f'cos({x}) = {cos(x)}')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**For39**. Даны целые положительные числа $m$ и $n$ ($m<n$). Вывести все целые числа от $m$ до $n$ включительно; при этом каждое число должно выводиться столько раз, каково его значение (например, число 3 выводится 3 раза)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "введите целое m(>0):  1\n",
      "введите целое n(>0):  9\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 \n",
      "2 2 \n",
      "3 3 3 \n",
      "4 4 4 4 \n",
      "5 5 5 5 5 \n",
      "6 6 6 6 6 6 \n",
      "7 7 7 7 7 7 7 \n",
      "8 8 8 8 8 8 8 8 \n",
      "9 9 9 9 9 9 9 9 9 \n"
     ]
    }
   ],
   "source": [
    "# Решение\n",
    "m = int(input(\"введите целое m(>0): \"))\n",
    "n = int(input(\"введите целое n(>0): \"))\n",
    "for i in range(m, n+1):\n",
    "    for _ in range(i):\n",
    "        print(i, end = ' ')\n",
    "    print()    \n",
    "  \n",
    "   \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Minmax2**. Дано целое число $n$ и набор из $n$ прямоугольников, заданных своими сторонами — парами чисел $(a, b)$. Найти минимальную площадь прямоугольника из данного набора."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "введите целое n(>0):  4\n",
      " 1\n",
      " 2\n",
      " 4\n",
      " 6\n",
      " 1\n",
      " 1\n",
      " 7\n",
      " 9\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.0\n"
     ]
    }
   ],
   "source": [
    "# Решение\n",
    "n = int(input(\"введите целое n(>0): \"))\n",
    "min_s = float('inf')\n",
    "for _ in range(n):\n",
    "    a = float(input())\n",
    "    b = float(input())\n",
    "    s = a * b\n",
    "    if min_s>s:\n",
    "        min_s = s\n",
    "print(min_s)        \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Minmax6**. Дано целое число $n$ и набор из $n$ целых чисел. Найти номера первого минимального и последнего максимального элемента из данного набора и вывести их в указанном порядке."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "введите целое n(>0):  7\n",
      " 1\n",
      " 2\n",
      " 3\n",
      " 1\n",
      " 3\n",
      " 1\n",
      " 2\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 5\n"
     ]
    }
   ],
   "source": [
    "# Решение\n",
    "n = int(input(\"введите целое n(>0): \"))\n",
    "min_n = 1\n",
    "max_n = 1\n",
    "min_first = max_last = int(input())\n",
    "for i in range(2, n+1):\n",
    "    a = int(input())\n",
    "    if a<min_first:\n",
    "        min_first = a\n",
    "        min_n = i\n",
    "    elif a>=max_last:\n",
    "        max_last = a\n",
    "        max_n = i\n",
    "print(min_n, max_n)        \n",
    "       \n",
    "# 1 2 3 1 3 1 2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Задачи с сайта pythontutor.ru"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Лесенка**. По данному натуральному $n\\leq9$ выведите лесенку из $n$ ступенек, $i$-я ступенька состоит из чисел от 1 до $i$ без пробелов. Например, при $n=5$ должно получиться\n",
    "```\n",
    "1\n",
    "12\n",
    "123\n",
    "1234\n",
    "12345\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "введите n(<=9):  7\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "12\n",
      "123\n",
      "1234\n",
      "12345\n",
      "123456\n",
      "1234567\n"
     ]
    }
   ],
   "source": [
    "# Решение\n",
    "n = int(input(\"введите n(<=9): \"))\n",
    "for i in range(1, n+1):\n",
    "    for j in range(1, i+1):\n",
    "        print(j, end='')\n",
    "    print()   \n",
    "        "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Карточка**. Для настольной игры используются карточки с номерами от 1 до $n$. Одна карточка потерялась. Найдите ее, зная номера оставшихся карточек.\n",
    "\n",
    "Дано число $n$, далее $n-1$ номер оставшихся карточек (различные числа от 1 до $n$). Программа должна вывести номер потерянной карточки."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "введите натуральное n:  6\n",
      "a =  6\n",
      "a =  2\n",
      "a =  5\n",
      "a =  1\n",
      "a =  3\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "потерялась 4\n"
     ]
    }
   ],
   "source": [
    "# Решение\n",
    "n = int(input(\"введите натуральное n: \"))\n",
    "s = (1+n)*n//2\n",
    "for _ in range(n-1):\n",
    "    a = int(input(\"a = \"))\n",
    "    s -= a\n",
    "print(\"потерялась\", s)    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Второй максимум**. Последовательность состоит из различных натуральных чисел и завершается числом 0. Определите значение второго по величине элемента в этой последовательности. Гарантируется, что в последовательности есть хотя бы два элемента."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "a= 6\n",
      "a= 2\n",
      "a= 5\n",
      "a= 1\n",
      "a= 3\n",
      "a= 0\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5\n"
     ]
    }
   ],
   "source": [
    "max1 = max2 = 0\n",
    "while True:\n",
    "    a = int(input(\"a=\"))\n",
    "    if a==0:\n",
    "        break\n",
    "    elif a>max1:\n",
    "        max2, max1 = max1, a\n",
    "    elif a>max2:\n",
    "        max2 = a\n",
    "print(max2)        \n",
    "        \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Готовимся к контрольной \n",
    "\n",
    "**Финальная задача демонстрационного варианта контрольной работы**\n",
    "\n",
    "Назовем положительное число $n$ *квадратно-четным*, если все цифры его \n",
    "квадрата $–$ четные. Среди однозначных таких чисел два (2 и 8), примером \n",
    "двухзначных могут служить числа 20 и 68 (202 = 400, 682 = 4624), 498 $–$ это \n",
    "пример трехзначного квадратно-четного числа (4982 = 248004). \n",
    "Разработайте программу, которая для заданного натурального числа $m$ \n",
    "($m<8$) определяет, сколько существует $m$-значных квадратно-четных чисел. \n",
    "Примерная схема взаимодействия программы с пользователем: \n",
    "\n",
    "\n",
    "|Введенное число|Сообщение программы|\n",
    "|:-------------:|:------------------|\n",
    "| m = -1 | Введенное Вами число должны быть положительно. Учтите это при следующем запуске программы   |\n",
    "| m = 10 | Ваше число больше семи. Программа может работать слишком долго. В следующий раз введите число поменьше   |\n",
    "| m = 2  | Кол-во 2-значных квадратно-четных чисел = 6     |\n",
    "| m = 3  | Кол-во 3-значных квадратно-четных чисел = 18    |\n",
    "| m = 7  | Кол-во 7-значных квадратно-четных чисел = 850   |\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "m: 7\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "таких чисел 850\n"
     ]
    }
   ],
   "source": [
    "# Решение\n",
    "m = int(input('m:'))\n",
    "if m<=0:\n",
    "    print('Введенное Вами число должны быть положительно. Учтите это при следующем запуске программы')\n",
    "elif m>7:    \n",
    "    print('Ваше число больше семи. Программа может работать слишком долго. В следующий раз введите число поменьше')\n",
    "else:\n",
    "    k = 0\n",
    "    for i in range(10**(m-1), 10**m):\n",
    "        i2 = i*i\n",
    "        ok = True\n",
    "        while i2>0:\n",
    "            c = i2%10\n",
    "            i2 //= 10\n",
    "            if c%2!=0:\n",
    "                ok = False\n",
    "                break\n",
    "        if ok:\n",
    "            k += 1\n",
    "    print('таких чисел', k)        \n",
    "            \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true
   },
   "source": [
    "---\n",
    "\n",
    "### Первое знакомство с методом половинного деления. Он же метод бинарного поиска. Или дихотомии. \n",
    "\n",
    "Дано вещественное число $z$. Найдите кубический корень из этого числа с заданной точностью $\\varepsilon$.\n",
    "\n",
    "*Найти с заданной точностью* означает \"найти такое число $x$, что $|x-\\sqrt[3]{z}|<\\varepsilon$\"."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3.14159265358862\n"
     ]
    }
   ],
   "source": [
    "p = 1\n",
    "z = 0\n",
    "for i in range(20):\n",
    "    z = (2+z)**0.5\n",
    "    p *= 2/z\n",
    "print(2*p)    \n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Сначала рассмотрим вспомогательную задачу:  \\\n",
    "*Дано натуральное число $N$. Проверьте, является ли это число кубом*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "N = int(input('Введите натуральное число: '))\n",
    "ans = 0\n",
    "while ans**3 < N:\n",
    "    ans += 1\n",
    "if ans**3 == N:\n",
    "    print('кубический корень равен',ans)\n",
    "else:\n",
    "    print('число не является точным кубом')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Для вычисления кубического корня из вещественного числа можно использовать эту же идею.\n",
    "Только прибавлять нужно не единицу, а $\\varepsilon$. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "z = float(input(\"z (>0): \"))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "2**(1/3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "К сожалению, эта программа работает очень медленно: если $\\varepsilon=10^{-12}$, то результата можем не дождаться (впрочем, желающие могут попробовать)\n",
    "\n",
    "**Идея:** кубический корень из положительного числа $z$ точно находится на отрезке \\[0, max(1,z)\\]. \n",
    "\n",
    "Сначала возьмем середину этого отрезка и обозначим ее через $c$. Корень слева от $c$, если $c^3>z$, или справа, если $c^3<z$. Выберем ту половину, где корень, и найдем ее середину. Повторяем процесс, пока очередная половинка не станет меньше, чем $\\varepsilon$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Решение\n",
    "z = float(input('z='))\n",
    "     \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Подумать:\n",
    "\n",
    "- что произойдет, если `с**3` окажется точно равным `z`?\n",
    "- Как исправить программу, чтобы корень извлекался и из положительных, и из отрицательных чисел?\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "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.11.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
