68 lines
2.1 KiB
Python
68 lines
2.1 KiB
Python
|
"""Functions to parse the dimensions string into a dictionary that represents
|
||
|
those dimenions in cm
|
||
|
"""
|
||
|
|
||
|
import logging
|
||
|
from typing import Dict, Optional
|
||
|
import re
|
||
|
|
||
|
|
||
|
UNIT_CONVERSIONS = {"inches": 2.54, "feet": 30.48, "cm": 1}
|
||
|
|
||
|
|
||
|
def parse_dimensions_measure(dimensions: str, measure: str) -> Optional[Dict]:
|
||
|
"""Using a regex, parse a measurement out of a dimensions string
|
||
|
I expect to find a value of the form `1.2 inches (W)` specifying the value,
|
||
|
unit and measurement.
|
||
|
Return a dictionary representing the parsed value and its unit.
|
||
|
"""
|
||
|
expr = rf"(?P<value>\d*[.,]?\d*)\s+(?P<unit>[a-zA-Z]*)\s+\({measure}\)"
|
||
|
if match := re.search(expr, dimensions):
|
||
|
match_value = match.group("value")
|
||
|
try:
|
||
|
value = float(match_value)
|
||
|
except ValueError:
|
||
|
logging.error("could not parse value `%s` as a float for a dimension")
|
||
|
return None
|
||
|
return {
|
||
|
"value": value,
|
||
|
"unit": match.group("unit").lower(),
|
||
|
}
|
||
|
return None
|
||
|
|
||
|
|
||
|
def units_to_cm(value: float, unit: str) -> Optional[float]:
|
||
|
"""Convert a given dimension unit into centimeters.
|
||
|
If unrecognized unit, return None"""
|
||
|
try:
|
||
|
conversion = UNIT_CONVERSIONS[unit]
|
||
|
except KeyError:
|
||
|
logging.error("unrecognized unit: %s", unit)
|
||
|
return None
|
||
|
return value * conversion
|
||
|
|
||
|
|
||
|
def parse_dimensions(dimensions: Optional[str]) -> Dict[str, Optional[float]]:
|
||
|
"""Parse a string representing dimensions"""
|
||
|
if dimensions is None:
|
||
|
return {
|
||
|
"height": None,
|
||
|
"width": None,
|
||
|
"depth": None,
|
||
|
}
|
||
|
height = parse_dimensions_measure(dimensions, "H")
|
||
|
width = parse_dimensions_measure(dimensions, "W")
|
||
|
depth = parse_dimensions_measure(dimensions, "D")
|
||
|
parsed_dimensions = {
|
||
|
"height": height,
|
||
|
"width": width,
|
||
|
"depth": depth,
|
||
|
}
|
||
|
result = {}
|
||
|
for key, value in parsed_dimensions.items():
|
||
|
if value is None:
|
||
|
result[key] = value
|
||
|
else:
|
||
|
result[key] = units_to_cm(**value)
|
||
|
return result
|