Spaces:
Runtime error
Runtime error
# models/property_specs.py | |
from datetime import datetime | |
from .logging_config import logger | |
def verify_property_specs(data): | |
""" | |
Verify property specifications for reasonableness and consistency. | |
This function checks if the provided property details are within reasonable ranges | |
for the Indian real estate market. | |
""" | |
specs_verification = { | |
'is_valid': True, | |
'bedrooms_reasonable': True, | |
'bathrooms_reasonable': True, | |
'total_rooms_reasonable': True, | |
'year_built_reasonable': True, | |
'parking_reasonable': True, | |
'sq_ft_reasonable': True, | |
'market_value_reasonable': True, | |
'issues': [] | |
} | |
try: | |
# Helper function to safely convert values | |
def safe_float_convert(value, default=0.0): | |
try: | |
if value is None: | |
return default | |
if isinstance(value, (int, float)): | |
return float(value) | |
if isinstance(value, str): | |
return float(value.replace(',', '').replace('₹', '').strip()) | |
return default | |
except (ValueError, TypeError) as e: | |
logger.warning(f"safe_float_convert error: {str(e)}") | |
return default | |
def safe_int_convert(value, default=0): | |
try: | |
if value is None: | |
return default | |
if isinstance(value, (int, float)): | |
return int(value) | |
if isinstance(value, str): | |
return int(float(value.replace(',', '').strip())) | |
return default | |
except (ValueError, TypeError) as e: | |
logger.warning(f"safe_int_convert error: {str(e)}") | |
return default | |
# Validate property type | |
valid_property_types = [ | |
'Apartment', 'House', 'Villa', 'Independent House', 'Independent Villa', | |
'Studio', 'Commercial', 'Office', 'Shop', 'Warehouse', 'Industrial' | |
] | |
property_type = str(data.get('property_type', '')).strip() | |
if not property_type or property_type not in valid_property_types: | |
specs_verification['is_valid'] = False | |
specs_verification['issues'].append(f"Invalid property type: {property_type if property_type else 'Not specified'}") | |
# Validate bedrooms | |
if 'bedrooms' in data: | |
bedrooms = safe_int_convert(data['bedrooms']) | |
if property_type in ['Apartment', 'Studio']: | |
if bedrooms > 5 or bedrooms < 0: | |
specs_verification['bedrooms_reasonable'] = False | |
specs_verification['issues'].append(f"Invalid number of bedrooms for {property_type}: {bedrooms}. Should be between 0 and 5.") | |
elif property_type in ['House', 'Villa', 'Independent House', 'Independent Villa']: | |
if bedrooms > 8 or bedrooms < 0: | |
specs_verification['bedrooms_reasonable'] = False | |
specs_verification['issues'].append(f"Invalid number of bedrooms for {property_type}: {bedrooms}. Should be between 0 and 8.") | |
elif property_type in ['Commercial', 'Office', 'Shop', 'Warehouse', 'Industrial']: | |
if bedrooms > 0: | |
specs_verification['bedrooms_reasonable'] = False | |
specs_verification['issues'].append(f"Commercial properties typically don't have bedrooms: {bedrooms}") | |
# Validate bathrooms | |
if 'bathrooms' in data: | |
bathrooms = safe_float_convert(data['bathrooms']) | |
if property_type in ['Apartment', 'Studio']: | |
if bathrooms > 4 or bathrooms < 0: | |
specs_verification['bathrooms_reasonable'] = False | |
specs_verification['issues'].append(f"Invalid number of bathrooms for {property_type}: {bathrooms}. Should be between 0 and 4.") | |
elif property_type in ['House', 'Villa', 'Independent House', 'Independent Villa']: | |
if bathrooms > 6 or bathrooms < 0: | |
specs_verification['bathrooms_reasonable'] = False | |
specs_verification['issues'].append(f"Invalid number of bathrooms for {property_type}: {bathrooms}. Should be between 0 and 6.") | |
elif property_type in ['Commercial', 'Office', 'Shop', 'Warehouse', 'Industrial']: | |
if bathrooms > 0: | |
specs_verification['bathrooms_reasonable'] = False | |
specs_verification['issues'].append(f"Commercial properties typically don't have bathrooms: {bathrooms}") | |
# Validate total rooms | |
if 'total_rooms' in data: | |
try: | |
total_rooms = safe_int_convert(data['total_rooms']) | |
if total_rooms < 0: | |
specs_verification['total_rooms_reasonable'] = False | |
specs_verification['issues'].append(f"Invalid total rooms: {total_rooms}. Cannot be negative.") | |
elif 'bedrooms' in data and 'bathrooms' in data: | |
bedrooms = safe_int_convert(data['bedrooms']) | |
bathrooms = safe_int_convert(data['bathrooms']) | |
if total_rooms < (bedrooms + bathrooms): | |
specs_verification['total_rooms_reasonable'] = False | |
specs_verification['issues'].append(f"Total rooms ({total_rooms}) is less than bedrooms + bathrooms ({bedrooms + bathrooms})") | |
except Exception as e: | |
logger.warning(f"Error validating total rooms: {str(e)}") | |
specs_verification['total_rooms_reasonable'] = False | |
specs_verification['issues'].append(f"Invalid total rooms data: must be a number ({str(e)})") | |
# Validate parking | |
if 'parking' in data: | |
try: | |
parking = safe_int_convert(data['parking']) | |
if property_type in ['Apartment', 'Studio']: | |
if parking > 2 or parking < 0: | |
specs_verification['parking_reasonable'] = False | |
specs_verification['issues'].append(f"Invalid parking spaces for {property_type}: {parking}. Should be between 0 and 2.") | |
elif property_type in ['House', 'Villa', 'Independent House', 'Independent Villa']: | |
if parking > 4 or parking < 0: | |
specs_verification['parking_reasonable'] = False | |
specs_verification['issues'].append(f"Invalid parking spaces for {property_type}: {parking}. Should be between 0 and 4.") | |
elif property_type in ['Commercial', 'Office', 'Shop', 'Warehouse', 'Industrial']: | |
if parking < 0: | |
specs_verification['parking_reasonable'] = False | |
specs_verification['issues'].append(f"Invalid parking spaces: {parking}. Cannot be negative.") | |
except Exception as e: | |
logger.warning(f"Error validating parking: {str(e)}") | |
specs_verification['parking_reasonable'] = False | |
specs_verification['issues'].append(f"Invalid parking data: must be a number ({str(e)})") | |
# Validate square footage | |
if 'sq_ft' in data: | |
try: | |
sq_ft = safe_float_convert(data['sq_ft']) | |
if sq_ft <= 0: | |
specs_verification['sq_ft_reasonable'] = False | |
specs_verification['issues'].append(f"Invalid square footage: {sq_ft}. Must be greater than 0.") | |
else: | |
if property_type in ['Apartment', 'Studio']: | |
if sq_ft > 5000: | |
specs_verification['sq_ft_reasonable'] = False | |
specs_verification['issues'].append(f"Square footage ({sq_ft}) seems unreasonably high for {property_type}") | |
elif sq_ft < 200: | |
specs_verification['sq_ft_reasonable'] = False | |
specs_verification['issues'].append(f"Square footage ({sq_ft}) seems unreasonably low for {property_type}") | |
elif property_type in ['House', 'Villa', 'Independent House', 'Independent Villa']: | |
if sq_ft > 10000: | |
specs_verification['sq_ft_reasonable'] = False | |
specs_verification['issues'].append(f"Square footage ({sq_ft}) seems unreasonably high for {property_type}") | |
elif sq_ft < 500: | |
specs_verification['sq_ft_reasonable'] = False | |
specs_verification['issues'].append(f"Square footage ({sq_ft}) seems unreasonably low for {property_type}") | |
except Exception as e: | |
logger.warning(f"Error validating square footage: {str(e)}") | |
specs_verification['sq_ft_reasonable'] = False | |
specs_verification['issues'].append(f"Invalid square footage data: must be a number ({str(e)})") | |
# Validate market value | |
if 'market_value' in data: | |
try: | |
market_value = safe_float_convert(data['market_value']) | |
if market_value <= 0: | |
specs_verification['market_value_reasonable'] = False | |
specs_verification['issues'].append(f"Invalid market value: {market_value}. Must be greater than 0.") | |
else: | |
if property_type in ['Apartment', 'Studio']: | |
if market_value > 500000000: # 5 crore limit for apartments | |
specs_verification['market_value_reasonable'] = False | |
specs_verification['issues'].append(f"Market value (₹{market_value:,.2f}) seems unreasonably high for {property_type}") | |
elif market_value < 500000: # 5 lakh minimum | |
specs_verification['market_value_reasonable'] = False | |
specs_verification['issues'].append(f"Market value (₹{market_value:,.2f}) seems unreasonably low for {property_type}") | |
elif property_type in ['House', 'Villa', 'Independent House', 'Independent Villa']: | |
if market_value > 2000000000: # 20 crore limit for houses | |
specs_verification['market_value_reasonable'] = False | |
specs_verification['issues'].append(f"Market value (₹{market_value:,.2f}) seems unreasonably high for {property_type}") | |
elif market_value < 1000000: # 10 lakh minimum | |
specs_verification['market_value_reasonable'] = False | |
specs_verification['issues'].append(f"Market value (₹{market_value:,.2f}) seems unreasonably low for {property_type}") | |
elif property_type in ['Commercial', 'Office', 'Shop']: | |
if market_value < 2000000: # 20 lakh minimum | |
specs_verification['market_value_reasonable'] = False | |
specs_verification['issues'].append(f"Market value (₹{market_value:,.2f}) seems unreasonably low for {property_type}") | |
elif property_type in ['Warehouse', 'Industrial']: | |
if market_value < 5000000: # 50 lakh minimum | |
specs_verification['market_value_reasonable'] = False | |
specs_verification['issues'].append(f"Market value (₹{market_value:,.2f}) seems unreasonably low for {property_type}") | |
# Check price per square foot | |
if 'sq_ft' in data and safe_float_convert(data['sq_ft']) > 0: | |
try: | |
sq_ft = safe_float_convert(data['sq_ft']) | |
price_per_sqft = market_value / sq_ft | |
if property_type in ['Apartment', 'Studio']: | |
if price_per_sqft < 1000: # Less than ₹1000 per sq ft | |
specs_verification['market_value_reasonable'] = False | |
specs_verification['issues'].append(f"Price per sq ft (₹{price_per_sqft:,.2f}) seems unreasonably low for {property_type}") | |
elif price_per_sqft > 50000: # More than ₹50k per sq ft | |
specs_verification['market_value_reasonable'] = False | |
specs_verification['issues'].append(f"Price per sq ft (₹{price_per_sqft:,.2f}) seems unreasonably high for {property_type}") | |
elif property_type in ['House', 'Villa', 'Independent House', 'Independent Villa']: | |
if price_per_sqft < 500: # Less than ₹500 per sq ft | |
specs_verification['market_value_reasonable'] = False | |
specs_verification['issues'].append(f"Price per sq ft (₹{price_per_sqft:,.2f}) seems unreasonably low for {property_type}") | |
elif price_per_sqft > 100000: # More than ₹1 lakh per sq ft | |
specs_verification['market_value_reasonable'] = False | |
specs_verification['issues'].append(f"Price per sq ft (₹{price_per_sqft:,.2f}) seems unreasonably high for {property_type}") | |
except Exception as e: | |
logger.warning(f"Error validating price per sq ft: {str(e)}") | |
except Exception as e: | |
logger.warning(f"Error validating market value: {str(e)}") | |
specs_verification['market_value_reasonable'] = False | |
specs_verification['issues'].append(f"Invalid market value data: must be a number ({str(e)})") | |
# Calculate verification score | |
try: | |
valid_checks = sum([ | |
specs_verification['bedrooms_reasonable'], | |
specs_verification['bathrooms_reasonable'], | |
specs_verification['total_rooms_reasonable'], | |
specs_verification['year_built_reasonable'], | |
specs_verification['parking_reasonable'], | |
specs_verification['sq_ft_reasonable'], | |
specs_verification['market_value_reasonable'] | |
]) | |
total_checks = 7 | |
specs_verification['verification_score'] = (valid_checks / total_checks) * 100 | |
except Exception as e: | |
logger.error(f"Error calculating verification score: {str(e)}") | |
specs_verification['verification_score'] = 0.0 | |
# Overall validity | |
try: | |
specs_verification['is_valid'] = all([ | |
specs_verification['bedrooms_reasonable'], | |
specs_verification['bathrooms_reasonable'], | |
specs_verification['total_rooms_reasonable'], | |
specs_verification['year_built_reasonable'], | |
specs_verification['parking_reasonable'], | |
specs_verification['sq_ft_reasonable'], | |
specs_verification['market_value_reasonable'] | |
]) | |
except Exception as e: | |
logger.error(f"Error calculating overall validity: {str(e)}") | |
specs_verification['is_valid'] = False | |
except Exception as e: | |
logger.error(f"Error in property specs verification: {str(e)}") | |
specs_verification['is_valid'] = False | |
specs_verification['issues'].append(f"Error in verification: {str(e)}") | |
return specs_verification | |