名前の読みから運勢バッチリな漢字の候補を大量に出してみた。

# 読み（響き）から赤ちゃんの名前を考えたい。
名前を決める場合、`漢字を先に決める(親の一字、意味などから)`のではなく、グローバルな世の中、読み（響き）から決める人も多いのではないでしょうか。
ただ、せっかくなら姓名判断もバッチリなやつがいいですよね。
調べると、読みから名前の候補を出してくれるサイトもいくつかありましたが、候補があまりたくさん出てきませんでした。

候補はたくさんあった方が、よりバッチリな名前を見つけやすいのではないかと思い、
とりあえず有り得る全ての候補をリスト化する仕組みを考えました。

# 0. まずは姓名判断の仕組み

細かいことはググると色々出てきますが、共通する内容としてはこんな感じでした。
### 項目
- 地格
名の総画数(名が一文字なら、名の画数+1)

- 人格
姓の最後と名の最初の文字の総画数

- 天格
姓の総画数(姓が一文字なら姓の文字数+1)

- 総格
姓名の総画数

- 外格
姓の最初と名の最後の文字の総画数(姓名どちらでも１字なら、それぞれ１画として計算)

### 画数が吉になる数
- 大吉
[11,16,21,23,31,32,41]

- 中吉
[3,5,6,8,13,15,18,24,25,29,33,37,39,44,45,47,48,51,52]

- 小吉
[7,17,27,30,34,35,36,38,40,42,43,49,53,57,58]

天格は苗字を変えない限り、どうしようもないのでそれ以外の４項目を考慮した名前を考えるものとします。
もちろん全部の格大吉になれば最高ですが、読みと画数両方完璧な名前が出てくるケースはかなり少ないと思います。

# 1. 読みの分解
漢字をどの文字のまとまりに当てるかのパターンを出力します。
例えば、
"あい"なら
[あい],[あ,い]

"たろう"なら
[た,ろ,う],[た、ろう],[たろ、う],[たろう]

"さぶろう"なら
[さぶろう],[さ、ぶろう],[さぶ,ろう],,,
といった具合に分ける必要があります。
今回は下記のようにしました。

```
def devide(yomi):
    str = yomi
    devided_names = []
    if len(str) == 2:
        devided_names.append([str[0],str[1]])
        devided_names.append([str[0]+str[1]])
    elif len(str) == 3:
        devided_names.append([str[0],str[1],str[2]])
        devided_names.append([str[0]+str[1],str[2]])
        devided_names.append([str[0],str[1]+str[2]])
        devided_names.append([str[0]+str[1]+str[2]])
    elif len(str) == 4:
        devided_names.append([str[0],str[1],str[2],str[3]])
        devided_names.append([str[0]+str[1],str[2],str[3]])
        devided_names.append([str[0],str[1]+str[2],str[3]])
        devided_names.append([str[0]+str[1]+str[2],str[3]])
        devided_names.append([str[0],str[1],str[2]+str[3]])
        devided_names.append([str[0]+str[1],str[2]+str[3]])
        devided_names.append([str[0],str[1]+str[2]+str[3]])
        devided_names.append([str[0]+str[1]+str[2]+str[3]])

    print(devided_names)
    return(devided_names)
```
組み合わせは2^(読み字数-1)あるので、指数関数的な増え方をします。
まぁとりあえず４文字ぐらいまでの名前であれば上記で対応できますが、
これ以上はfor文とかで上手く回してどうにかした方がいいですね。

# 2. 読みに対応した漢字の取得
こちらのAPIを利用させてもらいました。
https://mojikiban.ipa.go.jp/mji/

パターンを増やすため、音読み、訓読み両方の検索を実施します。
レスポンスから、UCSコードを抽出し、デコードした漢字と画数を結果として返します。
(例: [太,4],[田,5],,,,)

```
def get_kanji(letter):
    import jaconv
    import requests
    base_url= "https://mojikiban.ipa.go.jp/mji/q"
    kanjis = []
    #音読みパート
    query = {"読み":letter,"漢字施策":"人名用漢字"}
    r = requests.get(url = base_url,params=query)
    if r.json()["find"] == False:
         print("NO RESULT FOUND")
         list = []
    else:
        list = r.json()["results"]
    for i in list:
        moji = "\\"+i['UCS']["対応するUCS"].replace("+","").replace("^","\\").lower()
        kanji = moji.encode().decode("unicode-escape")
        kanjis.append([kanji,i["総画数"]])
    #訓読みパート
    another_letter = jaconv.hira2kata(letter)
    query = {"読み":another_letter,"漢字施策":"人名用漢字"}
    r = requests.get(url = base_url,params=query)
    if r.json()["find"] == False:
         print("NO RESULT FOUND")
         list = []
    else:
        list = r.json()["results"]
    for i in list:
        moji = "\\"+i['UCS']["対応するUCS"].replace("+","").replace("^","\\").lower()
        kanji = moji.encode().decode("unicode-escape")
        kanjis.append([kanji,i["総画数"]])
    return(kanjis)
```

# 3. 全てのパターンを組み合わせる
考えうるの読みに対応した漢字を上記で抽出したので、
次は漢字の組み合わせを全て作ってみます。3文字までぐらいの組み合わせは下記で対応できます。

```
    namaes = []
    for devided_name in devided_names: # devided_name=[[た,ろ,う],[た、ろう],[たろ、う],[たろう]]

        if len(devided_name) == 1:
            kanjis = kanji_stock[devided_name[0]]
        if len(devided_name) == 2:
            kanjis = list(itertools.product(kanji_stock[devided_name[0]],kanji_stock[devided_name[1]]))  
        namaes.extend(kanjis)
        if len(devided_name) == 3:
            kanjis = list(itertools.product(kanji_stock[devided_name[0]],kanji_stock[devided_name[1]],kanji_stock[devided_name[2]]))  
        namaes.extend(kanjis)
```

# 4. 画数を吉数と比較する
それぞれの"格"の計算方法で画数を数えて吉数であるかの比較をします。
上記行程３で

```
    daikichi_names = []
    daikichi_numbers = [11,16,21,23,31,32,41,3,5,6,8,13,15,18,24,25,29,33,37,39,44,45,47,48,51,52,7,17,27,30,34,35,36,38,40,42,43,49,53,57,58]
    #chikaku_part
    for namae in namaes:
         if type(namae) == list:#候補の名前が漢字一文字だとlistになる
             if namae[1] + 1 in daikichi_numbers:
                  daikichi_names.append(namae)
         if type(namae) == tuple:
             total = 0
             for part in namae:#候補の漢字が２文字以上だと、tupleになっている
                 total +=part[1]
             if total in daikichi_numbers:
                 daikichi_names.append(namae)
```
# 5. 候補から選ぶ
以上です。いい名前が見つかりますように。