Числа для продвинутых по Марку Лутцу

                                                                           Узнаёте циферки?)
                                                                           Узнаёте циферки?)

Доброго, прекрасного, сказочного времени суток, семья моя :) Пришло время углубляться… И искать крупицы в стоге сена, которые углубят моё представление о языке Python.

Ну что ж, начинаю рефлексировать и перечитывать уже законспектированный материал.

Итак, что такое числа с точки зрения Python?

Это объект класса. Проверить это очень просто. Достаточно лишь написать в программном интерпретаторе следующий код:

intNumber = 3 print(intNumber) #3 print(type(intNumber)) # <class 'int'>

Python есть такая встроенная функция type() называется. С помощью неё как раз можно узнать каким типом данных является объект. Поскольку статья посвящена числам, то мы проверяем числа. В итоге результатом проверки числа определился класс int (<class 'int'>)

По Лутцу числа являются не одиночным типом объектов, а категорией похожих объектов.

Давайте другой пример.

floatNumber = 2.5 # это число уже с другим типом данных print(floatNumber) print(type(floatNumber)) #<class 'float'>

Видите различие?

В первом примере, у нас класс целых ЧИСЕЛ, а в другом класс ЧИСЕЛ с плавающей точкой. По факту их объединяет единое понятие «ЧИСЛО», а вот <class 'float'> и <class 'int'> являются их категориями (или характеристиками).

Таким образом выделяются следующие категории чисел:

1) Целые числа и с плавающей точкой

floatNumber = 2.5 intNumber = 3

2) Комплексные числа

a = 3j print(a) # 3j

3) Десятичные числа

import decimal print(decimal.Decimal('2.6') + decimal.Decimal('1.2'))

4) Дроби

import fractions print(fractions.Fraction(1,2)) #1/2

5) Булевы числа (True/ False)

Laptop = True #эквивалент 1 KeyBoard = False #эквивалент 0

6) Встроенные функции и модули

import math print(math.sqrt(9))

Как можно увидеть исходя из категорий далеко не все представления чисел входят в базовый модуль Python. Например для работы с десятичными и дробными числами мне пришлось импортировать библиотеки decimal и fractions

При работе с числами очень важно знать операции, которые необходимы для их обработки. Операции применяются по старшенству. Я выделил это понятие, потому что несоблюдение данного правила могут вызвать ошибки в программе. Из правила старшинства следует перечень операций приоритетные к обработке по сравнению с другими. Перечень операторов можно взять из (https://letpy.com/handbook/operator-priorities/) этой таблицы. А в этой статье (https://habr.com/ru/company/vk/blog/337364/) можно встретить экзотические случаи, когда игнорирование правила старшенства может привести к ошибочному результату.

Числа в действии

Для того, чтобы приступить к разбору числовых типов данных необходимо помнить о правилах присвоения переменных.

М.Лутц

1. Переменные создаются, когда им присваиваются значения.

2. Переменные заменяются своими значениями, когда используются в выражениях

3. Переменным должны быть присвоены значения до того, как можно применять их в выражениях

4. Переменные ссылаются на объекты и не объявляются заранее

Ниже опишу это с помощью кода

1 правило:

Number =3 # Number - название переменной , 3 - значение # 1 утверждение

2 правило

Number =3 #объявление переменной NextNumber = Number + 4 # Замена переменной своим значением print(NextNumber) # 7

3 правило

""" Необходимо сначала ОБЪЯВЛЯТЬ, а потом выполнять операции, иначе ошибка """ Number1+Number2 # NameError: name 'Number1' is not defined Number1 = 3 Number2 = 5

4 правило

""" Так тоже нельзя """ print(Number) #NameError: name 'Number' is not defined Number = 3

Неочевидные вещи при работе с числами

1) Если я захочу вычислить несколько чисел в одной строке, то формальным результатом получу кортеж.

Numbers = 2 +3 , 3+4 print(Numbers) # (5, 7) print(type(Numbers)) # <class 'tuple'>

Вот показательный пример. Тут я запихал в переменную Numbers два выражения, их он оформил в кортеж. Если я проверю тип, то обнаружу, что он НЕ относится к числовому типу данных. Магия Python в действии :)

2) Если я захочу отформатировать строку, то можно воспользоваться следующими примерами.

На форматировании я останавливаюсь очень подробно в виду того, что очень привык к f-строкам (хотя это самый мощный и быстрый инструмент). На мой взгляд, такой расклад вещей не является Best Practice, поэтому приведу форматирование чисел как видит их Лутц.

3) Я мало использовал правила отображения.

Знаете ребят, я редко их применял в функциональном программировании, но это не значит, что они вообще не нужны. Как я понял они очень востребованы в ООП (там, где мы объявляем классы).

Как отличить отображение?

Лучше опишу конкретными примерами

repr('spam') # "'spam'" - это отображение как в коде str('spam') # 'spam' - более дружественный человеку вариант

repr () представляет собой представляет собой вывод выражения, таким образом, каким его видит код

str() представляет собой более дружественный вывод объекта

4) Немного о правилах деления.

Тут и без комментариев всё понятно, поэтому сразу к написанию программ:

10/4 # 2.5 # вывод - число с плавающей точкой 10//4 # 2 вывод - число типа int 10//4.0 #2.0 вывод - число типа float

Правила округления:

import math math.floor(2.525) # 2 - усечение в меньшую сторону math.trunc(2.5) # 2 - усечеение дробной части round(2.6) # 3 - округление в большую строну

5) О существовании представления комплексных чисел в Python я не знал, поэтому для меня это новая информация.

По Лутцу, комплексные числа являются отдельным основным типом объектов в Python. Данное число состоит из действующей и мнимой части. И записываются с добавлением суффикса j и J.

