diff --git a/helpers/flower_helpers.py b/helpers/flower_helpers.py new file mode 100644 index 0000000..ec055e9 --- /dev/null +++ b/helpers/flower_helpers.py @@ -0,0 +1,121 @@ +from typing import List, Dict, Optional, Union, Any +from datetime import datetime +import re +from sqlalchemy.orm import Session +from pydantic import BaseModel + +def validate_flower_name(name: str) -> bool: + """ + Validate flower name format. + + Args: + name: The flower name to validate + + Returns: + bool: True if name format is valid, False otherwise + """ + if not name or len(name) < 2 or not name.replace(' ','').isalpha(): + return False + return True + +def validate_hardiness_zone(zone: str) -> bool: + """ + Validate hardiness zone format (e.g. "6a", "7b", "4-9"). + + Args: + zone: Hardiness zone to validate + + Returns: + bool: True if zone format is valid, False otherwise + """ + zone_pattern = r'^(\d{1,2}[a-b]?(-\d{1,2}[a-b]?)?|)$' + return bool(re.match(zone_pattern, zone)) + +def get_flowers_by_season(db: Session, season: str) -> List[Any]: + """ + Get all flowers that bloom in a specific season. + + Args: + db: Database session + season: Season to filter by (Spring, Summer, Fall, Winter) + + Returns: + List of flower objects for that season + """ + return db.query(Flower).filter(Flower.bloom_season == season.capitalize()).all() + +def get_flowers_by_requirements( + db: Session, + sunlight: Optional[str] = None, + water: Optional[str] = None, + height_min: Optional[int] = None, + height_max: Optional[int] = None +) -> List[Any]: + """ + Get flowers matching specific growing requirements. + + Args: + db: Database session + sunlight: Sunlight requirement + water: Water requirement + height_min: Minimum height in inches + height_max: Maximum height in inches + + Returns: + List of matching flower objects + """ + query = db.query(Flower) + + if sunlight: + query = query.filter(Flower.sunlight_needs == sunlight) + if water: + query = query.filter(Flower.water_needs == water) + if height_min: + query = query.filter(Flower.height >= height_min) + if height_max: + query = query.filter(Flower.height <= height_max) + + return query.all() + +def format_flower_details(flower: Any) -> Dict[str, Any]: + """ + Format flower object into standardized dictionary. + + Args: + flower: Flower object to format + + Returns: + Dictionary with formatted flower details + """ + return { + "name": flower.name, + "scientific_name": flower.scientific_name, + "details": { + "color": flower.color, + "height": f"{flower.height} inches" if flower.height else None, + "bloom_season": flower.bloom_season, + "type": "Perennial" if flower.is_perennial else "Annual", + "care": { + "sunlight": flower.sunlight_needs, + "water": flower.water_needs, + "hardiness_zone": flower.hardiness_zone + } + } + } + +def search_flowers(db: Session, search_term: str) -> List[Any]: + """ + Search flowers by name or scientific name. + + Args: + db: Database session + search_term: Term to search for + + Returns: + List of matching flower objects + """ + search = f"%{search_term}%" + return db.query(Flower).filter( + (Flower.name.ilike(search)) | + (Flower.scientific_name.ilike(search)) + ).all() \ No newline at end of file