{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Знакомство с Jupyter Notebook" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В этой лекции мы познакомимся с возможностями, которые предоставляет Jupyter Notebook для разработки программ: редактирование и выполнение исходного кода, добавление к нему сопроводительной информации." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Содержание" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* [Запуск Jupyter Notebook](#Запуск-Jupyter-Notebook)\n", "* [Сервер Jupyter Notebook](#Сервер-Jupyter-Notebook)\n", "* [Интерфейс Jupyter Notebook](#Интерфейс-Jupyter-Notebook)\n", "* [Редактирование ноутбук-файлов](#Редактирование-ноутбук-файлов)\n", "* [Типы ячеек](#Типы-ячеек)\n", " * [Ячейки Code](#Ячейки-Code)\n", " * [Ячейки Markdown](#Ячейки-Markdown)\n", "* [Вопросы для самоконтроля](#Вопросы-для-самоконтроля)\n", "* [Задание](#Задание)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Запуск Jupyter Notebook" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Чтобы запустить Jupyter Notebook, в меню *Программы* ОС Windows нужно найти папку *Anaconda* и нажать на соответствующем элементе." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![Меню \"Программы\"](./images/03/programs.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "После этого будет открыто два новых окна. Первым появится небольшое черное окно, в котором будет запущен **сервер** Jupyter Notebook, а через некоторое время откроется браузер, в котором будет представлен **интерфейс** для создания и выполнения программ в среде Jupyter Notebook." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![Работающий Jupyter Notebook](./images/03/jupyter-working.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Работа в среде Jupyter Notebook в основном выполняется в специальных файлах, называемых **ноутбуками** и имеющих расширение *.ipynb*. В этих файлах хранится исходный код на языке Python, результаты его выполнения, а также любая дополнительная информация: текст, ссылки, математические формулы, изображения и другое." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Сервер Jupyter Notebook" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Cервер - это компонент Jupyter Notebook, чья задача заключается в выполнении команд, поступающих от пользователя через интерфейс в браузере. Окно сервера нельзя закрывать, если вы еще не закончили работу в Jupyter Notebook и не сохранили все свои изменения - они могут быть безвозвратно утеряны. В остальном, обращать внимание на то, что происходит в окне сервера, нам не понадобится." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Для каждого ноутбук-файла, с которым работает пользователь, сервер запускает **ядро** (kernel) - компонент, предоставляющий необходимый или полезный функционал для языка программирования Python. К этому функционалу в первую очередь относятся интерпретатор и набор специализированных расширений языка. Ядро для языка программирования Python называется **IPython**." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> Существуют ядра, добавляющие в среду разработки Jupyter Notebook поддержку других языков программирования, отличных от Python. Это означает, что в Jupyter Notebook можно писать программы на самых разных языках, однако Python используется наиболее часто." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Интерфейс Jupyter Notebook" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Для удобного взаимодействия с сервером существует достаточно простой и интуитивно понятный интерфейс, который открывается в браузере при запуске Jupyter Notebook." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Для начала давайте создадим новую папку *Notebooks*, в которой мы будем хранить ноутбук-файлы, содержащие наши программы. Для этого нужно нажать на кнопку \"New\" в правом верхнем углу и выбрать в списке *Folder*." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Поскольку новая папка по умолчанию получает имя *Untitled Folder*, нам потребуется переименовать ее. Для этого нужно кликнуть на нее и в появившемся в левом верхнем углу блоке \"Rename-Move-Delete\" выбрать *Rename*. Другие две кнопки позволяют переместить или удалить папку." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Теперь в новой папке создадим наш первый ноутбук-файл: переходим в папку *Notebooks*, снова нажимаем \"New\" и в появившемся списке на этот раз выбираем *Python 3*. После этого в браузере откроется новая вкладка, в которой мы в дальнейшем будем редактировать ноутбук-файл. Пока однако вернемся на вкладку *Home*, и посмотрим, как она выглядит теперь." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![Управление ноутбук-файлами](./images/03/notebook-management.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Только что созданный ноутбук-файл находится в состоянии **Running**, о чем сообщает зеленый цвет значка в виде книги слева от имени ноутбук-файла, а также строка *Running* в правой части окна. Это означает, что для него запущено ядро, а следовательно исходный код в нем можно выполнить и посмотреть результат. Список всех запущенных в данный момент ноутбук-файлов можно посмотреть на вкладке *Running* в этом же окне (выделена зеленым цветом)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Если нажать на флажок слева от значка в виде книги, то в левом верхнем углу появятся кнопки \"Duplicate-Shutdown-View-Edit-Delete\"style=\"display:inline;margin:auto\"/" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Кнопка *Duplicate* создает копию ноутбук-файла, *View* открывает интерфейс для его редактирования и выполнения содержащегося в нем исходного кода (см. далее), а *Shutdown* останавливает ядро, связанное с этим ноутбук-файлом. Заметим, что после остановки ядра значок книги меняет цвет на серый, а блок кнопок, представленный выше, принимает такой вид \"Duplicate-Rename-Move-Download-View-Edit-Delete\" При этом вы не сможете выполнить исходный код, находящийся в ноутбук-файле, ведь без работающего ядра нет доступа к интерпретатору Python." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Редактирование ноутбук-файлов" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Теперь рассмотрим интерфейс, с помощью которого мы будем редактировать наш ноутбук-файл и выполнять содержащийся в нем исходный код. Для этого нам нужно запустить его, либо кликнув по его имени, либо воспользовавшись кнопкой *View*, о которой мы рассказывали в предыдущем разделе. В результате будет открыта новая вкладка, в которой будет представлено содержимое нашего ноутбук-файла." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![Ноутбук-файл](./images/03/notebook-edit.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Как и при создании папки, новый ноутбук-файл по умолчанию получает имя *Untitled*. Давайте изменим его на *Test*. Для этого нужно либо кликнуть мышкой по имени файла (выделено красным), либо воспользоваться командой *Rename* в меню *File*. Там же можно найти и другие команды, традиционно помещаемые в меню *File* в ОС Windows: для открытия/закрытия файла, его печати и преобразования в другой формат. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Содержимое ноутбук-файла представляет собой набор **ячеек**, в которых содержится обычный текст или исходный код на языке Python. Существует два режима работы с ноутбук-файлом:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "1. **Командный режим** - текущая ячейка выделена серой рамкой с голубой левой гранью. На рисунке выше ноутбук-файл находится в этом режиме. В командном режиме осуществляется управление ячейками: создание новых, изменение положения существующих, удаление ненужных и т.д.\n", "2. **Режим правки** - текущая ячейка выделена зеленой рамкой с зеленой же левой гранью. В этом режиме осуществляется редактирование содержимого ячейки: ввод исходного кода или иной информации. Перейти в этот режим можно нажав клавишу *Enter* на нужной ячейке, вернуться обратно в командный режим можно нажав *Esc*. ![Режим правки](./images/03/cell-edit-mode.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Добавлять новые ячейки можно с помощью команд меню *Insert*, которые называются *Insert Cell Above* и *Insert Cell Below* или с помощью кнопки \"Plus\" на панели инструментов." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В меню *Edit* содержатся команды для различных операций над ячейками:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "1. Cut/Copy/Paste для ячеек. Вместо них можно использовать кнопки \"Cut-Copy-Paste\" на панели инструментов.\n", "2. Перемещение ячейки вверх или вниз (*Move Cell Up*, *Move Cell Down*) в списке. Для этого также могут использоваться кнопки \"Up-Down-Arrow\" на панели инструментов.\n", "3. Удаление ячеек (*Delete Сells*).\n", "4. Слияние нескольких ячеек в одну и наоборот, разбиение одной большой ячейки на несколько меньших (*Merge Cell*, *Split cell*)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В меню *View* содержатся команды, влияющие на внешний вид интерфейса для редактирования ноутбук-файла, например, скрывающие или показывающие панель инструментов." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В меню *Cell* содержатся команды для выполнения исходного кода в одной или сразу нескольких ячейках. Более подробно мы познакомимся с ними чуть позже." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В меню *Kernel* содержатся команды для управления ядром, связанным с данным ноутбук-файлом: его остановки, перезапуска и т.д. Наиболее полезна для нас команда *Interrupt* (кнопка \"Stop\" на панели инструментов), которая заставляет ядро прекратить выполнение текущей программы - это может понадобиться, если ваша программа \"зависла\" и не может закончить работу. Прервав ее выполнение, вы сможете исправить ошибку и запустить ее повторно." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В заключение заметим, что большинство команд в среде разработки Jupyter Notebook можно выполнять используя быстрые комбинации клавиш. Например, если ноутбук-файл находится в командном режиме, то для добавления новой ячейки достаточно просто нажать на клавиатуре клавишу *B*. Полный список таких комбинаций можно посмотреть в разделе *Keyboard Shortcuts* меню *Help* или нажав кнопку \"Keyboard\" (обратите внимание, что комбинации представлены раздельно для командного режима и режима правки)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Типы ячеек" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Существует два основных типа ячеек в ноутбук-файле:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "1. **Code** - ячейка с исходным кодом на языке Python. Эти ячейки обрабатываются интерпретатором Python, чтобы выполнить программу, написанную в них.\n", "2. **Markdown** - ячейка, содержащая любую информацию, не являющуюся исходным кодом: обычный текст, ссылки, математические формулы, изображения и другое. Эти ячейки не обрабатываются интерпретатором Python." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Тип ячейки можно выбрать на панели инструментов в списке \"Code\" или в разделе *Cell Type* меню *Cell*. По умолчанию все новые ячейки имеют тип Code. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Ячейки Code" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Эти ячейки визуально отличаются от остальных наличием слева надписи *In [ ]*. Внутри квадратных скобок может быть:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* пустота - если ячейка еще ни разу не выполнялась\n", "* символ \" \\* \" - если ячейка выполняется в данный момент\n", "* число - если ячейка была выполнена, при этом число означает ее порядковый номер среди всех выполненных ячеек" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Давайте напишем нашу первую программу на языке Python, которая будет складывать числа 1 и 2. Для этого нужно просто ввести в ячейку с типом Code выражение `1 + 2`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Следующим этапом должно стать выполнение нашей программы и получение результата ее работы. Для этого ячейку, в которую введен исходный код, нужно выполнить. Это можно сделать с помощью одной из команд *Run* меню *Cell* или нажав кнопку \"Run\" на панели инструментов. При этом происходит следующее:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "1. интерфейс дает ядру команду выполнить ячейку\n", "2. ядро \"видит\", что ячейка содержит исходный код Python и запускает интерпретатор\n", "3. интерпретатор выполняет программу и возвращает результат ее работы ядру\n", "4. ядро передает результат интерфейсу, чтобы отобразить его на экране" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В результате ваша ячейка примет такой вид:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 + 2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Напомним, что программа должна соответствовать определенным правилам (лексическим и синтаксическим), чтобы быть выполненной интерпретатором. Если при вводе программы разработчик допускает некоторую ошибку, то при ее выполнении будет сгенерировано **исключение**. В Jupyter Notebook при этом выводится полная информация о нем, которая поможет устранить ошибку:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "ename": "SyntaxError", "evalue": "invalid syntax (, line 1)", "output_type": "error", "traceback": [ "\u001b[1;36m File \u001b[1;32m\"\"\u001b[1;36m, line \u001b[1;32m1\u001b[0m\n\u001b[1;33m 1 +\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n" ] } ], "source": [ "1 +" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В примере выше мы \"забыли\" добавить второе слагаемое в выражение, поэтому при попытке выполнить эту программу было сгенерировано исключение `SyntaxError`. По его названию можно понять, что ошибка связана с некорректным синтаксисом программы. Кроме того, внимательно изучив информацию об ошибке, можно увидеть ее текстовое описание (\"invalid syntax\"), а также номер строки и позицию внутри нее, где она произошла. Более подробно с исключениями мы познакомимся в дальнейшем." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Упомянем еще о том, что в языке программирования Python можно размещать в исходном коде **комментарии** - произвольный текст, не обрабатываемый интерпретатором и как правило содержащий пояснения по работе программы. Комментарии нужны потому, что программа часто создается одними людьми, а сопровождается и модифицируется другими, которым потребуется разбираться в чужом исходном коде, и дополнительная информация о сложных или неочевидных моментах в нем придется очень кстати. Существует негласное правило о том, что комментарии в исходном коде должны быть на английском языке, однако в примерах в данном курсе мы в основном используем русский, чтобы проще было усваивать материал." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В языке Python однострочные комментарии создаются с помощью символа *#* - если этот символ встречается в строке исходного кода, то все, что следует после него и до конца строки считается комментарием. Если требуется создать комментарий, содержащий несколько строк, то перед первой строкой и в конце последней нужно поставить три одинарных кавычки *'''*." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "'''\n", "WARNING: This program is property of course developers\n", "and protected by copyright law!\n", "This is an example of multi-line comment and developers\n", "sense of humour.\n", "'''\n", "\n", "# soon we will calculate sum of 1 and 2\n", "\n", "1 + 2 # almost done..\n", "\n", "# done" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Ячейки Markdown" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Markdown - это упрощенный язык разметки, с помощью которого в обычный текст можно вставлять информацию о том, как он должен быть отформатирован. Например, если какую-то часть текста заключить в символы \" \\* \", то она будет выведена курсивом: \\*некоторый текст\\* будет преобразован в *некоторый текст*." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Чтобы применить форматирование, которое вы добавили в текст в ячейке Markdown, ее нужно выполнить тем же способом, что и ячейку Code. Естественно, что никакой интерепретатор при этом не вызывается (так как в ячейке Markdown не должен быть исходный код), вместо этого ячейка просто отображается с учетом вашего форматирования." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Поскольку среда разработки Jupyter Notebook ориентирована во многом на решение математических задач, было логично добавить в нее возможность легко вводить формулы в традиционной математической нотации. Это возможно благодаря наличию поддержки языка компьютерной верстки [LaTeX](https://ru.wikipedia.org/wiki/LaTeX), информацию о котором достаточно легко найти в интернете. Мы лишь приведем пример того, как выглядит формула плотности вероятности нормального распределения, записанная в нотации LaTeX до и после выполнения содержащей ее ячейки Markdown:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* до: \\$\\$f(x)=\\frac{1}{\\sigma\\sqrt{2\\pi}}\\exp\\left(-\\frac{(x-\\mu)^2}{2\\sigma^2}\\right)\\$\\$\n", "* после: $$f(x)=\\frac{1}{\\sigma\\sqrt{2\\pi}}\\exp\\left(-\\frac{(x-\\mu)^2}{2\\sigma^2}\\right)$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Мы не будем подробно рассматривать синтаксис языка разметки Markdown - всю необходимую информацию по нему легко можно получить в [статье](https://ru.wikipedia.org/wiki/Markdown) на Википедии. Еще один хороший англоязычный ресурс по Markdown находится [тут](https://www.markdownguide.org/)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Вопросы для самоконтроля" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "1. Что называется ноутбуком в среде разработки Jupyter Notebook? Что может содержаться в нем?\n", "2. Чем является IPython для среды разработки Jupyter Notebook? Какие функции он выполняет?\n", "3. В каком режиме осуществляется ввод программы или текста в ячейку? Как при этом она выглядит?\n", "4. Какой командой нужно воспользоваться, если ваша программа \"зависла\"?\n", "5. Какие типы ячеек существуют в ноутбук-файлах? Чем они отличаются?\n", "6. Что происходит, когда вы выполняете ячейку с исходным кодом?\n", "7. Что такое Markdown?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Задание" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "1. Создайте новый ноутбук-файл. Напишите в нем программу, высчитывающую любое сложное арифметическое выражение с операциями сложения/вычитания (\" + \" и \" - \") и умножения/деления (\" \\* \" и \" / \"). Убедитесь в том, что операции умножения/деления имеют более высокий приоритет и выполняются перед операциями сложения/вычитания, как и принято в математике. Воспользуйтесь скобками \" ( ) \" для того, чтобы изменить порядок вычислений в вашем выражении и получить иной результат." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- - -\n", "[Предыдущая: Установка Python](02_Installing_Python.ipynb) |\n", "[Содержание](00_Overview.ipynb#Содержание) |\n", "[Следующая: Типы данных](04_Data_Types.ipynb)" ] } ], "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.6.4" } }, "nbformat": 4, "nbformat_minor": 2 }