goofy_grothendieck
, ecstatic_lederberg
, quizzical_wu
, ...
Dockerのコンテナのように,ランダムなんだけど読みやすい名前を付けたいことってありますよね?moby/mobyにGo言語のコードを見つけたのでPythonに移植してmongというライブラリにしてみました.
2019/12/22追記: 続報書きました
使い方
Python 3.6と3.8で動作確認しています.Python3.5以降なら動くと思いますが,Python2はType Hintingなどが原因で動きません.
標準ライブラリだけしか使っていないので,インストールはすぐ終わるはずです.
$ pip install git+https://github.com/toshihikoyanase/mong.git
さっそく,ランダムに名前を生成してみましょう.
(2019/12/22修正: インスタンス化する方法から関数呼び出しに変更しました)
import mong
mong.get_random_name() # 'goofy_robinson'
mong.get_random_name() # 'stoic_feynman'
Google ColabにJupyter Notebookを用意しました.以下からすぐに試せます:
実装方針
オリジナルのコードを見ると名前の元となる単語の辞書がその大半をしめていました.移植先のコードに辞書をべた書きすると,メンテナンスが大変そうなので,オリジナルのコードから抽出する方法を選びました.
具体的には下記のとおりです.
-
mong/create_dict.py
でオリジナルのコードから名前のもととなる単語の辞書を抽出しています. -
mong/moby_dict.json
に抽出した辞書を保存しています. -
mong/name_generator.py
のNameGenerator
に名前生成ロジックを移植しています.
オリジナル(moby)の実装
Dockerの名前生成コードは moby/moby にあって,Go言語で書かれています.なお,mobyはコンテナシステムのためのツール集のようです.こちらのスライドに簡潔にまとめられています.
名前は2つの語からなっていて,形容詞と有名な科学者とハッカーの人名です.それらが _
でつながれています.
例
# 怒った(形容詞)_チューリング(人名)
angry_turing
形容詞はleft
,人名はright
というリストで管理されています.
left = [...]string{
"admiring",
"adoring",
"affectionate",
"agitated",
right = [...]string{
// Muhammad ibn Jābir al-Ḥarrānī al-Battānī was a founding father of astronomy. https://en.wikipedia.org/wiki/Mu%E1%B8%A5ammad_ibn_J%C4%81bir_al-%E1%B8%A4arr%C4%81n%C4%AB_al-Batt%C4%81n%C4%AB
"albattani",
// Frances E. Allen, became the first female IBM Fellow in 1989. In 2006, she became the first female recipient of the ACM's Turing Award. https://en.wikipedia.org/wiki/Frances_E._Allen
"allen",
名前の生成処理は,基本的にランダムに選択して,つなぐだけです.
// GetRandomName generates a random name from the list of adjectives and surnames in this package
// formatted as "adjective_surname". For example 'focused_turing'. If retry is non-zero, a random
// integer between 0 and 10 will be added to the end of the name, e.g `focused_turing3`
func GetRandomName(retry int) string {
begin:
name := fmt.Sprintf("%s_%s", left[rand.Intn(len(left))], right[rand.Intn(len(right))])
if name == "boring_wozniak" /* Steve Wozniak is not boring */ {
goto begin
}
if retry > 0 {
name = fmt.Sprintf("%s%d", name, rand.Intn(10))
}
return name
}
このQiita記事にもあるように, boring_wozniak
は生成されないようになっています.(出たらもう一度作り直しています.)
2019年12月21日時点で, left
は108語, right
は235語あったので合わせて25,379種類の名前が生成できます.意外と少ないような気がしますね.
なお,retry
引数についてはよくわかっていなくて,処理を見てもretry
しているように見えません.retry>0
だと 0
以上 9
以下の整数をランダムに選んで名前の末尾につけています.これは使う側のコードを読まないとわからないかもしれません.単純に1桁種類数を増やすためかな?
まとめと今後の課題
PythonでDockerコンテナ風のランダム名を生成できる mong というライブラリを作ってみました.
一応,動くところまでは書いたのですが,テストカバレッジが低かったり,エラー処理を省いていたり,CIをしていないなどいろいろ改善の余地はあります.また,pypiに登録していないので,インストールがやや面倒です.
(自分も含めて)ニーズがあればもう少し整えようかなと思っています.