Применение языка Python в инженерной практике

Единицы измерения физических величин в программах на языке Python

Введение

Язык Python (правильно это читается «Пайтон», но в русскоязычном сообществе так же прижилось и прочтение «Питон», мне оно тоже больше по душе;) в последнее время получил очень большую популярность в среде непрограммистов по двум причинам:

  • лёгкий синтаксис, очень близкий к естественным языкам и математическому мышлению;

  • огромное количество различных библиотек (модулей), написанных как на самом питоне, так и на более быстрых «профессиональных» языках С/С++ и Фортран.

Хотя для изучения основ Питона есть очень много хорошей литературы, в том числе и на русском языке, вопросы использования многих модулей описаны недостаточно. Особенно тяжело здесь русскоязычным инженерам. Этой статьёй я хочу начать цикл туториалов, в которых я поделюсь своим опытом использования языка Питон в практической инженерной деятельности. В настоящем туториале речь пойдёт о модуле Pint, который сильно упрощает манипулирование физическими величинами.

Настоящие туториалы нельзя рассматривать как основы языка Питон. Предполагается, что читатель с ними знаком, а так же знаком с модулями Math, CMath, Numpy, Scipy, Pandas. Язык Питон и перечисленные модули хорошо описаны в литературе и Интернете.

Для начала немного теории, что бы освежить мозг

В инженерных расчётах очень большое значение имеет приведение, преобразование и отображение единиц измерения. Результат любых инженерных измерений и расчётов не имеет никакого смысла, если не указаны две его основные характеристики: единица измерения и точность. О точности я напишу следующий туториал, а сейчас поговорим об единицах измерения.

Напомню основные определения:

Физической величиной называется физическое свойство материального объекта, процесса, физического явления, охарактеризованное количественно.

Значение физической величины выражается одним или несколькими числами, характеризующими эту физическую величину, с указанием единицы измерения.

Размером физической величины являются значения чисел, фигурирующих в значении физической величины.

Единицей измерения физической величины является величина фиксированного размера, которой присвоено числовое значение, равное единице. Применяется для количественного выражения однородных с ней физических величин.

Размерность физической величины — выражение, показывающее связь этой величины с основными величинами данной системы физических величин; записывается в виде произведения степеней сомножителей, соответствующих основным величинам, в котором численные коэффициенты опущены.

Системой единиц физических величин называют совокупность основных и производных единиц, основанную на некоторой системе величин. Широкое распространение получило всего лишь некоторое количество систем единиц. В большинстве случаев во многих странах пользуются метрической системой.

Измерить физическую величину — значит сравнить ее с другой такой же физической величиной, принятой за единицу. Например, длину предмета сравнивают с единицей длины, массу тела — с единицей веса и т.д. Но если один исследователь измерит длину в саженях, а другой в футах, им будет трудно сравнить эти две величины. Поэтому все физические величины во всем мире принято измерять в одних и тех же единицах. В 1963 году была принята Международная система единиц СИ (System international — SI). Для каждой физической величины в системе единиц должна быть предусмотрена соответствующая единица измерения. Эталоном единицы измерения является ее физическая реализация. Эталоном длины является метр — расстояние между двумя штрихами, нанесенными на стержне особой формы, изготовленном из сплава платины и иридия. Эталоном времени служит продолжительность какого-либо правильно повторяющегося процесса, в качестве которого выбрано движение Земли вокруг Солнца: один оборот Земля совершает за год. Но за единицу времени принимают не год, а секунду. Единицы измерения, для которых существуют физические эталоны, называют основными единицами

Производными единицами измерения физических величин называют такие единицы, для которых нет физических эталонов и которые определяются через соотношения основных единиц. Например, за единицу скорости принимают скорость такого равномерного прямолинейного движения, при котором тело за 1 с совершает перемещение в 1 м — поэтому единица скорости обозначается m/c. Единицей площади является площадь квадрата, длина каждой стороны которого равна 1 м — поэтому единица площади называется «квадратный метр» и обозначается m^2.

