KillerKing93/Transformers-InferenceServer-OpenAPI
0
1#!/usr/bin/env python2# -*- coding: utf-8 -*-3"""4Utility functions for AI Marketplace Platform5 6Functions:7- haversine_distance: Calculate distance between two coordinates8- sort_by_distance: Sort items by distance from user location9- extract_location_query: Parse location from natural language query10"""11 12import math13import re14from typing import List, Dict, Any, Optional, Tuple15 16 17def haversine_distance(lat1: float, lon1: float, lat2: float, lon2: float) -> float:18 """19 Calculate the great circle distance between two points on Earth.20 Uses the Haversine formula.21 22 Args:23 lat1, lon1: Latitude and longitude of point 1 (degrees)24 lat2, lon2: Latitude and longitude of point 2 (degrees)25 26 Returns:27 Distance in kilometers28 29 Example:30 >>> distance = haversine_distance(-6.2088, 106.8456, -6.9175, 107.6191)31 >>> print(f"{distance:.2f} km") # Jakarta to Bandung32 126.78 km33 """34 # Earth radius in kilometers35 R = 6371.036 37 # Convert degrees to radians38 lat1_rad = math.radians(lat1)39 lon1_rad = math.radians(lon1)40 lat2_rad = math.radians(lat2)41 lon2_rad = math.radians(lon2)42 43 # Differences44 dlat = lat2_rad - lat1_rad45 dlon = lon2_rad - lon1_rad46 47 # Haversine formula48 a = math.sin(dlat / 2)**2 + math.cos(lat1_rad) * math.cos(lat2_rad) * math.sin(dlon / 2)**249 c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))50 51 distance = R * c52 return distance53 54 55def sort_by_distance(56 items: List[Dict[str, Any]],57 user_lat: float,58 user_lon: float,59 lat_key: str = "latitude",60 lon_key: str = "longitude"61) -> List[Dict[str, Any]]:62 """63 Sort a list of items by distance from user location.64 Adds 'distance_km' field to each item.65 66 Args:67 items: List of dictionaries containing location data68 user_lat: User's latitude69 user_lon: User's longitude70 lat_key: Key name for latitude in items (default: "latitude")71 lon_key: Key name for longitude in items (default: "longitude")72 73 Returns:74 Sorted list with distance_km added to each item75 76 Example:77 >>> suppliers = [78 ... {"name": "Supplier A", "latitude": -6.2, "longitude": 106.8},79 ... {"name": "Supplier B", "latitude": -6.9, "longitude": 107.6}80 ... ]81 >>> sorted_suppliers = sort_by_distance(suppliers, -6.2088, 106.8456)82 >>> print(sorted_suppliers[0]["distance_km"])83 """84 for item in items:85 if lat_key in item and lon_key in item:86 item["distance_km"] = haversine_distance(87 user_lat, user_lon,88 item[lat_key], item[lon_key]89 )90 else:91 item["distance_km"] = float('inf') # Put items without location at the end92 93 # Sort by distance94 sorted_items = sorted(items, key=lambda x: x["distance_km"])95 return sorted_items96 97 98def extract_location_query(query: str) -> Optional[str]:99 """100 Extract city/location from natural language query.101 102 Args:103 query: Natural language query string104 105 Returns:106 Extracted location string or None107 108 Example:109 >>> extract_location_query("laptop gaming di Jakarta")110 'Jakarta'111 >>> extract_location_query("cari laptop Jakarta Selatan")112 'Jakarta Selatan'113 """114 # Common Indonesian location patterns115 patterns = [116 r'\b(?:di|dekat|sekitar|area)\s+([A-Z][a-zA-Z\s]+?)(?:\s|$|,)',117 r'\b([A-Z][a-zA-Z\s]+?)\s+(?:Selatan|Utara|Timur|Barat|Pusat)\b',118 r'\b(Jakarta|Bandung|Surabaya|Medan|Semarang|Makassar|Palembang|Tangerang|Depok|Bekasi|Bogor)\b'119 ]120 121 for pattern in patterns:122 match = re.search(pattern, query, re.IGNORECASE)123 if match:124 return match.group(1).strip()125 126 return None127 128 129def format_price_idr(price: float) -> str:130 """131 Format price as Indonesian Rupiah.132 133 Args:134 price: Price in Rupiah135 136 Returns:137 Formatted string (e.g., "Rp 10.000.000")138 139 Example:140 >>> format_price_idr(10000000)141 'Rp 10.000.000'142 """143 # Format with thousand separators (dot for Indonesian style)144 price_str = f"{int(price):,}".replace(",", ".")145 return f"Rp {price_str}"146 147 148def build_ai_context(products: List[Dict[str, Any]], user_query: str) -> str:149 """150 Build context string for AI with product information.151 152 Args:153 products: List of product dictionaries with supplier info154 user_query: User's original query155 156 Returns:157 Formatted context string for AI prompt158 159 Example:160 >>> products = [{"name": "Laptop ASUS", "price": 10000000, ...}]161 >>> context = build_ai_context(products, "laptop gaming")162 >>> print(context)163 """164 if not products:165 return f"""User query: {user_query}166 167Available products: None found. Inform the user that no products match their criteria and suggest alternatives."""168 169 product_list = []170 for idx, prod in enumerate(products, 1):171 supplier_name = prod.get("supplier_name", "Unknown")172 distance = prod.get("distance_km", "N/A")173 distance_str = f"{distance:.1f} km" if isinstance(distance, (int, float)) else distance174 175 product_info = f"""{idx}. {prod['name']}176 - Price: {format_price_idr(prod['price'])}177 - Stock: {prod['stock_quantity']} units178 - Category: {prod.get('category', 'N/A')}179 - Supplier: {supplier_name} ({distance_str} from user)180 - Description: {prod.get('description', 'No description')[:100]}..."""181 182 product_list.append(product_info)183 184 context = f"""User query: {user_query}185 186Available products (sorted by distance):187 188{chr(10).join(product_list)}189 190Instructions:1911. Recommend products based on user's needs and budget1922. Prioritize nearby suppliers (lower distance_km)1933. Explain why each recommendation fits the user's requirements1944. Mention stock availability1955. Provide price comparison if multiple options exist1966. Use natural, conversational Indonesian or English based on user's language"""197 198 return context199 