Пример с использованием комплексных чисел я приводил в самом начале статьи, поэтому останавливаться на этом больше не буду

6) Поддержка системы счисления. Данный пункт я прямо хорошо проработал на CodeWars. Здесь я лишь только скажу, что в базовой комплектации Python работает с двоичной, восьмеричной, десятичной, шестнадцатеричной системой счисления.

Преобразование в десятичный тип:

print(0o10, 0o20, 0o5) #8 16 5 преобразование в десятичный тип из восьмеричного print(0o10+ 0o20) #24 преобразование в десятичный тип print(0b001, 0b111) # 1 7 преобразование в десятичный из двоичного print(0x2f) #47 - преобразование в десятичный тип из шестнадцатеричного

Преобразование в обратную сторону:

print(hex(20)) # в шестнадцатеричный тип print(bin(2)) # в двоичный print(oct(20)) # в восьмеричный

Правила форматирования разных типов

'{0:o}, {1:x}, {2:b}'.format(64, 64, 64) # '100, 40, 1000000' # с применением метода format '%o, %x, %x, %X' % (64, 64, 255, 255) # '100, 40, ff, FF' без применения методов format

7) Существуют другие встроенные типы. К ним Лутц относит random и math. Есть и более продвинутые ( вроде NumPy но о них автор не рассказывает)

Их описание я привёл выше по тексту. Основные методы, которые содержит этот модуль можно взять из официальной документации.

Ребят, в программировании очень важна тренировка и отработка навыков, поэтому тут моя рекомендация: поэкспериментируйте с этими модулями, не бойтесь ошибаться. Уж лучше ошибиться сейчас, чем на собеседовании :)

Основы десятичных чисел . Для чего нужен модуль Decimal?

Как говорит Лутц математика с плавающей точкой не является точным представлением вычисляемого выражения. Для того, чтобы это исправить существует внутренняя библиотека decimal. В начале статьи я уже упоминал в вкратце об этом модуле.

В этом пункте привожу наиболее интересные случаи:

from decimal import Decimal Decimal('0.1') + Decimal('0.1') + Decimal('0.1') - Decimal('0.3') # Вывод: Decimal('0.0') Decimal(0.1) + Decimal(0.1) + Decimal(0.1) - Decimal(0.3) # Вывод: Decimal('2.775557561565156540423631668E-17')

Здесь в выводе следует особо обращать внимание на точность.

print(0.1+0.1+0.1-0.3) #5.551115123125783e-17 (похож на предыдущий пример)

Обратите внимание! Если вы хотите вывести число в более человекочитаемом виде, то рекомендуется отображать числа в строковом представлении

Глобальная установка точности

Чтобы установить точность модуля decimal необходимо его настроить. Для этого существует метод getcontext().prec

Вот пример из книги:

import decimal decimal.Decimal(1)/decimal.Decimal(7) # Decimal('0.1428571428571428571428571429') decimal.getcontext().prec = 4 # присвоение фиксированной точности decimal.Decimal(1)/decimal.Decimal(7) #Decimal('0.1429')

Ребята, знаете, если бы я знал об этом раньше, то работа с точными числами на CodeWars обходилось бы мне куда меньшей болью. Так что примите даннный модуль во внимание. Если вы столкнётесь с анализом больших данных и вычислении собственных показателей, он может вам оказать просто огромную службу

9) Поработаем с дробями. Это тоже полезный метод. С дробями, ребят я на CodeWars не сталкивался, но однако не факт, что подобного типа задач там нет.

Вот парочку примеров:

import fractions # импорт модуля с дробями xCoordinate = fractions.Fraction(1 , 3) # 1 - числитель, 3- знаменатель yCoordinate = fractions.Fraction(4, 6) # аналогично print(xCoordinate, yCoordinate) #1/3 2/3 (вывод координат X и Y)

Использование этого модуля автоматически упрощает дробь. Метод позволяет работать с числами разных типов. Для экспериментов можно обратиться к документации. (https://docs.python.org/3/library/fractions.html)

10) Поработаем со множествами. По Лутцу множества представляют неупорядоченную коллекцию уникальных и неизменяемых объектов, которая поддерживает операции, соответствующие математической теории множеств.

Сразу скажу, определение достаточно сложное. Его хорошо прорабатывать на практических примерах. Опишу его примерами:

x = 'abcde' y = 'bdxyz' print(set(x) , set(y)) {'c', 'd', 'a', 'e', 'b'} {'y', 'd', 'z', 'x', 'b'}

Множества описываются встроенным методом set()

Его методами являются такие операции как: разность, пересечение, объединение, симметрическая разность, надмножество, подмножество

x = 'abcde' y = 'bdxyz' setX, setY = set(x) , set(y) setX-setY # разность {'c', 'e', 'a'} setX | setY # объединение {'y', 'c', 'd', 'z', 'x', 'a', 'e', 'b'} setX & setY # пересечение {'d', 'b'} setX^setY # симметрическая разность (исключающее ИЛИ) {'c', 'z', 'a', 'e', 'x', 'y'} setX>setY, setX<setY # надмножество, подмножество

Вместе с операциями есть пара методов, среди которых: add() и update()

Для чего могут использоваться множества?

1) Для создания объектов с уникальными номерами

2) Для выделения различий в списках, строках и других объектах

3) Выполнения проверок на равенство, нейтральное к порядку

4) Обработка запросов, связанных с базами данных

Те пункты, которые я выделил, считаю наиболее важными.

Числа для продвинутых по Марку Лутцу

Вот и закончилось глубокое описание работы с числами в Python!

Начать дискуссию