Приставки используются для того, что бы сделать запись значения физической величины более компактным. Например, 1000000\Omega = 1M\Omega. приставки бывают десятичные и двоичные. Десятичные приставки представляют собой множители 10^x\; | x \in \mathbb{N} -24 \leq x \leq 24. Двоичные приставки представляют собой множители 2^y\; | y \in \{ 10, 20, 30, 40, 50, 60, 70, 80\}.

Основные единицы системы СИ

Величина

Наименование

Обозначение

Длина

метр

m

Масса

килограмм

kg

Время

секунда

s

Сила электрического тока

ампер

A

Термодинамическая температура

кельвин

K

Сила света

канделла

cd

Количество веществ

моль

mol

Плоский угол

радиан

rad

Телесный угол

стерадиан

sr

Производные единицы системы СИ

Величина

Наименование

Обозначение

Выражение через основные единицы

Выражение через производные единицы

Частота

герц

Hz

1\s

-

Сила

ньютон

N

kg \cdot m / s^2

-

Давление

паскаль

Pa

kg / m \cdot s^2

N / m^2

Энергия, работа, количество теплоты

джоуль

J

kg \cdot m^2 /s^2

N \cdot m

Мощность, поток энергии

ватт

W

kg \cdot m^2/s^3

J / s

Количество электричества, заряд

кулон

С

A \cdot s

-

Электрическое напряжение, потенциал

вольт

V

kg \cdot m^2 / A \cdot s^3

W / A

Электрическая ёмкость

фарада

F

A^2 \cdot s^3 / kg \cdot m^2

C / V

Электрическое сопротивление

ом

Ω

{kg \cdot m^2} / {A^2 \cdot s^3}

{V} / {A}

Электропроводность

сименс

S

{A^2 \cdot s^3} / {kg \cdot m^2}

{A} / {V} или{1} / {Ω}

Поток магнитной индукции

вебер

Wb

{kg \cdot m^2} / {A \cdot s^2}

V \cdot s

Магнитная индукция

тесла

Т

{kg} . {A \cdot s^2}

{Wb} / {m^2}

Индуктивность

генри

H

{kg \cdot m^2} / {A^2 \cdot s^2}

{Wb} / {A}

Световой поток

люмен

Im

cd \cdot sr

-

Освещённость

люкс

Ix

m^2 \cdot cd \cdot sr

-

Физические и технические константы

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

Наименование

Значение

Обозначение

\pi

3.1415926535

pi

Экспонента

2.718281884

e

Скорость света

299792458 \; {m} / {s}

c speed_of_light

Гравитационная постоянная

9.806650 \; {m} / {s^2}

g_0 graviti

Вакуумная проницаемость

4 \cdot \pi \cdot 1e^{-7}\; {N}/{A^2}

mu_0 magnetic_constant

Диэлектрическая проницаемость

{1} / {\mu_0 \cdot c^2}

electric_constant

Вакуумный импеданс

\mu_0 \cdot c

Z_0 impedance_of_free_space characteristic_impedance_of_vacuum

Постоянная Планка

6.62606957e^{-34} J\cdot s

h

Постоянная Дирака

{h} / {2\pi}

hbar

Гравитационная константа Ньютона

6.67384 \cdot 10^{-11} \; {m^3} / {kg^{-1} \cdot s^{-2}}

newtonian_constant_of_gravitation

Молярная газовая постоянная

8.3144621 \; {J} / {mol^{-1} \cdot K^{-1}}

R

Число Авогадро

6.02214129 \cdot 10^{23} mol^{-1}

N_A

Постоянная Больцмана

1.3806488 \cdot 10^{-23} \; {J} / {K^{-1}}

k

Постоянная Вина

5.8789254 \cdot 10^{10} \; {Hz} / {K^{-1}}

wien_frequency_displacement_law_constant

Постоянная Ридберга

10973731.568539 \; m^{-1}

rydberg_constant

Масса электрона

9.10938291\cdot 10^{-31} kg

m_e electron_mass

Масса нейтрона

1.674927351 \cdot 10^{-27} kg

