Skip to content

Weekly Weather Forecast Tracker

Description: Create a program that tracks and compares weather forecasts with actual weather.

Skills practiced: - File I/O - Data persistence - Date/time handling - Text parsing

Sample code:

import fetch_my_weather
import csv
import os
from datetime import datetime, timedelta

def extract_temperature(weather_text):
    """Extract temperature from weather text (simple approach)"""
    for line in weather_text.split('\n'):
        if '°C' in line:
            parts = line.split('°C')[0].split()
            if parts and parts[-1].replace('-', '').isdigit():
                return int(parts[-1])
    return None

def record_forecast():
    """Record today's forecast for the next few days"""
    location = "London"  # Change to your location

    # Get the weather forecast using JSON format with metadata
    response = fetch_my_weather.get_weather(
        location=location,
        format="json",
        with_metadata=True
    )

    # Extract data and metadata
    metadata = response.metadata
    weather_data = response.data

    # Check if using mock data
    if metadata.is_mock:
        print(f"Note: Using mock weather data. This may affect forecast accuracy.")
        if metadata.error_message:
            print(f"(Reason: {metadata.error_message})")

    # Record date and forecast
    today = datetime.now()

    # Check if forecast file exists, create it if not
    file_exists = os.path.isfile('weather_forecast.csv')

    with open('weather_forecast.csv', 'a', newline='') as csvfile:
        fieldnames = ['forecast_date', 'target_date', 'forecasted_temp', 'actual_temp']
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

        if not file_exists:
            writer.writeheader()

        # Get forecasted temperatures from structured data
        if weather_data.weather:
            for i, day in enumerate(weather_data.weather):
                if i == 0:  # Skip today
                    continue

                if i > 3:  # Only look at next 3 days
                    break

                # Get the date from the forecast
                target_date_str = day.date

                # Get max temperature for the day
                if day.maxtempC:
                    temp = day.maxtempC

                    writer.writerow({
                        'forecast_date': today.strftime('%Y-%m-%d'),
                        'target_date': target_date_str,
                        'forecasted_temp': temp,
                        'actual_temp': ''  # Will be filled in later
                    })
                    print(f"Recorded forecast for {target_date_str}: {temp}°C")
        else:
            print("No forecast data available")

def update_actual_temperatures():
    """Update recorded forecasts with actual temperatures"""
    today = datetime.now().strftime('%Y-%m-%d')

    # Get today's actual weather using JSON format with metadata
    response = fetch_my_weather.get_weather(
        format="json",
        with_metadata=True
    )

    # Extract data and metadata
    metadata = response.metadata
    weather_data = response.data

    # Check if using mock data
    if metadata.is_mock:
        print(f"Note: Using mock weather data for actual temperature.")
        if metadata.error_message:
            print(f"(Reason: {metadata.error_message})")

    # Get the current temperature from structured data
    actual_temp = None
    if weather_data.current_condition and weather_data.current_condition[0].temp_C:
        actual_temp = weather_data.current_condition[0].temp_C
        print(f"Current temperature: {actual_temp}°C")

    if actual_temp is not None:
        # Read the existing CSV
        rows = []
        with open('weather_forecast.csv', 'r', newline='') as csvfile:
            reader = csv.DictReader(csvfile)
            for row in reader:
                # Update rows where target_date is today and actual_temp is empty
                if row['target_date'] == today and not row['actual_temp']:
                    row['actual_temp'] = actual_temp
                    print(f"Updated actual temperature for {today}: {actual_temp}°C")
                rows.append(row)

        # Write the updated data back
        with open('weather_forecast.csv', 'w', newline='') as csvfile:
            fieldnames = ['forecast_date', 'target_date', 'forecasted_temp', 'actual_temp']
            writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
            writer.writeheader()
            writer.writerows(rows)
    else:
        print("Could not get current temperature data")

def show_forecast_accuracy():
    """Show how accurate the forecasts have been"""
    if not os.path.isfile('weather_forecast.csv'):
        print("No forecast data available yet.")
        return

    # Read the CSV and calculate accuracy
    with open('weather_forecast.csv', 'r', newline='') as csvfile:
        reader = csv.DictReader(csvfile)

        total_comparisons = 0
        total_difference = 0

        for row in reader:
            if row['actual_temp'] and row['forecasted_temp']:
                forecasted = int(row['forecasted_temp'])
                actual = int(row['actual_temp'])
                difference = abs(forecasted - actual)

                print(f"Date: {row['target_date']}")
                print(f"  Forecast made on: {row['forecast_date']}")
                print(f"  Forecasted temp: {forecasted}°C")
                print(f"  Actual temp: {actual}°C")
                print(f"  Difference: {difference}°C")
                print("-" * 30)

                total_comparisons += 1
                total_difference += difference

        if total_comparisons > 0:
            average_difference = total_difference / total_comparisons
            print(f"\nAverage forecast difference: {average_difference:.1f}°C over {total_comparisons} days")
        else:
            print("No completed forecast data available yet.")

# Run the functions
print("=== Weather Forecast Tracker ===")
print("1. Recording forecast...")
record_forecast()

print("\n2. Updating actual temperatures...")
update_actual_temperatures()

print("\n3. Forecast accuracy report:")
show_forecast_accuracy()

Extensions: - Add more weather data points (precipitation, wind, etc.) - Create visualization of forecast accuracy - Set up an automated system to run daily