{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Основы программирования в Python\n", "\n", "*Алла Тамбовцева, НИУ ВШЭ*\n", "\n", "*Данный ноутбук частично основан на [лекции](http://python.math-hse.info:8080/github/ischurov/pythonhse/blob/master/Lecture%201.ipynb) Щурова И.В., [курс](http://math-info.hse.ru/s15/m) «Программирование на языке Python для сбора и анализа данных» (НИУ ВШЭ).*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Python как калькулятор, переменные и типы переменных" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Python как калькулятор" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Привычные арифметические действия (сложение, вычитание, умножение, деление) в Python выглядят так же, как и в обычных калькуляторах:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 + 4 # сложение" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "11" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "5 * 4 - 9 # умножение и вычитание" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3.5" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "7 / 2 # деление" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Однако с делением всё не так просто: Python 3 всегда будет выдавать результат в виде числа с плавающей точкой (*float*), даже тогда, когда ожидается целочисленный ответ. Например:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4.0" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "8 / 2 # не 4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Получился дробный результат, где дробная часть равна 0. Как быть, если нужен ответ в виде целого числа? Можно воспользоваться целочисленным делением." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "8 // 2 # теперь 4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Тут важно помнить, что при использовании оператора `//` дробная часть всегда будет просто отбрасываться – никакого округления происходить не будет. Для округления (обычное арифметическое, в большую и в меньшую сторону) существуют специальные функции, и мы их обсудим позже." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "7 // 2 # от 3.5 осталось 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В Python 2 обычное деление (с помощью `/`) было целочисленным. Для того чтобы получить привычные результаты деления, нужно было либо импортировать обычное деление из модуля `__future__`, который позволяет использовать функционал более новых версий Python (см. [здесь](http://rextester.com/VMMS70343)), либо использовать другие хитрости, например, делить число с плавающей точкой на целое (см. [здесь](http://rextester.com/YJZV11974)).\n", "\n", "*Примечание:* для того, чтобы сравнивать исполнение одного и того же кода в Python 3 и Python 2 совсем необязательно устанавливать обе версии на компьютер. Можно воспользоваться онлайн-компиляторами (например, http://rextester.com: выбирать Python или Python 3) и запускать код прямо в браузере. Речь идет, конечно, о небольших фрагментах кода. Полноценно работать в них, не устанавливая Python, будет неудобно. Но для нескольких строк для сравнения как раз. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Что еще можно делать с числами? Возводить в степень и извлекать из них корень. При расчетах на калькуляторе для возведения числа в степень мы обычно используем символ `^`. Попробуем! " ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "6 ^ 2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Получилось что-то неожиданное. В Python оператор `^` используется для побитного сложения по модулю два. Для возведения числа в степень потребуется `**`: " ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "36" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "6 ** 2 # как нужно" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "216" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "6 ** 3" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1.8171205928321397" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "6 ** (1/3) # дробная степень - корень 3 степени" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Теперь попробуем извлечь квадратный корень из числа с помощью привычного `sqrt`." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'sqrt' is not defined", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0msqrt\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m9\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# не получается!\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mNameError\u001b[0m: name 'sqrt' is not defined" ] } ], "source": [ "sqrt(9) # не получается!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python пишет, что не знает, что такое `sqrt`. В каких случаях Python может такое писать? Например, если мы опечатались в названии функции (Python не понимает, что мы от него хотим) или если мы пытаемся обратиться к функции, которая не является базовой (Python не знает, откуда её брать). В данном случае мы столкнулись со второй проблемой. Функция для вычисления квадратного корня из числа хранится в специальном модуле `math`. Этот модуль стандартный, дополнительно устанавливать его не нужно. Но для того чтобы воспользоваться этой функцией, нужно сначала импортировать модуль, а потом вызвать из него функцию `sqrt`." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "import math # импортируем модуль math" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3.0" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "math.sqrt(9) # теперь все работает" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Если из `math` нам нужна только одна функция `sqrt` , можно извлечь только её, и тогда прописывать название модуля перед функцией не понадобится: " ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4.0" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from math import sqrt\n", "sqrt(16) # так тоже работает" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Иногда, если неизвестно, сколько функций потребуется, но каждый раз прописывать полностью название модуля не хочется, можно импортировать его сразу с сокращённым названием: " ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3.0" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import math as ma # сократили до ma\n", "ma.sqrt(9)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "*Примечание:* то же будет верно и для библиотек. Пока мы столкнулись с двумя модулями – `os` и `math`, в темах по обработке данных мы будем активно работать с разными библиотеками. Если совсем упростить, модуль – это набор функций, а библиотека – это набор модулей, то есть что-то более сложное по структуре и более насыщенное по функционалу." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В `math` есть много полезных функций для вычислений. Чтобы посмотреть, какие функции там есть, после импортирования всего модуля через `import math` можно набрать `math.` и нажать на *Tab* (табуляция, кнопка над *Caps Lock*). Помимо квадратного корня этот модуль поможет вычислить логарифм (натуральный и не только), синус, косинус и так далее." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.6931471805599453" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "math.log(2) # натуральный логарифм" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2.0" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "math.log10(100) # десятичный логарифм (логарифм по основанию 10)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.0" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "math.sin(0) # синус" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Здесь же хранятся функции для округления в большую или меньшую сторону:" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "9" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "math.ceil(8.7) # ceil - потолок" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "8" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "math.floor(8.7) # floor - пол" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "А ещё из `math` можно импортировать константы $\\pi$ и $e$:" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [], "source": [ "from math import pi, exp # можно сразу несколько - перечислить через запятую" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3.141592653589793" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pi" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2.718281828459045" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "exp(1) # e = e^1 = exp(1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Просто константу `e` можно также получить, вызвав `e`:" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2.718281828459045" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "math.e" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Примечание:** если мы знаем, что будем использовать практически все функции из модуля `math`, их можно извлечь все сразу, и тогда прописывать название библиотеки нам не понадобится нигде. " ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from math import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Однако в общем случае так делать нежелательно, потому что это нерационально и увеличивает время исполнения кода (Python подгружает все функции, а мы пользуемся только двумя, например)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "С чем ещё можно столкнуться, выполняя вычисления в Python? С такими вещами:" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4.1513310942010236e-32" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 / 18 ** 25" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Результат выше – компьютерная форма экспоненциальной записи числа. Возможно, тот, кто считал что-то на научных или инженерных калькуляторах, уже сталкивался с такой записью. Здесь `e-32` – это $10^{-32}$, а вся запись означает $4.1513310942010236 \\cdot 10^{-32}$, то есть примерно $4.15 \\cdot 10^{-32}$. Теоретически, если число было очень большим, `e` стояло бы в положительной степени. Но в Python такое не случается, обычно он выводит огромные числа, просто переходя на новую строку, если места на одной не хватает:" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "12899047957225248523006646539464335721979411301041340884781899303831010765027442196396594170642790934375007246578677182803636590164161819235523359334210795997877313526230138186880373768216363562984711930606834390635683889567066017501638286295454450223592921380025243612655929972891854670089005958782301313748919257409270999076443855743717129316401343809648755190213387432370099603517989905917859013302341878321325941570315088698234189444110362237214217846884135935952399097352427521852877620725021626938113437232848226058128334528859922677792198697568021708059256675191088006467069748109014817451375952598349790911535607651796493584493889427435570940502359773301622881259890983839926411232560174739455589741388073805529446667461505169110660161765843273557623843219490805708791092602475974648916336329253754550331716502327365416889998212147857020330942368277430427804385066546271943413689950822020931400593245046303758610973943882235592749794293155060009636680119916358947879472882782808870076229635495297702820410851089251120079429452529354919596272075046635023793735251154878700529432000342403111069160632592433095161936605646694694109530441088995393229754160740330575038216906404744009495445586324655891258721903641299986081018110880120922925030222636715904777957341225983442938451506259053249716900875692689602609775497863867095485915444153828849" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "23 ** 990" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Компьютерная форма записи числа отчасти помогает понять, почему дробные числа называются числами с плавающей точкой (*float*). Возьмем число попроще, например, $12.34$. Его можно записать как $12.34$, как $1.234 \\cdot 10$, как $123.4 \\cdot 10^{-1}$, $1234 \\cdot 10^{-2}$ и так далее. Точка, отделяющая дробную часть от целой, будет «плавать», однако само число при этом меняться не будет, будут меняться только множители – разные степени десятки." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "С числами с плавающей точкой связана ещё одна сложность — округление. На первый взгляд, всё хорошо:" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "13" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "round(12.6) # округлим до целого - по умолчанию" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "12.5" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "round(12.53, 1) # округлим до первого знака после запятой" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "С другой стороны, могут возникнуть странности: " ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "round(2.50) # не 3" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3.52" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "round(3.525, 2) # не 3.53" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Эти странности связаны с тем, что число, которое мы видим (например, 3.525), не совпадает с тем, которое хранится в компьютере, потому что оно при сохранении преобразовывается и превращается из точного 3.525 в такое:" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Decimal('3.524999999999999911182158029987476766109466552734375')" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from decimal import Decimal\n", "Decimal(3.525)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "И такое число будет законно округляться до 3.52 по правилам арифметического округления. В прикладном анализе данных такие сложности редко вызывают проблемы, но знать про нее полезно, чтобы не пугаться и не удивляться неожиданным результатам. Кроме того, полезно помнить, что числа с плавающей точкой (типа *float*) не рекомендуется использовать в финансовых вычислениях и вообще в вычислениях, требующих высокой точности, поскольку они «накапливают ошибку», то есть дают неточные результаты." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Переменные" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Переменные в программировании похожи на переменные в математике. Кроме того, их можно рассматривать как хранилища значений – контейнеры или «коробки», в которые мы что-то кладем. Python, в отличие от некоторых языков программирования (C, C++, Java), сам распознает что мы «кладем в коробку»: число, целое число, текст, список чисел... Поэтому при создании переменной нам не нужно указывать ее тип." ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [], "source": [ "x = 2 # Python поймет, что это целые числа\n", "y = 3" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n", "3\n" ] } ], "source": [ "print(x)\n", "print(y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Значения переменных мы можем обновлять – изменить значение и сохранить в переменную с тем же названием. " ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [], "source": [ "x = x + 1 # возьмем значение x, увеличим на 1 и сохраним изменения в переменной x" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [], "source": [ "y = y * 2 # возьмем значение y, увеличим в 2 раза и сохраним изменения" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3 6\n" ] } ], "source": [ "print(x, y) # одновременно два значения" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Названия переменных в Python могут быть почти любыми. Три общих правила: название переменной не должно начинаться с цифры, в названии не должно быть пробелов, название не должно совпадать со служебными (зарезервированными) словами в Python. Список зарезервированных слов можно узнать так:" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']\n" ] } ], "source": [ "import keyword\n", "print(keyword.kwlist)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Обычно рекомендуется давать переменным осмысленные названия: если речь идёт о доходе, называть переменную не `x`, а `income`, если речь идёт о данных по преступности, сохранять таблицу в переменную `crimes`, и так далее. Технически, Python 3 допускает названия на кириллице, но это будет выглядеть странно и неуместно." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Рассмотрим такую задачу. Пришла весна и решили мы заняться бегом по такой схеме: каждый день мы пробегаем столько, сколько в сумме за два предыдущих дня. При этом первые два дня мы морально готовимся: топчемся на месте и символически проходим по одному метру (полшага назад и полшага вперед). Если мы будем записывать все пройденные нами расстояния в ряд, мы получим последовательность из [чисел Фибоначчи](https://ru.wikipedia.org/wiki/%D0%A7%D0%B8%D1%81%D0%BB%D0%B0_%D0%A4%D0%B8%D0%B1%D0%BE%D0%BD%D0%B0%D1%87%D1%87%D0%B8). Давайте напишем код, который будет считать, сколько метров мы будем пробегать в следующий день." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Сначала создадим переменные, в которые сохраним данные по первым двум дням." ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [], "source": [ "b = 1 # день 1 - морально готовимся бегать, «бежим» 1 метр \n", "i = 1 # номер дня, когда начинаем бегать\n", "bnext = 1 # день 2 - снова морально готовимся бегать, «бежим» 1 метр\n", "i = i + 1 # перешли ко второму дню, увеличили i на 1" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3 2\n" ] } ], "source": [ "res = b + bnext # в следующий день пробегаем столько же, сколько за два предыдущих\n", "i = i + 1 # перешли к следующему дню, увеличили i на 1\n", "b = bnext # значение b нам уже не нужно, сдвигаемся к следующему дню - записываем bnext\n", "bnext = res # запомнили полученное значение res\n", "print(i, bnext) # выводим на экран номер дня и расстояние, которое нужно пробежать" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Теперь можно прогонять предыдущую ячейку много раз (через *Ctrl + Enter*) и получать результат по каждому дню. Например, на 20 день мы будем пробегать уже нормальное расстояние — 6765 метров, почти 7 километров. Конечно, прогонять одну и ту ячейку много раз неудобно и странно, но о том, как считать числа Фибоначчи более рационально, мы поговорим, когда будем разбирать циклы.\n", "\n", "**Важно:** если бы не разбили наш код на части (на две ячейки), ничего бы при повторном запуске ячейки не произошло — переменным `b`, `bnext` и `i` заново присваивались бы значения 1, и движения вперед бы не происходило.\n", "\n", "**Примечание:** можно было последней строкой написать `print(i, res)`, ничего бы не изменилось." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Типы переменных и преобразование типов" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Типы переменных (не путать с *data types* и *data scales*):\n", "\n", "* числовой c плавающей точкой (*float*);\n", "* целочисленный (*integer*);\n", "* строковый или текстовый (*string*);\n", "* логический (*boolean*): только два значения `True` и `False`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Посмотрим, как определить тип переменной:" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "float" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = 2.34\n", "type(x) # функция type" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "int" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y = 2\n", "type(y)" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "str" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r = 'hello'\n", "type(r)" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "bool" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "l = True\n", "type(l)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Иногда требуется преобразовать тип переменной, например, из числа с плавающей точкой сделать целое число. Зачем это бывает нужно? Для удобства и для более корректной выдачи результатов. Например, у нас есть база данных по респондентам, в которой указан их год рождения, и мы хотим добавить столбец с возрастом респондентов (числом полных лет). Из-за того, что кто-то ввел год в виде 1993.0, возраст при вычислениях тоже получится числом с плавающей точкой — 25.0. Так как мы знаем, что возраст всегда будет целым, чтобы дробная часть не смущала, можно привести все значения к целочисленному типу. " ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "25" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "int(25.0) # int - от integer" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Вообще функции для изменения типа переменных называются так же, как и сами типы или их сокращённые названия." ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "23.0" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "float(23)" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'2'" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "str(2) # str - от string" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "23" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "int(\"23\") # int - от integer" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Однако, если преобразование невозможно, Python выдаст ошибку (а точнее, исключение `ValueError`, про исключения поговорим позже):" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "ename": "ValueError", "evalue": "could not convert string to float: '23,56'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mfloat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'23,56'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mValueError\u001b[0m: could not convert string to float: '23,56'" ] } ], "source": [ "float('23,56')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Так как запятая в Python не воспринимается как десятичный разделитель (в качестве разделителя используется точка), превратить строку '23,56' в число не получится, нужно будет сначала заменить запятую на точку. Как работать со строками, мы обсудим позже, но если интересно, можно сделать следующее: создать любую строковую переменную, а потом после её названия поставить точку и нажать *Tab*. Так же, как и в случае с модулем *math*, выпадет список всех возможных методов, которые можно применять к строке. " ] } ], "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.8" } }, "nbformat": 4, "nbformat_minor": 2 }