Quantcast
Channel: Vimタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 5608

Vimでダミーデータを作る

$
0
0

そんなプラグインを書きました。この記事はその使い方の紹介です。

ダミーデータというのは、適当な名前とか、いわゆる Lorem ipsumみたいな無意味な文章といった穴埋め用途のテキストのことです。

:echo fake#gen("paragraph")

Ignota autem nostrud albucius sagittis no fabulas erat eam ridens
et per moderatius 98 movet. Sea iure est integre metus adipisci
justo id con ultrices omnes minim odioaccommodare. Consul omnium
enim volumus lectus habeo fuisset pri utinam sem tamquam no.

簡単な使い方

適当なプラグインマネージャーでインストールします。
https://github.com/tkhren/vim-fake

NeoBundle 'tkhren/vim-fake'

生成してみる

fake#gen({keyname})という関数を呼ぶと、実行ごとに異なる答えが返ってきます。
{keyname}にはいろいろありますが、例えば国の名前が得たいなら、"country"を使います。

:echo fake#gen("country")
Canada
:echo fake#gen("country")
Nigeria
:echo fake#gen("country")
Indonesia

挿入してみる

挿入モード中にダミーデータを生成したいなら、 Expression registerを使います。

<C-r>=fake#gen("country")

(適当なスニペットプラグインを使えばもっと簡単に挿入できるかもしれません。)

置換してみる①

次のテキストの dummyを男性の名前(male_name)で置換したいなら、

<ul><li> dummy </li><li> dummy </li><li> dummy </li></ul>

:%s/dummy/\=fake#gen("male_name")/gを実行するとdummyがテキトーな人の名前に変わります。

<ul><li> Steve </li><li> Rodney </li><li> Leonard </li></ul>

置換してみる②

いちいち置換コマンド打つのは面倒なとき、大量のテキストを生成したい時には、
プレースホルダーを使うのが便利です。

まず、編集中のファイルに FAKE__{keyname}__を書いておきます。

<user><name>FAKE__fullname__</name><age>FAKE__age__</age><job>FAKE__job__</job></user><user><name>FAKE__fullname__</name><age>FAKE__age__</age><job>FAKE__job__</job></user>

:FakeSubstituteを実行すると、FAKE__{keyname}__のそれぞれを fake#gen({keyname})で一括置換します。

<user><name>Lydia Dawson</name><age>59</age><job>Dentist</job></user><user><name>Charlie Adams</name><age>42</age><job>Musician</job></user>

データソース(keyname)の選択

ランダムデータの生成には fake#gen({keyname})を使います。
この {keyname}には使いたいデータの名前を指定します。デフォルトでは次のものが用意されています。

{keyname}内容並び順
male_name世界の男性名人口順
female_name世界の女性名人口順
surname世界の苗字人口順
country国の名前人口順
gtldgTLD登録数順
job仕事の名前 
word頻出英単語 
nonsense意味のない単語 

これらのデータソース(辞書ファイル)は、UNIXの/usr/share/dict/wordsのような単語が行ごとに羅列されただけの単純なテキストファイルです。

例えば country辞書には、世界の国の名前が書いてありますが、fake#gen("country")すればこのファイルの中のランダムな行が返されます。CanadaとかBrazilとかが返ってきます。選択する行は一様にランダムです。

:echo fake#gen("country")
China

辞書ファイルの追加

この辞書ファイルはいくつでも任意に追加することができ、globしてはじめに見つかったファイルを使います。g:fake_src_pathsには辞書ファイルの入ったディレクトリを指定します。

letg:fake_src_paths = ['/home/user/.vim/fake_src1',
                        \ '/home/user/.vim/fake_src2']

