Spaces:
Sleeping
Sleeping
from typing import List, Dict, Tuple | |
from dataclasses import dataclass | |
import json | |
from enum import Enum | |
class SizeLabel(Enum): | |
XS = 1 | |
S = 2 | |
M = 3 | |
L = 4 | |
XL = 5 | |
XXL = 6 | |
class SizeRange: | |
label: str | |
waist: List[int] | |
hip: List[int] | |
length: List[int] | |
class Brand: | |
brand: str | |
sizes: List[SizeRange] | |
def load_size_data() -> List[Brand]: | |
"""Load and parse the size data from JSON.""" | |
with open('./data/size_data_pants.json', 'r') as f: | |
data = json.load(f) | |
brands = [] | |
for brand_data in data: | |
sizes = [] | |
for size in brand_data['sizes']: | |
sizes.append(SizeRange( | |
label=size['label'], | |
waist=size['waist'], | |
hip=size['hip'], | |
length=size['length'] | |
)) | |
brands.append(Brand(brand=brand_data['brand'], sizes=sizes)) | |
return brands | |
def find_size_category(measurement: int, ranges: List[List[int]]) -> List[int]: | |
"""Find matching size indices for a given measurement.""" | |
return [i for i, (min_val, max_val) in enumerate(ranges) if min_val <= measurement <= max_val] | |
def get_best_size(brand_name: str, waist: int, hip: int, length: int) -> Tuple[str, Dict[str, str]]: | |
""" | |
Determine the best size for given measurements and brand. | |
Args: | |
brand_name (str): Name of the brand | |
waist (int): Waist measurement in cm | |
hip (int): Hip measurement in cm | |
length (int): Pants length in cm | |
Returns: | |
Tuple[str, Dict[str, str]]: Recommended size label and detailed fit information | |
""" | |
brands = load_size_data() | |
brand = next((b for b in brands if b.brand.lower() == brand_name.lower()), None) | |
if not brand: | |
raise ValueError(f"Brand '{brand_name}' not found") | |
waist_ranges = [size.waist for size in brand.sizes] | |
hip_ranges = [size.hip for size in brand.sizes] | |
length_ranges = [size.length for size in brand.sizes] | |
waist_sizes = find_size_category(waist, waist_ranges) | |
hip_sizes = find_size_category(hip, hip_ranges) | |
length_sizes = find_size_category(length, length_ranges) | |
if not waist_sizes or not hip_sizes or not length_sizes: | |
measurements_info = { | |
"waist": "too small" if waist < waist_ranges[0][0] else "too large" if waist > waist_ranges[-1][1] else "ok", | |
"hip": "too small" if hip < hip_ranges[0][0] else "too large" if hip > hip_ranges[-1][1] else "ok", | |
"length": "too short" if length < length_ranges[0][0] else "too long" if length > length_ranges[-1][1] else "ok" | |
} | |
return "No exact fit", measurements_info | |
all_indices = waist_sizes + hip_sizes + length_sizes | |
avg_size_index = round(sum(all_indices) / len(all_indices)) | |
recommended_size = brand.sizes[avg_size_index].label | |
fit_info = { | |
"waist": "perfect" if avg_size_index in waist_sizes else "tight" if avg_size_index > max(waist_sizes) else "loose", | |
"hip": "perfect" if avg_size_index in hip_sizes else "tight" if avg_size_index > max(hip_sizes) else "loose", | |
"length": "perfect" if avg_size_index in length_sizes else "short" if avg_size_index > max(length_sizes) else "long" | |
} | |
return recommended_size, fit_info | |
def print_size_recommendation(brand: str, waist: int, hip: int, length: int) -> None: | |
""" | |
Print a formatted size recommendation. | |
Args: | |
brand (str): Brand name | |
waist (int): Waist measurement in cm | |
hip (int): Hip measurement in cm | |
length (int): Pants length in cm | |
""" | |
try: | |
size, fit_info = get_best_size(brand, waist, hip, length) | |
print(f"\nSize Recommendation for {brand}:") | |
print(f"Recommended size: {size}") | |
print("\nFit Details:") | |
print(f"Waist: {fit_info['waist']}") | |
print(f"Hip: {fit_info['hip']}") | |
print(f"Length: {fit_info['length']}") | |
except ValueError as e: | |
print(f"Error: {str(e)}") | |
# Example usage | |
if __name__ == "__main__": | |
print_size_recommendation("Zara", 80, 95, 105) | |