"""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\d*[.,]?\d*)\s+(?P[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