m_n neutron_mass

Масса протона

1.672621777 \cdot 10^{-27} kg

m_p proton_mass

Несистемные единицы

Модуль Pint содержит единицы не только системы СИ, но и других известных систем единиц, что позволяет применять его для перевода значений физических величин из одной системы единиц в другую. В модуле определено очень много разных единиц, поэтому не будем раздувать туториал ещё одной таблицей, вместо этого ниже будет показано, как получить названия нужных единиц средствами самого питона.

Десятичные приставки

Множитель

Название

Обозначение

10^{-24}

иокто

y

10^{-21}

зепто

z

10^{-18}

aттo

a

10^{-15}

фемто

f

10^{-12}

пико

p

10^{-9}

нано

n

10^{-6}

микро

μ

10^{-3}

милли

m

10^{-2}

санти

c

10^{-1}

деци

d

10^1

дека

deka

10^2

гекта

h

$10^3

кило

k

10^6

мега

M

10^9

гига

G

$10^{12}

тера

T

$10^{15}

пента

P

$10^{18}

экса

E

$10^{21}

зетта

Z

$10^{24}

иотта

Y

Двоичные приставки

Множитель

Название

Обозначение

2^{10}

киби

Ki

2^{20}

меби

Mi

2^{30}

гиби

Gi

2^{40}

теби

Ti

2^{50}

пеби

Pi

2^{60}

эксби

Ei

2^{70}

зеби

Zi

2^{80}

иоби

Yi

Дополнительные приставки

Кроме стандартных приставок системы СИ, в модуле Pint определены три дополнительные приставки:

Множитель

Обозначение

0.1

demi

0.5

semi

1.5

sesqui

Установка и начало использования модуля Pint

Установка модуля производится стандартным для Python образом:

c:\>pip install pint

Если вы используете менеджер Anaconda, то команда установки будет такой:

c:\>conda install pint --channels conda-forge

Для использования модуля его надо импортировать в вашу программу. Рекомендуется это делать следующими командами:

>>>from pint import UnitRegistry
>>>ureg = UnitRegistry()

Вторая строка инициализирует объект класса UnitRegistry, который хранит определения единиц измерения, их связи и обрабатывает преобразования между единицами (разумеется, имя объекта может быть произвольным, совсем не обязательно ureg; можно даже определить несколько таких объектов, хотя я не могу представить, для чего это может быть нужно). При этом объект ureg заполняется списком единиц и префиксов по умолчанию, полный список которых можно посмотреть в файле default_en.txt, который находится в папке, в которую установлена библиотека. Узнать расположение этой паки можно командой:

c:\>pip show pint

Name: Pint
Version: 0.19.2
Summary: Physical quantities module
Home-page: https://github.com/hgrecco/pint
Author: Hernan E. Grecco
Author-email: hernan.grecco@gmail.com
License: BSD
Location: c:\users\andre\anaconda3\lib\site-packages
Requires:
Required-by:

Другой способ увидеть, какие несистемные единицы уже определены в модуле. Для этого надо вызвать метод get_compatible_units() объекта класса UnitRegistry, передав ему величину интересующих единиц (в даном примере мы получаем возможные единицы измерения энергии):

>>>ureg.get_compatible_units('[energy]')
frozenset({,
           ,
           ,
           ,
           ,
           ,
           ,
           ,
           ,
           ,
           ,
           ,
           ,
           ,
           ,
           ,
           ,
           ,
           })

Проверка того, определена ли единица измерения

Для того, что бы проверить, определена ли необходимая единица измерения, можно воспользоваться следующими командами Питона:

>>> 'MHz' in ureg
True
>>> 'gigatrees' in ureg
False

Дополнение списка единиц

Если требуемой единицы измерения в файле default_en.txt нет, её можно добавить тремя способами:
1. Дописать определение единицы в конец файла default_en.txt.
2. Создать свой собственный файл определения единиц, например, mydef.txt.
3. Добавить описание единицы программно.

Формат файла описания

