# �� Copilot �ͦ� import time import json from datetime import datetime def log_message(message: str, level: str = "INFO"): """�O����x�T��""" timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") print(f"[{timestamp}] {level}: {message}") def save_json(data, filename: str, output_dir: str = "output"): """�x�sJSON�榡���""" try: filepath = f"{output_dir}/{filename}" with open(filepath, 'w', encoding='utf-8') as f: json.dump(data, f, ensure_ascii=False, indent=2) log_message(f"��Ƥw�x�s�� {filepath}") return True except Exception as e: log_message(f"�x�s��Ʈɵo�Ϳ��~: {e}", "ERROR") return False def load_json(filename: str, output_dir: str = "output"): """���JJSON�榡���""" try: filepath = f"{output_dir}/{filename}" with open(filepath, 'r', encoding='utf-8') as f: data = json.load(f) log_message(f"���\���J {filepath}") return data except Exception as e: log_message(f"���J��Ʈɵo�Ϳ��~: {e}", "ERROR") return None def format_currency(amount: float) -> str: """�榡�ƪ��B���""" if amount >= 10000: return f"{amount:,.0f}" else: return f"{amount:.0f}" def safe_divide(numerator: float, denominator: float, default: float = 0.0) -> float: """�w�����k�A�קK���s���~""" try: if denominator == 0: return default return numerator / denominator except: return default def clean_text(text: str) -> str: """�M�z��r���e""" if not text: return "" # �����h�l�ť� text = " ".join(text.split()) # �����S���r�š]�O�d����B�^��B�Ʀr�M�`�μ��I�^ import re text = re.sub(r'[^\u4e00-\u9fff\w\s.,!?;:()�]�^�i�j�u�v\-]', '', text) return text.strip() def retry_request(func, max_retries: int = 3, delay: float = 1.0): """���վ���""" for attempt in range(max_retries): try: return func() except Exception as e: if attempt == max_retries - 1: raise e log_message(f"�ШD���ѡA{delay}���᭫��... (���� {attempt + 1}/{max_retries})", "WARNING") time.sleep(delay) delay *= 2 # ���ưh�� def validate_price(price_str: str) -> bool: """���һ���榡�O�_�X�z""" try: import re # �����Ʀr price_match = re.search(r'[\d,]+', price_str.replace(',', '')) if price_match: price = int(price_match.group().replace(',', '')) # �X�z�������d��G5000 - 100000 return 5000 <= price <= 100000 except: pass return False def validate_area(area_str: str) -> bool: """���ҩW�Ʈ榡�O�_�X�z""" try: import re area_match = re.search(r'(\d+(?:\.\d+)?)', area_str) if area_match: area = float(area_match.group(1)) # �X�z���W�ƽd��G10 - 100�W return 10 <= area <= 100 except: pass return False def create_output_directories(): """�Ыؿ�X�ؿ�""" import os directories = ['output', 'output/images', 'output/data', 'output/reports'] for directory in directories: if not os.path.exists(directory): os.makedirs(directory) log_message(f"�Ыإؿ�: {directory}") def get_current_timestamp() -> str: """������e�ɶ��W""" return datetime.now().strftime("%Y%m%d_%H%M%S") def calculate_statistics(data_list): """�p��έp�ƾ�""" if not data_list: return {} import numpy as np data_array = np.array(data_list) return { 'count': len(data_array), 'mean': float(np.mean(data_array)), 'median': float(np.median(data_array)), 'std': float(np.std(data_array)), 'min': float(np.min(data_array)), 'max': float(np.max(data_array)), 'q25': float(np.percentile(data_array, 25)), 'q75': float(np.percentile(data_array, 75)) } def progress_bar(current: int, total: int, length: int = 50): """��ܶi�ױ�""" if total == 0: return percent = (current / total) * 100 filled = int(length * current // total) bar = '�i' * filled + '-' * (length - filled) print(f'\r�i��: |{bar}| {percent:.1f}% ({current}/{total})', end='', flush=True) if current >= total: print() # �����ᴫ��