dayrize-usecase/pipeline/beam_etl/helpers/weight.py

52 lines
1.7 KiB
Python

"""Functions to parse the weigth string into a dictionary that represents
the weight in g
"""
import logging
from typing import Optional
import re
from helpers.misc import convert_units
UNIT_CONVERSIONS = {"pounds": 453.592, "ounces": 28.3495, "g": 1, "kg": 1000}
def parse_weight(weight: Optional[str]) -> Optional[float]:
"""Parse a weigth string into a dictionary representing the weight unit and
value"""
if weight is None:
return None
expr = r"(?P<value>\d*[.,]?\d*)\s+(?P<unit>[a-zA-Z]*)"
# strip is needed to prevent the regex from lazily
# matching just from the first whitespace separator,
# this could happen because the number part in the
# expression is technically all optional, to avoid
# an expression too complex and unreadable
if match := re.search(expr, weight.strip()):
match_value = match.group("value")
try:
value = float(match_value)
except ValueError:
logging.error("could not parse value `%s` as a float for a weight")
return None
unit = match.group("unit").lower()
return convert_units(value, unit, unit_conversions=UNIT_CONVERSIONS)
return None
def dimensional_weight(
height: Optional[float], width: Optional[float], depth: Optional[float]
) -> Optional[float]:
"""The dimensional weight (in kg) is calculated as:
Length * Height * Width (in cm) / 5000.
We'll return it in g here"""
if None in [height, width, depth]:
return None
dimensional_weight_kg = height * width * depth / 5000
return convert_units(
value=dimensional_weight_kg, unit="kg", unit_conversions=UNIT_CONVERSIONS
)