<jupyter_start><jupyter_text>Материал распространяется по  лицензии Creative Commons Attribution license, CC-BY 4.0; code under MIT license. Оригинальный курс (c)2014 <NAME>. Thanks: <NAME> and <NAME>, and NSF for support via CAREER award 1149784.Перевоод (c) 2018 <NAME>  Версия 0.1 -- Январь 2018  Ликбез по Python Перед вами короткое и весьма поверхностное введение в Python. Изложенной в нем информации должно хватить для работы с набором блокнотов, составляющих курс _AeroPython_. (Этот документ основан на вводной лекции курса [_CFD Python_](http://lorenabarba.com/blog/cfd-python-12-steps-to-navier-stokes/) профессора <NAME> (<NAME>)Может быть Python уже установлен на вашем компьютере, вероятность этого особенно высока, если вы используете в качестве операционной системы OSX или какой-нибудь вариант Linux. В любом случае, лучше скачать и установить свободный дистрибутив [Anaconda Scientific Python](https://www.continuum.io/downloads). Это сильно упростит знакомство с языком.Вероятно, вы захотите завести собственную локальную копию этого блокнота, или даже всего набора _AeroPython_. В таком случае, советую знакомиться с материалом последовательно, шаг за шагом, экспериментируя с кодом непосредственно в блокноте, или набирая его в отдельном интерактивном окне Python.Если вы хотите работать на своем компьютере, используя установленную Anacond'у, вам нужно открыть окно терминала в директории, содержащей файлы с расширением .ipynb. Для запуска сервера блокнотов наберите в терминале `jupyter notebook`Откроется окно браузера со вкладкой, отображающей список блокнотов в рабочей директории. Выбирайте нужный и начинайте работу!  Библиотеки Python это свободный язык  программирования высокого уровня. *Экосистема Python* включает в себя множество пакетов и библиотек, позволяющих, например, выполнять операции с массивами, рисовать графики и многое другое. Библиотеки можно импортировать в вашу программу для расширения возможностей языка.Давайте начнем с импорта нескольких полезных библиотек. Первая — **NumPy** содержит функции для работы с массивами, похожа на MATLAB. Мы будем очень часто её использовать. Вторая  — **Matplotlib**, библиотека для создания двумерной графики, мы будем пользоваться ею для отрисовки результатов.С этих строчек будет начинаться большинство ваших программ:<jupyter_code># <-- комментарии в Python обозначаются знаком решетки

import numpy                 # импорт библиотеки для работы с массивами
from matplotlib import pyplot    # импорт библиотеки для отрисовки графики<jupyter_output><empty_output><jupyter_text>Мы импортировали библиотеку `numpy` и _модуль_ `pyplot` из большой библиотеки `matplotlib`. Чтобы воспользоваться какой-нибудь функцией из этих библиотек, мы должны указать интерпретатору, где именно её искать. Для этого перед именем функции нужно написать имя библиотеки. Имена разделяются точкой. Например, если нужно использовать функцию [`linspace()`](http://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html) для создания массива чисел, равномерно распределённых на каком-либо интервале, это можно сделать при помощи вызова:<jupyter_code>myarray = numpy.linspace(0, 5, 10)
print(myarray)<jupyter_output>[ 0.          0.55555556  1.11111111  1.66666667  2.22222222  2.77777778
  3.33333333  3.88888889  4.44444444  5.        ]<jupyter_text>Если же не добавить к `linspace()` префикс `linspace()`, то **интерпретатор выдаст ошибку**, так как неизвестно, где искать необходимую функцию:<jupyter_code>myarray = linspace(0, 5, 10)<jupyter_output><empty_output><jupyter_text>Нужно сказать, что Функция [`linspace()`](http://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html) очень полезная. Попробуйте изменить входные параметры.  Способы импорта: Вам часто будут встречаться фрагменты кода, в которых используются строки такого вида:```Pythonimport numpy as npimport matplotlib.pyplot as plt```Для чего нужна конструкция `import-as`? Таким способом можно создать ссылку на импортируемые библиотеки или модули. Это довольно стандартная практика, однако в данном курсе мы будем использовать импорт в *явном* виде. Такой способ делает код более читаемым.  Советы профессионалов: Возможно, вам попадутся случаи, когда импортируется все содержимое библиотеки без создания ссылок (например, `from numpy import *`). Такой способ экономит усилия, связанные с набором текста программы, но несколько неряшлив. Лучше заводить хорошие привычки с самого начала!Для знакомства с доступными функциями, обратитесь к документации [NumPy Reference](http://docs.scipy.org/doc/numpy/reference/). Тем, кто хорошо знаком с `Matlab`,  может оказаться полезной вики-страничка [NumPy for Matlab Users](http://wiki.scipy.org/NumPy_for_Matlab_Users)  Переменные В Python не требуется явно указывать тип декларируемой переменной, в отличие от C, например. Нужно просто присвоить какое-нибудь значение переменной, и интерпретатор все поймет сам:<jupyter_code>a = 5      # a — целое число 5
b = 'five' # b — строка 'five'
c = 5.0    # c — число с плавающей точкой 5.0<jupyter_output><empty_output><jupyter_text>Можно узнать, какой тип был приписан переменной:<jupyter_code>type(a)
type(b)
type(c)<jupyter_output><empty_output><jupyter_text>В третьей версии языка (Python 3) результатом операции деления целых чисел, чисел с плавающей точкой или их комбинации будет число с плавающей точкой машинной точности. Например, два выражения<jupyter_code>14/a
14/c<jupyter_output><empty_output><jupyter_text>дадут один и тот же результат.  Отступы в Python Для группировки выражений в Python используются отступы и пробелы. Например, если нам потребуется написать короткий цикл на C, получится что-то такое:    for (i = 0, i < 5, i++){       printf("Hi! \n");    } В Python не используются фигурные скобки, вместо них — отступы. Та же самая программа на Python будет выглядеть так:<jupyter_code>for i in range(5):
    print("Hi \n")<jupyter_output>Hi 

Hi 

Hi 

Hi 

Hi<jupyter_text>Заметили функцию [`range()`](http://docs.python.org/release/1.5.1p1/tut/range.html)? Это встроенная функция, которая возвращает список, содержащий арифметическую прогрессию.Если циклы вложенные, то тело внутреннего цикла нужно выделить дополнительным отсупом:<jupyter_code>for i in range(3):
    for j in range(3):
        print(i, j)
    
    print("This statement is within the i-loop, but not the j-loop")<jupyter_output>0 0
0 1
0 2
This statement is within the i-loop, but not the j-loop
1 0
1 1
1 2
This statement is within the i-loop, but not the j-loop
2 0
2 1
2 2
This statement is within the i-loop, but not the j-loop<jupyter_text>Срезы массивов В NumPy можно оперировать с отдельными частями массивов, примерно теми же способами, что и в Matlab. Возьмём, к примеру, массив значений от 1 до 5:<jupyter_code>myvals = numpy.array([1, 2, 3, 4, 5])
myvals<jupyter_output><empty_output><jupyter_text>В Python **индексация начинается с 0**, как и в C, и у этого правила есть свои [рациональные обоснования](http://python-history.blogspot.ru/2013/10/why-python-uses-0-based-indexing.html). Вооружившись этим знанием, посмотрим на значения первого и последнего элемента созданного массива:<jupyter_code>myvals[0], myvals[4]<jupyter_output><empty_output><jupyter_text>В массиве `myvals` содержится 5 элементов, но если мы попробуем обратиться к элементу с индексом 5 `myvals[5]`, Python расстроится и выдаст ошибку, так как в этом случае фактически вызыавется несуществующий 6-й элемент массива.<jupyter_code>myvals[5]<jupyter_output><empty_output><jupyter_text>Иногда может потребоваться не весь массив, а его часть — *срез* (по-английски *slice*). Например, первые три элемента,<jupyter_code>myvals[0:3]<jupyter_output><empty_output><jupyter_text>Обратите внимание,  левый конец среза включается, а правый — нет. Так, в предыдущем примере срез состоит из значений `myvals[0]`, `myvals[1]` и `myvals[2]`, но без `myvals[3]`.  Это соглашение оказывается удобным, например, потому что позволяет посчитать число элементов в срезе — нужно из правого конца вычесть левый (в нашем случае $3-0 = 3$)  Присвоение и копирование массивов С одной из странностей/особенностей Python, которая часто становится источником ошибок и путаницы, сталкиваешься при присваивании и сравнении массивов. Вот пример. Заведем одномерный массив и назовем его `a`:<jupyter_code>a = numpy.linspace(1,5,5)
a<jupyter_output><empty_output><jupyter_text>Супер! У нас есть массив `a` со значениями от 1 до 5. Теперь я хочу сделать копию этого массива и назвать её `b`. Для этого я пишу такой текст:<jupyter_code>b = a
b<jupyter_output><empty_output><jupyter_text>Великолепно! В новом массиве `b`, так же как и в `a` теперь содержатся элементы от 1 до 5. Теперь, когда у нас есть бэкап, можно менять значения элементов `a`, не опасаясь потери данных.<jupyter_code>a[2] = 17
a<jupyter_output><empty_output><jupyter_text>Вот, третий элемент `a` теперь равен 17. Давайте проверим, что содержится в `b`. Что мы ожидаем там увидеть?<jupyter_code>b<jupyter_output><empty_output><jupyter_text>Неожиданный результат! При выполнении выражения `a = b` не происходит копирования значений массива `a` в новый массив `b`. Вместо этого Python создает ещё одну ссылку, привязанную к тому же массиву, что и `a`. Поэтому изменение значений в `a` влечет за собой точно такие же перемены в массиве `b` (фактически, это *присваивание по ссылке*). Если же нужно создать настоящую копию массива, то нужно указать это явным образом.<jupyter_code>c = a.copy()<jupyter_output><empty_output><jupyter_text>Теперь можно снова поменять что-то в `a` и посмотреть, приведет ли это к изменениям в `c`.<jupyter_code>a[2] = 3
a
c<jupyter_output><empty_output><jupyter_text>Ок, всё сработало так, как мы хотели. Если разница между выражинями `a = b` и `a = b.copy()` не ясна, лучше перечитайте вышеизложенное ещё раз. Это сэкономит вам кучу нервов впоследствии.---  Дополнительные материалы Существует огромное число онлайн ресурсов, с информацией об использовании NumPy и других библиотек. Но чтобы продемонстрировать мультимедийные возможность блокнотов Jupyter, вот вам ссылка на короткое YouTube видео на тему использования массивов NumPy.<jupyter_code>from IPython.display import YouTubeVideo
YouTubeVideo('vWkb7VahaXQ')<jupyter_output><empty_output><jupyter_text>--- Не обращайте внимания на следующую ячейку. При её исполнении загружаются стили для отображения блокнота<jupyter_code>from IPython.core.display import HTML
def css_styling():
    styles = open("../styles/custom.css", "r").read()
    return HTML(styles)
css_styling()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.07758702456606278, 'fraction_numerical': 0.01811628568718581, 'mean_word_length': 5.763309813983323, 'pattern_counts': {'":': 0, '<': 86, '<?xml version=': 0, '>': 84, 'https://': 1, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 8, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '20', 'dir': 'jupyter-structured-clean-dedup', 'id': '102226', 'license': 'CC-BY-4.0', 'n_tokens_mistral': 4342, 'n_tokens_neox': 4953, 'n_words': 1207, 'path': 'lessons/00_Lesson00_QuickPythonIntro.ipynb', 'repo_name': 'MIPT-DAFE-CS/ru_AeroPython', 'size': '10601'}