{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Базовые типы: численные типы #" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "На этой лекции мы начинаем знакомство с основными базовыми типами, которые есть в Python.\n", "\n", "## Целые числа (int) ##\n", "\n", "Первым в нашем списке будет идти тип int, это целые числа. Чтобы объявить целое число достаточно писать `num = 13`, тем самым мы связываем имя переменной `num` с малочисленным объектом со значением 13, точно также можно присвоить переменной 0 либо отрицательно целое число." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "num = 13\n", "num = 0\n", "num = -1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Начиная с Python 3.6 появилась возможность разделять порядки символом нижнего подчеркивания в длинных числах, тем самым мы можем улучшить читаемость этих чисел в исходном коде." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "kpop = 10_000_000" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Раз уж мы заговорили о длинных числах, стоит отметить, что Python поддерживает длинную арифметику при работе с целыми числами, то есть поддерживаются числа неограниченной длины. Прежде чем продолжить, давайте разберем еще одну встроенную функцию, которая есть в языке, это функция `Type`. Функция `type` доступна в глобальном пространстве имен и она позволяет в рантайме, в процессе работы программы посмотреть на тип объекта, если мы объявим переменную `num` и свяжем ее с малочисленным объектом 13, а затем посмотрим какой у неё тип, то мы увидим, что это класс `int`, то это действительно тип `integer` и в дальнейшем мы видим, что встроенные типы Python они реализованы как классы, об этом я буду говорить в третьем блоке нашего курса. Ну а сейчас просто важно запомнить, что функция `Type` позволяет увидеть тип объекта." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "int" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(kpop)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Вещественные числа (float) ##\n", "\n", "Также Python умеет работать с вещественными числами, то есть с числами с плавающей точкой, это тип `float`. Чтобы объявить вещественное число, можно написать `pi = 13.4`, то есть точка используется для того чтобы разделить целую и дробную часть вещественного числа, то же самое для 0, и то же самое для отрицательного вещественного числа. По аналогии с типом `int` мы можем использовать символ нижнего подчёркивания, для того, чтобы разделять порядки в длинном вещественном числе. " ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "pi = 13.4\n", "e = 2.718_281_828_459_045" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Также Python поддерживает экспоненциальную нотацию записи вещественного числа, а, как мы можем видеть `1.5Е2`, на самом деле это полтора, умножить на 10 в степени 2, то есть 150." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "150.0" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1.5E2" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "150.0" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1.5 * 10 ** 2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Конвертация типов ##\n", "\n", "Теперь поговорим о ещё одном важном аспекте - о конвертации типов. Посмотрим на пример, предположим, у нас есть переменная `num`, которая связана с вещественным объектом со значением 150,2, и мы видим что это тип `float`. В любой момент мы можем воспользоваться встроенным классом `int`, чтобы переменную, которая связана с типом `float`, перевести в объект типа `integer` и затем мы можем преобразовать `integer` обратно к вещественному типу, используя класс `float`, тем самым в процессе работы программы мы можем из одного типа конвертировать переменные в другой тип." ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "150.2" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "num = 150.2\n", "num" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "150" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "num = int(num)\n", "num" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "150.0" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "float(num)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Обратите внимание, что в процессе наших конвертаций на примере, мы потеряли дробную часть вещественного числа.\n", "\n", "## Комплексные числа (complex) ##\n", "\n", "Также Python умеет работать с комплексными числами, это тип комплекс, для того, чтобы определить комплексное число нужно для мнимой части использовать символ `J`, посмотрите на пример, мы определили комплексное число `14 + 1J` и можем убедиться, что его тип действительно комплекс, используя встроенную функцию `Type`." ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(14+1j)" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "num = 14 + 1J\n", "num" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "complex" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(num)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "А также, чтобы достучаться до реальной и мнимой части комплексного числа, мы можем воспользоваться атрибутами `real` и `imag`." ] }, { "cell_type": "code", "execution_count": 109, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "14.0" ] }, "execution_count": 109, "metadata": {}, "output_type": "execute_result" } ], "source": [ "num = 14 + 1J\n", "num.real" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1.0" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "num.imag" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Что стоит отметить? Что в Pyton-e есть еще два модуля, которые позволяют работать с числами, эти модули очень полезны, мы не будем рассматривать их подробно, но знать о них нужно. В первую очередь, это модуль `deccimal`, который позволяет работать с вещественными числами с фиксированной точностью, а второй модуль это модуль `fractions`, который позволяет работать с рациональными числами, проще говоря с дробями.\n", "\n", "## Основные операции с числами ##\n", "\n", "Теперь посмотрим на основные операции с числами, как я уже говорил, Python хорош в качестве калькулятора и, конечно же, он умеет работать с числами очень хорошо. Для того, чтобы сложить два числа, мы используем просто математический оператор плюс. 1+1=2, сумма двух целых чисел дает нам целое число, если мы складываем целое число и вещественное число, то результат у нас получается вещественный. То же самое с вычитанием, если мы вычитаем из целого целое, получается целое число, если мы вычитаем из вещественного целое, то результат вещественный. Для того, чтобы разделить числа, мы можем воспользоваться символом прямого слэша, и обратите внимание, что результат деления всегда вещественный. Делить на 0 нельзя. Если мы попытаемся разделить на 0, то мы получим исключение `ZeroDivisionError`. Про исключения, как я уже говорил, мы с вами будем говорить в дальнейшем, научим вас их отлавливать и обрабатывать. Для того чтобы умножить числа, мы можем использовать звездочку, а для того, чтобы возвести число в степень, мы можем использовать две звездочки, на примере мы возводим число 2 в 4 степень. Чтобы произвести целочисленное деление, мы используем два прямых слэша. Чтобы получить остаток от деления, используем процент. Важно подчеркнуть, что Python использует порядок операций в выражениях с числами такой, какой используется в правилах математики и,в если мы посмотрим на пример, то выражение 3 плюс 10 умножить на 3, сначала выполнится умножение, а потом сложение. Если же нам нужно подчеркнуть, что нужно сначала выполнить сложение, а потом результат сложения умножить на 3, то мы можем воспользоваться круглыми скобочками для этого." ] }, { "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": [ "1 + 1" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2.5" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 + 1.5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Вычитание:" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "6 - 2" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4.0" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "6 - 2.0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Деление:" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3.0" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "6 / 2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Делить на 0 нельзя:" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "ename": "ZeroDivisionError", "evalue": "division by zero", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mZeroDivisionError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[1;36m6\u001b[0m \u001b[1;33m/\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mZeroDivisionError\u001b[0m: division by zero" ] } ], "source": [ "6 / 0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Умножение:" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2 * 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Возведение числа в степень:" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "16" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2 ** 4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Целочисленное деление:" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "10 // 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Остаток от деления:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "10 % 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Порядок операций в выражениях с числами:" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "33" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "3 + 10 * 3" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "39" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(3 + 10) * 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Побитовые операции ##\n", "\n", "Также Python поддерживает побитовые операции для чисел, среди них побитово или, побитово исключающие или, и так далее." ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Побитовое или: 7\n", "Побитовое исключающее или: 7\n", "Побитовое и: 0\n", "Битовый сдвиг влево: 32\n", "Битовый сдвиг вправо: 2\n", "Инверсия битов: -5\n" ] } ], "source": [ "x = 4\n", "y = 3\n", "\n", "print(\"Побитовое или:\", x | y)\n", "print(\"Побитовое исключающее или:\", x ^ y)\n", "print(\"Побитовое и:\", x & y)\n", "print(\"Битовый сдвиг влево:\", x << 3)\n", "print(\"Битовый сдвиг вправо:\", x >> 1)\n", "print(\"Инверсия битов:\", ~x)" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "## Задачка ##\n", "\n", "Теперь посмотрим на задачку. Задача найти расстояние между двумя точками в декартовых координатах, эта задача известна всем нам из школьного курса математики, и для того, чтобы ее решить по большому счёту, нам нужно найти гипотенузу прямоугольного треугольника. Давайте посмотрим на решение на Python.\n", "\n", "![График](graph.svg \"График\")" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5.0\n" ] } ], "source": [ "x1, y1 = 0, 0\n", "x2 = 3\n", "y2 = 4\n", "\n", "distance = ((x2 - x1) ** 2 + (y2 - y1) ** 2) ** .5\n", "print(distance)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Вначале мы объявляем переменные, это координаты точек. Обратите внимание на самую верхнюю запись `x1, y1 = 0, 0`. Это синтаксис, который поддерживается Python'ом, он позволяет через запятую перечислить названия переменных, а далее, через запятую перечислить те значения, которые этим переменным нужно присвоить. Это очень удобно. Для того, чтобы найти расстояние, мы воспользуемся формулой, корень из суммы квадратов катетов, и здесь мы видим, как мы вычисляем расстояние. Вместо того, чтобы брать корень, мы возводим выражение в скобках в степени 0,5, что эквивалентно взятию корня. И далее печатаем на экран ответ, мы видим, что ответ получился правильный." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "А что ещё хочется отметить про синтаксис Python, это мы видели в предыдущем примере то, что можно на одной строчке присвоить значения нескольким переменным. Однако, тот же самый трюк позволяет, например, поменять значения у 2 переменных без использования временной переменной, то есть мы определяем две переменные, дальше пишем `a, b = b, a`, и значение переменных меняется местами. Также очень удобно." ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2 1\n" ] } ], "source": [ "a = 1\n", "b = 2\n", "a, b = b, a\n", "\n", "print(a, b)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Что еще можно сделать было бы? Мы могли бы записать вместо `x, y = 0, 0`, `x = y = 0`, тем самым мы бы связали переменную `x` и переменную `y` с объектом, с зачисленным объектом 0. Однако нужно быть внимательным. первый объект это изменяемый объект, а второй - это неизменяемые, изменяемые объекты это объекты, которые после создания могут менять свое значение, а неизменяемые, соответственно, это объекты, которые после создания свое значение не меняют. Примитивные основные типы, которые мы разбираем на этой неделе, по большому счету, не изменяемы, поэтому для нашей задачи запись `x = y = 0` была бы оправдана. В данном случае, если бы мы поменяли только `х`, например, добавили бы к `х` впоследствии единичку, у нас `х` стал бы равен 1, а `у` остался бы нулем." ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 0\n" ] } ], "source": [ "a = b = 0\n", "a += 1\n", "\n", "print(a, b)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Но если бы мы написали `х = у = пустой список`, а пустой список - это объект-контейнер, который мы будем разбирать на дальнейших неделях, он позволяет хранить последовательность объектов в себе, а этот объект уже изменяемый, поэтому, когда мы присваиваем `х = у = пустой список`, а затем в список `х` добавляем два элемента, то, если мы выведем на экран `х` и `у`, то мы увидим, что изменились значения обеих переменных. С этим нужно быть внимательным, это нюанс, который необходимо понимать и необходимо понимать, что в Python-е есть неизменяемые объекты и изменяемые объекты." ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 2] [1, 2]\n" ] } ], "source": [ "a = b = list()\n", "\n", "a.append(1)\n", "a.append(2)\n", "\n", "print(a, b)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "На этой лекции мы с вами поговорили об основных численных типах, которые есть в языке, рассмотрели математические операции с ними, узнали о конвертации типов, а также затронули тему изменяемых и не изменяемых объектов в 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": 4 }