{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e69d30e2",
   "metadata": {},
   "source": [
    "# Лабораторная работа 5\n",
    "\n",
    "## Функции и цикл `while`\n",
    "\n",
    "Во всех задачах с функциями сначала опишите функцию, а затем вызовите её ниже в основной программе.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "532ed0b9",
   "metadata": {},
   "source": [
    "### Проверка функций\n",
    "\n",
    "Для целых чисел и строк можно использовать `assert result == expected`. Для булевых значений достаточно написать `assert result`, если функция возвращает `true` и `assert not result`, если возвращает `false`. Для вещественных чисел обычно достаточно `isclose` с относительной погрешностью `rel_tol`. Если ожидаемое значение равно нулю или очень близко к нему, добавляют и абсолютную погрешность `abs_tol`.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fa1de9a8",
   "metadata": {},
   "source": [
    "**Задача 1. Функция без `return`**\n",
    "\n",
    "Опишите функцию `show_sign(number)`, которая выводит строку `положительное`, `отрицательное` или `нулевое`. Функция ничего не должна возвращать.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4ddc90da",
   "metadata": {},
   "outputs": [],
   "source": [
    "def show_sign(number):\n",
    "    ...\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bcc6873b-cf9a-4536-b97b-7975249525d7",
   "metadata": {},
   "source": [
    "**Вопрос**: можно ли такую функцию поместить в `print`?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c53c77ad-0344-4c47-ac54-ba614c8d2864",
   "metadata": {},
   "source": [
    "**Ответ**: ..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e961042f",
   "metadata": {},
   "source": [
    "**Задача 2. Функция со строковым результатом**\n",
    "\n",
    "Опишите функцию `sign_description(number)`, которая возвращает строку `положительное`, `отрицательное` или `нулевое`. Выведите результат её работы.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3b6f5584",
   "metadata": {},
   "outputs": [],
   "source": [
    "def sign_description(number):\n",
    "    ...\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bf4dbc73",
   "metadata": {},
   "source": [
    "**Задача 3. Количество корней**\n",
    "\n",
    "Опишите функцию `root_count(a, b, c)`, возвращающую количество корней квадратного уравнения $a \\cdot x^2 + b \\cdot x + c = 0$, где $a \\neq 0$.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e7728021",
   "metadata": {},
   "outputs": [],
   "source": [
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c17bce00",
   "metadata": {},
   "source": [
    "*Пример проверки.* Запустите ячейку с функцией, затем эту ячейку. Допишите еще несколько тестов.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "a6601d5c",
   "metadata": {},
   "outputs": [],
   "source": [
    "assert root_count(1, 0, -4) == 2\n",
    "assert root_count(1, 2, 1) == 1\n",
    "assert root_count(1, 0, 1) == 0\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "45dd15cd",
   "metadata": {},
   "source": [
    "**Задача 4. Площадь круга**\n",
    "\n",
    "Опишите функцию `circle_area(radius)`, возвращающую площадь круга. Внутри функции используйте локальную переменную $\\pi = 3.14$.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e1e5e316",
   "metadata": {},
   "outputs": [],
   "source": [
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3cb4887a",
   "metadata": {},
   "source": [
    "*Пример проверки.* Запустите ячейку с функцией, затем эту ячейку. Допишите еще несколько тестов.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "bd54a119",
   "metadata": {},
   "outputs": [],
   "source": [
    "from math import isclose\n",
    "\n",
    "assert isclose(circle_area(2), 12.56, rel_tol = 1e-9)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d1d8eb8b",
   "metadata": {},
   "source": [
    "**Задача 5. Периметр равнобедренного треугольника**\n",
    "\n",
    "Опишите функцию `triangle_perimeter(base, height)`, возвращающую периметр равнобедренного треугольника по основанию и высоте, проведённой к основанию.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "33df47db",
   "metadata": {},
   "outputs": [],
   "source": [
    "from math import sqrt\n",
    "\n",
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3719ff07",
   "metadata": {},
   "source": [
    "**Задача 6. Цена с параметрами по умолчанию**\n",
    "\n",
    "Опишите функцию `format_price(price, digits=2, currency='руб.')`, возвращающую строку с ценой, округлённой до `digits` знаков после запятой. Вызовите её обычным способом и с именованными аргументами.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "41c6ef39",
   "metadata": {},
   "outputs": [],
   "source": [
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "70476881",
   "metadata": {},
   "source": [
    "**Задача 7. Время в секундах**\n",
    "\n",
    "Опишите функцию `time_to_hms(seconds)`, возвращающую количество полных часов, минут и секунд в данном количестве секунд. Распакуйте результат в три переменные.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a34f48af",
   "metadata": {},
   "outputs": [],
   "source": [
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4b64236e",
   "metadata": {},
   "source": [
    "*Пример проверки.* Запустите ячейку с функцией, затем эту ячейку. Допишите еще несколько тестов.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "c8a4d3c3",
   "metadata": {},
   "outputs": [],
   "source": [
    "assert time_to_hms(3661) == (1, 1, 1)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5ed8e282",
   "metadata": {},
   "source": [
    "**Задача 8. Информация о прямоугольнике**\n",
    "\n",
    "Опишите функцию `rectangle_info(a, b)`, возвращающую площадь и периметр прямоугольника. В основной программе распакуйте оба результата.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "53b6fd77",
   "metadata": {},
   "outputs": [],
   "source": [
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e7a7ab31",
   "metadata": {},
   "source": [
    "*Пример проверки.* Запустите ячейку с функцией, затем эту ячейку. Допишите еще несколько тестов.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "5733e5e1",
   "metadata": {},
   "outputs": [],
   "source": [
    "from math import isclose\n",
    "\n",
    "area, perimeter = rectangle_info(2.5, 4)\n",
    "assert isclose(area, 10.0, rel_tol = 1e-9)\n",
    "assert isclose(perimeter, 13.0, rel_tol = 1e-9)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "290f2ed4",
   "metadata": {},
   "source": [
    "**Задача 9. Високосный год**\n",
    "\n",
    "Опишите булеву функцию `is_leap_year(year)`. Год високосный, если он делится на 4, кроме годов, делящихся на 100 и не делящихся на 400.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bf6a0871",
   "metadata": {},
   "outputs": [],
   "source": [
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e12b779b",
   "metadata": {},
   "source": [
    "*Пример проверки.* Запустите ячейку с функцией, затем эту ячейку. Допишите еще несколько тестов.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "eff5396c",
   "metadata": {},
   "outputs": [],
   "source": [
    "assert is_leap_year(2024)\n",
    "assert not is_leap_year(2100)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "17e81217",
   "metadata": {},
   "source": [
    "**Задача 10. Количество цифр**\n",
    "\n",
    "Опишите функцию `digit_count(number)`, возвращающую количество цифр положительного целого числа.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fc339a81",
   "metadata": {},
   "outputs": [],
   "source": [
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bf6b16eb",
   "metadata": {},
   "source": [
    "**Задача 11. Переворот числа**\n",
    "\n",
    "Опишите функцию `reverse_digits(number)`, возвращающую для положительного целого `number` число, записанное теми же цифрами в обратном порядке.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9b13d7cb",
   "metadata": {},
   "outputs": [],
   "source": [
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2d511583",
   "metadata": {},
   "source": [
    "**Задача 12. Двойной факториал**\n",
    "\n",
    "Опишите функцию `double_factorial(N)`, вычисляющую двойной факториал целого положительного числа $N$ по формуле:\n",
    "\n",
    "$$\n",
    "N!! = N \\cdot (N - 2) \\cdot (N - 4) \\ldots\n",
    "$$\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a6682601",
   "metadata": {},
   "outputs": [],
   "source": [
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fe3ea88c",
   "metadata": {},
   "source": [
    "**Задача 13. Число Фибоначчи**\n",
    "\n",
    "Опишите функцию `fibonacci(N)`, возвращающую $N$-е ($N > 0$) число Фибоначчи: $F_1 = F_2 = 1$.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f9abd409",
   "metadata": {},
   "outputs": [],
   "source": [
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0b19a5bb",
   "metadata": {},
   "source": [
    "**Задача 14. Игра «Угадай число»**\n",
    "\n",
    "Игрок задает нижнюю `A` и верхнюю `B` границы диапазона для загадываемого компьютером числа (вводит 2 целых числа с клавиатуры). После ввода с помощью `assert` следует проверить, что нижняя граница `A` не больше верхней `B`.\n",
    "\n",
    "Далее игрок задает максимально доступное количество попыток `MAX_ATTEMPTS` (вводит 1 положительное целое число с клавиатуры). После ввода с помощью `assert` следует проверить, что данное число больше нуля и меньше числа элементов в диапазоне $[A, B]$.\n",
    "\n",
    "Компьютер загадывает число `X` из заданного пользователем диапазона $[A, B]$. Игрок должен угадать это число за `MAX_ATTEMPTS` попыток.\n",
    "\n",
    "Игрок вводит число `N` из заданного диапазона: если это то самое загаданное число, игра заканчивается; в противном случае компьютер сообщает, как `N` соотносится с загаданным `X` (то есть меньше ли `X`, чем полученное `N`, или больше), и игра продолжается — игрок снова пытается угадать число.\n",
    "\n",
    "Если игрок не угадал число за отведённое число шагов, он проигрывает.\n",
    "\n",
    "При реализации игры нужно обратить внимание на несколько деталей:\n",
    "- Должны быть заданы корректные границы диапазона, то есть нижняя граница `A` не должна быть больше верхней `B`.\n",
    "- На каждом шаге угадывания числа игрок видит номер попытки и диапазон значений, который он уже отгадал.\n",
    "- Если игрок вводит число вне текущего диапазона, он проигрывает.\n",
    "- Используйте `while True` и `break`.\n",
    "\n",
    "**Примеры запусков игры**: <br>\n",
    "\n",
    "**Пример выигрыша**. <br>\n",
    "Введите нижнюю границу дипазона A:  -10 <br>\n",
    "Введите верхнюю границу дипазона B: 10  <br>\n",
    "Введите максимальное количество попыток MAX_ATTEMPTS: 15 <br>\n",
    "\n",
    "Задан диапазон: -10..10. <br>\n",
    "Компьютер загадал число. Попробуйте отгадать его! У вас есть 15 попыток. <br>\n",
    "\n",
    "Попытка #1/15. <br>\n",
    "Введите число из диапазона -10..10: 0 <br>\n",
    "Загаданное число больше 0. <br>\n",
    "\n",
    "Попытка #2/15. <br>\n",
    "Введите число из диапазона 1..10: 5 <br>\n",
    "Загаданное число меньше 5. <br>\n",
    "\n",
    "Попытка #3/15. <br>\n",
    "Введите число из диапазона 1..4: 3 <br>\n",
    "Загаданное число больше 3. <br>\n",
    "\n",
    "Попытка #4/15. <br>\n",
    "Введите число из диапазона 4..4: 4 <br>\n",
    "\n",
    "Число отгадано! Это 4. <br>\n",
    "Вы угадали число за 4 шагов. <br>\n",
    "\n",
    "**Пример проигрыша: число выходит за границы диапазона**. <br>\n",
    "\n",
    "Введите нижнюю границу дипазона A:  1 <br>\n",
    "Введите верхнюю границу дипазона B: 5  <br>\n",
    "Введите максимальное количество попыток MAX_ATTEMPTS: 4 <br>\n",
    "\n",
    "Задан диапазон: 1..5. <br>\n",
    "Компьютер загадал число. Попробуйте отгадать его! У вас есть 4 попыток. <br>\n",
    "\n",
    "Попытка #1/5. <br>\n",
    "Введите число из диапазона 1..5: 4 <br>\n",
    "Загаданное число меньше 4. <br>\n",
    "\n",
    "Попытка #2/5. <br>\n",
    "Введите число из диапазона 1..3: 5 <br>\n",
    "\n",
    "Вы проиграли! <br>\n",
    "Было загадано число 2. <br>\n",
    "\n",
    "**Пример проигрыша: исчерпано количество попыток**. <br>\n",
    "\n",
    "Введите нижнюю границу дипазона A:  0 <br>\n",
    "Введите верхнюю границу дипазона B: 50  <br>\n",
    "Введите максимальное количество попыток MAX_ATTEMPTS: 5 <br>\n",
    "\n",
    "Задан диапазон: 0..50. <br>\n",
    "Компьютер загадал число. Попробуйте отгадать его! У вас есть 5 попыток. <br>\n",
    "\n",
    "Попытка #1/5. <br>\n",
    "Введите число из диапазона 0..50: 25 <br>\n",
    "Загаданное число больше 25.<br>\n",
    "\n",
    "Попытка #2/5. <br>\n",
    "Введите число из диапазона 26..50: 35 <br>\n",
    "Загаданное число меньше 35.<br>\n",
    "\n",
    "Попытка #3/5.<br>\n",
    "Введите число из диапазона 26..34: 30<br>\n",
    "Загаданное число меньше 30.<br>\n",
    "\n",
    "Попытка #4/5.<br>\n",
    "Введите число из диапазона 26..29: 29<br>\n",
    "Загаданное число меньше 29.<br>\n",
    "\n",
    "Попытка #5/5.<br>\n",
    "Введите число из диапазона 26..28: 27<br>\n",
    "Загаданное число больше 27.<br>\n",
    "\n",
    "Вы проиграли! Исчерпано допустимое количество попыток.<br>\n",
    "Было загадано число 28."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d7c241c4",
   "metadata": {},
   "outputs": [],
   "source": [
    "from random import randint\n",
    "\n",
    "..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "13592998-66a8-4d1b-bbdb-8209354018f1",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:base] *",
   "language": "python",
   "name": "conda-base-py"
  },
  "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.13.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
