From 9bbb4f8f3a1d8e2bfe1f06c945081153435de940 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Mon, 20 May 2019 23:36:49 +0200 Subject: o Replacing digikey-normalize-facts with part-apply-function. Moving code from tool to ee.digikey.functions. --- src/ee/digikey/functions.py | 157 ++++++++++++++++++++++++++++++++++++++ src/ee/digikey/normalize_facts.py | 153 ------------------------------------- 2 files changed, 157 insertions(+), 153 deletions(-) create mode 100644 src/ee/digikey/functions.py delete mode 100644 src/ee/digikey/normalize_facts.py (limited to 'src/ee/digikey') diff --git a/src/ee/digikey/functions.py b/src/ee/digikey/functions.py new file mode 100644 index 0000000..047fad1 --- /dev/null +++ b/src/ee/digikey/functions.py @@ -0,0 +1,157 @@ +import re +from typing import List, Tuple, Union, Mapping, Callable, Any + +from ee import EeVal, EeException +from ee.part import Part +from ee.xml import types, uris + +__all__ = ["normalize_facts"] + + +# TODO: this should be moved to a generic normalizer +def handle_tolerance(tolerance: types.Fact, capacitance: types.Fact) -> List[types.Fact]: + cap_value = float(EeVal.parse(capacitance.valueProp)) + + s = tolerance.valueProp + print("tolerance: {}".format(s)) + is_plus_minus = s.startswith("±") + s = s[1:] if is_plus_minus else s + + is_percent = s.endswith("%") + + is_farad = s.endswith("F") + + print("tolerance={}, is_plus_minus={}, is_farad={}, is_percent={}".format( + tolerance.valueProp, is_plus_minus, is_farad, is_percent)) + print("capacitance={}".format(EeVal.parse(capacitance.valueProp))) + + low_pct = low_value = None + high_pct = high_value = None + facts = [] # type: List[Tuple[str, str, Union[str, EeVal]]] + + if is_farad: + s = s[0:-1] if is_farad else s + + try: + farad = EeVal.parse(s) + except EeException: + farad = None + + elif is_percent: + s = s[0:-1] + pct_value = int(s) + + if is_plus_minus: + low_pct = high_pct = str(pct_value) + pct = float(pct_value) / 100 + low_value = EeVal(value=cap_value * (1 - pct), exp=1, unit="F") + high_value = EeVal(value=cap_value * (1 + pct), exp=1, unit="F") + else: + raise EeException("bad combination") + + if low_pct: + facts.append(("tolerance-percent-lower", "Tolerance, lower (%)", low_pct)) + if high_pct: + facts.append(("tolerance-percent-upper", "Tolerance, upper (%)", high_pct)) + if low_value: + facts.append(("tolerance-lower", "Tolerance, lower", low_value)) + if high_value: + facts.append(("tolerance-upper", "Tolerance, upper", high_value)) + + if low_pct and low_pct == high_pct: + facts.append(("tolerance-percent", "Tolerance (±%)", low_pct)) + + return [types.Fact(key=uris.make_fact_key(key), label=label, value=str(value)) for key, label, value in facts] + + +def re_parser(pattern, kis: List[Tuple[str, int]]): + r = re.compile(pattern) + + def parse(value): + m = r.match(value) + + if not m: + return + + return [(k, m.group(i)) for k, i in kis] + + return parse + + +def no_parser(key): + def parse(value): + return key, value + + return parse + + +def ee_val_parser(key): + def parse(value): + return key, EeVal.parse(value) + + return parse + + +_operating_temperature_re = re.compile("-([0-9]+)°C ~ ([0-9])+°C") +_height_seated_re = re.compile("([0-9]+\\.[0-9]+)\" \\(([0-9]+\\.[0-9]+)mm\\)") +_land_size_re = re.compile("([0-9]+\\.[0-9]+)\" L x ([0-9]+\\.[0-9]+)\" W " + "\\(([0-9]+\\.[0-9]+)mm x ([0-9]+\\.[0-9]+)mm\\)") # 0.260" L x 0.260" W (6.60mm x 6.60mm) +_parsers: Mapping[int, Callable[[str], Any]] = { + 3: no_parser("tolerance"), + 1471: ee_val_parser("voltage-input-min"), # Voltage - Input (Min) + 573: ee_val_parser("voltage-input-max"), # Voltage - Input (Max) + 1429: ee_val_parser("voltage-output-max"), # Voltage - Output (Max) + 252: re_parser(_operating_temperature_re, [("temperature-min", 1), ("temperature-max", 2)]), + 1686: re_parser(_operating_temperature_re, [("temperature-junction-min", 1), ("temperature-junction-max", 2)]), + + 1500: re_parser(_height_seated_re, [("part-height", 2)]), + 884: re_parser(_land_size_re, [("land-size-x", 3), ("land-size-y", 4)]), + + 2049: ee_val_parser("capacitance"), + 2079: ee_val_parser("voltage-rating"), +} + + +# noinspection PyUnusedLocal +def normalize_facts(**kwargs): + parsers: Mapping[str, Callable[[str], Any]] = {uris.make_digikey_fact_key(k): v for k, v in _parsers.items()} + + def on_part(part: Part) -> Part: + for dk_key, parser in parsers.items(): + value = part.facts.get_value(dk_key) + + if value is None or value == "-": + continue + + res = parser(value) + + if res is not None: + if isinstance(res, list): + for key, value in res: + key = uris.make_fact_key(key) + part.facts.add(key, value) + else: + key, value = res + key = uris.make_fact_key(key) + part.facts.add(key, value) + + return part + + return on_part + + +def default(**kwargs): + function_factories = [ + normalize_facts, + ] + + functions = [factory(**kwargs) for factory in function_factories] + functions = [f for f in functions if f is not None] + + def on_part(part: Part) -> Part: + for f in functions: + part = f(part) + + return part + + return on_part diff --git a/src/ee/digikey/normalize_facts.py b/src/ee/digikey/normalize_facts.py deleted file mode 100644 index 1ffc16a..0000000 --- a/src/ee/digikey/normalize_facts.py +++ /dev/null @@ -1,153 +0,0 @@ -import re -from pathlib import Path -from typing import List, Tuple, Union, Mapping, Callable, Any - -from ee import EeVal, EeException -from ee.part import PartDb, load_db, save_db -from ee.xml import types, uris - -__all__ = ["normalize_facts"] - - -# TODO: this should be moved to a generic normalizer -def handle_tolerance(tolerance: types.Fact, capacitance: types.Fact) -> List[types.Fact]: - cap_value = float(EeVal.parse(capacitance.valueProp)) - - s = tolerance.valueProp - print("tolerance: {}".format(s)) - is_plus_minus = s.startswith("±") - s = s[1:] if is_plus_minus else s - - is_percent = s.endswith("%") - - is_farad = s.endswith("F") - - print("tolerance={}, is_plus_minus={}, is_farad={}, is_percent={}".format( - tolerance.valueProp, is_plus_minus, is_farad, is_percent)) - print("capacitance={}".format(EeVal.parse(capacitance.valueProp))) - - low_pct = low_value = None - high_pct = high_value = None - facts = [] # type: List[Tuple[str, str, Union[str, EeVal]]] - - if is_farad: - s = s[0:-1] if is_farad else s - - try: - farad = EeVal.parse(s) - except EeException: - farad = None - - elif is_percent: - s = s[0:-1] - pct_value = int(s) - - if is_plus_minus: - low_pct = high_pct = str(pct_value) - pct = float(pct_value) / 100 - low_value = EeVal(value=cap_value * (1 - pct), exp=1, unit="F") - high_value = EeVal(value=cap_value * (1 + pct), exp=1, unit="F") - else: - raise EeException("bad combination") - - if low_pct: - facts.append(("tolerance-percent-lower", "Tolerance, lower (%)", low_pct)) - if high_pct: - facts.append(("tolerance-percent-upper", "Tolerance, upper (%)", high_pct)) - if low_value: - facts.append(("tolerance-lower", "Tolerance, lower", low_value)) - if high_value: - facts.append(("tolerance-upper", "Tolerance, upper", high_value)) - - if low_pct and low_pct == high_pct: - facts.append(("tolerance-percent", "Tolerance (±%)", low_pct)) - - return [types.Fact(key=uris.make_fact_key(key), label=label, value=str(value)) for key, label, value in facts] - - -def re_parser(pattern, kis: List[Tuple[str, int]]): - r = re.compile(pattern) - - def parse(value): - m = r.match(value) - - if not m: - return - - return [(k, m.group(i)) for k, i in kis] - - return parse - - -def no_parser(key): - def parse(value): - return key, value - - return parse - - -def ee_val_parser(key): - def parse(value): - return key, EeVal.parse(value) - - return parse - - -_operating_temperature_re = re.compile("-([0-9]+)°C ~ ([0-9])+°C") -_height_seated_re = re.compile("([0-9]+\\.[0-9]+)\" \\(([0-9]+\\.[0-9]+)mm\\)") -_land_size_re = re.compile("([0-9]+\\.[0-9]+)\" L x ([0-9]+\\.[0-9]+)\" W " - "\\(([0-9]+\\.[0-9]+)mm x ([0-9]+\\.[0-9]+)mm\\)") # 0.260" L x 0.260" W (6.60mm x 6.60mm) -parsers: Mapping[int, Callable[[str], Any]] = { - 3: no_parser("tolerance"), - 1471: ee_val_parser("voltage-input-min"), # Voltage - Input (Min) - 573: ee_val_parser("voltage-input-max"), # Voltage - Input (Max) - 1429: ee_val_parser("voltage-output-max"), # Voltage - Output (Max) - 252: re_parser(_operating_temperature_re, [("temperature-min", 1), ("temperature-max", 2)]), - 1686: re_parser(_operating_temperature_re, [("temperature-junction-min", 1), ("temperature-junction-max", 2)]), - - 1500: re_parser(_height_seated_re, [("part-height", 2)]), - 884: re_parser(_land_size_re, [("land-size-x", 3), ("land-size-y", 4)]), - - 2049: ee_val_parser("capacitance"), - 2079: ee_val_parser("voltage-rating"), -} - - -def normalize_facts(in_path: Path, out_path: Path): - in_db = load_db(in_path) - out_parts = PartDb() - - for part in in_db.iterparts(): # type: types.Part - fact_list: types.FactList = part.factsProp - if fact_list is None: - continue - - in_facts: List[types.Fact] = fact_list.factProp - out_facts = [] - - for f in in_facts: - key = uris.parse_digikey_fact_key(f.keyProp) - - value = f.valueProp - - if value == "-": - continue - - parser = parsers.get(key) - - if parser is not None: - res = parser(value) - - if res is not None: - if isinstance(res, list): - results = res - else: - results = [res] - facts = [types.Fact(key=uris.make_fact_key(key), value=value) for key, value in results] - out_facts.extend(facts) - - part.factsProp.factProp = out_facts - out_parts.add_entry(part, True) - - print("Saving {} work parts".format(out_parts.size())) - save_db(out_path, out_parts, sort=True) -- cgit v1.2.3