2021-11-12 20:14:02 +01:00
|
|
|
|
|
|
|
class EngineeringNumberConverter():
|
|
|
|
|
2022-08-05 21:47:33 +02:00
|
|
|
prefixes = [
|
|
|
|
('y', 1e-24),
|
|
|
|
('z', 1e-21),
|
|
|
|
('a', 1e-18),
|
|
|
|
('f', 1e-15),
|
|
|
|
('p', 1e-12),
|
|
|
|
('n', 1e-9),
|
|
|
|
('u', 1e-6),
|
|
|
|
('m', 1e-3),
|
|
|
|
# We skip centi and dezi because no one really uses these besides for length measurements
|
|
|
|
('', 1),
|
|
|
|
# We also skip h for hekto
|
|
|
|
('k', 1e3),
|
|
|
|
('M', 1e6),
|
|
|
|
('G', 1e9),
|
|
|
|
('T', 1e12),
|
|
|
|
('P', 1e15),
|
|
|
|
('E', 1e18),
|
|
|
|
('Z', 1e21),
|
|
|
|
('Y', 1e24),
|
|
|
|
]
|
|
|
|
it_prefixes = [
|
|
|
|
('', 1),
|
|
|
|
('Ki', 1024),
|
|
|
|
('Mi', 1024*1024),
|
|
|
|
('Gi', 1024*1024*1024),
|
|
|
|
('Ti', 1024*1024*1024*1024)
|
|
|
|
]
|
2021-11-12 20:14:02 +01:00
|
|
|
|
2022-08-05 21:47:33 +02:00
|
|
|
@classmethod
|
|
|
|
def number_to_engineering(c, number, it_unit=False):
|
|
|
|
"""
|
|
|
|
Convert a number to engineering SI syntax with prefix.
|
|
|
|
This function will return a tuple of (new_number, prefix)
|
|
|
|
"""
|
|
|
|
if it_unit:
|
|
|
|
used_prefixes = c.it_prefixes
|
|
|
|
else:
|
|
|
|
used_prefixes = c.prefixes
|
2021-11-12 20:14:02 +01:00
|
|
|
|
2022-08-05 21:47:33 +02:00
|
|
|
if (len(used_prefixes) < 2):
|
|
|
|
return (number / used_prefixes[0][1], used_prefixes[0])
|
2021-11-12 20:14:02 +01:00
|
|
|
|
2022-08-05 21:47:33 +02:00
|
|
|
for i, (prefix, scale) in enumerate(used_prefixes[1:], 1):
|
|
|
|
if number < scale:
|
|
|
|
return (number / used_prefixes[i-1][1], used_prefixes[i-1][0])
|
2021-11-12 20:14:02 +01:00
|
|
|
|
2022-08-05 21:47:33 +02:00
|
|
|
return (number / used_prefixes[-1][1], used_prefixes[-1][0])
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def engineering_to_number(c, input):
|
|
|
|
cleaned_input = input.strip().replace(' ', '')
|
|
|
|
|
|
|
|
selected_scaling = 1
|
|
|
|
|
|
|
|
for (prefix, scale) in c.prefixes+c.it_prefixes:
|
|
|
|
if prefix == '':
|
|
|
|
continue
|
|
|
|
if cleaned_input.endswith(prefix):
|
|
|
|
cleaned_input = cleaned_input.replace(prefix, '')
|
|
|
|
selected_scaling = scale
|
|
|
|
break
|
|
|
|
|
|
|
|
return float(cleaned_input) * selected_scaling
|