This project teaches API integration, JSON data handling, error management, and creating a useful utility application. We'll create a console-based weather application that fetches current weather and forecasts from a simulated API, with features like city search, temperature unit conversion, and weather alerts.
# WEATHER APP WITH API
import json
import datetime
import sys
print("WEATHER APPLICATION")
print("=" * 50)
class WeatherApp:
"""A weather application using simulated API data"""
def __init__(self):
self.units = "metric" # Celsius by default
self.recent_searches = []
self.favorite_cities = []
self.api_key = "demo_key" # In real app, store securely
# Simulated API data for demonstration
self.weather_data = {
"New York": {
"current": {
"temp_c": 15,
"temp_f": 59,
"condition": "Partly Cloudy",
"humidity": 65,
"wind_kph": 12,
"feelslike_c": 14,
"uv": 5,
"last_updated": "2024-03-15 14:30"
},
"forecast": [
{"date": "2024-03-16", "max_temp_c": 16, "min_temp_c": 8, "condition": "Sunny"},
{"date": "2024-03-17", "max_temp_c": 14, "min_temp_c": 7, "condition": "Rainy"},
{"date": "2024-03-18", "max_temp_c": 12, "min_temp_c": 5, "condition": "Cloudy"}
]
},
"London": {
"current": {
"temp_c": 10,
"temp_f": 50,
"condition": "Rainy",
"humidity": 85,
"wind_kph": 18,
"feelslike_c": 8,
"uv": 2,
"last_updated": "2024-03-15 14:45"
},
"forecast": [
{"date": "2024-03-16", "max_temp_c": 11, "min_temp_c": 6, "condition": "Cloudy"},
{"date": "2024-03-17", "max_temp_c": 12, "min_temp_c": 7, "condition": "Partly Cloudy"},
{"date": "2024-03-18", "max_temp_c": 10, "min_temp_c": 5, "condition": "Rainy"}
]
},
"Tokyo": {
"current": {
"temp_c": 18,
"temp_f": 64,
"condition": "Sunny",
"humidity": 55,
"wind_kph": 8,
"feelslike_c": 19,
"uv": 7,
"last_updated": "2024-03-15 15:00"
},
"forecast": [
{"date": "2024-03-16", "max_temp_c": 19, "min_temp_c": 12, "condition": "Sunny"},
{"date": "2024-03-17", "max_temp_c": 17, "min_temp_c": 11, "condition": "Cloudy"},
{"date": "2024-03-18", "max_temp_c": 16, "min_temp_c": 10, "condition": "Rainy"}
]
}
}
def display_menu(self):
"""Display main menu"""
print("\n" + "☀️" * 20)
print("WEATHER APP MENU")
print("☀️" * 20)
print("1. Check Current Weather")
print("2. Check Weather Forecast")
print("3. Toggle Temperature Units (C/F)")
print("4. Recent Searches")
print("5. Manage Favorite Cities")
print("6. Weather Alerts")
print("7. Exit")
print("-" * 40)
print(f"Current units: {'°C' if self.units == 'metric' else '°F'}")
def get_city_input(self):
"""Get city name from user"""
city = input("\nEnter city name: ").strip().title()
if not city:
print("City name cannot be empty!")
return None
return city
def simulate_api_call(self, city):
"""Simulate API call to get weather data"""
# Simulate network delay
import time
print(f"Fetching weather data for {city}...")
time.sleep(1) # Simulate API delay
if city in self.weather_data:
# Add to recent searches
if city not in self.recent_searches:
self.recent_searches.append(city)
if len(self.recent_searches) > 5:
self.recent_searches.pop(0)
return self.weather_data[city]
else:
# Simulate city not found
print(f"City '{city}' not found in our database.")
print("Available cities: New York, London, Tokyo")
return None
def convert_temperature(self, temp_c):
"""Convert temperature based on selected units"""
if self.units == "imperial":
return temp_c * 9/5 + 32
return temp_c
def get_temperature_unit(self):
"""Get temperature unit symbol"""
return "°F" if self.units == "imperial" else "°C"
def display_current_weather(self, city, weather):
"""Display current weather information"""
current = weather["current"]
print("\n" + "=" * 50)
print(f"🌤 CURRENT WEATHER IN {city.upper()}")
print("=" * 50)
# Temperature
temp = self.convert_temperature(current["temp_c"])
feels_like = self.convert_temperature(current["feelslike_c"])
unit = self.get_temperature_unit()
print(f"Temperature: {temp:.1f}{unit}")
print(f"Feels like: {feels_like:.1f}{unit}")
# Weather condition with emoji
condition = current["condition"]
condition_emoji = self.get_weather_emoji(condition)
print(f"Condition: {condition_emoji} {condition}")
# Other details
print(f"Humidity: {current['humidity']}%")
print(f"Wind Speed: {current['wind_kph']} km/h")
print(f"UV Index: {current['uv']}")
# UV index warning
uv = current["uv"]
if uv >= 8:
print("⚠ High UV! Wear sunscreen!")
elif uv >= 6:
print("⚠ Moderate UV protection needed")
print(f"Last Updated: {current['last_updated']}")
print("=" * 50)
# Weather advice
self.give_weather_advice(condition, temp)
def get_weather_emoji(self, condition):
"""Get emoji for weather condition"""
emoji_map = {
"Sunny": "☀️",
"Partly Cloudy": "⛅",
"Cloudy": "☁️",
"Rainy": "🌧️",
"Snowy": "❄️",
"Stormy": "⛈️",
"Windy": "💨",
"Foggy": "🌫️"
}
return emoji_map.get(condition, "🌡️")
def give_weather_advice(self, condition, temperature):
"""Give advice based on weather conditions"""
print("\n💡 WEATHER ADVICE:")
if "Rain" in condition:
print(" • Don't forget your umbrella! ☔")
print(" • Drive carefully on wet roads")
elif temperature > 30:
print(" • Stay hydrated! 💧")
print(" • Avoid outdoor activities during peak heat")
elif temperature < 5:
print(" • Bundle up! 🧣🧤")
print(" • Watch for icy conditions")
elif "Sunny" in condition:
print(" • Perfect day for outdoor activities! 🌳")
print(" • Don't forget sunscreen! ☀️")
elif "Windy" in condition:
print(" • Secure loose outdoor items")
print(" • Be cautious while driving")
else:
print(" • Enjoy your day! 😊")
def display_forecast(self, city, weather):
"""Display weather forecast"""
forecast = weather["forecast"]
print("\n" + "=" * 50)
print(f"📅 3-DAY FORECAST FOR {city.upper()}")
print("=" * 50)
for day in forecast:
date_obj = datetime.datetime.strptime(day["date"], "%Y-%m-%d")
weekday = date_obj.strftime("%a") # Monday, Tuesday, etc
max_temp = self.convert_temperature(day["max_temp_c"])
min_temp = self.convert_temperature(day["min_temp_c"])
unit = self.get_temperature_unit()
emoji = self.get_weather_emoji(day["condition"])
print(f"\n{weekday} ({day['date']}):")
print(f" {emoji} {day['condition']}")
print(f" High: {max_temp:.1f}{unit}, Low: {min_temp:.1f}{unit}")
# Special notes
if "Rain" in day["condition"]:
print(" ☔ Rain expected")
elif day["max_temp_c"] > 25:
print(" 🔥 Hot day ahead")
elif day["min_temp_c"] < 0:
print(" ❄️ Freezing temperatures overnight")
print("=" * 50)
def toggle_units(self):
"""Toggle between Celsius and Fahrenheit"""
if self.units == "metric":
self.units = "imperial"
print("\n✅ Switched to Fahrenheit (°F)")
else:
self.units = "metric"
print("\n✅ Switched to Celsius (°C)")
def show_recent_searches(self):
"""Show recently searched cities"""
if not self.recent_searches:
print("\nNo recent searches.")
return
print("\n" + "=" * 40)
print("RECENT SEARCHES")
print("=" * 40)
for i, city in enumerate(self.recent_searches, 1):
print(f"{i}. {city}")
# Quick weather summary
if city in self.weather_data:
weather = self.weather_data[city]["current"]
temp = self.convert_temperature(weather["temp_c"])
unit = self.get_temperature_unit()
print(f" {self.get_weather_emoji(weather['condition'])} {temp:.1f}{unit} - {weather['condition']}")
print("=" * 40)
# Option to select from recent
try:
choice = input("\nEnter number to view details (or press Enter to skip): ")
if choice.strip():
idx = int(choice) - 1
if 0 <= idx < len(self.recent_searches):
city = self.recent_searches[idx]
weather = self.simulate_api_call(city)
if weather:
self.display_current_weather(city, weather)
except (ValueError, IndexError):
print("Invalid selection.")
def manage_favorites(self):
"""Manage favorite cities"""
print("\n" + "=" * 40)
print("FAVORITE CITIES")
print("=" * 40)
if not self.favorite_cities:
print("No favorite cities yet.")
else:
print("Your favorite cities:")
for i, city in enumerate(self.favorite_cities, 1):
print(f"{i}. {city}")
print("\nOptions:")
print("1. Add favorite city")
print("2. Remove favorite city")
print("3. View weather for favorites")
print("4. Back to main menu")
choice = input("\nEnter choice: ").strip()
if choice == "1":
city = self.get_city_input()
if city and city not in self.favorite_cities:
self.favorite_cities.append(city)
print(f"✅ Added {city} to favorites!")
elif choice == "2":
if self.favorite_cities:
for i, city in enumerate(self.favorite_cities, 1):
print(f"{i}. {city}")
try:
idx = int(input("Enter number to remove: ")) - 1
if 0 <= idx < len(self.favorite_cities):
removed = self.favorite_cities.pop(idx)
print(f"✅ Removed {removed} from favorites.")
except (ValueError, IndexError):
print("Invalid selection.")
else:
print("No favorites to remove.")
elif choice == "3":
if not self.favorite_cities:
print("No favorite cities to display.")
else:
print("\nWeather for your favorite cities:")
print("-" * 40)
for city in self.favorite_cities:
if city in self.weather_data:
weather = self.weather_data[city]
temp = self.convert_temperature(weather["current"]["temp_c"])
unit = self.get_temperature_unit()
condition = weather["current"]["condition"]
emoji = self.get_weather_emoji(condition)
print(f"{city}: {emoji} {temp:.1f}{unit} - {condition}")
else:
print(f"{city}: Data not available")
elif choice == "4":
return
else:
print("Invalid choice.")
def show_weather_alerts(self):
"""Show weather alerts"""
print("\n" + "=" * 50)
print("⚠ WEATHER ALERTS")
print("=" * 50)
# Simulated alerts
alerts = [
{"city": "London", "type": "Rain", "severity": "Moderate", "message": "Heavy rain expected tonight"},
{"city": "New York", "type": "Wind", "severity": "High", "message": "Strong winds expected tomorrow"}
]
if alerts:
for alert in alerts:
severity_emoji = "🟡" if alert["severity"] == "Moderate" else "🔴"
print(f"\n{severity_emoji} {alert['city']} - {alert['type']} Alert ({alert['severity']})")
print(f" {alert['message']}")
print(f" Issued: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M')}")
else:
print("\n✅ No active weather alerts in your area.")
print("\n" + "=" * 50)
def check_current_weather(self):
"""Check current weather for a city"""
city = self.get_city_input()
if not city:
return
weather = self.simulate_api_call(city)
if weather:
self.display_current_weather(city, weather)
def check_weather_forecast(self):
"""Check weather forecast for a city"""
city = self.get_city_input()
if not city:
return
weather = self.simulate_api_call(city)
if weather:
self.display_forecast(city, weather)
def run(self):
"""Run the weather application"""
print("\n🌤️ Welcome to the Weather App!")
print("Get accurate weather information for any city.")
while True:
self.display_menu()
try:
choice = input("\nEnter your choice (1-7): ").strip()
if choice == "1":
self.check_current_weather()
elif choice == "2":
self.check_weather_forecast()
elif choice == "3":
self.toggle_units()
elif choice == "4":
self.show_recent_searches()
elif choice == "5":
self.manage_favorites()
elif choice == "6":
self.show_weather_alerts()
elif choice == "7":
print("\n👋 Thank you for using Weather App!")
print("Stay safe and have a great day! 🌈")
break
else:
print("\n❌ Invalid choice. Please enter 1-7.")
except KeyboardInterrupt:
print("\n\n👋 Goodbye!")
break
except Exception as e:
print(f"\n❌ An error occurred: {e}")
# Run the application
if __name__ == "__main__":
app = WeatherApp()
app.run()