西暦2025年は昭和100年みたいな計算をするPythonスクリプト

# 西暦2024年は昭和99年
西暦2024年は昭和99年だったそうです。
であれば西暦2025年は昭和100年ですが、他の元号にもキリ番があるに違いないです。
与えられた年について和暦で100の倍数年の元号を返すスクリプトを作ってみました。

# コード全体
```python
import sys


era_dict = {
    "大化":645, 
    "白雉":650, 
    "朱鳥":686, 
    "大宝":701, 
    "慶雲":704, 
    "和銅":708, 
    "霊亀":715, 
    "養老":717, 
    "神亀":724, 
    "天平":729, 
    "天平感宝":749, 
    "天平勝宝":749, 
    "天平宝字":757, 
    "天平神護":765, 
    "神護景雲":767, 
    "宝亀":770, 
    "天応":781, 
    "延暦":782, 
    "大同":806, 
    "弘仁":810, 
    "天長":824, 
    "承和":834, 
    "嘉祥":848, 
    "仁寿":851, 
    "斉衡":854, 
    "天安":857, 
    "貞観":859, 
    "元慶":877, 
    "仁和":885, 
    "寛平":889, 
    "昌泰":898, 
    "延喜":901, 
    "延長":923, 
    "承平":931, 
    "天慶":938, 
    "天暦":947, 
    "天徳":957, 
    "応和":961, 
    "康保":964, 
    "安和":968, 
    "天禄":970, 
    "天延":973, 
    "貞元":976, 
    "天元":978, 
    "永観":983, 
    "寛和":985, 
    "永延":987, 
    "永祚":989, 
    "正暦":990, 
    "長徳":995, 
    "長保":999, 
    "寛弘":1004, 
    "長和":1013, 
    "寛仁":1017, 
    "治安":1021, 
    "万寿":1024, 
    "長元":1028, 
    "長暦":1037, 
    "長久":1040, 
    "寛徳":1044, 
    "永承":1046, 
    "天喜":1053, 
    "康平":1058, 
    "治暦":1065, 
    "延久":1069, 
    "承保":1074, 
    "承暦":1077, 
    "永保":1081, 
    "応徳":1084, 
    "寛治":1087, 
    "嘉保":1095, 
    "永長":1097, 
    "承徳":1097, 
    "康和":1099, 
    "長治":1104, 
    "嘉承":1106, 
    "天仁":1108, 
    "天永":1110, 
    "永久":1113, 
    "元永":1118, 
    "保安":1120, 
    "天治":1124, 
    "大治":1126, 
    "天承":1131, 
    "長承":1132, 
    "保延":1135, 
    "永治":1141, 
    "康治":1142, 
    "天養":1144, 
    "久安":1145, 
    "仁平":1151, 
    "久寿":1154, 
    "保元":1156, 
    "平治":1160, 
    "永暦":1160, 
    "応保":1161, 
    "長寛":1163, 
    "永万":1165, 
    "仁安":1166, 
    "嘉応":1169, 
    "承安":1171, 
    "安元":1175, 
    "治承":1177, 
    "養和":1181, 
    "寿永":1182, 
    "元暦":1184, 
    "文治":1185, 
    "建久":1190, 
    "正治":1199, 
    "建仁":1201, 
    "元久":1204, 
    "建永":1206, 
    "承元":1207, 
    "建暦":1211, 
    "建保":1214, 
    "承久":1219, 
    "貞応":1222, 
    "元仁":1224, 
    "嘉禄":1225, 
    "安貞":1228, 
    "寛喜":1229, 
    "貞永":1232, 
    "天福":1233, 
    "文暦":1234, 
    "嘉禎":1235, 
    "暦仁":1238, 
    "延応":1239, 
    "仁治":1240, 
    "寛元":1243, 
    "宝治":1247, 
    "建長":1249, 
    "康元":1256, 
    "正嘉":1257, 
    "正元":1259, 
    "文応":1260, 
    "弘長":1261, 
    "文永":1264, 
    "建治":1275, 
    "弘安":1278, 
    "正応":1288, 
    "永仁":1293, 
    "正安":1299, 
    "乾元":1302, 
    "嘉元":1303, 
    "徳治":1307, 
    "延慶":1308, 
    "応長":1311, 
    "正和":1312, 
    "文保":1317, 
    "元応":1319, 
    "元亨":1321, 
    "正中":1324, 
    "嘉暦":1326, 
    "元徳":1329, 
    "元弘":1331, 
    "正慶":1332, 
    "建武":1334, 
    "延元":1336, 
    "興国":1340, 
    "正平":1347, 
    "建徳":1370, 
    "文中":1372, 
    "天授":1375, 
    "弘和":1381, 
    "元中":1384, 
    "暦応":1338, 
    "康永":1342, 
    "貞和":1345, 
    "観応":1350, 
    "文和":1352, 
    "延文":1356, 
    "康安":1361, 
    "貞治":1362, 
    "応安":1368, 
    "永和":1375, 
    "康暦":1379, 
    "永徳":1381, 
    "至徳":1384, 
    "嘉慶":1387, 
    "康応":1389, 
    "明徳":1390, 
    "応永":1394, 
    "正長":1428, 
    "永享":1429, 
    "嘉吉":1441, 
    "文安":1444, 
    "宝徳":1449, 
    "享徳":1452, 
    "康正":1455, 
    "長禄":1457, 
    "寛正":1461, 
    "文正":1466, 
    "応仁":1467, 
    "文明":1469, 
    "長享":1487, 
    "延徳":1489, 
    "明応":1492, 
    "文亀":1501, 
    "永正":1504, 
    "大永":1521, 
    "享禄":1528, 
    "天文":1532, 
    "弘治":1555, 
    "永禄":1558, 
    "元亀":1570, 
    "天正":1573, 
    "文禄":1593, 
    "慶長":1596, 
    "元和":1615, 
    "寛永":1624, 
    "正保":1645, 
    "慶安":1648, 
    "承応":1652, 
    "明暦":1655, 
    "万治":1658, 
    "寛文":1661, 
    "延宝":1673, 
    "天和":1681, 
    "貞享":1684, 
    "元禄":1688, 
    "宝永":1704, 
    "正徳":1711, 
    "享保":1716, 
    "元文":1736, 
    "寛保":1741, 
    "延享":1744, 
    "寛延":1748, 
    "宝暦":1751, 
    "明和":1764, 
    "安永":1772, 
    "天明":1781, 
    "寛政":1789, 
    "享和":1801, 
    "文化":1804, 
    "文政":1818, 
    "天保":1831, 
    "弘化":1845, 
    "嘉永":1848, 
    "安政":1855, 
    "万延":1860, 
    "文久":1861, 
    "元治":1864, 
    "慶応":1865, 
    "明治":1868, 
    "大正":1912, 
    "昭和":1926, 
    "平成":1989, 
    "令和":2019, 
}

target_year_str = input("What year?:" )

try:
    target_year_int = int(target_year_str)
except:
    print("The value must be an integer.")
    sys.exit()

if target_year_int <= 0:
    print("The value must be larger than 0.")
    sys.exit()

is_memorial = False
print("西暦" + target_year_str + "年は")

for key, value in era_dict.items():
    if (target_year_int - value + 1) % 100 == 0 and (target_year_int - value + 1) > 0:
        is_memorial = True
        print(key + str(target_year_int - value + 1) + "年")

if is_memorial == False:
    print("100の倍数年に相当する元号はない年", end="")

print("です。")
```

