Turn the following skeleton code into actual working code:

import requests
import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
import matplotlib.pyplot as plt
from datetime import datetime

# Step 1: Data Fetching
def fetch_climate_data():
    # Placeholder function - replace with actual API data fetching logic
    # Example endpoint for NOAA: https://www.ncei.noaa.gov/access/services/data/v1/
    url = "https://data_source_url"  # Replace with actual URL
    response = requests.get(url)
    if response.status_code == 200:
        data = response.json()  # Adjust based on data format (CSV/JSON)
        return pd.DataFrame(data)
    else:
        raise Exception("Data fetching failed. Please check the data source URL or requirements.")

# Step 2: Data Preprocessing
def preprocess_data(df):
    # Parse dates and filter for the last 20 years
    df['Date'] = pd.to_datetime(df['Date'])
    df = df[df['Date'].dt.year >= datetime.now().year - 20]
    return df

# Divide India into zones based on lat/long or state
def zone_division(df):
    zones = {
        "North": ["Jammu", "Punjab", "Himachal"],  # Add all northern states
        "West": ["Rajasthan", "Gujarat"],
        "South": ["Tamil Nadu", "Kerala"],
        "East": ["West Bengal", "Odisha"],
        "Central": ["Madhya Pradesh"]
    }
    df['Zone'] = df['State'].apply(lambda x: next((zone for zone, states in zones.items() if x in states), None))
    return df.dropna(subset=['Zone'])

# Step 3: Historical Trend Visualization
def plot_historical_trends(df, zone):
    plt.figure(figsize=(12, 6))
    zone_data = df[df['Zone'] == zone]
    plt.plot(zone_data['Date'], zone_data['Temperature'], label="Temperature")
    plt.plot(zone_data['Date'], zone_data['Rainfall'], label="Rainfall")
    plt.title(f"Historical Climate Trends for {zone}")
    plt.xlabel("Year")
    plt.ylabel("Climate Indicator")
    plt.legend()
    plt.show()

# Step 4: Prediction with Random Forest
def climate_prediction(df, zone):
    zone_data = df[df['Zone'] == zone]
    X = zone_data[['Temperature', 'Rainfall', 'Humidity']].values
    y = zone_data['Temperature'].values  # Predicting future temperature

    # Split data
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
    
    # Train Random Forest Regressor
    rf_model = RandomForestRegressor(n_estimators=100, random_state=42)
    rf_model.fit(X_train, y_train)
    
    # Predict next 20 years based on historical trends
    predictions = []
    future_years = np.arange(1, 21)  # Placeholder for years 2024-2043
    for year in future_years:
        pred = rf_model.predict([X[-1]])  # Using the last known data for forecasting
        predictions.append(pred[0])
        X = np.vstack((X, pred))  # Update X to include the new prediction

    # Plot predictions
    plt.figure(figsize=(12, 6))
    plt.plot(zone_data['Date'], zone_data['Temperature'], label="Historical Temperature")
    plt.plot(pd.date_range(zone_data['Date'].iloc[-1], periods=20, freq="Y"), predictions, label="Predicted Temperature", linestyle='--')
    plt.title(f"Predicted Climate Trend for {zone} (Next 20 Years)")
    plt.xlabel("Year")
    plt.ylabel("Temperature")
    plt.legend()
    plt.show()

# Example Execution
try:
    # Fetch data
    df = fetch_climate_data()
    
    # Preprocess data
    df = preprocess_data(df)
    
    # Zone division
    df = zone_division(df)
    
    # Plot historical trends for each zone
    for zone in df['Zone'].unique():
        plot_historical_trends(df, zone)
        climate_prediction(df, zone)
    
except Exception as e:
    print("Error:", e)

We have the following requirements/constraints.

1. The program should fetch data from a public source which doesn't require login or payment

2. The program should divide India into 5 zones - North, West, South, East and Central

3. The program should make charts in matplotlib for historical climate trends (20 years or so) and then use machine learning to predict climate for future 20 years by the means of random forest for each zone. The ticks on x axis should be for per year each.