File size: 5,480 Bytes
3f046ba
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
"""
Weather Data Analyzer
Statistical analysis of weather data
"""

import statistics
from globals import (
    TEMP_COLD_THRESHOLD, TEMP_HOT_THRESHOLD,
    WIND_CALM, WIND_MODERATE, WIND_STRONG,
    PRECIP_LIGHT, PRECIP_MODERATE, PRECIP_HEAVY,
    DECIMAL_PLACES
)

class WeatherAnalyzer:
    def __init__(self):
        self.data_points = []
    
    def add_data(self, weather_data):
        """
        Add weather data for analysis
        """
        self.data_points.append(weather_data)
    
    def get_temperature_stats(self):
        """
        Calculate temperature statistics
        """
        temps = [d.temperature for d in self.data_points if d.temperature is not None]
        
        if not temps:
            return None
        
        stats = {
            'count': len(temps),
            'mean': round(statistics.mean(temps), DECIMAL_PLACES),
            'median': round(statistics.median(temps), DECIMAL_PLACES),
            'min': round(min(temps), DECIMAL_PLACES),
            'max': round(max(temps), DECIMAL_PLACES)
        }
        
        if len(temps) > 1:
            stats['stdev'] = round(statistics.stdev(temps), DECIMAL_PLACES)
        
        return stats
    
    def get_humidity_stats(self):
        """
        Calculate humidity statistics
        """
        humidity = [d.humidity for d in self.data_points if d.humidity is not None]
        
        if not humidity:
            return None
        
        return {
            'mean': round(statistics.mean(humidity), DECIMAL_PLACES),
            'median': round(statistics.median(humidity), DECIMAL_PLACES),
            'min': round(min(humidity), DECIMAL_PLACES),
            'max': round(max(humidity), DECIMAL_PLACES)
        }
    
    def classify_temperature(self, temp):
        """
        Classify temperature as cold, mild, or hot
        """
        if temp < TEMP_COLD_THRESHOLD:
            return "Cold"
        elif temp > TEMP_HOT_THRESHOLD:
            return "Hot"
        else:
            return "Mild"
    
    def classify_wind(self, speed):
        """
        Classify wind speed
        """
        if speed < WIND_CALM:
            return "Calm"
        elif speed < WIND_MODERATE:
            return "Moderate"
        elif speed < WIND_STRONG:
            return "Strong"
        else:
            return "Severe"
    
    def classify_precipitation(self, precip):
        """
        Classify precipitation intensity
        """
        if precip < PRECIP_LIGHT:
            return "Light"
        elif precip < PRECIP_MODERATE:
            return "Moderate"
        elif precip < PRECIP_HEAVY:
            return "Heavy"
        else:
            return "Very Heavy"
    
    def get_weather_distribution(self):
        """
        Get distribution of weather conditions
        """
        distribution = {
            'Cold': 0,
            'Mild': 0,
            'Hot': 0
        }
        
        for data in self.data_points:
            if data.temperature is not None:
                classification = self.classify_temperature(data.temperature)
                distribution[classification] += 1
        
        return distribution
    
    def find_extreme_days(self):
        """
        Find days with extreme weather
        """
        extreme_days = []
        
        for data in self.data_points:
            if data.is_extreme_weather():
                extreme_days.append(data)
        
        return extreme_days
    
    def calculate_comfort_index(self, temp, humidity):
        """
        Calculate simple comfort index
        """
        if temp is None or humidity is None:
            return None
        
        # Simple heat index approximation
        if temp > 27:
            heat_index = temp + (0.5 * (humidity - 50))
            if heat_index > 32:
                return "Uncomfortable"
        
        if temp < 10:
            return "Cold"
        
        if humidity > 80:
            return "Humid"
        
        return "Comfortable"
    
    def get_average_by_location(self):
        """
        Calculate average temperature by location
        """
        location_temps = {}
        
        for data in self.data_points:
            if data.temperature is None:
                continue
            
            if data.location not in location_temps:
                location_temps[data.location] = []
            
            location_temps[data.location].append(data.temperature)
        
        averages = {}
        for location, temps in location_temps.items():
            averages[location] = round(statistics.mean(temps), DECIMAL_PLACES)
        
        return averages
    
    def detect_trend(self):
        """
        Detect if temperature is trending up or down
        """
        if len(self.data_points) < 3:
            return "Insufficient data"
        
        temps = [d.temperature for d in self.data_points if d.temperature is not None]
        
        if len(temps) < 3:
            return "Insufficient data"
        
        # Simple linear trend detection
        first_half = temps[:len(temps)//2]
        second_half = temps[len(temps)//2:]
        
        avg_first = statistics.mean(first_half)
        avg_second = statistics.mean(second_half)
        
        diff = avg_second - avg_first
        
        if abs(diff) < 1:
            return "Stable"
        elif diff > 0:
            return "Warming"
        else:
            return "Cooling"