Added options to normalize R, L and C values.
This commit is contained in:
parent
7544f75a53
commit
e35ef8ec3c
|
|
@ -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])])
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue