Skip to content

Commit

Permalink
Fixed and improved the read_resistance function for better resistance…
Browse files Browse the repository at this point in the history
… handling. Fixes yaqwsx#117
  • Loading branch information
Electro707 committed Oct 11, 2022
1 parent 5e28b31 commit 72061dc
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 21 deletions.
24 changes: 12 additions & 12 deletions pcbdraw/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -951,20 +951,20 @@ def _apply_resistor_code(self, root: etree.Element, id_prefix: str, ref: str, va

def _get_resistance_from_value(self, value: str) -> Tuple[Decimal, str]:
res, tolerance = None, "5%"
value_l = value.split(" ", maxsplit=1)
try:
value_l = value.split(" ", maxsplit=1)
res = read_resistance(value_l[0])
if len(value_l) > 1:
t_string = value_l[1].strip().replace(" ", "")
if "%" in t_string:
s = self._plotter.get_style("tht-resistor-band-colors")
if not isinstance(s, dict):
raise RuntimeError(f"Invalid style specified, tht-resistor-band-colors should be dictionary, got {type(s)}")
if t_string.strip() not in s:
raise UserWarning(f"Invalid resistor tolerance {value_l[1]}")
tolerance = t_string
except decimal.InvalidOperation:
raise UserWarning(f"Invalid value {value}") from None
except ValueError:
raise UserWarning(f"Invalid resistor value {value_l[0]}")
if len(value_l) > 1:
t_string = value_l[1].strip().replace(" ", "")
if "%" in t_string:
s = self._plotter.get_style("tht-resistor-band-colors")
if not isinstance(s, dict):
raise RuntimeError(f"Invalid style specified, tht-resistor-band-colors should be dictionary, got {type(s)}")
if t_string.strip() not in s:
raise UserWarning(f"Invalid resistor tolerance {value_l[1]}")
tolerance = t_string
return res, tolerance


Expand Down
28 changes: 19 additions & 9 deletions pcbdraw/unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,35 @@ def erase(string: str, what: List[str]) -> str:
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), Decimal(1e-6)],
"K": [Decimal(1e3), Decimal(1)],
"k": [Decimal(1e3), Decimal(1)],
"M": [Decimal(1e6), Decimal(1e3)],
"G": [Decimal(1e9), Decimal(1e6)]
"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:
split = [Decimal(x) if x != "" else Decimal(0) for x in p_value.split(prefix)]
numerical_value = split[0] * table[0] + split[1] * table[1]
# 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 not None:
return numerical_value
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")

0 comments on commit 72061dc

Please sign in to comment.