File size: 4,573 Bytes
f205f47
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# �� 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()  # �����ᴫ��