{
"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*, в которой мы будем хранить ноутбук-файлы, содержащие наши программы. Для этого нужно нажать на кнопку в правом верхнем углу и выбрать в списке *Folder*."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Поскольку новая папка по умолчанию получает имя *Untitled Folder*, нам потребуется переименовать ее. Для этого нужно кликнуть на нее и в появившемся в левом верхнем углу блоке выбрать *Rename*. Другие две кнопки позволяют переместить или удалить папку."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Теперь в новой папке создадим наш первый ноутбук-файл: переходим в папку *Notebooks*, снова нажимаем и в появившемся списке на этот раз выбираем *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": [
"Если нажать на флажок слева от значка в виде книги, то в левом верхнем углу появятся кнопки "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Кнопка *Duplicate* создает копию ноутбук-файла, *View* открывает интерфейс для его редактирования и выполнения содержащегося в нем исходного кода (см. далее), а *Shutdown* останавливает ядро, связанное с этим ноутбук-файлом. Заметим, что после остановки ядра значок книги меняет цвет на серый, а блок кнопок, представленный выше, принимает такой вид При этом вы не сможете выполнить исходный код, находящийся в ноутбук-файле, ведь без работающего ядра нет доступа к интерпретатору 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* или с помощью кнопки на панели инструментов."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"В меню *Edit* содержатся команды для различных операций над ячейками:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"1. Cut/Copy/Paste для ячеек. Вместо них можно использовать кнопки на панели инструментов.\n",
"2. Перемещение ячейки вверх или вниз (*Move Cell Up*, *Move Cell Down*) в списке. Для этого также могут использоваться кнопки на панели инструментов.\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* (кнопка на панели инструментов), которая заставляет ядро прекратить выполнение текущей программы - это может понадобиться, если ваша программа \"зависла\" и не может закончить работу. Прервав ее выполнение, вы сможете исправить ошибку и запустить ее повторно."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"В заключение заметим, что большинство команд в среде разработки Jupyter Notebook можно выполнять используя быстрые комбинации клавиш. Например, если ноутбук-файл находится в командном режиме, то для добавления новой ячейки достаточно просто нажать на клавиатуре клавишу *B*. Полный список таких комбинаций можно посмотреть в разделе *Keyboard Shortcuts* меню *Help* или нажав кнопку (обратите внимание, что комбинации представлены раздельно для командного режима и режима правки)."
]
},
{
"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": [
"Тип ячейки можно выбрать на панели инструментов в списке или в разделе *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* или нажав кнопку на панели инструментов. При этом происходит следующее:"
]
},
{
"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
}