# コードの解説
## モジュールのインポート
```python
import sys
```
`sys.exit()`でプログラムを終了させるときに使います。

## 元号とその開始年の辞書
```python
era_dict = {
    "大化":645, 
    "白雉":650, 
    ...
    "平成":1989, 
    "令和":2019, 
}
```
元号と、その開始年を西暦で記した辞書を用意します。
大化から令和まで248個の元号があり、それを全部手書きで入力するのは大変なのである程度はウェブスクレイピングを使って作成しました。
要素数がかなり多いので外部ファイルにして読み込んだ方がコードはすっきりするのですが、既存の値を修正する場合を除きメンテナンスが発生するのは数十年周期と思われるので気にしないことにします。

## 処理対象の西暦年の指定
```python
target_year_str = input("What year?:" )
```
`input`で入力された値は数字であっても文字列として扱われます。
この後整数型に変換するのでこの段階では文字列であることがわかる名前の変数に処理対象の数字を格納します。

```python
try:
    target_year_int = int(target_year_str)
except:
    print("The value must be an integer.")
    sys.exit()
```
この後数値の計算をするために指定された西暦年を整数型に変換します。
しかし、入力された値がアルファベットなど整数に変換できない値である可能性があるので例外処理を入れておきます。
入力された値が整数型に変換できなかった場合は、値は整数型である必要がある旨を表示してからプログラムを終了します。

```python
if target_year_int <= 0:
    print("The value must be larger than 0.")
    sys.exit()
```
入力できる西暦年を1以上の値に制限します。

## ループ処理
```python
is_memorial = False
print("西暦" + target_year_str + "年は")

for key, value in era_dict.items():
    if (target_year_int - value + 1) % 100 == 0 and (target_year_int - value + 1) > 0:
        is_memorial = True
        print(key + str(target_year_int - value + 1) + "年")

if is_memorial == False:
    print("100の倍数年に相当する元号はない年", end="")

print("です。")
```
100の倍数年に相当する元号がある場合とない場合とで処理を分けたいので、フラグ is_memorial を用意してFalseにしておきます。
まず、「西暦xx年は」と出力します。
辞書からkey（元号）とvalue（西暦年）を1個ずつ取り出し、指定された年からvalueを引いて1を足した値を100で割った余りが0の場合（つまり、その和暦が指定された年まで続いたと仮定した時にその和暦が100の倍数の場合）、`元号xx年`と出力します。
if文はもともと `if (target_year_int - value + 1) % 100 == 0` だけでしたが、その場合「元号0年」も出力されるとの指摘をいただいたので、 `(target_year_int - value + 1) > 0` を追加しました。
また、100の倍数年に相当する元号がない場合、
```shell
西暦1999年は
です。
```
というように出力されるとの指摘もいただいたので `is_memorial == False` の場合として処理を追加しました。
そして最後に「です。」と出力します。

# 出力例
```shell
What year?:0
The value must be larger than 0.

What year?:1
西暦1年は
100の倍数年に相当する元号はない年です。

What year?:2018
西暦2018年は
承久800年
元応700年
です。

```


# 最後に

```shell
西暦2025年は
大治900年
嘉暦700年
昭和100年
です。
```

ちなみに、大治（だいじ）は1126年から1131年で崇徳（すとく）天皇の時代、嘉暦（かりゃく）は1326年から1329年で後醍醐（ごだいご）天皇の時代だそうです。
それぞれ、だいじないいふろすとくてんのう、かりゃくいみふろごだいごてんのうと覚えるとよいと思います。