Pythonで誕生日から星座を判定するプログラムを作ってみた

### 前置き
私の誕生日は、2005年10月24日だ。1024の結果は2の10乗にある。また、奇しくも埼玉西武ライオンズの元監督の辻発彦、歌手Adoと同じ誕生日だ。そこで、私は誕生日を入力したら星座が出力されるプログラムを作成してみたくなった。

引用元：https://ja.wikipedia.org/wiki/Ado
引用元：https://npb.jp/bis/players/31933869.html
https://ja.wikipedia.org/wiki/%E8%BE%BB%E7%99%BA%E5%BD%A6

### 星座の一覧
![201802180125_box_img0_A.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518583/c13af0f3-b35a-bab6-ee5b-9c0b3d0063cc.jpeg)

引用元：https://weathernews.jp/s/topics/201802/180125/

### プログラムコード
``` python
def find_zodiac_sign(day, month):
  if (month == 3 and day >= 21) or (month == 4 and day <= 19):
      return "牡羊座 (Aries)"
  elif (month == 4 and day >= 20) or (month == 5 and day <= 20):
      return "牡牛座 (Taurus)"
  elif (month == 5 and day >= 21) or (month == 6 and day <= 20):
      return "双子座 (Gemini)"
  elif (month == 6 and day >= 21) or (month == 7 and day <= 22):
      return "蟹座 (Cancer)"
  elif (month == 7 and day >= 23) or (month == 8 and day <= 22):
      return "獅子座 (Leo)"
  elif (month == 8 and day >= 23) or (month == 9 and day <= 22):
      return "乙女座 (Virgo)"
  elif (month == 9 and day >= 23) or (month == 10 and day <= 22):
      return "天秤座 (Libra)"
  elif (month == 10 and day >= 23) or (month == 11 and day <= 21):
      return "蠍座 (Scorpio)"
  elif (month == 11 and day >= 22) or (month == 12 and day <= 21):
      return "射手座 (Sagittarius)"
  elif (month == 12 and day >= 22) or (month == 1 and day <= 19):
      return "山羊座 (Capricorn)"
  elif (month == 1 and day >= 20) or (month == 2 and day <= 18):
      return "水瓶座 (Aquarius)"
  elif (month == 2 and day >= 19) or (month == 3 and day <= 20):
      return "魚座 (Pisces)"
  else:
      return "無効な日付です"

def main():
  birthday = input("誕生日を入力してください (例: YYYY-MM-DD): ")
  try:
      year, month, day = map(int, birthday.split('-'))
      zodiac_sign = find_zodiac_sign(day, month)
      print(f"あなたの星座は {zodiac_sign} です。")
  except ValueError:
      print("正しい形式で誕生日を入力してください (YYYY-MM-DD).")

if __name__ == "__main__":
  main()
```
### 出力結果
``` python
誕生日を入力してください (例: YYYY-MM-DD): 2005-10-24
あなたの星座は 蠍座 (Scorpio) です。
誕生日を入力してください (例: YYYY-MM-DD): 2000-08-14
あなたの星座は 獅子座 (Leo) です。
誕生日を入力してください (例: YYYY-MM-DD): 1994-7-5
あなたの星座は 蟹座 (Cancer) です。
誕生日を入力してください (例: YYYY-MM-DD): 1998-06-28
あなたの星座は 蟹座 (Cancer) です。
誕生日を入力してください (例: YYYY-MM-DD): 1985-12-17
あなたの星座は 射手座 (Sagittarius) です。
誕生日を入力してください (例: YYYY-MM-DD): 1964-10-1
あなたの星座は 天秤座 (Libra) です。
誕生日を入力してください (例: YYYY-MM-DD): 1955-02-07
あなたの星座は 水瓶座 (Aquarius) です。
```
このように、ユーザーが自身の誕生日を入力すると、星座が出力される。

上の表を参考にしてもらうとわかるが、10月24日は蠍座(Scorpio)であり、8月14日は獅子座（Leo)であり、7月5日と6月28日は蟹座（Cancer)であり、12月17日は射手座（Sagittarius)であり、10月1日は天秤座(Libra)であり、2月7日は水瓶座（Aquarius)となっており、出力結果がちゃんと一致している。

