2019/02/21
(2019/2/23更新 PyPIに登録し、pip installで使えるようになりました)
きんみさん(@_kinmi)の悟空語ジェネレーターに触発され、Pythonモジュール版であるgokulang
を作成しました
Web API化もしたので、ぜひご自由に叩いてください(https://gokulang.herokuapp.com/)
Pythonモジュール版のソースコードはhttps://github.com/shonansurvivors/goku-lang
Web APIのソースコードはhttps://github.com/shonansurvivors/goku-lang-api
ぺぇぴーえぇ(PyPI)に登録済みなので、pip install
で使えます。
(venv) $ pip install gokulang
なお、
janome
pykakasi
semidbm
, six
に依存していますので一緒にインストールされます。
(venv) $ pip list
Package Version
---------- -------
gokulang 1.0.1
Janome 0.3.7
pip 10.0.1
pykakasi 0.94
semidbm 0.5.1
setuptools 39.1.0
six 1.12.0
無事インストールされたら、gokulang.py
からGokuLang
クラスをimportし、インスタンス化の上、translate
メソッドに日本語文章を渡してください。
(venv) $ python
>>> from gokulang.gokulang import GokuLang
>>> g = GokuLang()
>>> g.translate('FF外から失礼します')
'FFげぇからしつれぇすっぞ'
以下環境で動作確認しています。
パラメータtext
に日本語文章を入れてください。
レスポンスの
original
には入力値であるtext
そのままtranslated
には変換後の文章が入ります。
$ curl https://gokulang.herokuapp.com/api/?text=お願いします
{"original": "お願いします", "translated": "おねげぇすっぞ"}
$ curl https://gokulang.herokuapp.com/api/ -X POST -d 'text=もう帰ります'
{"original": "もう帰ります", "translated": "もうけぇっぞ"}
なお、API側にデータベースなどは持っていませんので、POSTを実行しても何かが更新されるようなことはありません。
考え方は悟空語ジェネレーターとほぼ同じです。
janome
で形態素解析を行い、各単語とその読み、品詞を取得pykakasi
でローマ字に変換RomanKanaTable ジェネレーター
を参考に平仮名に戻す。変化の無かった語は、当初の内容に戻す。ただ、悟空語ジェネレーターのソースを解析して作ったわけではないので、変換結果は大なり小なり差はあるかと思います。
また、悟空語ジェネレーターに存在した以下仕様には現時点では対応はしていません。
2019年2月現在、私はコードを全く書くことの無い仕事をしており、恥ずかしながら今回の個人開発で初めてテストコードを書きました。
悟空語変換ロジックを作り上げる過程では、ロジックの追加・修正の都度、従来上手く行っていた変換がおかしくなることがありました。
>>> g.translate('登録したぞ')
'登録すっぞぞ'
頻発するデグレートの発見と再修正を効率良く行う上で、テストコードは不可欠でした。
import unittest
from gokulang import GokuLang
class GokuLangTest(unittest.TestCase):
def setUp(self):
self.G = GokuLang()
def tearDown(self):
pass
def test_ai_ae(self):
q = '最初の試合は緊張するだろうけど、今のお前なら大丈夫だ'
a = 'せぇしょのしえぇは緊張するだろうけど、今のおめぇならでぇじょうぶだ'
self.assertEqual(a, self.G.translate(q))
def test_ei_ae_oi(self):
q = '冷静に考えろ、奴は強いぞ'
a = 'れぇせぇにかんげぇろ、奴はつえぇぞ'
self.assertEqual(a, self.G.translate(q))
def test_oe(self):
q = 'ここを越えるよ'
a = 'ここをけぇるよ'
self.assertEqual(a, self.G.translate(q))
def test_kaeru(self):
q = 'もう帰ります'
a = 'もうけぇっぞ'
self.assertEqual(a, self.G.translate(q))
def test_non_reading_shimasu(self):
q = 'FF外から失礼します'
a = 'FFげぇからしつれぇすっぞ'
self.assertEqual(a, self.G.translate(q))
def test_ta(self):
# 見送っぞ にならないことのテスト
q = '見送った'
a = '見送った'
self.assertEqual(a, self.G.translate(q))
def test_ta2(self):
# 登録すっぞぞ にならないことのテスト
q = '登録したぞ'
a = '登録したぞ'
self.assertEqual(a, self.G.translate(q))
def test_nai(self):
# みえっぞ にならないことのテスト
q = '見えない'
a = '見えねぇ'
self.assertEqual(a, self.G.translate(q))
def test_da(self):
# あそっぞ や あそぶぞ にならないことのテスト
q = '遊んだ'
a = '遊んだ'
self.assertEqual(a, self.G.translate(q))
def test_dekami(self):
q = 'ぱいぱいでか美'
a = 'ぺぇぺぇでか美'
self.assertEqual(a, self.G.translate(q))
if __name__ == '__main__':
unittest.main()
Web APIを作るのも初めてで、Djangoにて手探りで作ってみました。
APIとしての考え方やお作法など、何か間違っている点があればご指摘いただけると幸いです。
import json
from django.views.generic import View, TemplateView
from django.http.response import HttpResponse
from .gokulang.gokulang import GokuLang
class GokuLangView(View):
def get(self, request):
text = request.GET.get('text') if request.GET.get('text') else ''
g = GokuLang()
translated = g.translate(text)
response = {'original': text, 'translated': translated}
return HttpResponse(json.dumps(response, ensure_ascii=False), content_type='application/json')
def post(self, request):
text = request.POST.get('text') if request.POST.get('text') else ''
g = GokuLang()
translated = g.translate(text)
response = {'original': text, 'translated': translated}
return HttpResponse(json.dumps(response, ensure_ascii=False), content_type='application/json')
# ...
def get
もdef post
もやっていることがほぼ同じなので、コードが冗長ですね・・・。