{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "9ccc4a00",
   "metadata": {},
   "source": [
    "# Виртуальное окружение #"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cdd20ab8",
   "metadata": {},
   "source": [
    "На этой лекции мы с вами посмотрим, как работать со сторонними библиотеками с ресурсов `pypi.org`, мы установим нашу систему клиент-сервер серверное приложение `Jupiter` ноутбук, которые я активно применяю для создания слайдов в наших уроках. Однако это не единственное применение `Jupiter` Ноутбук, это очень распространённое приложение, которое применяется повсеместно разработчиками на Python, а также учеными для презентации своей работы, для того чтобы показывать сниппеты кода на Python, алгоритмы, результаты проведенной работы и показывать это интерактивно."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "50ad6169",
   "metadata": {},
   "source": [
    "Для того чтобы начать мы должны поговорить о том как поставить сторонний пакет на нашу операционную систему, для этого в Python существует замечательная утилита, которая называется `pip`. наберём `pip install` и название сторонних библиотек, которые мы хотим поставить, в данном случае написал `requests`, это замечательная библиотека для работы с `http` запросами. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "4d11a3c7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Requirement already satisfied: requests in c:\\programdata\\anaconda3\\lib\\site-packages (2.25.1)\n",
      "Requirement already satisfied: idna<3,>=2.5 in c:\\programdata\\anaconda3\\lib\\site-packages (from requests) (2.10)\n",
      "Requirement already satisfied: chardet<5,>=3.0.2 in c:\\programdata\\anaconda3\\lib\\site-packages (from requests) (4.0.0)\n",
      "Requirement already satisfied: certifi>=2017.4.17 in c:\\programdata\\anaconda3\\lib\\site-packages (from requests) (2020.12.5)\n",
      "Requirement already satisfied: urllib3<1.27,>=1.21.1 in c:\\programdata\\anaconda3\\lib\\site-packages (from requests) (1.26.4)\n"
     ]
    }
   ],
   "source": [
    "! pip install requests"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5c66f0b0",
   "metadata": {},
   "source": [
    "`pip install request` ставит request в нашу систему, мы сейчас видим что библиотека `requests` уже установлена в глобальную директорию Python, это не очень удобно, мы не хотим трогать эту установленную версию библиотеки, поэтому следующим шагом нам нужно будет создать виртуальное окружение."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fc9717e7",
   "metadata": {},
   "source": [
    "Виртуальное окружение в Python это окружение, которое позволяет изолировать зависимости для определенного проекта. Например, предположим вы разрабатываете на машине два проекта, причем в этих проектах используется одна и та же библиотека, но разных версий. В одном проекте чуть более старая версия этой библиотеки, в другом чуть более новая. Виртуальное окружение позволяет вам изолировать эти две зависимости друг от друга, так что вы можете работать над двумя проектами параллельно на одном компьютере. Это очень удобно. Тем самым, обновляя библиотеку в одном проекте, вы не сломаете код другого проекта."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "57a1610b",
   "metadata": {},
   "source": [
    "Чтобы создать виртуальное окружение мы воспользуемся модулем, который идет в поставке Рython3 из коробки он называется `venv`."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "393b562d",
   "metadata": {},
   "source": [
    "Чтобы создать виртуальное окружение мы пишем `python3 -m venv` и дальше название директории, в которой будет создано наше виртуальное окружение."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cde9b0a1",
   "metadata": {},
   "source": [
    "Однако перед этим давайте опять создадим директорию, в которой мы будем работать и перейдём в нее. А вот теперь мы можем применить ту команду, о которой я говорил `python3 -m venv .env` запустить ее."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6e3d4421",
   "metadata": {},
   "source": [
    "В этот момент создается виртуальное окружение и если мы посмотрим на структуру директорий, мы видим что создалось папочка `env`, да, как мы ее и назвали. Давайте посмотрим что внутри этой папочки, ограничимся уровнем вложенности три и мы видим что внутри папочки `env` создалось несколько директорий, одна из них `bin`, другая `include`, а также `lib`.\n",
    "\n",
    "```shell\n",
    "tree -L 3\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "52a2b541",
   "metadata": {},
   "outputs": [],
   "source": [
    "! python -m venv .env"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "dc02a475",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "‘вагЄвга  Ї Ї®Є\n",
      "‘ҐаЁ©­л© ­®¬Ґа в®¬ : 044F0438 581B:1E7B\n",
      "C:\\USERS\\MIKHAYLOVAF\\PYTHON\\1. ‚‚…„…Ќ€… ‚ PYTHON\\4. ЋђѓЂЌ€‡Ђ–€џ ЉЋ„Ђ € ЋЉђ“†…Ќ€…\\.ENV\n",
      "ГДДДInclude\n",
      "ГДДДLib\n",
      "і   АДДДsite-packages\n",
      "і       ГДДДpip\n",
      "і       і   ГДДД_internal\n",
      "і       і   і   ГДДДcli\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   ГДДДcommands\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   ГДДДdistributions\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   ГДДДindex\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   ГДДДmodels\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   ГДДДnetwork\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   ГДДДoperations\n",
      "і       і   і   і   ГДДДbuild\n",
      "і       і   і   і   і   АДДД__pycache__\n",
      "і       і   і   і   ГДДДinstall\n",
      "і       і   і   і   і   АДДД__pycache__\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   ГДДДreq\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   ГДДДresolution\n",
      "і       і   і   і   ГДДДlegacy\n",
      "і       і   і   і   і   АДДД__pycache__\n",
      "і       і   і   і   ГДДДresolvelib\n",
      "і       і   і   і   і   АДДД__pycache__\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   ГДДДutils\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   ГДДДvcs\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   АДДД__pycache__\n",
      "і       і   ГДДД_vendor\n",
      "і       і   і   ГДДДcachecontrol\n",
      "і       і   і   і   ГДДДcaches\n",
      "і       і   і   і   і   АДДД__pycache__\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   ГДДДcertifi\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   ГДДДchardet\n",
      "і       і   і   і   ГДДДcli\n",
      "і       і   і   і   і   АДДД__pycache__\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   ГДДДcolorama\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   ГДДДdistlib\n",
      "і       і   і   і   ГДДД_backport\n",
      "і       і   і   і   і   АДДД__pycache__\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   ГДДДhtml5lib\n",
      "і       і   і   і   ГДДДfilters\n",
      "і       і   і   і   і   АДДД__pycache__\n",
      "і       і   і   і   ГДДДtreeadapters\n",
      "і       і   і   і   і   АДДД__pycache__\n",
      "і       і   і   і   ГДДДtreebuilders\n",
      "і       і   і   і   і   АДДД__pycache__\n",
      "і       і   і   і   ГДДДtreewalkers\n",
      "і       і   і   і   і   АДДД__pycache__\n",
      "і       і   і   і   ГДДД_trie\n",
      "і       і   і   і   і   АДДД__pycache__\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   ГДДДidna\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   ГДДДmsgpack\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   ГДДДpackaging\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   ГДДДpep517\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   ГДДДpkg_resources\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   ГДДДprogress\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   ГДДДrequests\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   ГДДДresolvelib\n",
      "і       і   і   і   ГДДДcompat\n",
      "і       і   і   і   і   АДДД__pycache__\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   ГДДДtoml\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   ГДДДurllib3\n",
      "і       і   і   і   ГДДДcontrib\n",
      "і       і   і   і   і   ГДДД_securetransport\n",
      "і       і   і   і   і   і   АДДД__pycache__\n",
      "і       і   і   і   і   АДДД__pycache__\n",
      "і       і   і   і   ГДДДpackages\n",
      "і       і   і   і   і   ГДДДbackports\n",
      "і       і   і   і   і   і   АДДД__pycache__\n",
      "і       і   і   і   і   ГДДДssl_match_hostname\n",
      "і       і   і   і   і   і   АДДД__pycache__\n",
      "і       і   і   і   і   АДДД__pycache__\n",
      "і       і   і   і   ГДДДutil\n",
      "і       і   і   і   і   АДДД__pycache__\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   ГДДДwebencodings\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   АДДД__pycache__\n",
      "і       і   АДДД__pycache__\n",
      "і       ГДДДpip-20.2.3.dist-info\n",
      "і       ГДДДpkg_resources\n",
      "і       і   ГДДДextern\n",
      "і       і   і   АДДД__pycache__\n",
      "і       і   ГДДД_vendor\n",
      "і       і   і   ГДДДpackaging\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   АДДД__pycache__\n",
      "і       і   АДДД__pycache__\n",
      "і       ГДДДsetuptools\n",
      "і       і   ГДДДcommand\n",
      "і       і   і   АДДД__pycache__\n",
      "і       і   ГДДДextern\n",
      "і       і   і   АДДД__pycache__\n",
      "і       і   ГДДД_distutils\n",
      "і       і   і   ГДДДcommand\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   АДДД__pycache__\n",
      "і       і   ГДДД_vendor\n",
      "і       і   і   ГДДДpackaging\n",
      "і       і   і   і   АДДД__pycache__\n",
      "і       і   і   АДДД__pycache__\n",
      "і       і   АДДД__pycache__\n",
      "і       ГДДДsetuptools-49.2.1.dist-info\n",
      "і       АДДД__pycache__\n",
      "АДДДScripts\n"
     ]
    }
   ],
   "source": [
    "! tree .env"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f0562d32",
   "metadata": {},
   "source": [
    "Директория `bin` содержит исполняемый файл python который на самом деле ссылается на наш глобально установленный python, также внутри `bin` директория Virtualenv есть утилита `pip`, а также другие вещи важные из которых скрипт `activate`, этот скрипт позволит нам активировать наше виртуальное окружение. Также обратите внимание на папочку `lib`, именно в эту директорию будут ставится сторонние зависимости когда мы будем работать в виртуальном окружении. Итак, давайте активируем виртуальное окружение. Обратите внимание, что все примеры, которые я здесь показываю для работы с виртуальным окружением в данном случае я работаю на Linux, а вот для Windows виртуальное окружение, структура его директории будут немного отличаться. Все остальные концепции, о которых я буду рассказывать справедливы для всех систем.\n",
    "\n",
    "- [Виртуальное окружение на Windows](Виртуальное%20окружение%20на%20Windows.ipynb)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "643ab7b8",
   "metadata": {},
   "source": [
    "Итак мы должны активировать виртуальное окружение, это делается с помощью команды `source` на unix-подобных системах и мы должны вызвать `source env/bin/activate`, чтобы деактивировать виртуальное окружение, мы набираем `deactivite`."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "13a3e80c",
   "metadata": {},
   "source": [
    "Однако нам всё же нужно работать в виртуальном окружении поэтому давайте его активируем опять и теперь установим в него сторонний модуль. Установим библиотечку `requests`, с которой мы уже начинали, она быстро устанавливается и теперь, когда мы пишем `python`, мы уже можем писать не `python3`, а `python` потому что, в данном случае мы находится в виртуальном окружении и `python` ссылается на `python3`.\n",
    "\n",
    "```shell\n",
    "pip install requests\n",
    "```\n",
    "\n",
    "```python\n",
    "import requests\n",
    "```\n",
    "\n",
    "Мы можем делать импорт только что установленной библиотечки `request`.\n",
    "\n",
    "- [Работа offline](Работа%20offline.ipynb)\n",
    "\n",
    "Продолжим идти к нашей цели, напомню, это `Jupiter` ноутбук и установим его, делается это точно также `pip install jupiter` ноутбук содержится в пакете `jupiter`, запускаем. Как вы видите пошёл процесс установки, в этот момент `pip` утилита загружает все необходимые зависимости пакета `jupither` с ресурса по `pip.org` а также зависимости зависимостей, среди которых на самом деле достаточно много всевозможных пакетов, но тем не менее, всё это происходит автоматически и когда процесс заканчивается у вас всё должно быть успешно установлено.\n",
    "\n",
    "Вот мы видим на экране, что у нас всё получилось и прежде чем запустить `Jupiter` ноутбук хотелось бы обратить внимание на ещё на один полезный пакет, который установился вместе с зависимостями `Jupiter` это пакет `ipython`. `ipython` это расширенная версия интерактивный интерпретатор Python. Если вы любите экспериментировать в интерактивном интерпретаторе Python, то рассмотрите `ipython` в качестве альтернативы, помимо подсветки синтаксиса, которая присутствует в `ipython`, там есть ещё много классных особенностей, которые позволят вам упростить жизнь. Например, это автодополнение, хранение истории и всевозможные полезные макросы."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a59124a3",
   "metadata": {},
   "source": [
    "Теперь мы можем попробовать всё-таки запустить наш `Jupiter` ноутбук, он установлен в виртуальное окружение, теперь его исполняемые файлы находятся в папочке `bin` виртуального окружения и командой `jupiter-notebook` мы можем его запустить. Как я говорил это клиент-серверное веб-приложение, которое запускается в веб-браузере, веб-браузер у меня открылся автоматически и мы внутри этого веб-приложения можем создавать наши ноутбуки. Нажимаю на кнопочку `New`, выбираем `Python3` и у нас открывается наш ноутбук, по сути он состоит из ячеек в которых мы можем набирать питоновский код, делать любые импорты пакетов, которые у нас установлены и по сути всё, что мы можем делать в интерактивном интерпретаторе Python, мы можем сделать здесь, однако все эти ноутбуки можно сохранить, можно вернуться к ним в дальнейшем и проглядеть заново, перезапустить ячейки, это очень удобно. Как вы можете видеть я слайдах использую Jupiter ноутбук в качестве инструмента для создания слайдов например.\n",
    "\n",
    "На этой лекции мы с вами познакомились с виртуальным окружением в Python, научились ставить пакеты в нашу операционную систему, также мы установили Jupiter ноутбук, который является полезным инструментом для всех программистов на Python."
   ]
  }
 ],
 "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.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
