# -*- coding: utf-8 -*- """ This file contains a set of functions for matching values which may be written in different formats e.g. 0.1uF = 100n (different suffix specified, one has missing unit) 0R1 = 0.1Ohm (Unit replaces decimal, different units) """ from __future__ import unicode_literals import re PREFIX_MICRO = [u"μ", "u", "micro"] PREFIX_MILLI = ["milli", "m"] PREFIX_NANO = ["nano", "n"] PREFIX_PICO = ["pico", "p"] PREFIX_KILO = ["kilo", "k"] PREFIX_MEGA = ["mega", "meg"] PREFIX_GIGA = ["giga", "g"] # All prefixes PREFIX_ALL = PREFIX_PICO + PREFIX_NANO + PREFIX_MICRO + PREFIX_MILLI + PREFIX_KILO + PREFIX_MEGA + PREFIX_GIGA # Common methods of expressing component units UNIT_R = ["r", "ohms", "ohm", u"Ω"] UNIT_C = ["farad", "f"] UNIT_L = ["henry", "h"] UNIT_ALL = UNIT_R + UNIT_C + UNIT_L def getUnit(unit): """ Return a simplified version of a units string, for comparison purposes """ if not unit: return None unit = unit.lower() if unit in UNIT_R: return "R" if unit in UNIT_C: return "F" if unit in UNIT_L: return "H" return None def getPrefix(prefix): """ Return the (numerical) value of a given prefix """ if not prefix: return 1 prefix = prefix.lower() if prefix in PREFIX_PICO: return 1.0e-12 if prefix in PREFIX_NANO: return 1.0e-9 if prefix in PREFIX_MICRO: return 1.0e-6 if prefix in PREFIX_MILLI: return 1.0e-3 if prefix in PREFIX_KILO: return 1.0e3 if prefix in PREFIX_MEGA: return 1.0e6 if prefix in PREFIX_GIGA: return 1.0e9 return 1 def groupString(group): # Return a reg-ex string for a list of values return "|".join(group) def matchString(): return "^([0-9\.]+)(" + groupString(PREFIX_ALL) + ")*(" + groupString(UNIT_ALL) + ")*(\d*)$" def compMatch(component): """ Return a normalized value and units for a given component value string e.g. compMatch("10R2") returns (10, R) e.g. compMatch("3.3mOhm") returns (0.0033, R) """ # Remove any commas component = component.strip().replace(",", "").lower() match = matchString() result = re.search(match, component) if not result: return None if not len(result.groups()) == 4: return None value, prefix, units, post = result.groups() # Special case where units is in the middle of the string # e.g. "0R05" for 0.05Ohm # In this case, we will NOT have a decimal # We will also have a trailing number if post and "." not in value: try: value = float(int(value)) postValue = float(int(post)) / (10 ** len(post)) value = value * 1.0 + postValue except: return None try: val = float(value) except: return None val = "{0:.15f}".format(val * 1.0 * getPrefix(prefix)) return (val, getUnit(units)) def componentValue(valString): result = compMatch(valString) if not result: return valString # Return the same string back if not len(result) == 2: # Result length is incorrect return valString val = result[0] return val def compareValues(c1, c2): """ Compare two values """ r1 = compMatch(c1) r2 = compMatch(c2) if not r1 or not r2: return False (v1, u1) = r1 (v2, u2) = r2 if v1 == v2: # Values match if u1 == u2: return True # Units match if not u1: return True # No units for component 1 if not u2: return True # No units for component 2 return False