Python初学者が天気予報通知システムを作ってみた

## 0:背景
学校の課題でAPIを利用したシステムを作ることになったので,そのついでに記事を書いてみることにしました。
Pythonの基本的なライブラリや文法を理解した初学者の方が「Pythonで何か作ってみたいな〜」となった時には,参考にしていただけるといいな〜と思っています。

## 1:作ったものの概要
Pythonを使用して天気予報を取得し、その情報をLINE Notifyを通じて通知するシステムを作りました。天気情報はweather.tsukumijima.netのAPIから取得され、LINE Notifyを使用して通知されます。

**使用する技術とサービス**
- プログラミング言語: Python
- 外部API:
    - 天気予報API:https://weather.tsukumijima.net/
    - LINE Notify

## 2:必要な準備
2.1 Pythonのインストール

2.2 必要なライブラリのインストール
```
pip install requests
```

## 3:プロジェクトのセットアップ
**3.1 ファイル構成**
このプロジェクトは以下の2つのファイルで構成されています

1.weather_api.py: 天気情報を取得するためのファイル
2.send_line.py: 天気情報をLINE Notifyで通知するためのファイル

**3.2 ファイルの内容**


このファイルは天気予報APIから情報を取得し、整形して辞書形式で返す関数を含んでいます。


``` python:weather_api.py
import requests

# 天気予報APIのエンドポイントと大阪市の都市コード
end_point = "https://weather.tsukumijima.net/api/forecast/city/270000"

def get_weather_forecast():
    response = requests.get(end_point)  # APIにリクエストを送信
    dict_data = response.json()  # レスポンスを辞書形式に変換
    
    # 明日の日時
    date = dict_data['forecasts'][1]['date']
    
    # 明日の天気
    weather = dict_data['forecasts'][1]['telop']
    
    # 明日の最高気温
    max_temp_data = dict_data['forecasts'][1]['temperature']['max']
    max_temp = max_temp_data['celsius'] if max_temp_data else "データなし"
    
    # 明日の最低気温
    min_temp_data = dict_data['forecasts'][1]['temperature']['min']
    min_temp = min_temp_data['celsius'] if min_temp_data else "データなし"
    
    # 明日の降水確率（平均値）
    chanceOfRainOfKey = dict_data['forecasts'][1]['chanceOfRain']
    
    chanceOfRainList = {
        "T00_06": int(chanceOfRainOfKey['T00_06'].replace('%', '')),
        "T06_12": int(chanceOfRainOfKey['T06_12'].replace('%', '')),
        "T12_18": int(chanceOfRainOfKey['T12_18'].replace('%', '')),
        "T18_24": int(chanceOfRainOfKey['T18_24'].replace('%', ''))
    }
    
    averageChanceOfRain = sum(chanceOfRainList.values()) / len(chanceOfRainList)
    
    # 取得したデータを辞書形式に整形
    weather_info = {
        "date": date,
        "weather": weather,
        "max_temp": max_temp,
        "min_temp": min_temp,
        "averageChanceOfRain": averageChanceOfRain
    }
    
    return weather_info  # 辞書形式のデータを返す

if __name__ == "__main__":
    weather_info = get_weather_forecast()
    print(weather_info)  # 取得したデータを表示
    print(type(weather_info))  # データのタイプを表示

```
このファイルはweather_api.pyから天気情報を取得し、その情報をLINE Notifyで通知する機能を持っています。
```python:send_line.py
import requests
from weather_api import get_weather_forecast  # weather_apiから関数をインポート

# LINE Notifyのトークン
line_notify_token = "YOUR_LINE_NOTIFY_TOKEN"
line_notify_api_url = "https://notify-api.line.me/api/notify"

def send_line_notify(message):
    headers = {
        "Authorization": f"Bearer {line_notify_token}"
    }
    data = {
        "message": message
    }
    requests.post(line_notify_api_url, headers=headers, data=data)  # メッセージを送信

def main():
    weather_info = get_weather_forecast()  # 天気情報を取得
    
    # デバッグ用に weather_info の内容とタイプを表示
    print(weather_info)  # 取得したデータを表示
    print(type(weather_info))  # データのタイプを表示
    
    # weather_info が辞書形式であることを確認
    if isinstance(weather_info, dict):
        message = (
            f"明日の日時は {weather_info['date']} です\n"
            f"明日の天気は {weather_info['weather']} です\n"
            f"明日の最高気温は {weather_info['max_temp']}°C です\n"
            f"明日の最低気温は {weather_info['min_temp']}°C です\n"
            f"明日の降水確率の平均は {weather_info['averageChanceOfRain']:.2f}% です"
        )
        send_line_notify(message)  # メッセージをLINE Notifyで送信
    else:
        print("Error: weather_info is not a dictionary")

if __name__ == "__main__":
    main()
```

## 4:実行結果
実行すると、指定された都市の明日の天気情報がLINEに通知されます。これにより、毎日自動的に天気予報をLINEで受け取ることができます。
![スクリーンショット 2024-07-25 17.53.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677649/875986c3-9f4d-cf10-fe9e-b458ceae9284.png)


## 5:余談
weather_api.pyファイルで取得したデータを辞書型にしていなかったことが原因のエラーでしばらく悩んでいたので,デバッグ用のコードが追加されています。
今回の記事を作成するにあたってChatgptを使ったおかげで素早く仕上げることができたので,今後も活用していきたいな〜と思いました。