ちなみに、今日6月28日は、阪神タイガースの中野拓夢選手の28歳の誕生日ということもあり、ユーザーが入力した日付と一致したら”N歳の誕生日おめでとうございます”と出力するようにプログラムコードを改良してみた。
引用元：https://npb.jp/bis/players/41445153.html

### 改良したプログラムコード
``` python
from datetime import datetime

def find_zodiac_sign(day, month):
    if (month == 3 and day >= 21) or (month == 4 and day <= 19):
        return "牡羊座 (Aries)"
    elif (month == 4 and day >= 20) or (month == 5 and day <= 20):
        return "牡牛座 (Taurus)"
    elif (month == 5 and day >= 21) or (month == 6 and day <= 20):
        return "双子座 (Gemini)"
    elif (month == 6 and day >= 21) or (month == 7 and day <= 22):
        return "蟹座 (Cancer)"
    elif (month == 7 and day >= 23) or (month == 8 and day <= 22):
        return "獅子座 (Leo)"
    elif (month == 8 and day >= 23) or (month == 9 and day <= 22):
        return "乙女座 (Virgo)"
    elif (month == 9 and day >= 23) or (month == 10 and day <= 22):
        return "天秤座 (Libra)"
    elif (month == 10 and day >= 23) or (month == 11 and day <= 21):
        return "蠍座 (Scorpio)"
    elif (month == 11 and day >= 22) or (month == 12 and day <= 21):
        return "射手座 (Sagittarius)"
    elif (month == 12 and day >= 22) or (month == 1 and day <= 19):
        return "山羊座 (Capricorn)"
    elif (month == 1 and day >= 20) or (month == 2 and day <= 18):
        return "水瓶座 (Aquarius)"
    elif (month == 2 and day >= 19) or (month == 3 and day <= 20):
        return "魚座 (Pisces)"
    else:
        return "無効な日付です"

def check_birthday_today(birthdate):
    today = datetime.now().date()
    if birthdate.month == today.month and birthdate.day == today.day:
        return True
    else:
        return False

def main():
    birthday_str = input("誕生日を入力してください (例: Name, YYYY-MM-DD): ")
    try:
        birthday = datetime.strptime(birthday_str, "%Y-%m-%d").date()
        zodiac_sign = find_zodiac_sign(birthday.day, birthday.month)
        print(f"あなたの星座は {zodiac_sign} です。")

        if check_birthday_today(birthday):
            age = datetime.now().year - birthday.year
            print(f"{age}歳の誕生日おめでとうございます！")
    except ValueError:
        print("正しい形式で誕生日を入力してください。(YYYY-MM-DD).")

if __name__ == "__main__":
    main()
```
### オリジナルコードとの相違点
1. 誕生日の入力方法の変更:
元のコードでは input を直接受け取っていましたが、修正後のコードでは datetime.strptime を使用して入力された文字列を日付オブジェクトに変換しています。
2. 誕生日が今日と一致するかの判定:
修正後のコードには check_birthday_today 関数が追加されており、誕生日が今日と一致するかどうかを確認するための機能が追加されています。
3. 特別なメッセージの追加:
修正後のコードでは、誕生日が今日であればその年齢の誕生日おめでとうございますというメッセージが追加されています。
4. エラーハンドリングの改善:
修正後のコードでは、誕生日の入力形式が正しくない場合にエラーメッセージを表示する処理が改善されています。
5. datetime モジュールの使用:
修正後のコードでは、日付の比較や日付オブジェクトの作成に datetime モジュールを使用しています。

### 実際の出力結果
``` python
氏名を入力してください: 中野拓夢
誕生日を入力してください (例: YYYY-MM-DD): 1996-06-28
中野拓夢さんの星座は 蟹座 (Cancer) です。
中野拓夢選手、28歳の誕生日おめでとうございます！
```
このように、中野拓夢選手、28歳の誕生日おめでとうございます！と出力された。

改良したプログラムコードで、明日NNNN年6月29日と入力したら2024-N歳のお誕生日おめでとうございますと出力されます。オリジナルコードだけでは、星座しか出力されない。余談にはなるが、全国的な雨の影響で、今日、敵地の神宮球場での阪神戦は中止になった。明日、明後日と勝利を期待したい。

皆さんも時間のある時に、このプログラムコードを参考にして、ご自分の誕生日を入力して、自身の星座を確認してみてはいかがでしょうか。