""" Height Conversion Tool A simple and efficient tool for converting height measurements between different units. """ from typing import Tuple, Union import re class HeightConverter: """Main class for height conversions.""" # Conversion constants INCH_TO_CM = 2.54 FEET_TO_CM = 30.48 FEET_TO_INCH = 12 CM_TO_INCH = 1 / INCH_TO_CM METER_TO_CM = 100 def __init__(self): """Initialize the HeightConverter.""" pass def feet_to_cm(self, feet: Union[int, float], inches: float = 0) -> float: """ Convert feet and inches to centimeters. Args: feet: Number of feet inches: Number of inches (default: 0) Returns: Height in centimeters Examples: >>> converter = HeightConverter() >>> converter.feet_to_cm(5, 10) 177.8 """ if feet < 0 or inches < 0: raise ValueError("Height values cannot be negative") total_inches = (feet * self.FEET_TO_INCH) + inches cm = total_inches * self.INCH_TO_CM return round(cm, 2) def cm_to_feet(self, cm: float) -> Tuple[int, float]: """ Convert centimeters to feet and inches. Args: cm: Height in centimeters Returns: Tuple of (feet, inches) Examples: >>> converter = HeightConverter() >>> converter.cm_to_feet(180) (5, 10.9) """ if cm < 0: raise ValueError("Height cannot be negative") total_inches = cm * self.CM_TO_INCH feet = int(total_inches // self.FEET_TO_INCH) inches = total_inches % self.FEET_TO_INCH return feet, round(inches, 1) def meters_to_feet(self, meters: float) -> Tuple[int, float]: """ Convert meters to feet and inches. Args: meters: Height in meters Returns: Tuple of (feet, inches) Examples: >>> converter = HeightConverter() >>> converter.meters_to_feet(1.75) (5, 8.9) """ if meters < 0: raise ValueError("Height cannot be negative") cm = meters * self.METER_TO_CM return self.cm_to_feet(cm) def feet_to_meters(self, feet: Union[int, float], inches: float = 0) -> float: """ Convert feet and inches to meters. Args: feet: Number of feet inches: Number of inches (default: 0) Returns: Height in meters Examples: >>> converter = HeightConverter() >>> converter.feet_to_meters(6, 0) 1.83 """ cm = self.feet_to_cm(feet, inches) meters = cm / self.METER_TO_CM return round(meters, 2) def cm_to_meters(self, cm: float) -> float: """ Convert centimeters to meters. Args: cm: Height in centimeters Returns: Height in meters """ if cm < 0: raise ValueError("Height cannot be negative") return round(cm / self.METER_TO_CM, 2) def meters_to_cm(self, meters: float) -> float: """ Convert meters to centimeters. Args: meters: Height in meters Returns: Height in centimeters """ if meters < 0: raise ValueError("Height cannot be negative") return round(meters * self.METER_TO_CM, 2) def parse_height_string(self, height_str: str) -> dict: """ Parse a height string into its components. Args: height_str: Height string (e.g., "5'10\"", "180cm", "1.8m") Returns: Dictionary with parsed values and unit Examples: >>> converter = HeightConverter() >>> converter.parse_height_string("5'10\"") {'feet': 5, 'inches': 10, 'unit': 'feet'} """ height_str = height_str.strip().lower() # Pattern for feet and inches (5'10", 5'10, 5ft10in, etc.) feet_pattern = r"(\d+)(?:'|ft|feet)\s*(\d+(?:\.\d+)?)?(?:\"|in|inches)?" match = re.match(feet_pattern, height_str) if match: feet = int(match.group(1)) inches = float(match.group(2)) if match.group(2) else 0 return {'feet': feet, 'inches': inches, 'unit': 'feet'} # Pattern for centimeters (180cm, 180 cm) cm_pattern = r"(\d+(?:\.\d+)?)\s*cm" match = re.match(cm_pattern, height_str) if match: cm = float(match.group(1)) return {'cm': cm, 'unit': 'cm'} # Pattern for meters (1.8m, 1.8 m) m_pattern = r"(\d+(?:\.\d+)?)\s*m(?:eters?)?" match = re.match(m_pattern, height_str) if match: meters = float(match.group(1)) return {'meters': meters, 'unit': 'meters'} raise ValueError(f"Unable to parse height string: {height_str}") def convert(self, input_str: str, to_unit: str = "cm") -> str: """ Flexible conversion from string input. Args: input_str: Height string (e.g., "5'10\"", "180cm", "1.8m") to_unit: Target unit ("cm", "feet", "meters") Returns: Converted height as formatted string Examples: >>> converter = HeightConverter() >>> converter.convert("5'10\"", "cm") '177.8 cm' """ parsed = self.parse_height_string(input_str) to_unit = to_unit.lower() # Convert to target unit if to_unit == "cm": if parsed['unit'] == 'feet': result = self.feet_to_cm(parsed['feet'], parsed['inches']) return f"{result} cm" elif parsed['unit'] == 'meters': result = self.meters_to_cm(parsed['meters']) return f"{result} cm" else: return f"{parsed['cm']} cm" elif to_unit == "feet": if parsed['unit'] == 'cm': feet, inches = self.cm_to_feet(parsed['cm']) return f"{feet}'{inches:.1f}\"" elif parsed['unit'] == 'meters': feet, inches = self.meters_to_feet(parsed['meters']) return f"{feet}'{inches:.1f}\"" else: return f"{parsed['feet']}'{parsed['inches']:.1f}\"" elif to_unit == "meters" or to_unit == "m": if parsed['unit'] == 'feet': result = self.feet_to_meters(parsed['feet'], parsed['inches']) return f"{result} m" elif parsed['unit'] == 'cm': result = self.cm_to_meters(parsed['cm']) return f"{result} m" else: return f"{parsed['meters']} m" else: raise ValueError(f"Unknown target unit: {to_unit}") def main(): """Command line interface for the height converter.""" import argparse parser = argparse.ArgumentParser( description='Convert height between different units' ) parser.add_argument( 'height', type=str, help='Height to convert (e.g., "5\'10\"", "180cm", "1.8m")' ) parser.add_argument( '--to', type=str, default='cm', choices=['cm', 'feet', 'meters', 'm'], help='Target unit (default: cm)' ) args = parser.parse_args() converter = HeightConverter() try: result = converter.convert(args.height, args.to) print(result) except ValueError as e: print(f"Error: {e}") return 1 return 0 if __name__ == '__main__': exit(main())