Ответ 1
Я решил одну и ту же проблему один раз. И ИМХО с большей элегантностью. Никаких степеней и температур.
def sign(x, value=1):
"""Mathematical signum function.
:param x: Object of investigation
:param value: The size of the signum (defaults to 1)
:returns: Plus or minus value
"""
return -value if x < 0 else value
def prefix(x, dimension=1):
"""Give the number an appropriate SI prefix.
:param x: Too big or too small number.
:returns: String containing a number between 1 and 1000 and SI prefix.
"""
if x == 0:
return "0 "
l = math.floor(math.log10(abs(x)))
if abs(l) > 24:
l = sign(l, value=24)
div, mod = divmod(l, 3*dimension)
return "%.3g %s" % (x * 10**(-l + mod), " kMGTPEZYyzafpnµm"[div])
Степени:
def intfloatsplit(x):
i = int(x)
f = x - i
return i, f
def prettydegrees(d):
degrees, rest = intfloatsplit(d)
minutes, rest = intfloatsplit(60*rest)
seconds = round(60*rest)
return "{degrees}° {minutes}' {seconds}''".format(**locals())
изменить
Добавленный размер единицы
>>> print(prefix(0.000009, 2))
9 m
>>> print(prefix(0.9, 2))
9e+05 m
Второй вывод не очень хорош, я знаю. Вы можете отредактировать строку форматирования.
изменить
Разбирайте входы, такие как 0.000009 m²
. Работает с размерами менее 10.
import unicodedata
def unitprefix(val):
"""Give the unit an appropriate SI prefix.
:param val: Number and a unit, e.g. "0.000009 m²"
"""
xstr, unit = val.split(None, 2)
x = float(xstr)
try:
dimension = unicodedata.digit(unit[-1])
except ValueError:
dimension = 1
return prefix(x, dimension) + unit