diff --git a/03ip214/Pr02.ipynb b/03ip214/Pr02.ipynb new file mode 100644 index 0000000..271a7d4 --- /dev/null +++ b/03ip214/Pr02.ipynb @@ -0,0 +1,237 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "82c6045f-466b-435d-827b-c69c7d1b99d2", + "metadata": {}, + "source": [ + "# Практическая работа №2" + ] + }, + { + "cell_type": "markdown", + "id": "1475d839-a1ea-4bd4-8631-909bb21d45f5", + "metadata": {}, + "source": [ + "## Задание 3.0" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "4d46b466-d726-4ea4-b954-6a84d7a73600", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "27 82 41 124 62 31 94 47 142 71 214 107 322 161 484 242 121 364 182 91 274 137 412 206 103 310 155 466 233 700 350 175 526 263 790 395 1186 593 1780 890 445 1336 668 334 167 502 251 754 377 1132 566 283 850 425 1276 638 319 958 479 1438 719 2158 1079 3238 1619 4858 2429 7288 3644 1822 911 2734 1367 4102 2051 6154 3077 9232 4616 2308 1154 577 1732 866 433 1300 650 325 976 488 244 122 61 184 92 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1 \n" + ] + } + ], + "source": [ + "n = 27\n", + "\n", + "while True:\n", + " print(n, end=' ')\n", + " if n == 1:\n", + " break\n", + " if n % 2:\n", + " n = 3 * n + 1\n", + " else:\n", + " n = n // 2\n", + "print()" + ] + }, + { + "cell_type": "markdown", + "id": "200135c2-cad7-434b-8c51-a47b54b696ab", + "metadata": {}, + "source": [ + "## Задание 3.1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2ef34f4a-2182-407b-a859-e588496b0a4d", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "\n", + "try:\n", + " n = int(sys.argv[1])\n", + " if n < 1:\n", + " raise ValueError\n", + "except (IndexError, ValueError):\n", + " print('Введите число больше 0 в командную строку')\n", + " sys.exit(1)\n", + "\n", + "while True:\n", + " print(n, end=' ')\n", + " if n == 1:\n", + " break\n", + " if n % 2:\n", + " n = 3 * n + 1\n", + " else:\n", + " n = n // 2\n", + "print()" + ] + }, + { + "cell_type": "markdown", + "id": "7bd26cf2-d748-4a12-9fc1-7e8a03d84f3c", + "metadata": {}, + "source": [ + "## Задание 3.2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "15339645-baae-4f02-bd91-69d29c16c483", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import math\n", + "\n", + "haversin = lambda alpha: math.sin(alpha/2)**2\n", + "\n", + "def gc_distance(loc1, loc2, R=6378.1):\n", + " (phi1, lambda1), (phi2, lambda2) = loc1, loc2\n", + " d = 2 * R * math.asin(math.sqrt(haversin(phi2-phi1) + math.cos(phi1)*math.cos(phi2)*haversin(lambda2-lambda1)))\n", + " return d\n", + "\n", + "loc1, loc2 = sys.argv[1:]\n", + "phi1, lambda1 = [math.radians(float(x)) for x in loc1.split(',')]\n", + "phi2, lambda2 = [math.radians(float(x)) for x in loc2.split(',')]\n", + "\n", + "d = gc_distance((phi1, lambda1), (phi2, lambda2))\n", + "print('{} km'.format(int(d)))" + ] + }, + { + "cell_type": "markdown", + "id": "35f05b60-d423-4e39-8e80-4bea34315cdc", + "metadata": {}, + "source": [ + "## Задание 3.3" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fb152e4e-d13c-42a2-ab61-7dc16071f860", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import math\n", + "\n", + "nfigs = 20\n", + "HOME = os.getenv('HOME')\n", + "pathdir = os.path.join(HOME, 'test')\n", + "if not os.path.exists(pathdir):\n", + " os.mkdir(pathdir)\n", + "\n", + "canvas_height, canvas_width = 500, 500\n", + "cx, cy = canvas_height / 2, canvas_width / 2\n", + "r1, r2 = 200, 20\n", + "\n", + "alphas = [2*math.pi / nfigs * n for n in range(nfigs)]\n", + "\n", + "for n, alpha in enumerate(alphas):\n", + " filename = os.path.join(pathdir, 'fig{:02d}.svg'.format(n))\n", + " with open(filename, 'w') as fo:\n", + " # SVG preamble\n", + " print(\"\"\"\n", + " \"\"\".format(\n", + " canvas_width, canvas_height, '#ffffff'), file=fo)\n", + " print(''.format(cx, cy, r1),file=fo)\n", + " cx2, cy2 = cx+(r1-r2) * math.cos(alpha), cy+(r1-r2) * math.sin(alpha)\n", + " print(''\n", + " .format(cx2, cy2, r2), file=fo)\n", + " print('', file=fo)" + ] + }, + { + "cell_type": "markdown", + "id": "35946f8f-1adf-46e3-919a-331730a929e7", + "metadata": {}, + "source": [ + "## Задание 3.4" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b2153350-e452-405c-92c6-f0909e61e178", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import sys\n", + "\n", + "months = ['jan', 'feb', 'mar', 'apr', 'may', 'jun',\n", + " 'jul', 'aug', 'sep', 'oct', 'nov', 'dec']\n", + "\n", + "try:\n", + " dir_name = sys.argv[1]\n", + "except IndexError:\n", + " print('No directory name provided. Usage:')\n", + " print('{} '.format(sys.argv[0]))\n", + " sys.exit(1)\n", + "\n", + "if not os.path.exists(dir_name):\n", + " print('Directory {} does not exist'.format(dir_name))\n", + " sys.exit(1)\n", + "\n", + "for filename in os.listdir(dir_name):\n", + " try:\n", + " d, month, y = int(filename[5:7]), filename[8:11], int(filename[12:14])\n", + " except (IndexError, ValueError):\n", + " print('Skipping file', filename)\n", + " continue\n", + " \n", + " try:\n", + " m = months.index(month.lower())+1\n", + " except ValueError:\n", + " print('Skipping file {} (unrecognised month)'.format(filename))\n", + " continue\n", + " \n", + " newname = 'data-20{:02d}-{:02d}-{:02d}.txt'.format(y, m, d)\n", + " newpath = os.path.join(dir_name, newname)\n", + " oldpath = os.path.join(dir_name, filename)\n", + " print(oldpath, '->', newpath)\n", + " os.rename(oldpath, newpath)" + ] + } + ], + "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.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/03ip214/Pr04.ipynb b/03ip214/Pr04.ipynb new file mode 100644 index 0000000..d2b3d8f --- /dev/null +++ b/03ip214/Pr04.ipynb @@ -0,0 +1,268 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "65ea7569-ae67-4db8-933e-e425f7487a5f", + "metadata": {}, + "source": [ + "# Практическая работа №4" + ] + }, + { + "cell_type": "markdown", + "id": "c88b6718-2fea-4def-8db1-5621baf3349f", + "metadata": {}, + "source": [ + "## Задание 3.1" + ] + }, + { + "cell_type": "markdown", + "id": "0ccf8cc9-b540-4c5c-9ea4-00cdb153961c", + "metadata": {}, + "source": [ + "### а)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "ec22d2d3-e0f2-45ad-9e81-9a372bc0273a", + "metadata": {}, + "outputs": [], + "source": [ + "class BankAccount:\n", + " # \"\"\" Абстрактный базовый класс, представляющий банковский счет.\"\"\"\n", + " currency = '$'\n", + " def __init__(self, customer, account_number, balance=0):\n", + " # \"\"\"\n", + " # Инициализация класса BankAccount значениями имени клиента, номера счета и\n", + " # баланса при открытии счета (по умолчанию 0).\n", + " # \"\"\"\n", + " try:\n", + " ccno = str(account_number)\n", + " ccl = []\n", + " for n in ccno:\n", + " if n == ' ':\n", + " continue\n", + " ccl.append(int(n))\n", + " for i in range(0,16,2):\n", + " ccl[i] *= 2\n", + " if ccl[i] > 9:\n", + " ccl[i] = 1 + (ccl[i] - 10)\n", + " checksum = sum(ccl) % 10\n", + " if checksum:\n", + " raise ValueError()\n", + " else:\n", + " self.account_number = account_number\n", + " self.customer = customer\n", + " self.balance = balance\n", + " print(ccno, 'is a valid credit card number')\n", + " except:\n", + " raise ValueError(f'{ccno} is not a valid credit card number')\n", + "\n", + "def deposit(self, amount):\n", + " \"\"\" Deposit amount into the bank account.\"\"\"\n", + " # \"\"\"Размер вклада на банковский счет.\"\"\"\n", + " if amount > 0:\n", + " self.balance += amount\n", + " else:\n", + " print('Invalid deposit amount:', amount)\n", + "\n", + "def withdraw(self, amount):\n", + " # \"\"\"\n", + " # Сумма средств, снимаемых с банковского счета, при условии достаточной суммы\n", + " # на этом счете.\n", + " # \"\"\"\n", + " \n", + " if amount > 0:\n", + " if amount > self.balance:\n", + " print('Insufficient funds')\n", + " else:\n", + " self.balance -= amount\n", + " else:\n", + " print('Invalid withdrawal amount:', amount)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "ddf7d39c-8500-4e54-9b15-fe7fccf52516", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4556737586899855 is a valid credit card number\n" + ] + } + ], + "source": [ + "valid_account = BankAccount('Joe Bloggs', 4556737586899855)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "ff4a1754-a506-4c92-8b80-17a524ebb99f", + "metadata": {}, + "outputs": [ + { + "ename": "ValueError", + "evalue": "21457288 is not a valid credit card number", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mIndexError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 17\u001b[0m, in \u001b[0;36mBankAccount.__init__\u001b[0;34m(self, customer, account_number, balance)\u001b[0m\n\u001b[1;32m 16\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mrange\u001b[39m(\u001b[38;5;241m0\u001b[39m,\u001b[38;5;241m16\u001b[39m,\u001b[38;5;241m2\u001b[39m):\n\u001b[0;32m---> 17\u001b[0m \u001b[43mccl\u001b[49m\u001b[43m[\u001b[49m\u001b[43mi\u001b[49m\u001b[43m]\u001b[49m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m2\u001b[39m\n\u001b[1;32m 18\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m ccl[i] \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m9\u001b[39m:\n", + "\u001b[0;31mIndexError\u001b[0m: list index out of range", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[3], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m not_valid_account \u001b[38;5;241m=\u001b[39m \u001b[43mBankAccount\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mJoe Bloggs\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m21457288\u001b[39;49m\u001b[43m)\u001b[49m\n", + "Cell \u001b[0;32mIn[1], line 29\u001b[0m, in \u001b[0;36mBankAccount.__init__\u001b[0;34m(self, customer, account_number, balance)\u001b[0m\n\u001b[1;32m 27\u001b[0m \u001b[38;5;28mprint\u001b[39m(ccno, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mis a valid credit card number\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 28\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m:\n\u001b[0;32m---> 29\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mccno\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m is not a valid credit card number\u001b[39m\u001b[38;5;124m'\u001b[39m)\n", + "\u001b[0;31mValueError\u001b[0m: 21457288 is not a valid credit card number" + ] + } + ], + "source": [ + "not_valid_account = BankAccount('Joe Bloggs', 21457288)" + ] + }, + { + "cell_type": "markdown", + "id": "25d7e0e0-6bc4-45b4-9377-7a7d39ebf1b1", + "metadata": {}, + "source": [ + "### б)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "e45a188b-2623-4190-a62f-88e21ca87e75", + "metadata": {}, + "outputs": [], + "source": [ + "class CurrentAccount(BankAccount):\n", + " # \"\"\" Класс, представляющий текущий (чековый) счет. \"\"\"\n", + " def __init__(self, customer, account_number, annual_fee, transaction_limit, overdraft, balance=0):\n", + " # \"\"\" Инициализация текущего счета. \"\"\"\n", + " self.annual_fee = annual_fee\n", + " self.transaction_limit = transaction_limit\n", + " self.overdraft = overdraft\n", + " super().__init__(customer, account_number, balance)\n", + " \n", + " def withdraw(self, amount):\n", + " # \"\"\"\n", + " # Снятие денежной суммы, если на счете имеется достаточно средств и снимаемая сумма\n", + " # меньше лимита, установленного для одной транзакции.\n", + " # \"\"\"\n", + " if amount <= (0 - self.overdraft):\n", + " print('Invalid withdrawal amount:', amount)\n", + " return\n", + " if amount > (self.balance + self.overdraft):\n", + " print('Insufficient funds')\n", + " return\n", + " if amount > self.transaction_limit:\n", + " print('{0:s}{1:.2f} exceeds the single transaction limit of {0:s}{2:.2f}'.format(self.currency, amount, self.transaction_limit))\n", + " return\n", + " self.balance -= amount\n", + " \n", + " def apply_annual_fee(self):\n", + " # \"\"\" Удержание ежегодной оплаты с баланса счета. \"\"\"\n", + " self.balance = max(0., self.balance - self.annual_fee)\n", + "\n", + " def print_balance(self):\n", + " # \"\"\" Вывод баланса счета. \"\"\"\n", + " print(self.balance)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "fa420cc8-8bc8-495a-8158-0995b0b782f3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4556737586899855 is a valid credit card number\n" + ] + } + ], + "source": [ + "my_current = CurrentAccount('Alison Wicks', 4556737586899855, 20., 500, 100, 200)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "229dc92c-aaa8-4773-9172-07c2dc8be422", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-99\n" + ] + } + ], + "source": [ + "my_current.withdraw(299)\n", + "my_current.print_balance()" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "07425750-b183-4c8c-b61b-ed41fd6a760d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Insufficient funds\n", + "-99\n" + ] + } + ], + "source": [ + "my_current.withdraw(2)\n", + "my_current.print_balance()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "edd27a00-5afb-420b-8022-2ea0e03a34f9", + "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.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/03ip214/p7.png b/03ip214/p7.png new file mode 100644 index 0000000..8d92f52 Binary files /dev/null and b/03ip214/p7.png differ diff --git "a/\320\234\320\224\320\232 02.03 \320\234\320\260\321\202\320\265\320\274\320\260\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\274\320\276\320\264\320\265\320\273\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/1 \320\236\321\201\320\275\320\276\320\262\321\213 Python/.ipynb_checkpoints/pr02 \320\241\320\265\321\200\320\262\320\270\321\201\321\213 \320\276\320\277\320\265\321\200\320\260\321\206\320\270\320\276\320\275\320\275\320\276\320\271 \321\201\320\270\321\201\321\202\320\265\320\274\321\213-checkpoint.ipynb" "b/\320\234\320\224\320\232 02.03 \320\234\320\260\321\202\320\265\320\274\320\260\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\274\320\276\320\264\320\265\320\273\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/1 \320\236\321\201\320\275\320\276\320\262\321\213 Python/.ipynb_checkpoints/pr02 \320\241\320\265\321\200\320\262\320\270\321\201\321\213 \320\276\320\277\320\265\321\200\320\260\321\206\320\270\320\276\320\275\320\275\320\276\320\271 \321\201\320\270\321\201\321\202\320\265\320\274\321\213-checkpoint.ipynb" new file mode 100644 index 0000000..ea3b51c --- /dev/null +++ "b/\320\234\320\224\320\232 02.03 \320\234\320\260\321\202\320\265\320\274\320\260\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\274\320\276\320\264\320\265\320\273\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/1 \320\236\321\201\320\275\320\276\320\262\321\213 Python/.ipynb_checkpoints/pr02 \320\241\320\265\321\200\320\262\320\270\321\201\321\213 \320\276\320\277\320\265\321\200\320\260\321\206\320\270\320\276\320\275\320\275\320\276\320\271 \321\201\320\270\321\201\321\202\320\265\320\274\321\213-checkpoint.ipynb" @@ -0,0 +1,506 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Практическая работа №2.Сервисы операционной системы" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Модуль sys" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Модуль ```sys``` предоставляет конкретные, зависимые от операционной системы\n", + "параметры и функции. Многие из них представляют интерес только для достаточно продвинутых пользователей менее распространенных реализаций Python (например, подробности реализации арифметики с плавающей точкой могут отличаться в разных системах, но, вероятнее всего, одинаковы на всех самых распространенных платформах). Однако в модуле ```sys```\n", + "представлены также некоторые полезные и важные параметры и функции, которые описаны в следующих подразделах." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Список sys.argv" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Список ```sys.argv``` содержит аргументы командной строки, передаваемые\n", + "в Python-программу при ее выполнении. Это список строк. Первый элемент\n", + "```sys.argv[0]``` – имя самой программы. Это обеспечивает некоторую степень интерактивности без необходимости чтения из файлов конфигурации и обязательности прямого ввода пользователя, а также означает, что другие программы и/или скрипты командной оболочки могут вызывать Python-программу и передавать ей конкретные входные значения или параметры настройки. Например, рассмотрим простой скрипт возведения в квадрат заданного числа:" + ] + }, + { + "cell_type": "raw", + "metadata": {}, + "source": [ + "# square.py\n", + "import sys\n", + "n = int(sys.argv[1])\n", + "print(n, 'squared is', n**2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "(Обратите внимание: необходимо преобразовать входное значение в число\n", + "типа ```int```, потому что оно хранится в списке ```sys.argv``` как строка.) При запуске\n", + "этой программы в командной строке с передачей аргумента\n", + "\n", + "```\n", + "python square.py 3\n", + "\n", + "```\n", + "\n", + "выводится ожидаемый результат:\n", + "\n", + "```\n", + "3 squared is 9\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Но поскольку значение ```n``` не было жестко закодировано в исходном коде, ту\n", + "же программу можно выполнить с другим аргументом:\n", + "\n", + "```\n", + "python square.py 4\n", + "```\n", + "\n", + "и получить правильный результат:\n", + "\n", + "```\n", + "4 squared is 16\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Метод sys.exit" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Вызов ```sys.exit``` приводит к завершению работы программы и к выходу из программной среды Python. Это происходит «аккуратно», поэтому сначала выполняются все команды в блоке ```finally``` конструкции ```try``` и закрываются все открытые файлы. Необязательным аргументом для ```sys.exit``` может быть любой\n", + "объект: если это целое число, то оно передается в командную оболочку, которая, как предполагается, знает, что с ним делать. (По крайней мере, если это число в диапазоне 0–127. Для значений вне этого диапазона могут быть получены неопределенные результаты).\n", + "Например, ```0``` обычно означает «успешное» завершение программы, а ненулевое значение сообщает об ошибке некоторого типа. Отсутствие аргумента или передача значения None равнозначны ```0```. Если в качестве аргумента для ```sys.exit``` задан любой другой объект,то он передается в поток ```stderr```, реализацию Python стандартного потока ошибок.\n", + "Например, строка выводится в консоли как сообщение об ошибке (если в командной оболочке не было выполнено перенаправление потоков вывода)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Пример 15**. Распространенный способ помощи пользователям при работе со\n", + "скриптами, которые принимают аргументы из командной строки, – вывод сообщения-подсказки, если скрипт используется неправильно, как показано в листинге 3." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Листинг 3**. Вывод сообщения-подсказки для скрипта, принимающего аргументы из командной строки" + ] + }, + { + "cell_type": "raw", + "metadata": {}, + "source": [ + "# square.py\n", + "import sys\n", + "try:\n", + " n = int(sys.argv[1])\n", + "except (IndexError , ValueError):\n", + " sys.exit('Please enter an integer , , on the command line.\\nUsage: python {:s} '.format(sys.argv[0]))\n", + " print(n, 'squared is', n**2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Здесь выводится понятное сообщение об ошибке и завершается работа программы, если не был задан аргумент командной строки (т. е. при обращении\n", + "по индексу ```sys.argv[1]``` генерируется исключение ```IndexError```) или строку аргумента командной строки невозможно преобразовать в целое число (в этом\n", + "случае попытка преобразования с помощью метода ```int``` приводит к генерации\n", + "исключения ```ValueError```). Ниже показан пример вывода этой программы:\n", + "\n", + "```\n", + "$ python square.py hello\n", + "Please enter an integer, , on the command line.\n", + "Usage: python square.py \n", + "$ python square.py 5\n", + "5 squared is 25\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Модуль os" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Модуль ```os``` предоставляет разнообразные интерфейсы операционной системы\n", + "способом,не зависящим от какой-либо конкретной платформы. Многочисленные функции и параметры этого модуля подробно описаны в официальной документации46, но некоторые наиболее важные из них рассматриваются в этом подразделе." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Информация о процессе" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "В программной среде Python процесс (process) – это конкретный экземпляр\n", + "приложения на языке Python, которое выполняется определенной программой (или предоставляет командную оболочку Python для интерактивного использования).Модуль os предлагает ряд функций для извлечения информации\n", + "о контексте,в которомработаетпроцессPython.Например,функция os.uname()\n", + "возвращает информацию об операционной системе, в которой функционирует\n", + "Python, и о сетевом имени компьютера, выполняющего данный процесс.\n", + "Одна из функций имеет специфическое предназначение: os.getenv(key)\n", + "возвращает значение переменной среды key, если такая переменная существует (или значение None, если переменной не существует). Многие переменные\n", + "среды зависят от конкретной системы, но к общим для большинства систем\n", + "относятся следующие:\n", + " \n", + "- HOME – путь к домашнему каталогу пользователя;\n", + "- PWD – текущий рабочий каталог;\n", + "- USER – текущее имя пользователя;\n", + "- PATH – переменная, содержащая системный путь поиска (может содержать несколько путей поиска).\n", + "\n", + "Например:\n", + "\n", + "```\n", + ">>> os.getenv('HOME')\n", + "'/Users/christian'\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Команды файловой системы" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Часто возникаетнеобходимость в перемещении по дереву системных каталогов\n", + "и в работе с файлами и каталогами непосредственно в Python-программе. Модуль ```os``` предоставляет для таких операций функции, перечисленные в табл. 4.\n", + "Разумеется, при этом существует определенная степень опасности: Python программа может сделать все, что может сделать пользователь, в том числе\n", + "переименовывать и удалять файлы." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Таблица 4**. Модуль os: некоторые команды файловой системы" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "|Функция|Описание|\n", + "|:------|:-------|\n", + "|os.listdir(path='.')|Выводит список элементов каталога, заданного аргументом path (если каталог не задан, то по умолчанию выводится содержимое текущего рабочего каталога)|\n", + "|os.remove(path) |Удаляет файл, заданный аргументом path (если path – каталог, то генерируется исключение OSError; необходимо использовать функцию os.rmdir)|\n", + "|os.rename(old_name,new_name)|Выполняет переименование файла или каталога old_name в new_name. Если файл с именем new_name уже существует, то он будет замещен (с учетом пользовательских прав доступа)|\n", + "|os.rmdir(path) |Удаляет каталог, заданный аргументом path. Если каталог не пуст, то генерируется исключение OSError|\n", + "|os.mkdir(path) |Создает каталог, заданный аргументом path\n", + "|os.system(command)|Выполняет команду command в порожденном экземпляре командной оболочки. Если команда генерирует какой-либо вывод, то он перенаправляется в стандартный поток вывода интерпретатора stdout|\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Операции с путевым именем" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Модуль ```os.path``` предоставляет группу полезных функций для работы с путевыми именами. Версия этой библиотеки, установленная вместе с Python, будет\n", + "именно той, которая подходит для операционной системы, на которой она работает (например, на компьютере с ОС Windows компоненты путевого имени\n", + "разделяются символом обратного слеша \\, тогда как в системах Unix и Linux\n", + "используется символ (обычного) слеша /.\n", + "Наиболее часто функции модуля ```os.path``` используются для поиска (выделения) имени файла в путевом имени (basename), для проверки существования\n", + "файла или каталога (```exists```),для объединения строк, чтобы сформировать полное путевое имя (join), для разделения имени файла на основу («root») и расширение («extension») (splitext), а также для определения времени последнего изменения файла (getmtime). Все эти часто применяемые методы кратко\n", + "описаны в табл. 5." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Таблица 5**. Модуль ```os.path```: часто применяемые операции с путевым именем" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "|Функция|Описание|\n", + "|:------|:-------|\n", + "|os.path.basename(path)|Возвращает имя файла из путевого имени path, определяющего относительный или абсолютный путь к файлу: обычно это означает собственно имя файла|\n", + "|os.path.dirname(path) |Возвращает имя каталога из путевого имени path|\n", + "|os.path.exists(path)|Возвращает True, если каталог или файл, заданный в path, существует, иначе возвращает False|\n", + "|os.path.getmtime(path)|Возвращает время последнего изменения файла path|\n", + "|os.path.getsize(path)|Возвращает размер файла path в байтах|\n", + "|os.path.join(path1,path2,...)|Возвращает путевое имя, сформированное объединением путевых компонентов path1, path2 и т. д. с применением разделителя каталогов, соответствующего используемой операционной системе|\n", + "|os.path.split(path)|Разделяет путевое имя path на каталог и имя файла, возвращаемые как кортеж (равнозначно вызову функций dirname и basename соответственно)\n", + "|\n", + "|os.path.splitext(path) |Разделяет путевое имя path на основу («root») и расширение («extension») (возвращаемые как пара кортежа)|\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Ниже показаны примеры некоторых операций, выполняемых с файлом\n", + "/home/brian/test.py:\n", + "\n", + "```\n", + ">>> os.path.basename('/home/brian/test.py')\n", + "'test.py' # Только имя файла.\n", + ">>> os.path.dirname('/home/brian/test.py')\n", + "'/home/brian' # Только каталог.\n", + ">>> os.path.split('/home/brian/test.py')\n", + "('/home/brian', 'test.py') # Каталог и имя файла в кортеже.\n", + ">>> os.path.splitext('/home/brian/test.py')\n", + "('/home/brian/test', '.py') # Путь к файлу с основой и расширение файла в кортеже.\n", + ">>> os.path.join(os.getenv('HOME'), 'test.py')\n", + "'/home/brian/test.py' # Объединение каталогов и/или имени файла.\n", + ">>> os.path.exists('/home/brian/test.py')\n", + "False # Файл не существует.\n", + "\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Пример 16**. Предположим, что существует каталог с файлами данных, идентифицируемых по именам в формате data-DD-Mon-YY.txt, где DD – число месяца из\n", + "двух цифр, Mon – сокращенное обозначение месяца из трех букв, YY – две последние цифры года, например '02-Feb-10’. Программа в листинге 4 преобразовывает\n", + "имена файлов в формат data-YYYY-MM-DD.txt, чтобы упорядочение по алфавиту\n", + "имен файлов размещало их в правильном хронологическом порядке." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Листинг 4**. Переименование файлов данных для упорядочения по дате" + ] + }, + { + "cell_type": "raw", + "metadata": {}, + "source": [ + "# eg4-osmodule.py\n", + "import os\n", + "import sys\n", + "months = ['jan', 'feb', 'mar', 'apr', 'may', 'jun','jul', 'aug', 'sep', 'oct', 'nov', 'dec']\n", + "dir_name = sys.argv[1]\n", + "for filename in os.listdir(dir_name):\n", + " # Имя файла должно быть представлено в формате 'data-DD-MMM-YY.txt'\n", + " d, month , y = int(filename[5:7]), filename[8:11], int(filename[12:14])\n", + " m = months.index(month.lower())+1 ❶\n", + " newname = 'data-20{:02d}-{:02d}-{:02d}.txt'.format(y, m, d)\n", + " newpath = os.path.join(dir_name, newname)\n", + " oldpath = os.path.join(dir_name, filename)\n", + " print(oldpath , '->', newpath)\n", + " os.rename(oldpath , newpath)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Номер месяца вычисляется по индексу соответствующего сокращенного\n", + "обозначения месяца в списке months с добавлением 1, так как в Python\n", + "индексы списка нумеруются, начиная с 0.\n", + "\n", + "Например, рассмотрим каталог testdir, содержащий следующие файлы:\n", + "\n", + "```\n", + "data-02-Feb-10.txt\n", + "data-10-Oct-14.txt\n", + "data-22-Jun-04.txt\n", + "data-31-Dec-06.txt\n", + "```\n", + "При выполнении команды python eg4-osmodule.py testdir выводится следующий результат:\n", + "\n", + "```\n", + "testdir/data-02-Feb-10.txt -> testdir/data-2010-02-02.txt\n", + "testdir/data-10-Oct-14.txt -> testdir/data-2014-10-10.txt\n", + "testdir/data-22-Jun-04.txt -> testdir/data-2004-06-22.txt\n", + "testdir/data-31-Dec-06.txt -> testdir/data-2006-12-31.txt\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Упражнения" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Задачи" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**З 0**. Последовательность чисел-градин (hailstone sequence; гипотеза Коллатца – Collatz conjecture), начинающаяся с целого числа n > 0, генерируется с помощью многократно повторяющегося применения следующих трех правил:\n", + "- если n = 1, то последовательность завершается;\n", + "- если n четное, то следующее число последовательности равно n/2;\n", + "- если n нечетное, то следующее число последовательности равно 3n + 1.\n", + "а) Написать программу вычисления последовательности чисел-градин, начиная с 27.\n", + "б) Установить время останова процесса как количество чисел в заданной последовательности чисел-градин. Изменить программу вычисления последовательности чисел-градин, чтобы она возвращала время останова процесса (stopping time) вместо самих чисел-градин. Дополнить программу\n", + "возможностью демонстрации того факта, что последовательности чиселградин, начинающиеся с числа 1 ≤ n ≤ 100, согласуются с гипотезой Коллатца\n", + "(утверждающей, что все последовательности чисел-градин в конце концов\n", + "завершают\n", + "\n", + "**З 1**. Изменить генератор последовательности чисел-градин из задачи **З 0**\n", + "для генерации последовательности чисел-градин,начиная с произвольного положительного целого числа, которое вводит пользователь в командной строке (использовать ```sys.argv```). Необходимо правильно («аккуратно») обрабатывать случай, когда пользователь забывает задать исходное число ```n``` или указывает\n", + "некорректное значение для ```n```." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**З 2**. Формула гаверсинуса (haversine) позволяет вычислять кратчайшее расстояние (по дуге большой окружности,или по ортодромии) d между двумя точками на сфере радиуса R по значениям долготы (λ1,λ2) и широты (φ1,φ2) этих точек:\n", + "\n", + "![image.png](attachment:image.png)\n", + "\n", + "где функция haversine для угла α определяется формулой\n", + "\n", + "haversin(α) = sin^2(α/2).\n", + "\n", + "Написать программу для вычисления кратчайшего расстояния в километрах между двумя точками на поверхности Земли (рассматривая Землю как\n", + "сферу с радиусом 6378.1 км), заданными как два аргумента командной строки,\n", + "каждый из которых представлен в форме пары значений широта, долгота в градусах. Например, расстояние между Парижем и Римом вычисляется так:\n", + "\n", + "```\n", + "python greatcircle.py 48.9,2.4 41.9,12.5\n", + "1107 km\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**З 3**.Написать программу для создания каталога ```test``` в домашнем каталоге\n", + "пользователя и поместить в этот каталог 20 файлов в формате ```SVG``` (Scalable\n", + "Vector Graphics), изображающих маленький закрашенный красным цветом\n", + "круг внутри большой незакрашенной черной окружности. Например:\n", + "\n", + "```xml\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "```\n", + "В каждом файле маленький красный круг должен сдвигаться вдоль внутренней границы большой окружности так, чтобы эти 20 файлов в совокупности\n", + "могли создать эффект анимации.\n", + "Один из способов достижения такого результата – использование бесплатной программы ImageMagick (www.imagemagick.org/). Проследить за тем, чтобы\n", + "все SVG-файлы имели имена fig00.svg, fig01.svg и т. д. Затем выполнить в командной строке операционной системы следующую команду:\n", + "\n", + "```\n", + "convert -delay 5 -loop 0 fig*.svg animation.gif\n", + "```\n", + "для создания анимированного изображения в формате GIF\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**З 4**. Изменить программу из примера **П 16** (листинг 4) так, чтобы она\n", + "перехватывала следующие ошибки и аккуратно обрабатывала их:\n", + "\n", + "- пользователь не указал имя каталога в командной строке (необходимо вывести сообщение-подсказку по использованию программы);\n", + "- заданный каталог не существует;\n", + "- имя файла в заданном каталоге не соответствует корректному формату;\n", + "- имя файла записано в правильном формате, но сокращенное обозначение месяца не определено (не найдено в списке допустимых обозначений месяцев).\n", + "\n", + "В первых двух случаях программа должна завершать свое выполнение.\n", + "В третьем и четвертом случаях некорректное имя файла должно быть пропущено." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.4.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git "a/\320\234\320\224\320\232 02.03 \320\234\320\260\321\202\320\265\320\274\320\260\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\274\320\276\320\264\320\265\320\273\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/1 \320\236\321\201\320\275\320\276\320\262\321\213 Python/.ipynb_checkpoints/pr03 \320\234\320\276\320\264\321\203\320\273\320\270 \320\270 \320\277\320\260\320\272\320\265\321\202\321\213-checkpoint.ipynb" "b/\320\234\320\224\320\232 02.03 \320\234\320\260\321\202\320\265\320\274\320\260\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\274\320\276\320\264\320\265\320\273\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/1 \320\236\321\201\320\275\320\276\320\262\321\213 Python/.ipynb_checkpoints/pr03 \320\234\320\276\320\264\321\203\320\273\320\270 \320\270 \320\277\320\260\320\272\320\265\321\202\321\213-checkpoint.ipynb" new file mode 100644 index 0000000..6c65fa5 --- /dev/null +++ "b/\320\234\320\224\320\232 02.03 \320\234\320\260\321\202\320\265\320\274\320\260\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\274\320\276\320\264\320\265\320\273\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/1 \320\236\321\201\320\275\320\276\320\262\321\213 Python/.ipynb_checkpoints/pr03 \320\234\320\276\320\264\321\203\320\273\320\270 \320\270 \320\277\320\260\320\272\320\265\321\202\321\213-checkpoint.ipynb" @@ -0,0 +1,1485 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "2b2317f3", + "metadata": {}, + "source": [ + "# Модули и пакеты" + ] + }, + { + "cell_type": "markdown", + "id": "1757d38c", + "metadata": {}, + "source": [ + "Как мы уже видели, Python является вполне модульным языком, и его\n", + "функциональность не ограничивается основными принципами программирования (т. е. встроенными методами и структурами данных, с которыми мы\n", + "имели дело до сих пор). В любой программе доступны также расширенные\n", + "функциональные свойства, включаемые с помощью команды ```import```. Эта команда создает ссылку на модули, представляющие собой обычные Pytho nфайлы, содержащие определения и инструкции. Встретив строку\n", + "\n", + "```python\n", + "import \n", + "```\n", + "интерпретатор Python выполняет инструкции в файле ```.py``` и включает\n", + "имя модуля `````` в текущее пространство имен, после чего атрибуты, определяемые этим модулем, становятся доступными с применением синтаксиса\n", + "точки: ```.```.\n", + "\n", + "Определить собственный модуль так же просто, как поместить исходный\n", + "код в файл ```.py```, расположенный в локации, в которой интерпретатор Python может найти его (для небольших проектов это обычно тот же каталог, в котором расположена программа, импортирующая модуль). С учетом\n", + "синтаксиса команды ```import``` необходимо избегать такого именования модуля, которое не соответствует корректному идентификатору Python. Например, имя файла ```.py``` не должно содержать символ дефиса и не должно начинаться с цифры. Не рекомендуется давать модулю имя, совпадающее с именем какого-либо встроенного модуля (такого как ```math``` или\n", + "```random```), поскольку встроенные модули имеют более высокий приоритет при\n", + "импорте Python.\n", + "\n", + "**Пакет (package)** языка Python – это просто структурированный комплект\n", + "модулей, размещенный в некотором каталоге файловой системы. Пакеты\n", + "представляют собой естественный способ организации и распространения\n", + "крупных проектов на языке Python. Для создания пакета файлы модулей\n", + "помещаются в один каталог вместе с файлом ```__init__.py```. Этот файл запускается при импорте пакета и может выполнять некоторые операции инициализации и собственные команды импорта. Если особенная инициализация\n", + "не требуется, то этот файл может быть пустым (длиной ноль байтов), но он\n", + "обязательно должен существовать, чтобы Python распознавал такой каталог\n", + "как пакет.\n", + "Например, пакет ```NumPy``` (см. главу Numpy) существует как показанный ниже каталог (некоторые файлы и подкаталоги не показаны для экономии места):\n", + "\n", + "```\n", + "numpy/\n", + " __init__.py\n", + " core/\n", + " fft/\n", + " __init__.py\n", + " fftpack.py\n", + " info.py\n", + " ...\n", + " linalg/\n", + " __init__.py\n", + " linalg.py\n", + " info.py\n", + " ...\n", + " polynomial/\n", + " __init__.py\n", + " chebyshev.py\n", + " hermite.py\n", + " legendre.py\n", + " ...\n", + " random/\n", + " version.py\n", + " ...\n", + "```\n", + "Здесь, например, ```polynomial``` – это вложенный пакет в структуре пакета\n", + "numpy, содержащий несколько модулей, в том числе модуль ```legendre```, который\n", + "можно импортировать:\n", + "\n", + "```python\n", + "import numpy.polynomial.legendre\n", + "```\n", + "Чтобы избежать использования развернутого синтаксиса с точкой при обращении к атрибутам этого модуля, удобнее воспользоваться такой командой:\n", + "\n", + "```python\n", + "from numpy.polynomial import legendre\n", + "```\n", + "\n", + "В табл. 6 перечислены некоторые основные бесплатные модули и пакеты\n", + "Python для программных приложений общего назначения, а также для вычислительной и научной работы. Некоторые из них устанавливаются вместе с основным дистрибутивом Python (стандартная библиотека Standard Library),\n", + "другие можно загрузить и установить отдельно. Перед тем как приступить\n", + "к реализации какого-либо собственного алгоритма, проверьте, не включена ли\n", + "такая реализация в один из существующих пакетов Python.\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "114f8775", + "metadata": {}, + "source": [ + "**Таблица 6**. Модули и пакеты Python. Помеченные звездочкой (\\*) компоненты не являются\n", + "частью Python Standard Library, поэтому должны устанавливаться отдельно, например с помощью утилиты pip" + ] + }, + { + "cell_type": "markdown", + "id": "3431658e", + "metadata": {}, + "source": [ + "|Модуль/пакет |Описание |\n", + "|:---|:---|\n", + "|os, sys|Сервисы операционной системы|\n", + "|math, cmath|Математические функции|\n", + "|random|Генератор случайных чисел |\n", + "|collections|Типы данных для контейнеров, расширяющие функциональность словарей, кортежей и т. п.|\n", + "|itertools|Инструменты для эффективных итераторов, расширяющие функциональность простых циклов Python|\n", + "|glob|Расширение шаблона путевого имени в стиле Unix|\n", + "|datetime|Парсинг и обработка дат и времени |\n", + "|fractions|Арифметика рациональных чисел (правильных дробей)|\n", + "|re|Регулярные выражения|\n", + "|argparse|Парсер для ключей и аргументов командной строки|\n", + "|urllib |Открытие, чтение и парсинг URL (включая веб-страницы) (см. раздел 4.5.2)|\n", + "|* Django (django)|Широко известная рабочая среда для веб-приложений|\n", + "|* pyparsing|Лексический парсер для простых грамматик|\n", + "|pdb |Отладчик языка Python|\n", + "|logging|Встроенный в Python модуль ведения журналов|\n", + "|xml, lxml|Парсеры языка разметки XML|\n", + "|* VPython (visual)|Трехмерная визуализация|\n", + "|unittest |Рабочая среда модульного тестирования для систематического проведения тестирования и валидации отдельных единиц (модулей) кода|\n", + "|NumPy (numpy) |Научные вычисления и численные методы|\n", + "|SciPy (scipy)|Научные вычислительные алгоритмы|\n", + "|Matplotlib (matplotlib)|Графическое отображение данных (см. главы 3 и 7)|\n", + "|SymPy (sympy)|Символические вычисления (компьютерная алгебра)|\n", + "|pandas|Обработка и анализ данных с использованием табличных структур данных|\n", + "|scikit-learn|Машинное обучение|\n", + "|Beautiful Soup 4 (beautifulsoup4)|Парсер языка разметки HTML с возможностями обработки некорректно сформированных документов|\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "c855767d", + "metadata": {}, + "source": [ + "Несмотря на существование других менеджеров пакетов, приложение pip\n", + "стало фактическим стандартом. Приложение pip обычно устанавливается по\n", + "умолчанию вместе с большинством дистрибутивов Python и великолепно выполняет работу по управлению версиями и зависимостями пакетов. Для установки пакета package из командной строки используется показанный ниже синтаксис:\n", + "\n", + "```\n", + "pip install package # Установка самой последней версии пакета.\n", + "pip install package==X.Y.Z # Установка версии X.Y.Z.\n", + "pip install 'package>=X.Y.Z' # Установка версии не ниже X.Y.Z.\n", + "```\n", + "Для корректного удаления (деинсталляции) пакета применяется следующая\n", + "команда:\n", + "\n", + "```\n", + "pip uninstall package\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "b414f365", + "metadata": {}, + "source": [ + "## Модуль random" + ] + }, + { + "cell_type": "markdown", + "id": "14b6ee45", + "metadata": {}, + "source": [ + "Для имитаций, моделирования и некоторых вычислительных алгоритмов\n", + "часто требуется генерация случайных чисел из некоторого распределения.\n", + "Тема генерации случайных чисел весьма сложна и интересна, но в данном\n", + "случае для нас важен тот факт, что в Python, как и в большинстве других языков программирования, имеется реализация генератора псевдослучайных\n", + "чисел (ГПСЧ). Этот алгоритм генерирует последовательность чисел, свойства\n", + "которых приближенно соответствуют свойствам «истинных» случайных чисел. Такие последовательности определяются с помощью исходного состояния seed (семя, посев) и при одном и том же значении seed всегда одинаковы: в этом смысле последовательности являются детерминированными. Это может быть положительным свойством (можно повторно воспроизвести вычисление с использованием определенной последовательности случайных чисел) или отрицательным свойством (например, в криптографии, когда последовательность случайных чисел должна храниться в секрете). Любой ГПСЧ будет генерировать последовательность, которая в конце концов повторяется, но у качественного генератора весьма длительный период неповторяющихся чисел. Реализованный в Python ГПСЧ – это вихрь Мерсенна (Mersenne Twister),\n", + "надежный, хорошо изученный алгоритм с периодом 219937 − 1 (это число, содержащее более 6000 знаков по основанию 10)." + ] + }, + { + "cell_type": "markdown", + "id": "871e5b1d", + "metadata": {}, + "source": [ + "### Генерация случайных чисел" + ] + }, + { + "cell_type": "markdown", + "id": "16b621d8", + "metadata": {}, + "source": [ + "Исходный посев (seed) для генератора случайных чисел можно выполнить с помощьюлюбого хешируемого объекта (например,неизменяемого объекта,такого\n", + "как целое число). Сразу после импорта модуля выполняется посев с использованием представления текущего системного времени (если операционная система\n", + "не предоставляет более эффективный источник случайного посева). Посев для\n", + "ГПСЧ можно в любой момент изменить с помощью вызова ```random.seed```.\n", + "Основным методом генерации случайных чисел является random.random.Этот\n", + "метод генерирует случайное число, выбранное из равномерного распределения\n", + "в полуоткрытом интервале ```[0,1)```, т. е. включающем 0, но не включающем 1." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "35a87fca", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.6323708898476204" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import random\n", + "random.random() # \"Случайный\" посев для ГПСЧ." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "9f78af52", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.6394267984578837" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "random.seed(42) # Посев для ГПСЧ с использованием конкретного числового значения.\n", + "random.random()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "f3995a40", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.025010755222666936" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "random.random()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "d26120e8", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.6394267984578837" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "random.seed(42) # Повторный посев с тем же значением, что и ранее.\n", + "random.random() # Поэтому последовательность случайных чисел повторяется." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "274e355f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.025010755222666936" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "random.random()" + ] + }, + { + "cell_type": "markdown", + "id": "d5c3b2e3", + "metadata": {}, + "source": [ + "При вызове ```random.seed()``` без аргумента выполняется повторный посев для\n", + "ГПСЧ со «случайным» значением, которое использовалось модулем ```random``` сразу после импорта.\n", + "Для выбора случайного числа с плавающей точкой ```N``` из заданного интервала\n", + "```a ≤ N ≤ b``` используется метод ```random.uniform(a,b)```:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "c3f0d8d2", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-0.899882726523523" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "random.uniform(-2., 2.)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "d71e5fae", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-1.107157047404709" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "random.uniform(-2., 2.)" + ] + }, + { + "cell_type": "markdown", + "id": "5459a867", + "metadata": {}, + "source": [ + "В модуле ```random``` есть несколько методов для произвольного выбора случайных чисел из неравномерных распределений (см. документацию здесь: https://\n", + "docs.python.org/3/library/random.html) – это очень важно для случаев, описанных\n", + "ниже.\n", + "Чтобы вернуть число из нормального распределения со средним значением mu и стандартным отклонением ```sigma```, используется метод ```random.normalvariate(mu, sigma)```:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "e7a7dea7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "118.82178896586194" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "random.normalvariate(100, 15)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "25d81b08", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "97.92911405885782" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "random.normalvariate(100, 15)" + ] + }, + { + "cell_type": "markdown", + "id": "17942a41", + "metadata": {}, + "source": [ + "Для выбора случайного целого числа ```N``` из заданного интервала ```a ≤ N ≤ b``` применяется метод ```random.randint(a,b)```:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "151da565", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "9" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "random.randint(5, 10)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "de58df0f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "random.randint(5, 10)" + ] + }, + { + "cell_type": "markdown", + "id": "4dbab9d7", + "metadata": {}, + "source": [ + "## Последовательности случайных чисел" + ] + }, + { + "cell_type": "markdown", + "id": "8f03e453", + "metadata": {}, + "source": [ + "Иногда может потребоваться выбор случайного элемента из некоторой последовательности, например из списка. Это можно сделать с помощью метода\n", + "```random.choice```:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "9043b5ef", + "metadata": {}, + "outputs": [], + "source": [ + " seq = [10, 5, 2, 'ni', -3.4]" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "7c4e965a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-3.4" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + " random.choice(seq)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "28f6d880", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "random.choice(seq)" + ] + }, + { + "cell_type": "markdown", + "id": "06bf43ab", + "metadata": {}, + "source": [ + "Другой метод ```random.shuffle``` в случайном порядке перемешивает (переставляет) элементы в последовательности (изменяя саму последовательность):" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "860d22cd", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[5, 'ni', 2, 10, -3.4]" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "random.shuffle(seq)\n", + "seq" + ] + }, + { + "cell_type": "markdown", + "id": "6f83bd5c", + "metadata": {}, + "source": [ + "Обратите внимание: поскольку случайная перестановка выполняется в самой последовательности, эта последовательность непременно должна быть\n", + "изменяемой: например, нельзя перемешивать содержимое кортежей.\n", + "Наконец, для произвольного выбора списка с ```k``` неповторяющимися элементами из последовательности или множества (без замены) ```population``` существует метод ```random.sample(population, k)```:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "185922d7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[91507, 55393, 44598, 36422, 20380]" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "raffle_numbers = range(1, 100001)\n", + "winners = random.sample(raffle_numbers , 5)\n", + "winners" + ] + }, + { + "cell_type": "markdown", + "id": "55229297", + "metadata": {}, + "source": [ + "Итоговый список содержит элементы в порядке их выбора (первый по индексу элемент – выбранный первым), поэтому можно, например, без предвзятости объявить билет с номером 89 734 выигравшим джекпот, а остальные\n", + "четыре номера – «победителями второй категории»." + ] + }, + { + "cell_type": "markdown", + "id": "68a89d9e", + "metadata": {}, + "source": [ + "---" + ] + }, + { + "cell_type": "markdown", + "id": "ab7eb4c4", + "metadata": {}, + "source": [ + "**Пример 17**. Парадокс (задача) Монти Холла (Monty Hall problem) – широко известная задача теории вероятностей, излагаемая в форме воображаемого игрового\n", + "шоу. Участнику предлагается выбрать одну из трех дверей: за одной находится автомобиль, за двумя другими – козы. Участник выбирает дверь, после чего ведущий\n", + "открывает другую дверь, за которой обнаруживается коза. Ведущий заранее знает,\n", + "за какой дверью скрыт автомобиль. Затем участнику предлагается изменить выбор,\n", + "чтобы открыть другую дверь, или оставить в силе свой первоначальный выбор.\n", + "Вопреки здравому смыслу наилучшей стратегией для выигрыша машины\n", + "является изменение выбора, как показано в приведенной ниже имитации\n", + "в листинге 5." + ] + }, + { + "cell_type": "markdown", + "id": "adf1cffe", + "metadata": {}, + "source": [ + "**Листинг 5**. Задача Монти Холла" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "03d57341", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Monty Hall Problem with 3 doors\n", + "Proportion of wins without switching: 0.3242\n", + "Proportion of wins with switching: 0.6561\n" + ] + } + ], + "source": [ + "# eg4-montyhall.py\n", + "import random\n", + "def run_trial(switch_doors, ndoors=3):\n", + " \"\"\"\n", + " Run a single trial of the Monty Hall problem, with or without switching\n", + " after the game show host reveals a goat behind one of the unchosen doors.\n", + " (switch_doors is True or False). The car is behind door number 1 and the\n", + " game show host knows that. Returns True for a win, otherwise returns False.\n", + " \"\"\"\n", + " # \"\"\"\n", + " # Запуск одиночного испытания парадокса (задачи) Монти Холла с изменением или без\n", + " # изменения варианта выбора, после того как ведущий предъявил козу, открыв одну из\n", + " # невыбранных дверей. (Смена выбора двери обозначена как True или False.) Автомобиль\n", + " # находится за дверью номер 1, и ведущий знает это. При выигрыше возвращается значение\n", + " # True,\n", + " # \"\"\"\n", + " # Выбор случайной двери из доступных ndoors.\n", + " chosen_door = random.randint(1, ndoors)\n", + " if switch_doors:\n", + " # Обнаружена коза.\n", + " revealed_door = 3 if chosen_door==2 else 2\n", + " # Изменение варианта выбора на любую другую дверь, отличную от выбранной\n", + " # изначально, при одной открытой двери, за которой обнаружилась коза.\n", + " available_doors = [dnum for dnum in range(1, ndoors+1) if dnum not in (chosen_door, revealed_door)]\n", + " chosen_door = random.choice(available_doors)\n", + " # Выигрыш, если выбрана дверь номер 1.\n", + " return chosen_door == 1\n", + "\n", + "def run_trials(ntrials , switch_doors , ndoors=3):\n", + " \"\"\"\n", + " Run ntrials iterations of the Monty Hall problem with ndoors doors, with\n", + " and without switching (switch_doors = True or False). Returns the number\n", + " of trials which resulted in winning the car by picking door number 1.\n", + " \"\"\"\n", + " # \"\"\"\n", + " # Запуск ntrials итераций задачи Монти Холла с ndoors дверьми с изменением или без\n", + " # изменения варианта выбора (switch_doors = True или False). Возвращает количество\n", + " # испытаний, завершившихся выигрышем автомобиля при выборе двери номер 1.\n", + " # \"\"\"\n", + " nwins = 0\n", + " for i in range(ntrials):\n", + " if run_trial(switch_doors, ndoors):\n", + " nwins += 1\n", + " return nwins\n", + "\n", + "ndoors, ntrials = 3, 10000\n", + "nwins_without_switch = run_trials(ntrials, False, ndoors)\n", + "nwins_with_switch = run_trials(ntrials, True, ndoors)\n", + "print('Monty Hall Problem with {} doors'.format(ndoors))\n", + "print('Proportion of wins without switching: {:.4f}'.format(nwins_without_switch/ntrials))\n", + "print('Proportion of wins with switching: {:.4f}'.format(nwins_with_switch/ntrials))" + ] + }, + { + "cell_type": "markdown", + "id": "50c08f20", + "metadata": {}, + "source": [ + "Без нарушения общности условий задачи можно поместить автомобиль\n", + "за дверью номер 1, оставив для участника возможность выбора любой\n", + "двери случайным образом.\n", + "Чтобы сделать код чуть более интересным, было введено переменное количество дверей в имитации этой задачи (но при этом остается только один\n", + "автомобиль)." + ] + }, + { + "cell_type": "markdown", + "id": "6c752f3f", + "metadata": {}, + "source": [ + "## Пакет urllib" + ] + }, + { + "cell_type": "markdown", + "id": "87fc2bba", + "metadata": {}, + "source": [ + "Пакет ```urllib``` в Python 3 – это набор модулей для открытия и извлечения содержимого (контента), на который указывают URL (Uniform Resource Locators),\n", + "обычно в форме веб-адресов, доступных по протоколу HTTP (HyperText Transfer Protocol), HTTPS или FTP (File Transfer Protocol). В этом разделе предлагается краткая вводная инструкция по использованию пакета ```urllib```." + ] + }, + { + "cell_type": "markdown", + "id": "26726224", + "metadata": {}, + "source": [ + "### Открытие и чтение URL" + ] + }, + { + "cell_type": "markdown", + "id": "e04b54d3", + "metadata": {}, + "source": [ + "Для получения содержимого по URL с использованием протокола HTTP сначала необходимо подготовить HTTP-запрос (HTTP request), создав объект Request. Например:" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "2ad52a66", + "metadata": {}, + "outputs": [], + "source": [ + "import urllib.request\n", + "req = urllib.request.Request('https://www.wikipedia.org')" + ] + }, + { + "cell_type": "markdown", + "id": "45bf58c2", + "metadata": {}, + "source": [ + "Объект ```Request``` позволяет передавать данные (используя команду GET или\n", + "POST) и другую информацию о запросе (метаданные, передаваемые в заголовках HTTP, – см. ниже). Но для простого запроса можно просто открыть URL напрямую как объект, подобный файлу, с помощью метода ```urlopen()```:" + ] + }, + { + "cell_type": "raw", + "id": "b0d2e754", + "metadata": {}, + "source": [ + "response = urllib.request.urlopen(req)" + ] + }, + { + "cell_type": "markdown", + "id": "32f60b85", + "metadata": {}, + "source": [ + "Правильной практической методикой является перехват двух основных типов исключений, которые генерируются при выполнении этой инструкции.\n", + "Первый тип ```URLError``` генерируется, если сервер не существует или если отсутствует сетевое соединение. Второй тип ```HTTPError``` генерируется, если сервер\n", + "возвращает код ошибки (например, 404: Page Not Found).Эти исключения определяются в модуле ```urllib.error```." + ] + }, + { + "cell_type": "raw", + "id": "3d832ed4", + "metadata": {}, + "source": [ + "from urllib.error import URLError , HTTPError\n", + "try:\n", + " response = urllib.request.urlopen(req)\n", + "except HTTPError as e:\n", + " print('The server returned error code', e.code)\n", + "except URLError as e:\n", + " print('Failed to reach server at {} for the following reason:\\n{}'.format(url, e.reason))\n", + "else:\n", + " # Получен ответ об успешном выполнении запроса: OK" + ] + }, + { + "cell_type": "markdown", + "id": "81c070ce", + "metadata": {}, + "source": [ + "Предполагая, что метод ```urlopen()``` отработал успешно, часто не требуются\n", + "какие-либо дополнительные действия, кроме простого чтения контента из\n", + "объекта ответа:" + ] + }, + { + "cell_type": "raw", + "id": "fd058f3b", + "metadata": {}, + "source": [ + "content = response.read()" + ] + }, + { + "cell_type": "markdown", + "id": "1f6ea0f8", + "metadata": {}, + "source": [ + "Контент будет возвращен как строка байтов (bytestring). Для перекодировки\n", + "ее в строку Python (Unicode) необходимо знать, как именно закодирована исходная строка. Правильный ресурс включает определение используемого набора символов в атрибут Content-Type HTTP-заголовка. Его можно применять\n", + "следующим образом:" + ] + }, + { + "cell_type": "raw", + "id": "58febc50", + "metadata": {}, + "source": [ + "charset = response.headers.get_content_charset()\n", + "html = content.decode(charset)" + ] + }, + { + "cell_type": "markdown", + "id": "ba30d615", + "metadata": {}, + "source": [ + "Здесь html становится декодированной Unicode-строкой Python. Если в возвращаемых заголовках не указан используемый набор символов, то можно попытаться сделать вероятное предположение (например, установить charset='utf-8')." + ] + }, + { + "cell_type": "markdown", + "id": "9ee91696", + "metadata": {}, + "source": [ + "## Запросы GET и POST" + ] + }, + { + "cell_type": "markdown", + "id": "8d8df90c", + "metadata": {}, + "source": [ + "Часто необходимо вместе с URL передавать данные для извлечения контента\n", + "с сервера. Например, при заполнении HTML-формы на веб-странице значения\n", + "для соответствующих полей должны быть переведены в требуемую кодировку\n", + "и переданы на сервер в соответствии с протоколами GET или POST.\n", + "Модуль ```urllib.parse``` позволяет кодировать данные из словаря Python в форму, пригодную для передачи на веб-сервер. Ниже приведен пример из «Википедии» для API с использованием запроса GET:" + ] + }, + { + "cell_type": "raw", + "id": "71916f8a", + "metadata": {}, + "source": [ + "url = 'https://wikipedia.org/w/api.php'\n", + "data = {'page': 'Monty_Python', 'prop': 'text', 'action': 'parse', 'section': 0}\n", + "encoded_data = urllib.parse.urlencode(data)\n", + "full_url = url + '?' + encoded_data\n", + "full_url\n", + "req = urllib.request.Request(full_url)\n", + "response = urllib.request.urlopen(req)\n", + "html = response.read().decode('utf-8')" + ] + }, + { + "cell_type": "markdown", + "id": "43811e8b", + "metadata": {}, + "source": [ + "Для выполнения запроса POST вместо добавления перекодированных данных в строку ```?``` эти данные напрямую передаются в конструктор ```Request```:" + ] + }, + { + "cell_type": "raw", + "id": "3a7625de", + "metadata": {}, + "source": [ + "req = urllib.request.Request(url, encoded_data)" + ] + }, + { + "cell_type": "markdown", + "id": "6568996f", + "metadata": {}, + "source": [ + "## Модуль datetime" + ] + }, + { + "cell_type": "markdown", + "id": "4bc679d1", + "metadata": {}, + "source": [ + "Модуль ```datetime``` предоставляет классы для работы с датамии временем.Существует множество тонкостей, связанных с обработкой таких данных (временные́\n", + "пояса и зоны, различные календари, переход на летнее и зимнее время и т. д.),\n", + "поэтому полная документация по модулю datetime доступна в онлайн-режиме\n", + "(https://docs.python.org/3/library/datetime.html). В этом разделе представлен краткий обзор наиболее часто встречающихся вариантов использования." + ] + }, + { + "cell_type": "markdown", + "id": "b7938fd0", + "metadata": {}, + "source": [ + "**Даты**\n", + "Объект ```datetime.date``` представляет конкретный день, месяц и год в идеализированном календаре (предполагается, что используемый в настоящее\n", + "время григорианский календарь применяется для всех дат в прошлом и в\n", + "будущем). Для создания объекта ```date``` необходимо передать в явной форме\n", + "числовые значения, соответствующие году, месяцу и дню, или вызвать конструктор ```date.today```:" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "08812462", + "metadata": {}, + "outputs": [ + { + "ename": "ValueError", + "evalue": "day is out of range for month", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)", + "Input \u001b[1;32mIn [37]\u001b[0m, in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mdatetime\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m date\n\u001b[0;32m 2\u001b[0m birthday \u001b[38;5;241m=\u001b[39m date(\u001b[38;5;241m2004\u001b[39m, \u001b[38;5;241m11\u001b[39m, \u001b[38;5;241m5\u001b[39m) \u001b[38;5;66;03m# OK\u001b[39;00m\n\u001b[1;32m----> 3\u001b[0m notadate \u001b[38;5;241m=\u001b[39m \u001b[43mdate\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m2005\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m2\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m29\u001b[39;49m\u001b[43m)\u001b[49m\n", + "\u001b[1;31mValueError\u001b[0m: day is out of range for month" + ] + } + ], + "source": [ + "from datetime import date\n", + "birthday = date(2004, 11, 5) # OK\n", + "notadate = date(2005, 2, 29) # Ошибка: 2005 год не был високосным." + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "e31a8087", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "datetime.date(2022, 9, 24)" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "today = date.today()\n", + "today" + ] + }, + { + "cell_type": "markdown", + "id": "a531e3e8", + "metadata": {}, + "source": [ + "Допустимыми являются даты в интервале от 1/1/1 до 31/12/9999. Парсинг дат\n", + "с преобразованием в строки и наоборот также поддерживается (см. strptime\n", + "и strftime).\n", + "\n", + "Ниже показано применение некоторых полезных методов объекта ```date```:" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "45ced0fd", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'2004-11-05'" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "birthday.isoformat() # Формат даты по стандарту ISO 8601: YYYY -MM-DD." + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "8bc15811", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "4" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + " birthday.weekday() # Понедельник = 0, Вторник = 1, ..., Воскресенье = 6." + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "ad8ed845", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "birthday.isoweekday() # Понедельник = 1, Вторник = 2, ..., Воскресенье = 7." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "498834ca", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Fri Nov 5 00:00:00 2004'" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "birthday.ctime() # Вывод времени по стандарту C." + ] + }, + { + "cell_type": "markdown", + "id": "e7fe74a3", + "metadata": {}, + "source": [ + "Кроме того, объекты ```date``` можно сравнивать (в хронологическом порядке):" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "627ac21d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "birthday < today" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "id": "e4e04a7f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "today == birthday" + ] + }, + { + "cell_type": "markdown", + "id": "3a49237b", + "metadata": {}, + "source": [ + "## Время" + ] + }, + { + "cell_type": "markdown", + "id": "9f886499", + "metadata": {}, + "source": [ + "Объект ```datetime.time``` представляет (местное) время суток с округлением до\n", + "ближайшей микросекунды. Для создания объекта ```time``` необходимо передать\n", + "числовые значения часов, минут, секунд и микросекунд (в указанном здесь\n", + "порядке, для пропущенных значений по умолчанию устанавливается нулевое\n", + "значение)." + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "fe4a3e0b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "datetime.time(13, 30)" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from datetime import time\n", + "lunchtime = time(hour=13, minute=30)\n", + "lunchtime" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "id": "8f875edd", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'13:30:00'" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "lunchtime.isoformat() # Формат времени по стандарту ISO 8601: HH:MM:SS, если нет мс." + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "id": "3445be28", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'04:46:36.501982'" + ] + }, + "execution_count": 48, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "precise_time = time(4,46,36,501982)\n", + "precise_time.isoformat() # Формат времени по стандарту ISO 8601: HH:MM:SS.mmmmmm" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "id": "b154c1d9", + "metadata": {}, + "outputs": [ + { + "ename": "ValueError", + "evalue": "hour must be in 0..23", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)", + "Input \u001b[1;32mIn [49]\u001b[0m, in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[0m witching_hour \u001b[38;5;241m=\u001b[39m \u001b[43mtime\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m24\u001b[39;49m\u001b[43m)\u001b[49m\n", + "\u001b[1;31mValueError\u001b[0m: hour must be in 0..23" + ] + } + ], + "source": [ + "witching_hour = time(24) # Ошибка: значение часа должно находиться в интервале 0 <=" + ] + }, + { + "cell_type": "markdown", + "id": "824baf03", + "metadata": {}, + "source": [ + "### Объект datetime" + ] + }, + { + "cell_type": "markdown", + "id": "51fef22e", + "metadata": {}, + "source": [ + "Объект ```datetime.datetime``` содержит информацию из обоих объектов ```date```\n", + "и ```time```: year, month, day, hour, minute, second, microsecond. Для этого объекта\n", + "возможна передача значений для всех перечисленных выше атрибутов в конструктор ```datetime```, а также доступны методы ```today``` (возвращает текущую дату)\n", + "и ```now``` (возвращает текущую дату и время):" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "id": "d2fd3eeb", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "datetime.datetime(2022, 9, 24, 10, 7, 22, 527462)" + ] + }, + "execution_count": 50, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from datetime import datetime # Весьма опасная операция импорта.\n", + "now = datetime.now()\n", + "now" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "id": "baeacbfd", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'2022-09-24T10:07:22.527462'" + ] + }, + "execution_count": 51, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "now.isoformat()" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "id": "1596b011", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Sat Sep 24 10:07:22 2022'" + ] + }, + "execution_count": 52, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "now.ctime()" + ] + }, + { + "cell_type": "markdown", + "id": "7e1ffdbb", + "metadata": {}, + "source": [ + "## Форматирование даты и времени" + ] + }, + { + "cell_type": "markdown", + "id": "5a19ca3c", + "metadata": {}, + "source": [ + "Объекты ```date```, ```time``` и ```datetime``` поддерживают метод ```strftime``` для вывода своих значений в виде строки, отформатированной в соответствии с настройками синтаксиса с использованием спецификаторов формата, перечисленных\n", + "в табл. 7." + ] + }, + { + "cell_type": "markdown", + "id": "232d5eca", + "metadata": {}, + "source": [ + "**Таблица 7**. Спецификаторы формата для методов ```strftime``` и ```strptime```. Обратите внимание:\n", + "многие спецификаторы зависят от локали (например, в системе с немецким языком %A будет\n", + "генерировать дни недели Sonntag, Montag и т. д.)" + ] + }, + { + "cell_type": "markdown", + "id": "76c9015d", + "metadata": {}, + "source": [ + "|Спецификатор|Описание|\n", + "|:-----------|:-------|\n", + "|%a|Сокращенное название дня недели (Sun, Mon и т. д.)|\n", + "|%A|Полное название дня недели (Sunday, Monday и т. д.)|\n", + "|%w|Номер дня недели (0 = воскресенье, 1 = понедельник, …, 6 = суббота)|\n", + "|%d|Дополненное нулем число месяца: 01, 02, 03, …, 31|\n", + "|%b|Сокращенное название месяца (Jan, Feb и т. д.)|\n", + "|%B|Полное название месяца (January, February и т. д.)|\n", + "|%m|Дополненный нулем номер месяца: 01, 02, …, 12|\n", + "|%y|Год без века (из двух цифр, с дополнением нулем): 01, 02, …, 99|\n", + "|%Y|Год с веком (из четырех цифр, с дополнением нулями): 0001, 0002, …, 9999|\n", + "|%H|Часы в 24-часовом формате с дополнением нулем: 00, 01, …, 23|\n", + "|%I|Часы в 12-часовом формате с дополнением нулем: 00, 01, …, 12|\n", + "|%p|AM или PM (или равнозначные обозначения в конкретной локали)|\n", + "|%M|Минуты (из двух цифр, с дополнением нулем): 00, 01, …, 59|\n", + "|%S|Секунды (из двух цифр, с дополнением нулем): 00, 01, …, 59|\n", + "|%f |Микросекунды (из шести цифр, с дополнением нулем): 000000, 000001, …, 999999|\n", + "|%%|Знак % как литерал|" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "id": "432add94", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Friday, 05 November 2004'" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "birthday.strftime('%A, %d %B %Y')" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "id": "3f8e30d9", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'10:07:22 on 24/09/22'" + ] + }, + "execution_count": 54, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + " now.strftime('%I:%M:%S on %d/%m/%y')" + ] + }, + { + "cell_type": "markdown", + "id": "36f74a76", + "metadata": {}, + "source": [ + "Для выполнения обратного процесса, т. е. для преобразования строки в объект ```datetime```, применяется метод ```strptime```:" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "id": "74981bba", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1969-07-16 09:32:00\n" + ] + } + ], + "source": [ + "launch_time = datetime.strptime('09:32:00 July 16, 1969', '%H:%M:%S %B %d, %Y')\n", + "print(launch_time) " + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "id": "2205a4b4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "09:32 AM on Wednesday, 16 Jul 1969\n" + ] + } + ], + "source": [ + "print(launch_time.strftime('%I:%M %p on %A, %d %b %Y'))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "29ffee17", + "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.9.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git "a/\320\234\320\224\320\232 02.03 \320\234\320\260\321\202\320\265\320\274\320\260\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\274\320\276\320\264\320\265\320\273\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/1 \320\236\321\201\320\275\320\276\320\262\321\213 Python/pr02 \320\241\320\265\321\200\320\262\320\270\321\201\321\213 \320\276\320\277\320\265\321\200\320\260\321\206\320\270\320\276\320\275\320\275\320\276\320\271 \321\201\320\270\321\201\321\202\320\265\320\274\321\213.ipynb" "b/\320\234\320\224\320\232 02.03 \320\234\320\260\321\202\320\265\320\274\320\260\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\274\320\276\320\264\320\265\320\273\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/1 \320\236\321\201\320\275\320\276\320\262\321\213 Python/pr02 \320\241\320\265\321\200\320\262\320\270\321\201\321\213 \320\276\320\277\320\265\321\200\320\260\321\206\320\270\320\276\320\275\320\275\320\276\320\271 \321\201\320\270\321\201\321\202\320\265\320\274\321\213.ipynb" index ea3b51c..fb6c88a 100644 --- "a/\320\234\320\224\320\232 02.03 \320\234\320\260\321\202\320\265\320\274\320\260\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\274\320\276\320\264\320\265\320\273\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/1 \320\236\321\201\320\275\320\276\320\262\321\213 Python/pr02 \320\241\320\265\321\200\320\262\320\270\321\201\321\213 \320\276\320\277\320\265\321\200\320\260\321\206\320\270\320\276\320\275\320\275\320\276\320\271 \321\201\320\270\321\201\321\202\320\265\320\274\321\213.ipynb" +++ "b/\320\234\320\224\320\232 02.03 \320\234\320\260\321\202\320\265\320\274\320\260\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\274\320\276\320\264\320\265\320\273\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/1 \320\236\321\201\320\275\320\276\320\262\321\213 Python/pr02 \320\241\320\265\321\200\320\262\320\270\321\201\321\213 \320\276\320\277\320\265\321\200\320\260\321\206\320\270\320\276\320\275\320\275\320\276\320\271 \321\201\320\270\321\201\321\202\320\265\320\274\321\213.ipynb" @@ -2,6 +2,7 @@ "cells": [ { "cell_type": "markdown", + "id": "0ba9faa7", "metadata": {}, "source": [ "Практическая работа №2.Сервисы операционной системы" @@ -9,6 +10,7 @@ }, { "cell_type": "markdown", + "id": "72665103", "metadata": {}, "source": [ "## Модуль sys" @@ -16,6 +18,7 @@ }, { "cell_type": "markdown", + "id": "2f2b757e", "metadata": {}, "source": [ "Модуль ```sys``` предоставляет конкретные, зависимые от операционной системы\n", @@ -25,6 +28,7 @@ }, { "cell_type": "markdown", + "id": "6a32ce01", "metadata": {}, "source": [ "## Список sys.argv" @@ -32,6 +36,7 @@ }, { "cell_type": "markdown", + "id": "dbfd9a95", "metadata": {}, "source": [ "Список ```sys.argv``` содержит аргументы командной строки, передаваемые\n", @@ -41,6 +46,7 @@ }, { "cell_type": "raw", + "id": "c961893b", "metadata": {}, "source": [ "# square.py\n", @@ -51,6 +57,7 @@ }, { "cell_type": "markdown", + "id": "14e4c914", "metadata": {}, "source": [ "(Обратите внимание: необходимо преобразовать входное значение в число\n", @@ -71,6 +78,7 @@ }, { "cell_type": "markdown", + "id": "328611f8", "metadata": {}, "source": [ "Но поскольку значение ```n``` не было жестко закодировано в исходном коде, ту\n", @@ -89,6 +97,7 @@ }, { "cell_type": "markdown", + "id": "047fa426", "metadata": {}, "source": [ "## Метод sys.exit" @@ -96,6 +105,7 @@ }, { "cell_type": "markdown", + "id": "04c3d713", "metadata": {}, "source": [ "Вызов ```sys.exit``` приводит к завершению работы программы и к выходу из программной среды Python. Это происходит «аккуратно», поэтому сначала выполняются все команды в блоке ```finally``` конструкции ```try``` и закрываются все открытые файлы. Необязательным аргументом для ```sys.exit``` может быть любой\n", @@ -106,6 +116,7 @@ }, { "cell_type": "markdown", + "id": "3b7e605f", "metadata": {}, "source": [ "**Пример 15**. Распространенный способ помощи пользователям при работе со\n", @@ -114,6 +125,7 @@ }, { "cell_type": "markdown", + "id": "d857f449", "metadata": {}, "source": [ "**Листинг 3**. Вывод сообщения-подсказки для скрипта, принимающего аргументы из командной строки" @@ -121,6 +133,7 @@ }, { "cell_type": "raw", + "id": "6626d3ac", "metadata": {}, "source": [ "# square.py\n", @@ -134,6 +147,7 @@ }, { "cell_type": "markdown", + "id": "51569c71", "metadata": {}, "source": [ "Здесь выводится понятное сообщение об ошибке и завершается работа программы, если не был задан аргумент командной строки (т. е. при обращении\n", @@ -152,6 +166,7 @@ }, { "cell_type": "markdown", + "id": "540fa1f9", "metadata": {}, "source": [ "## Модуль os" @@ -159,6 +174,7 @@ }, { "cell_type": "markdown", + "id": "59dda26f", "metadata": {}, "source": [ "Модуль ```os``` предоставляет разнообразные интерфейсы операционной системы\n", @@ -167,6 +183,7 @@ }, { "cell_type": "markdown", + "id": "0d9a1ccd", "metadata": {}, "source": [ "### Информация о процессе" @@ -174,6 +191,7 @@ }, { "cell_type": "markdown", + "id": "51925f51", "metadata": {}, "source": [ "В программной среде Python процесс (process) – это конкретный экземпляр\n", @@ -201,6 +219,7 @@ }, { "cell_type": "markdown", + "id": "62f56879", "metadata": {}, "source": [ "## Команды файловой системы" @@ -208,6 +227,7 @@ }, { "cell_type": "markdown", + "id": "45d76718", "metadata": {}, "source": [ "Часто возникаетнеобходимость в перемещении по дереву системных каталогов\n", @@ -218,6 +238,7 @@ }, { "cell_type": "markdown", + "id": "677e0d6e", "metadata": {}, "source": [ "**Таблица 4**. Модуль os: некоторые команды файловой системы" @@ -225,6 +246,7 @@ }, { "cell_type": "markdown", + "id": "61df2458", "metadata": {}, "source": [ "|Функция|Описание|\n", @@ -242,6 +264,7 @@ }, { "cell_type": "markdown", + "id": "9c1f2c7e", "metadata": {}, "source": [ "## Операции с путевым именем" @@ -249,6 +272,7 @@ }, { "cell_type": "markdown", + "id": "9eed942a", "metadata": {}, "source": [ "Модуль ```os.path``` предоставляет группу полезных функций для работы с путевыми именами. Версия этой библиотеки, установленная вместе с Python, будет\n", @@ -262,6 +286,7 @@ }, { "cell_type": "markdown", + "id": "f2ee6bd6", "metadata": {}, "source": [ "**Таблица 5**. Модуль ```os.path```: часто применяемые операции с путевым именем" @@ -269,6 +294,7 @@ }, { "cell_type": "markdown", + "id": "60b98821", "metadata": {}, "source": [ "|Функция|Описание|\n", @@ -286,6 +312,7 @@ }, { "cell_type": "markdown", + "id": "cf5d5aa1", "metadata": {}, "source": [ "Ниже показаны примеры некоторых операций, выполняемых с файлом\n", @@ -310,6 +337,7 @@ }, { "cell_type": "markdown", + "id": "913b9c86", "metadata": {}, "source": [ "**Пример 16**. Предположим, что существует каталог с файлами данных, идентифицируемых по именам в формате data-DD-Mon-YY.txt, где DD – число месяца из\n", @@ -320,6 +348,7 @@ }, { "cell_type": "markdown", + "id": "7941aae9", "metadata": {}, "source": [ "**Листинг 4**. Переименование файлов данных для упорядочения по дате" @@ -327,6 +356,7 @@ }, { "cell_type": "raw", + "id": "5208f53f", "metadata": {}, "source": [ "# eg4-osmodule.py\n", @@ -347,6 +377,7 @@ }, { "cell_type": "markdown", + "id": "d992560c", "metadata": {}, "source": [ "Номер месяца вычисляется по индексу соответствующего сокращенного\n", @@ -373,6 +404,7 @@ }, { "cell_type": "markdown", + "id": "33af3a2c", "metadata": {}, "source": [ "# Упражнения" @@ -380,6 +412,7 @@ }, { "cell_type": "markdown", + "id": "c09094cb", "metadata": {}, "source": [ "## Задачи" @@ -387,6 +420,7 @@ }, { "cell_type": "markdown", + "id": "0a30c766", "metadata": {}, "source": [ "**З 0**. Последовательность чисел-градин (hailstone sequence; гипотеза Коллатца – Collatz conjecture), начинающаяся с целого числа n > 0, генерируется с помощью многократно повторяющегося применения следующих трех правил:\n", @@ -406,6 +440,7 @@ }, { "cell_type": "markdown", + "id": "42357ecb", "metadata": {}, "source": [ "**З 2**. Формула гаверсинуса (haversine) позволяет вычислять кратчайшее расстояние (по дуге большой окружности,или по ортодромии) d между двумя точками на сфере радиуса R по значениям долготы (λ1,λ2) и широты (φ1,φ2) этих точек:\n", @@ -428,6 +463,7 @@ }, { "cell_type": "markdown", + "id": "e59052be", "metadata": {}, "source": [ "**З 3**.Написать программу для создания каталога ```test``` в домашнем каталоге\n", @@ -458,6 +494,7 @@ }, { "cell_type": "markdown", + "id": "91b7bc64", "metadata": {}, "source": [ "**З 4**. Изменить программу из примера **П 16** (листинг 4) так, чтобы она\n", @@ -475,8 +512,12 @@ { "cell_type": "code", "execution_count": null, + "id": "28f537aa", "metadata": { - "collapsed": true + "collapsed": true, + "jupyter": { + "outputs_hidden": true + } }, "outputs": [], "source": [] @@ -484,7 +525,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -498,7 +539,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.4.3" + "version": "3.11.5" } }, "nbformat": 4, diff --git "a/\320\234\320\224\320\232 02.03 \320\234\320\260\321\202\320\265\320\274\320\260\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\274\320\276\320\264\320\265\320\273\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/1 \320\236\321\201\320\275\320\276\320\262\321\213 Python/pr03 \320\234\320\276\320\264\321\203\320\273\320\270 \320\270 \320\277\320\260\320\272\320\265\321\202\321\213.ipynb" "b/\320\234\320\224\320\232 02.03 \320\234\320\260\321\202\320\265\320\274\320\260\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\274\320\276\320\264\320\265\320\273\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/1 \320\236\321\201\320\275\320\276\320\262\321\213 Python/pr03 \320\234\320\276\320\264\321\203\320\273\320\270 \320\270 \320\277\320\260\320\272\320\265\321\202\321\213.ipynb" index 6c65fa5..a8b57da 100644 --- "a/\320\234\320\224\320\232 02.03 \320\234\320\260\321\202\320\265\320\274\320\260\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\274\320\276\320\264\320\265\320\273\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/1 \320\236\321\201\320\275\320\276\320\262\321\213 Python/pr03 \320\234\320\276\320\264\321\203\320\273\320\270 \320\270 \320\277\320\260\320\272\320\265\321\202\321\213.ipynb" +++ "b/\320\234\320\224\320\232 02.03 \320\234\320\260\321\202\320\265\320\274\320\260\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\274\320\276\320\264\320\265\320\273\320\270\321\200\320\276\320\262\320\260\320\275\320\270\320\265/1 \320\236\321\201\320\275\320\276\320\262\321\213 Python/pr03 \320\234\320\276\320\264\321\203\320\273\320\270 \320\270 \320\277\320\260\320\272\320\265\321\202\321\213.ipynb" @@ -1477,7 +1477,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.12" + "version": "3.11.5" } }, "nbformat": 4,