Стандартная библиотека Python. Модули pprint, sys, decimal
Внутренние и внешние пакеты
Одним из достоинств Python является то, что для решения разного рода задач, скорее всего, существует уже готовый модуль или пакет. Программисту не нужно заново писать код и, в таком случае, он может воспользоваться уже готовым решением. Вместе с Python устанавливается и стандартная библиотека Python. Другие пакеты, не входящие в нее, можно установить отдельно.
Встроенные модули устанавливаются вместе с Python в виде стандартной библиотекой (Python standard library). Их можно использовать без дополнительных условий. Со стандартной библиотекой Python можно ознакомиться по ссылке.
Примеры некоторых модулей библиотеки:
sys
– взаимодействие с интерпретаторомdecimal
– дробные числа повышенной точностиrandom
– генерация случайных чиселtime
иdatetime
– работа с датой и временемre
– поиск с помощью регулярных выражений- И другие.
Импорт встроенной функции pprint
В том случае, если мы пытаемся импортировать имя из встроенного пакета, то предварительно не нужно его устанавливать. Вы имеете доступ к ним из любого модуля Python. Модуль pprint
содержит функцию pprint
, которая позволяет красиво отображать длинные списки и словари. При этом сохраняется структура объекта и отображение, которое выводит pprint
, можно использовать для создания объекта.
## функция pprint для красивого вывода длинных списков и словарей
from pprint import pprint
pprint(dir(__builtins__))
Модуль sys и stdin
Модуль sys
необходим для регулирования работы интерпретатора Python, например, для контроля словарей имен переменных. Функция stdin
используется для интерактивного ввода с консоли, включая вызовы input()
. В случае запуска функции stdin
вы можете вводить данные в консоль.
## для ввода с консоли
from sys import stdin
lines = []
for line in stdin:
lines.append(line)
print(lines)
Как прервать исполнение кода?
Чтобы завершить ввод, нажмите сочетание клавиш Ctrl + Z
(D
для Mac), затем Enter
. Данная комбинация запустит End of line
и завершит код.
Модуль decimal
Решение проблемы потери точности
Как известно, числа с плавающей точкой (float
) имеют точность хранения в памяти – 8 или 16 байт. Но даже в этом объеме не получается учесть все вариации десятичных дробей. Поэтому возникает проблема потери точности.
В таком случае, для контроля точности можно использовать тип данных Decimal
— в нем можно контролировать нужную точность и способы округления.
Рассмотрим пример сложения в случае с float
.
В случае с Decimal
,
from decimal import Decimal, getcontext
print(Decimal('0.3') + Decimal('0.3') + Decimal('0.3') + Decimal('0.1'))
Decimal
хранит заданное количество знаков после запятой, которое можно настроить.
Задача №1. Точность подсчетов
Условие задачи
Внимательно прочтите условие задачи и скопируйте в среду разработки.
## имеем список строк доходов в долларах
## посчитайте сумму налога к выплате в рублях
## переведите значения списка в float и отдельно в Decimal
exchange_rate_rubles_in_dollars = 0.01
profit_tax_rate = 0.13
Примечание:
- Cписок строк доходов в долларах вы можете скачать по ссылке.
- Создайте списки из
float
иDecimal
. - Для расчета суммы налога вам необходимо
exchange_rate*tax_rate*sum(income)
Решение
from decimal import Decimal
from income import income # предварительно скачайте файл income
# Исходные данные
exchange_rate_rubles_in_dollars = 0.01
profit_tax_rate = 0.13
## Создаем функцию расчета суммы налога
def tax_calculation(income_in_dollars, exchange_rate, tax_rate):
return tax_rate * exchange_rate * sum(income_in_dollars)
## Генерируем списки из float и Decimal через списковое включение
f_income = [float(i) for i in income]
d_income = [Decimal(i) for i in income]
## Вызываем функцию tax_calculation для двух списоков
profit_tax_amount = tax_calculation(f_income, exchange_rate_rubles_in_dollars, profit_tax_rate)
print(f'Итоговая сумма налога {profit_tax_amount}')
d_profit_tax_amount = tax_calculation(d_income, Decimal(exchange_rate_rubles_in_dollars), Decimal(profit_tax_rate))
print(f'Ещё одная сумма налога {d_profit_tax_amount}')
Зачастую разница незаметна, но она есть!
Задача №2. Округления
Условие задачи
Внимательно прочтите условие задачи и скопируйте в среду разработки.
## В отчете значения доходов не могут выглядеть так
## 1.6559281935215...
## округлите полученные ранее значения до сотых для float и для Decimal.
Примечание:
- Обратите внимание на остатки при суммировании.
- Будут ли равны результаты суммировании?
Решение
from decimal import Decimal
## используйте списки f_income и d_income из Задачи 1
## для округления используем функцию round
## округление для float
## могут возникать странные остатки при суммировании float
print([round(p, 2) for p in f_income][:3])
print(sum([round(p, 2) for p in f_income]))
## округление для Decimal
print([round(p, 2) for p in d_income][:3])
print(sum([round(p, 2) for p in d_income])) # результат суммирования
Округления round() и quantize() в Decimal
Вспомним пример округления.
При арифметическом округлении
в большую сторону округляются 5,6,7,8,9, в меньшую 1,2,3,4. Однако, в реальности мы работаем не со случайным набором чисел, а с конечным. Таким образом, выходит, что больше чисел округляется вверх. Случайная ошибка такого подхода при случайной выборке довольно высока. Решением является банковский метод
округления числа к ближайшему четному числу. Данный метод реализован в Python 3.
Стандарт IEEE 754
описывает способы округления. В Decimal существует quantize(), который реализует следующие способы округления.
Название | Обозначение |
---|---|
round-down | усечение по направлению к нулю |
round-half-up | арифметическое округление |
round-half-even | банковское округление |
round-ceiling | округление к плюс-бесконечности |
round-floor | округление к минус-бесконечности |
Примеры Decimal().quantize()
from decimal import Decimal, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_FLOOR
## банковский метод округления
print(Decimal("10.025").quantize(Decimal("1.00"), ROUND_HALF_EVEN))
## арифметический метод округления
print(Decimal("10.025").quantize(Decimal("1.00"), ROUND_HALF_UP))
## округление вниз
print(Decimal("10.025").quantize(Decimal("1.00"), ROUND_FLOOR))
Промежуточные итоги
- Python использует стандартную библиотеку модулей и пакетов, которая расширяет возможности языка.
- Модуль decimal позволяет контролировать точность чисел с плавающей точкой.