Независимо от того, дописывается ли единица в файл default_en.txt или создаётся новый файл описания единиц, структура описания каждой единицы следующая:

hour = 60 * minute = h = hr
minute = 60 * second = min

Это довольно просто, не так ли? Мы говорим, что минута равна 60 секундам и также известна как «мин».

  1. Первое слово — это всегда каноническое имя.

  2. После знака равенства следует определение единицы, основанное на других, ранее определённых единицах.

  3. После следующего знака равенства, опционально, указывается символ единицы измерения.

  4. Наконец, опять же опционально, приводится список псевдонимов единицы измерения, разделенных знаками равенства. Если надо указать только псевдонимы без символа единицы, символ единицы должен быть заменён на символ »_»:

millennium = 1e3 * year = _ = millennia

Эта команда определяет единицу «millennium», равную 1000 годам («year», определена в файле default_en.txt) без символа единицы измерения. Так же определён псевдоним «millennia», который может использоваться в программе вместо обозначения «millennium».

Порядок определения единиц измерения не имеет значения, Pint разрешит зависимости, чтобы определить их в правильном порядке. Важно только, что бы все единицы, использованные справа от первого знака равенства, были определены в доступных файлах определения единиц. Если надо добавить единицу, которую нельзя выразить через другие определённые единицы, её следует выражать через эталонные физические размерности:

second = [time] = s = sec

Новые физические величины так же можно определять через другие физические величины:

[density] = [mass] / [volume]

Обратите внимание, что первичные физические величины не нужно объявлять.

Кроме основных единиц измерения, в файле описания определяются их кратные десятичные префиксы, они обозначаются конечным тире:

yocto- = 10.0**-24 = y-

Наконец, можно добавить псевдонимы к уже существующему определению единицы:

@alias meter = metro = metr

Кроме того, файл описания может содержать необрабатываемый библиотекой Pint комментарии, начинающиеся с символа »#» (как в синтаксисе Питона)

Создание собственного файла описания

Если вы добавляете новые описания в файл default_en.txt, то они могут пропасть при обновлении версии библиотеки — при этом будет установлен новый стандартный файл default_en.txt без добавленных вами определений. Что бы этого избежать, лучше собственные определения поместить в отдельный текстовой файл с произвольным именем, например, mydef.txt и загружать его в своих программах после импорта библиотеки и создания объекта класса UnitRegistry() с помощью команды:

>>>ureg.load_definitions('/your_path/mydef.txt')

При этом ваши определения добавятся к стандартным. Если же вы ходите получить только свои определения и не загружать стандартные (например, если вы переопределяете стандартную единицу измерения), то передайте свой файл конструктору объекта:

