Added options to normalize R, L and C values.

This commit is contained in:
SET 2020-08-13 22:45:25 -03:00
parent 7544f75a53
commit e35ef8ec3c
3 changed files with 46 additions and 33 deletions

View File

@ -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])])

View File

@ -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)

View File

@ -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