このソースディレクトリは階層にすることもできるので言語や用途ごとに分けたりできます(fake#gen("ja/male_name")のようにアクセスできる)。

データ生成を定義する

本領はここからです。 辞書ファイルを組み合わせることで、いろいろなデータの生成を定義することができます。

fake#define({keyname}, {code})という関数を使って新しい{keyname}を定義します。

fake#gen({keyname}){keyname}が定義されていれば、eval({code})を返し、もし定義されていなければ、g:fake_src_pathsに辞書ファイルを探しに行き、そのランダムな行を返します。

どんな組み合わせができるかというと、例えば

"" リストからランダムにひとつ要素を返すcall fake#define('sex','fake#choice(["male", "female"])')"" 男性と女性の名前を得るcall fake#define('name','fake#int(1) ? fake#gen("male_name")'
                                \ . ' : fake#gen("female_name")')"" フルネームを得るcall fake#define('fullname','fake#gen("name") . " " . fake#gen("surname")')"" 世代人口に沿った年齢を返すcall fake#define('age','float2nr(floor(110 * fake#betapdf(1.0, 1.45)))')"" 国の人口割合に応じて国の名前を返す(China, Indiaが頻繁に返る)call fake#define('country','fake#get(fake#load("country"),'
                        \ . 'fake#betapdf(0.2, 4.0))')"" 登録ウェブサイトの数に応じたgTLDを返す(com, netあたりが頻繁に出る)call fake#define('gtld','fake#get(fake#load("gtld"),'
                        \ . 'fake#betapdf(0.2, 3.0))')"" メールアドレスを生成call fake#define('email','tolower(printf("%s@%s.%s",'
                        \ . 'fake#gen("name"),'
                        \ . 'fake#gen("surname"),'
                        \ . 'fake#gen("gtld")))')"" Lorem ipsum みたいな意味不明な文章を生成call fake#define('sentense','fake#capitalize('
                        \ . 'join(map(range(fake#int(3,15)),"fake#gen(\"nonsense\")"))'
                        \ . ' . fake#chars(1,"..............!?"))')call fake#define('paragraph','join(map(range(fake#int(3,10)),"fake#gen(\"sentense\")"))')"" エイリアスを作るならこんな感じcall fake#define('lipsum','fake#gen("paragraph")')

このようなコードをvimrcあたりに書いておけば、fake#gen("fullname")のような形で呼び出すことができます。上のコードは :let g:fake_bootstrap = 1を定義すれば勝手に読み込まれ、デフォルトは 0 です。好みに応じてONにしてください。

生成方法に偏りをつける(重み付け乱択)

int()とかcapitalize()などは命名からなんとなく分かるかもしれませんが、それ以外にも幾つか知らない関数が出てきたと思います。

"" 辞書ファイル({dictname})の行のリストを返す(内部的に一時キャッシュされる)
fake#load({dictname})"" listからランダムな要素を返す。
fake#choice({list})"" リストの要素を相対位置で取得する。rateは0.0 ~ 1.0"" 例えば rate=0.0 ならリストの先頭要素を返す, 0.5 ならリストの中央の要素を返す
fake#get({list}, {rate})"" a,bで与えられるベータ分布を返す(形状パラメーターa,b > 0, 返り値は0.0 ~ 1.0)
fake#betapdf({a}, {b})

choice()は与えられたリストからランダムに要素を取り出します。取り出し方は一様であり、偏りはありません。

重み付けされた要素選択をしたい場合は、get()betapdf()を組み合わせます。get()は第二引数に取り出したい要素のインデックスを相対位置で指定できるため、0.0~1.0を返すbetapdf()を指定すると、リストのどのあたりの要素を頻繁に取り出したいかを指定できます。

betapdf()は 0.0 ~ 1.0 を返すベータ分布の確率密度関数で、一様ではない偏った乱数を得ることができます。パラメーターa,bの取り方は、次の記事を参考にしながら決めてください。

http://www.ntrand.com/jp/beta-distribution/
http://keisan.casio.jp/exec/system/1161228837

実は country辞書は人口の多い順に国名が並んでいます。なので人口の多いChinaとかIndiaを頻繁に欲しいなら、次のように書けばリストの先頭要素(辞書ファイルの先頭要素)を多く選択するので、それっぽくシュミレーションできます。 ※厳密な人口比率に沿った乱択をするわけではありません。

"" 国の人口割合に応じて国の名前を返す(China, Indiaが頻繁に返る)call fake#define('country',
    \ 'fake#get(fake#load("country"), fake#betapdf(0.2, 4.0))'):echo fake#gen("country")
China
:echo fake#gen("country")
India
:echo fake#gen("country")
China

下図 betapdf(0.2, 4.0)のグラフ
87746340248.png

その他

乱数の精度

Vimには組み込みの乱数生成関数が無いので、sha256()を10進数に直して苦し紛れに乱数としています。そのため、MTとかXorShiftと比較すれば一様性は非常に悪いと思います。それでも今回の用途としては十分な品質と考えているので、Vital.vimにXorShiftがありますが結局使いませんでした。

データソースの内容について

デフォルトの辞書ファイルは使い方を説明するためだけにバンドルしているようなもので、内容が充実しているとは言えませんし正確性も保証できません。なので今後勝手に内容更新したりする可能性もあります。内容に不備・不満等があれば、自前で辞書を用意したほうが早いと思います。


Viewing all articles
Browse latest Browse all 5608

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>