# Complex demo: Call OpenWeather API, fetch weather data for multiple cities, preprocess, classify temperature category, visualize with Matplotlib
import requests
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import LabelEncoder
import matplotlib.pyplot as plt

def advanced_weather_api_demo(api_key, cities=['London', 'Paris', 'Berlin', 'Tokyo', 'New York']):
    # Fetch weather data for multiple cities
    weather_data = []
    for city in cities:
        url = f"http://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}&units=metric"
        response = requests.get(url)
        if response.status_code == 200:
            data = response.json()
            weather_data.append({
                'City': data['name'],
                'Temperature': data['main']['temp'],
                'Humidity': data['main']['humidity'],
                'Pressure': data['main']['pressure'],
                'Weather': data['weather'][0]['main']
            })
    # Preprocess API response to DataFrame
    weather_df = pd.DataFrame(weather_data)
    # Feature engineering: Create temperature-humidity ratio
    weather_df['Temp_Humidity_Ratio'] = weather_df['Temperature'] / (weather_df['Humidity'] + 1e-5)
    # Create temperature category (e.g., cold, moderate, hot)
    weather_df['Temp_Category'] = pd.cut(weather_df['Temperature'], bins=[-float('inf'), 10, 20, float('inf')], labels=['Cold', 'Moderate', 'Hot'])
    # Label encode for classification
    le = LabelEncoder()
    weather_df['Temp_Category_Code'] = le.fit_transform(weather_df['Temp_Category'])
    # Prepare data for modeling
    X = weather_df[['Temperature', 'Humidity', 'Pressure', 'Temp_Humidity_Ratio']].values
    y = weather_df['Temp_Category_Code'].values
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
    # Train model
    model = RandomForestClassifier(n_estimators=50, random_state=42)
    model.fit(X_train, y_train)
    y_pred = model.predict(X_test)
    acc = accuracy_score(y_test, y_pred)
    print(f"Accuracy: {acc:.2f}")
    # Visualize temperature across cities
    plt.figure(figsize=(8, 5))
    plt.bar(weather_df['City'], weather_df['Temperature'], color='skyblue')
    plt.title('Weather Temperature from OpenWeather API')
    plt.ylabel('Temperature (°C)')
    plt.xlabel('City')
    plt.annotate('Highest Temp', xy=(weather_df['Temperature'].idxmax(), weather_df['Temperature'].max()),
                 xytext=(weather_df['Temperature'].idxmax() + 0.5, weather_df['Temperature'].max() + 1),
                 arrowprops=dict(facecolor='black', shrink=0.05))
    plt.show()

# Replace with your OpenWeather API key
advanced_weather_api_demo('your_api_key')