>>>ureg = UnitRegistry('/your_path/mydef.txt')`

Добавление определения единицы измерения непосредственно в программе

Вы можете легко добавлять единицы измерения, измерения или псевдонимы в реестр программным путем. Давайте добавим dog_year (иногда пишется как dy), эквивалентный 52 (человеческим) дням:

>>>from pint import UnitRegistry
>>>ureg = UnitRegistry()
>>>Q_ = ureg.Quantity

>>>#Здесь мы добавляем новую единицу
>>>ureg.define('dog_year = 52 * day = dy')

>>>#Далее создаём количественную переменную и переводим её в новые единицы
>>>lassie_lifespan = Q_(10, 'year')
>>>print(lassie_lifespan.to('dog_years'))

В результате получим: 70.24038461538461 dog_year. Обратите внимание, что мы использовали имя dog_years хотя мы не определили форму множественного числа как псевдоним. Модуль Pint заботится об этом, поэтому вам не нужно этого делать. Формы множественного числа, которые не просто строятся путем добавления суффикса «s» к форме единственного числа, должны быть явно указаны как псевдонимы (см., например, millennia)

Вот, что тут любопытно: если вместо формы множественного числа

>>>print(lassie_lifespan.to('dog_years'))

написать в единственном числе:

>>>print(lassie_lifespan.to('dog_year'))

результат будет тот же самый. Зачем это сделано? Не знаю… Вероятно, что бы следовать принципам Питона в стремлении к максимальному приближению к естественному языку.

Вы также можете добавить префиксы программным путем:

>>>ureg.define('myprefix- = 30 = my-')

где число указывает на коэффициент умножения.

То же самое для псевдонимов и производных размеров:

>>>ureg.define('@alias meter = metro = metr')
>>>ureg.define('[hypervolume] = [length] ** 4')

Некоторые единицы содержат константы. Они могут быть определены с помощью ведущего подчеркивания:

>>>ureg.define('_100km = 100 * kilometer')
>>>ureg.define('mpg = 1 * mile / gallon')
>>>fuel_ec_europe = 5 * ureg.L / ureg._100km
>>>fuel_ec_us = (1 / fuel_ec_europe).to(ureg.mpg)

ПРЕДУПРЕЖДЕНИЕ
Единицы измерения, префиксы и псевдонимы, добавленные программным путем, забываются при завершении работы программы.

Присоединение единиц измерения к числам и переменным и вычисления с ними

Пожалуй, это самое главное назначение модуля Pint. Он позволяет присоединять единицы измерения к операндам вычислений и автоматически получать единицу результата. Для присоединения единиц измерения к операнду математической операции, надо всего лишь умножить операнд на объект ureg:

>>>10 * ureg.kg +  20 * ureg.kg
 30 

В данном примере мы сложили 10 килограммов и 20 килограммов и получили 30 килограммов. Т.е. Питон сработал чисто математически — он вынес ureg.kg за скобки и сложил 10 + 20. Но модуль Pint позволяет правильно прибавлять и граммы к килограммам:

>>>10 * ureg.kg + 300 * ureg.g
10.3 

Если присвоить единицу измерения переменной, то она изменит свой тип на объект класса Quantity():

>>>distance = 24.0 # пока без единицы измерения
>>>type(distance)
float
>>>distance = distance * ureg.km # теперь distance равно 24 километра
>>>type(distance)
pint.quantity.build_quantity_class..Quantity

Теперь обычная математика с переменной distance невозможна:

>>>distance + 3
DimensionalityError: Cannot convert from 'kilometer' to 'dimensionless'

Так же нельзя и прибавить несовместимую единицу:

>>>distance + 3 * ureg.g
DimensionalityError: Cannot convert from 'kilometer' ([length]) to 'gram' ([mass])

Разумно — сложение расстояния и массы не имеет физического смысла. А вот умножать, делить и возводить в степени переменные с разными единицами можно:

>>>distance = 24.0 * ureg.km # расстояние 24 км
>>>time = 3.0 * ureg.hour + 30.0 * ureg.minute # время 3 часа 30 минут
>>>speed = distance / time # скорость это действительно пройденное расстояние, делённое на затраченное время
>>>print(speed)
7.199999999999999 kilometer / hour # поэтому иы и получили километры в час
>>>acceleration = distance / time ** 2
>>>print(acceleration)
2.1599999999999997 kilometer / hour ** 2

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

>>>print(speed.dimensionality)
[length] / [time]
>>>print(acceleration.dimensionality)
[length] / [time] ** 2

При вычислении ускорения получилось вроде и правильно, но как то непривычно видеть \frac{km}{h^2}. Можно преобразовать к более каноничным \frac{m}{s^2}:

>>>print(acceleration.to('m/s**2'))
0.00016666666666666663 meter / second ** 2

В последнем примере интересно не только простота преобразования единиц измерения (метод to() объектов класса Quantity()), но и новый способ представления единиц измерения — в виде строки. Этот способ работает не только при преобразовании величин, но и во всех других случаях применения модуля Pint. Например:

>>>distance = 24.0 * ureg('km')
>>>print(distance)
24.0 kilometer

Вообще оба способа представления единиц измерения взаимозаменяемы во всех случаях и могут как угодно комбинироваться в одном выражении. Например, видоизменим команду преобразования единицы:

>>>print(distance.to(ureg.m))
24000.0 meter

Объекты Quantity() также хорошо работают с массивами NumPy (соответственно, переменными с присоединенными единицами измерения можно использовать все функции математических модулей Numpy и Scipy) и таблицами Pandas

Выделение значения и единицы измерения

Как было выше сказано, после присоединения к переменной единицы измерения, переменная превращается в объект класса Quantity() и дальнейшая математика с ней возможна только с другими объектами класса Quantity() (величинами или переменными, имеющими совместимые единицы измерения). Строго говоря, это не совсем так. При необходимости из переменной (объекта) класса Quantity() можно выделить её значение в обычную переменную типа int или float. Это возможно благодаря тому, что у всех объектов класса Quantity() есть два свойства: magnetude и units — содержащие. соответственно, значение и единицу измерения:

>>>type(distance)
pint.quantity.build_quantity_class..Quantity
>>>d = distance.magnitude
>>>type(d)
float
>>>print(distance.magnetude)
24.0
>>>print(distance.units)
kilometer

Упрощение единиц измерения

Иногда величина величины будет очень большой или очень маленькой. Метод to_compact() может корректировать единицы измерения, чтобы сделать количество более удобочитаемым для человека:

>>>wavelength = 1550 * ureg.nm # длина волны 1550 нанометров
>>>frequency = (ureg.speed_of_light / wavelength).to('Hz') # разделим скорость света на длину волны и приведём результат к герцам
>>>print(frequency)
193414489032258.03 hertz
>>>print(frequency.to_compact())
193.41448903225802 terahertz

193 терагерца воспринимается человеком более естественно и понятно, чем 193414489032258 герц

Существуют также методы to_base_units() и ito_base_units(), которые автоматически преобразуют несистемные единицы в эталонные единицы СИ правильной размерности:

>>>height = 5.0 * ureg.foot + 9.0 * ureg.inch
>>>print(height)
5.75 foot
>>>print(height.to_base_units())
1.7525999999999997 meter
>>>print(height)
5.75 foot
>>>height.ito_base_units()
>>>print(height)
1.7525999999999997 meter

Из примера видно, что разница между этими методами в том. что метод to_base_units() возвращет результат преобразования, а метод ito_base_units() изменяет саму переменную.

Модуль Pint может автоматически приводить результаты вычислений к эталонным единицам СИ. Для этого при создании объекта класса UnitRegistry надо передать конструктору параметр autoconvert_offset_to_baseunit = True.

Существуют также методы to_reduced_units() и ito_reduced_units(), которые выполняют упрощенное уменьшение размеров, объединяя единицы измерения с одинаковой размерностью и не затрагивая остальные единицы измерения:

>>>density = 1.4 * ureg.gram / ureg.cm ** 3
>>>volume = 10 * ureg.cc
>>>mass = density * volume
>>>print(mass)
14.0 cubic_centimeter * gram / centimeter ** 3
>>>print(mass.to_reduced_units())
>>>print(mass)
14.0 cubic_centimeter * gram / centimeter ** 3
>>>mass.ito_reduced_units()
>>>print(mass)
14.0 gram

Конечно, измерять массу в кубических сантиметрах и граммах неправильно. Учитывая, что cubic\_centimeter = centimeter^3, метод сокращает эти единицы и остаются правильные граммы.

Модуль Pint может автоматически сокращать единицы и упрощать результат. Для этого при создании объекта класса UnitRegistry надо передать конструктору параметр auto_reduce_dimensions = True.

Синтаксический анализ строк

Как уже было показано выше, ещиницы измерения объекту ureg можно передавать в виде строк. При этом содержимое строки может быть в достаточной степени произвольным. Всё дело в том. что модуль Pint содержит в себе мощный синтаксический анализатор строковых выражений. И его возможности не ограничиваются одним присоединением и преобразованием единиц измерения. Числа также анализируются, поэтому вы можете использовать выражение:

>>>ureg('2.54 * centimeter')
2.54 

Можно так же использовать конструктор объекта класса Quantity:

>>>Q_ = ureg.Quantity
>>>Q_('2.54 * centimeter')
2.54 

Более того, знак »*» можно опускать:

>>>Q_('2.54cm')
2.54 

Это позволяет вам написать простой конвертер единиц измерения:

>>>user_input = '2.54 * centimeter to inch'
>>>src, dst = user_input.split(' to ')
>>>Q_(src).to(dst)
 1.0 

Строки, содержащие значения, могут быть проанализированы более глубоко с помощью метода parse_pattern(). В качестве шаблона используется строка, подобная формату, с определенными в ней единицами измерения:

>>>input_string = '10 feet 10 inches'
>>>pattern = '{feet} feet {inch} inches'
>>>ureg.parse_pattern(input_string, pattern)
[10.0 , 10.0 ]

Чтобы выполнить поиск нескольких совпадений, установите параметр many = True. Следующий пример демонстрирует, как анализатор может находить совпадения среди символов-заполнителей:

>>>input_string = '10 feet - 20 feet ! 30 feet.'
>>>pattern = '{feet} feet'
>>>ureg.parse_pattern(input_string, pattern, many=True)
[[10.0 ], [20.0 ], [30.0 ]]

Обратите внимание, что фигурные скобки ({}) преобразуются синтаксическим анализатором в шаблон сопоставления с плавающей точкой.

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

Форматирование строк

Физические величины можно легко распечатать несколькими способами.

Стандартный код форматирования строки

>>>accel = 1.3 * ureg['meter/second**2']
>>>print('The str is {!s}'.format(accel))
print('The str is {!s}'.format(accel))

Стандартный код форматирования представления

>>>print('The repr is {!r}'.format(accel))
print('The repr is {!r}'.format(accel))

Доступ к полезным атрибутам

>>>print('The magnitude is {0.magnitude} with units {0.units}'.format(accel))
The magnitude is 1.3 with units meter / second ** 2

Модуль Pint также поддерживает форматирование с плавающей запятой для массивов Numpy:

>>>import numpy as np
>>>accel = np.array([-1.1, 1e-6, 1.2505, 1.3]) * ureg['meter/second**2']
>>>print('The array is {:.2f}'.format(accel))
The array is [-1.10 0.00 1.25 1.30] meter / second ** 2
>>>print('The array is {:+.2E~P}'.format(accel))
The array is [-1.10E+00 +1.00E-06 +1.25E+00 +1.30E+00] m/s²

Модуль Pint поддерживает f-строки Питона:

>>>accel = 1.3 * ureg['meter/second**2']
>>>print(f'The str is {accel}')
he str is 1.3 meter / second ** 2
>>>print(f'The str is {accel:.3e}')
The str is 1.300e+00 meter / second ** 2
>>>print(f'The str is {accel:~}')
The str is 1.3 m / s ** 2
>>>print(f'The str is {accel:~.3e}')
The str is 1.300e+00 m / s ** 2

Так же можно выводить строки в форматах HTML и LaTeX:

>>>accel = 1.3 * ureg['meter/second**2']
>>>print('The pretty representation is {:P}'.format(accel))
The pretty representation is 1.3 meter/second²
>>>print('The HTML representation is {:H}'.format(accel))
The HTML representation is 1.3 meter/second2
>>>print('The LaTeX representation is {:L}'.format(accel))
The LaTeX representation is 1.3\ \frac{\mathrm{meter}}{\mathrm{second}^{2}}

Если вы хотите использовать сокращенные названия единиц измерения, добавьте перед спецификацией префикс ~.

Спецификации форматирования (L, H и P) можно использовать с синтаксисом форматирования строк с плавающей точкой. Например, научная нотация:

>>>print('Scientific notation: {:.3e~L}'.format(accel))
Scientific notation: 1.300\\times 10^{0}\\ \\frac{\\mathrm{m}}{\\mathrm{s}^{2}}

Кроме того, вы можете указать спецификацию формата по умолчанию:

>>>ureg.default_format = 'P'
>>>print('The acceleration is {}'.format(accel))
The acceleration is 1.3 meter/second²

© Habrahabr.ru