From e35ef8ec3c47469c5b66a1b71800d7ddb94a6bea Mon Sep 17 00:00:00 2001 From: SET Date: Thu, 13 Aug 2020 22:45:25 -0300 Subject: [PATCH] Added options to normalize R, L and C values. --- kiplot/bom/bom.py | 24 +++++++++++++++++++-- kiplot/bom/units.py | 51 ++++++++++++++++++--------------------------- kiplot/out_bom.py | 4 ++++ 3 files changed, 46 insertions(+), 33 deletions(-) diff --git a/kiplot/bom/bom.py b/kiplot/bom/bom.py index 785e27c1..adb990d3 100644 --- a/kiplot/bom/bom.py +++ b/kiplot/bom/bom.py @@ -4,6 +4,7 @@ This code is adapted from https://github.com/SchrodingersGat/KiBoM by Oliver Hen Here is all the logic to convert a list of components into the rows and columns used to create the BoM. """ +import locale from copy import deepcopy from .units import compare_values, comp_match from .bom_writer import write_bom @@ -315,7 +316,7 @@ def get_value_sort(comp): """ Try to better sort R, L and C components """ res = comp.value_sort if res: - value, mult, unit = res + value, (mult, mult_s), unit = res if comp.ref_prefix in "CL": # fempto Farads value = "{0:15d}".format(int(value * 1e15 * mult + 0.1)) @@ -326,6 +327,18 @@ def get_value_sort(comp): return comp.value +def normalize_value(c, decimal_point): + if c.value_sort is None: + return c.value + value, (mult, mult_s), unit = c.value_sort + ivalue = int(value) + if value == ivalue: + value = ivalue + elif decimal_point: + value = str(value).replace('.', decimal_point) + return '{} {}{}'.format(value, mult_s, unit) + + def group_components(cfg, components): groups = [] # Iterate through each component, and test whether a group for these already exists @@ -338,7 +351,7 @@ def group_components(cfg, components): continue # Cache the value used to sort if c.ref_prefix in RLC_PREFIX: - c.value_sort = comp_match(c.value) + c.value_sort = comp_match(c.value, c.ref_prefix) else: c.value_sort = None # Try to add the component to an existing group @@ -354,11 +367,18 @@ def group_components(cfg, components): g.add_component(c) groups.append(g) # Now unify the data from the components of each group + decimal_point = None + if cfg.normalize_locale: + decimal_point = locale.localeconv()['decimal_point'] + if decimal_point == '.': + decimal_point = None for g in groups: # Sort the references within each group g.sort_components() # Fill the columns g.update_fields(cfg.use_alt) + if cfg.normalize_values: + g.fields[ColumnList.COL_VALUE_L] = normalize_value(g.components[0], decimal_point) # Sort the groups # First priority is the Type of component (e.g. R?, U?, L?) groups = sorted(groups, key=lambda g: [g.components[0].ref_prefix, get_value_sort(g.components[0])]) diff --git a/kiplot/bom/units.py b/kiplot/bom/units.py index 5786797d..cb44bd5c 100644 --- a/kiplot/bom/units.py +++ b/kiplot/bom/units.py @@ -41,13 +41,17 @@ match = None decimal_point = None -def get_unit(unit): +def get_unit(unit, ref_prefix): """ Return a simplified version of a units string, for comparison purposes """ if not unit: - return None + if ref_prefix == 'L': + return "H" + if ref_prefix == 'C': + return "F" + return u"Ω" unit = unit.lower() if unit in UNIT_R: - return "R" + return u"Ω" if unit in UNIT_C: return "F" if unit in UNIT_L: @@ -57,29 +61,29 @@ def get_unit(unit): def get_prefix(prefix): """ Return the (numerical) value of a given prefix """ if not prefix: - return 1 + return 1, '' # 'M' is mega, 'm' is milli if prefix != 'M': prefix = prefix.lower() if prefix in PREFIX_PICO: - return 1.0e-12 + return 1.0e-12, 'p' if prefix in PREFIX_NANO: - return 1.0e-9 + return 1.0e-9, 'n' if prefix in PREFIX_MICRO: - return 1.0e-6 + return 1.0e-6, u"µ" if prefix in PREFIX_MILLI: - return 1.0e-3 + return 1.0e-3, 'm' if prefix in PREFIX_KILO: - return 1.0e3 + return 1.0e3, 'k' if prefix in PREFIX_MEGA: - return 1.0e6 + return 1.0e6, 'M' if prefix in PREFIX_GIGA: - return 1.0e9 + return 1.0e9, 'G' # Unknown, we shouldn't get here because the regex matched # BUT: I found that sometimes unexpected things happend, like mu matching micro and then we reaching this code # Now is fixed, but I can't be sure some bizarre case is overlooked logger.error('Unknown prefix, please report') # pragma: no cover - return 1 # pragma: no cover + return 1, '' # pragma: no cover def group_string(group): # Return a reg-ex string for a list of values @@ -90,7 +94,7 @@ def match_string(): return r"(\d*\.?\d*)\s*(" + group_string(PREFIX_ALL) + ")*(" + group_string(UNIT_ALL) + r")*(\d*)$" -def comp_match(component): +def comp_match(component, ref_prefix): """ Return a normalized value and units for a given component value string e.g. comp_match('10R2') returns (10, R) @@ -145,22 +149,7 @@ def comp_match(component): val = float(value) # Return all the data, let the caller join it - return (val, get_prefix(prefix), get_unit(units)) - - -# def component_value(valString): -# -# result = comp_match(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 + return (val, get_prefix(prefix), get_unit(units, ref_prefix)) def compare_values(c1, c2): @@ -174,8 +163,8 @@ def compare_values(c1, c2): return False # Join the data to compare - (v1, p1, u1) = r1 - (v2, p2, u2) = r2 + (v1, (p1, ps1), u1) = r1 + (v2, (p2, ps2), u2) = r2 v1 = "{0:.15f}".format(v1 * 1.0 * p1) v2 = "{0:.15f}".format(v2 * 1.0 * p2) diff --git a/kiplot/out_bom.py b/kiplot/out_bom.py index 292a6dd9..0e13f3c5 100644 --- a/kiplot/out_bom.py +++ b/kiplot/out_bom.py @@ -250,6 +250,10 @@ class BoMOptions(BaseOptions): self.columns = BoMColumns """ [list(dict)|list(string)] List of columns to display. Can be just the name of the field """ + self.normalize_values = False + """ Try to normalize the R, L and C values, producing uniform units and prefixes """ + self.normalize_locale = False + """ When normalizing values use the locale decimal point """ self.html = BoMHTML """ [dict] Options for the HTML format """ self.xlsx = BoMXLSX