forked from yaqwsx/PcbDraw
-
Notifications
You must be signed in to change notification settings - Fork 0
/
unit.py
49 lines (44 loc) · 1.81 KB
/
unit.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
from decimal import Decimal
from typing import List
def erase(string: str, what: List[str]) -> str:
"""
Given a string and a list of string, removes all occurrences of items from
what in the string
"""
for x in what:
string = string.replace(x, "")
return string
def read_resistance(value: str) -> Decimal:
"""
Given a string, try to parse resistance and return it as Ohms (Decimal)
This function can raise a ValueError if the value is invalid
"""
p_value = erase(value, ["Ω", "Ohms", "Ohm"]).strip()
p_value = p_value.replace(" ", "") # Sometimes there are spaces after decimal place
unit_prefixes = {
"m": Decimal('1e-3'),
"R": Decimal('1'),
"K": Decimal('1e3'),
"k": Decimal('1e3'),
"M": Decimal('1e6'),
"G": Decimal('1e9')
}
try:
numerical_value = None
for prefix, table in unit_prefixes.items():
if prefix in p_value:
# Example: 4k7 will have the 4 converted to Decimal(4) and 7 to Decimal(0.7)
# Then each gets multiplied by the factor and added, so 4000 + 700
# This method ensures that 4k7 and 4k700 for example yields the same result
split = p_value.split(prefix)
n_whole = Decimal(split[0]) if split[0] != "" else Decimal(0)
n_dec = Decimal('.'+split[1]) if split[1] != "" else Decimal(0)
numerical_value = n_whole * table + n_dec * table
break
if numerical_value is None:
# If this fails, a decimal.InvalidOperation is raised which is handled by the Exception catch
numerical_value = Decimal(p_value)
return numerical_value
except Exception:
pass
raise ValueError(f"Cannot parse '{value}' to resistance")