本記事は株式会社Works Human Intelligenceのアドベントカレンダー、「Develop fun!」を体現する Works Human Intelligence #2の6日目になります。
弊社ではアドベントカレンダーを2枚実施しておりますので、1枚目もぜひご覧ください!
はじめに
伝説のJa婆婆から始まった湯婆婆の奔流は、たちまちノリの良いQiitter達の心を鷲掴みにし、一大ムーブメントを巻き起こすこととなりました。しまいにはアドベントカレンダーまで作られた挙句、しっかりと全日分事前登録が為されている始末です。
弊社の @Keita_INAGAKI 氏や @e99h2121 氏もその魅力に取りつかれた一人です。
しかし、いろんな湯婆婆を見ていくうちに、自分の中に違和感が芽生え、その違和感はだんだん大きくなってゆくのでした。……この違和感は何だろう……
そんな折、令和のHello World!
というパワーワードを生み出したこの記事を読んでいるときに、唐突に違和感の正体に気づきました。どの湯婆婆も、フルネームから1文字取り出している、と。
自分の記憶が正しければ、契約のシーンでの湯婆婆のセリフは、「千尋というのかい。贅沢な名前だねぇ。」的なもので、下の名前だけを口にしていたはずです。一方で、契約書にはフルネームを書くはずです。
実際に確認してみると、やはり自分の記憶が正しかった。千尋は契約書にフルネームを書き、湯婆婆は下の名前だけを口にしたうえで、下の名前から1文字を残し、名前の他の部分を奪った、のです。
https://kakiokoshi.hatenablog.com/entry/2017/01/22/214718
https://twitter.com/oscarnoyukue/status/535734804180770816
つまり、現在存在する湯婆婆たちは、湯婆婆の仕様を完全に満たしているわけではない、ということです。例えるならそう、繭に閉じこもってから4ターンしか経過していない幼虫、脚がないジオンの象徴のようなものです。
気づいてしまったからにはやるしかありません。筆者は自らの手で究極完全体湯婆婆を創造するため、筆を執ることにしたのでした。
パーフェクト湯婆婆の概要
湯婆婆は以下のように定義できます。
- コンソールで対話的にフルネームを受け取る
- 受け取ったフルネームから、下の名前を取り出す
- コンソールに「フン、${下の名前}というのかい。贅沢な名だねぇ。」と表示
- 下の名前から1文字を抽出
- コンソールに「今からお前の名前は${下の名前の1文字}だ。…」と表示
ここで問題になるのは、やはり2.の「下の名前を取り出す」の部分です。当然名前により姓名の文字数は異なります。姓と名の間にスペースの入力を強制することで、スペースでの分割が可能にはなりますが、湯婆婆の契約書には姓と名を分けて記載する欄があるわけでもなく、千尋も姓名を連続して書いています。
姓と名の間にスペースの入力を強制する、などとしてしまっては、到底パーフェクト湯婆婆などと呼ぶことはできません。
ではどうするか。少しググってみると、お誂え向きに便利なものがありました。
NameDividerを利用する
https://internet.watch.impress.co.jp/docs/yajiuma/1289735.html
NameDividerは、姓と名の間にスペースが入っていない氏名を与えると、姓と名に分割してくれるという正にパーフェクト湯婆婆のために作られたような大変便利なライブラリです。
今回はnamedivider-pythonを利用してパーフェクト湯婆婆を実装していくことにします。
NameDividerによる名の取り出し
from namedivider import NameDivider
full_name = "萩野千尋"
name_divider = NameDivider()
print(name_divider.divide_name(full_name).given)
# 千尋
namedivider-pythonはこのように扱うことができます。READMEからはname_divider.divide_name(full_name)
で返ってくるのが、姓名の入った文字列のように見えますが、実はこれはDividedName
クラスです。
名のみを取り出すには、givenプロパティを参照します。
名を取り出す方法は分かったので、あとは粛々と実装するのみです。
パーフェクト湯婆婆の実装
import random
from namedivider import NameDivider
GIVEN_NAME_INDEX = 1
print("契約書だよ。そこに名前を書きな、働かせてやる。")
full_name = input("乙 ")
name_divider = NameDivider()
given_name = name_divider.divide_name(full_name).given
print(f"フン、{given_name}というのかい。贅沢な名だねぇ。")
extracted_character = random.choice(given_name)
print(f"乙 {extracted_character}")
print(f"今からお前の名前は{extracted_character}だ。いいかい。{extracted_character}だよ。分かったら返事をするんだ、{extracted_character}!!")
できました。これこそが完全なる湯婆婆です。契約書の記入欄である乙
も完全再現しています。
では試してみましょう。
/mnt/c/workspace/python-workspace/namedivider-yubaba$ python yubabaPlayground.py
契約書だよ。そこに名前を書きな、働かせてやる。
乙 萩野 千尋
フン、 千尋というのかい。贅沢な名だねぇ。
乙
今からお前の名前は だ。いいかい。 だよ。分かったら返事をするんだ、 !!
……あ、あれ?おかしいですね。名前の一文字が出力されません。
…………
間違えました。契約書に書くべきは姓名が連続したフルネームです。
NameDividerでは、スペースが入っている場合にスペースを除いてくれるわけではなく、姓か名のどちらかにくっつけてしまうために起きる現象です。
/mnt/c/workspace/python-workspace/namedivider-yubaba$ python yubabaPlayground.py
契約書だよ。そこに名前を書きな、働かせてやる。
乙 萩野千尋
フン、千尋というのかい。贅沢な名だねぇ。
乙 千
今からお前の名前は千だ。いいかい。千だよ。分かったら返事をするんだ、千!!
今度こそうまくいきました。
……しかし、よく考えてみると、スペースが入っている氏名に対応できないケースがある湯婆婆が「パーフェクト湯婆婆」と呼べるでしょうか?
千尋はたまたま姓名を連続して書いていましたが、姓と名を、間をあけて書く人も結構な割合でいるはずです。当然、それに対応できないような湯婆婆をパーフェクトなどと形容できようはずもありません。
スペース入りの場合はsplit()
NameDividerを用いたのはそもそも「姓名が連続したフルネームに対応するため」です。スペースが入っているならそこで分ければよいので、スペース入りかどうかで条件分岐し、スペース入りならそこで分割するようにします。
文字列の分割にはsplit()が使えます。
引数なしのsplit()の場合には、半角スペースだけでなく全角スペースでも分割に対応しています。
https://www.lifewithpython.com/2018/01/python-split.html#%E5%BC%95%E6%95%B0%E3%81%AA%E3%81%97%E3%81%A7%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B
究極完全体パーフェクト湯婆婆の実装
さてさて実践です。
import random
from namedivider import NameDivider
GIVEN_NAME_INDEX = 1
print("契約書だよ。そこに名前を書きな、働かせてやる。")
full_name = input("乙 ")
if len(full_name.split()) == 2:
given_name = full_name.split()[GIVEN_NAME_INDEX]
else:
name_divider = NameDivider()
given_name = name_divider.divide_name(full_name).given
print(f"フン、{given_name}というのかい。贅沢な名だねぇ。")
extracted_character = random.choice(given_name)
print(f"乙 {extracted_character}")
print(f"今からお前の名前は{extracted_character}だ。いいかい。{extracted_character}だよ。分かったら返事をするんだ、{extracted_character}!!")
爆誕しました。これこそ究極完全体パーフェクト湯婆婆です。
/mnt/c/workspace/python-workspace/namedivider-yubaba$ python ultimateAndPerfectYubaba.py
契約書だよ。そこに名前を書きな、働かせてやる。
乙 萩野 千尋
フン、千尋というのかい。贅沢な名だねぇ。
乙 千
今からお前の名前は千だ。いいかい。千だよ。分かったら返事をするんだ、千!!
いいですね。
/mnt/c/workspace/python-workspace/namedivider-yubaba$ python ultimateAndPerfectYubaba.py
契約書だよ。そこに名前を書きな、働かせてやる。
乙 萩野千尋
フン、千尋というのかい。贅沢な名だねぇ。
乙 尋
今からお前の名前は尋だ。いいかい。尋だよ。分かったら返事をするんだ、尋!!
素晴らしいです。
/mnt/c/workspace/python-workspace/namedivider-yubaba$ python ultimateAndPerfectYubaba.py
契約書だよ。そこに名前を書きな、働かせてやる。
乙
Traceback (most recent call last):
File "ultimateAndPerfectYubaba.py", line 13, in <module>
given_name = name_divider.divide_name(full_name).given
File "/home/works/.local/lib/python3.8/site-packages/namedivider/name_divider.py", line 321, in divide_name
self._validate(undivided_name)
File "/home/works/.local/lib/python3.8/site-packages/namedivider/name_divider.py", line 236, in _validate
raise ValueError("Name length needs at least 2 chars")
ValueError: Name length needs at least 2 chars
もちろん、名前が入力されていないと究極完全体パーフェクト湯婆婆といえどもクラッシュします。例え究極完全体と言えど、原初の理に逆らうことは叶いません。後完璧超人がふとした時に見せる弱さって萌えますよね
最後に
さて、弊社には7VALUEs
という大切にしている価値観があります。
今回の筆者の取り組みは、「湯婆婆とはそもそも何なのか、の本質を追求する」「湯婆婆の本質をリスペクトする」「湯婆婆の本質をもう一度人々に思い起こさせるのは自分である、という当事者意識を持つ」「本質の伝道、という難易度の高い挑戦に恐れずに取り組む」という、まさしく7VALUEs
を体現した取り組みといえるでしょう!
もちろんこの取り組みをしていて楽しかった。Work fun! / Develop fun!
は当然のことながら全うしています。
それでは、いい感じに締まったところで、この記事はここまでとさせていただきます。
最後までご覧いただき、ありがとうございました!
???「琥珀川は?」
……え?
???「琥珀川はどうなんだ?」
…………
/mnt/c/workspace/python-workspace/namedivider-yubaba$ python ultimateAndPerfectYubaba.py
契約書だよ。そこに名前を書きな、働かせてやる。
乙 琥珀川
フン、珀川というのかい。贅沢な名だねぇ。
乙 川
今からお前の名前は川だ。いいかい。川だよ。分かったら返事をするんだ、川!!
…………
……………………
ありがとうございました!