最近の英語学習
いまのところ日常業務で英語を使うことはあまりないんだけど、学習の習慣は失ったら取り戻せなくなってしまいそうなのでゆるゆると続けているのでダンプしておこうと思う。
実際現状の英語力はどれくらいなのかはまったくわかんないけど TOEIC を最後に受けたのはたぶん3, 4年前で、そのときのスコアは600くらいだったように思う。実用で言えば、Uber が道を間違えたときに正すことが出来て、飲み会のガチネイティブフリーカンバセーションは一切ついていけないけど、コンテキストが限定されたディスカッションならばなんとかなるかもしれないくらいのレベル感。わかりづらいですね。
DMM 英会話
いまのところは DMM 英会話をやっています。やったりやらなかったりなので習慣づけてちゃんと毎日やりたい。
今日は英語やったので偉い
— Satoshi SUZUKI (@studio3104) November 29, 2019
コースはネイティブスピーカーを選択可能な「プラスネイティブプラン」ってやつに一応している。 eikaiwa.dmm.com
オンライン英会話はテキスト通りにやるのはホントにダルいしあんま意味ねえなって思ってしまうので極力やらないようにしています。単語と例文があって、チューターに続けて「リピートアフターミー」して読むだけとかダルいし、反射で英語が口から出るようになりたいのでそのための練習としては効果があまり出ないなあと感じるので。 では何をしているのかというと、最近はトピックだけを決めてそれについてフリートークするって感じでやっています。そのトピック決めのためにちょっとだけテキストを参照するとかはある。
YouTube
あとは英語の動画を結構観るようにしている。寝落ちるまで YouTube でコーディングプロブレムの解説動画とか、日常系とか、英語学習者向け解説動画とかをとにかく観まくってる。解説動画は日本人向けのモノでも極力は英語で解説しているものを観るようにしていて、その中でも最近めっちゃいいなって思ってるのは IU-CONNECT のやつ。時折挟まれる日本語と、ちょっとした日本語表示があるので、英語だけ聴いててもかなり理解が進んでいて「ワシ英語結構聞き取れるやん」という誤解が捗るし最高。 www.youtube.com
他に最近よく観ているのはこれらなんだが詳細は割愛だ。 www.youtube.com www.youtube.com www.youtube.com www.youtube.com www.youtube.com www.youtube.com
Netflix
スポンジボブを英語で観るのも楽しいので良いです。子が NHK で観てたりするので一緒に楽しめるし、なんなら子は聞き取れていなくても言わんとしてることがわかるようなのでゲラゲラ笑ってたりする。オヤジより先にペラになるといいな。 www.netflix.com
あとは英語音声英語字幕で映画観たりしてる。
短期留学、プログリット、RIZAP
「外国語学習は筋トレと同じで、突然大きくは上達しないし、サボったらすぐに衰える。とにかく日々の継続が肝要だ。」って前職の同僚のアメリカ人が言ってた。とはいえガッと短期間で高効率にどうにかする方法はねえのかって毎日思ってる。ドーピングしたい。
とにかく英会話が成立しないことによって物事が進行しないみたいな出来事が発生することが予見されているので、高効率に短期間で凝縮した学習を行いたい。セブ島行くかプログリットやるか。どっちがええやろか。両方やったらええんか?
— Satoshi SUZUKI (@studio3104) February 4, 2020
てことで短期留学とかプログリットとか RIZAP English とかが気になり始めているところ。まだ実際には何もしてません。こちらのエントリにも影響を受けています。 hiroshix.hatenablog.com hiroshix.hatenablog.com
まとめ
まとまらんな。学習キリがないので早く習得したい。強制的に日常的に使うようなところに身を置くしかないかな。
自動的に Annotation を追加してくれる pyannotate が便利そう
TL; DR
こいつを使うと、Annotation を追加していない部分に自動的に適用してくれます。
もう少し詳しく
詳しい使い方はリポジトリを見ていただくとして、要はこの実装に対して実行すると、
こういう風になります。
残念ながらこのエントリを書いている本日現在では python3 形式での変換には対応していないようですが、README の TODO に Python 3 code generation.
と書いてあるのでそのうち対応されるんではないでしょうか。
ちなみに手動で書き換えるとこういう風になるんだと思います。
pytest と組み合わせるとさらに便利
pyannotate
は実際に実行してみた結果を収集しながら型情報を適用するための JSON ファイルを生成してから、それをベースにして適用を行うという仕組みです。
pyannotate/example at master · dropbox/pyannotate · GitHub を覗いてみると、以下のような説明があり、pytest
で実際に走破された箇所に対しての JSON ファイルを生成するためのヘルパーを含んだ conftest.py
のサンプルがあります。
Alternative, using pytest For pytest users, the example_conftest.py file shows how to automatically configures pytest to collect types when running tests. The test_gcd.py file contains a simple test to demonstrate this. Copy the contents of example_conftest.py to your conftest.py file and run pytest; it will then generate a type_info.json file like the one above.
どうせテストは書くんだからこれはかなり便利なんじゃないでしょうか。
今回の例を出すために使用した実装は以下にアップしていますが、実際にその conftest.py
を使用してみています。
雑感
このライブラリから得られた結果をそのままで使うというよりもあくまで参考にする程度の気持ちでいたほうが良さそう。
上に例示した内容の場合もそうですが、たとえばネストされた dict
だと Dict[str, Any]
になりがちです。しかしながら実際の実装では本当は構造がちゃんと決まっているかもしれないので、その場合は適切に書き換えてあげる必要があるでしょう。極力 Any
は使いたくない。
また、これも例示した内容に含まれていますが、requests
のようなサードパーティライブラリであっても適切にどのクラスのオブジェクトインスタンスなのかということを判断して import
も自動的に挿入してくれるのはとても便利ですね。
なんにしても、Python で type hinting を始めてみようという段階ではとんでもなく便利だと思います。
GPG encrypted なファイルを直接編集したいときは
これを使えば完全に解決します。vim plugin です。
ミスって Cmd + q で Chrome を落としてしまったら
Chrome を起動し直してから Cmd + Shift + t で全部生き返るよ。
意外と知らない人が多いようなのでしたためておこう。
突然 ERD を要求されたときに便利な eralchemy
開発してるプロダクトで突然 ERD 出せと言われることがあります。
そんなときには eralchemy を使うと便利です。
実際の Schema から ERD を出力してくれます。
使いからは上記のリンク先の README を見るだけでイナフですがこんな感じ。
brew install eralchemy eralchemy -i sqlite:///db.sqlite -o erd_from_sqlite.pdf
スーパーイージーですね。pip からもインストール出来ます。
Django の Abstract Model を py.test でテストする
※これは Python Advent Calendar 2015 2日目のエントリです。
各モデルが共通のカラムや振る舞いを持つようになってきたら
Django
でアプリケーションを開発していると、各モデルに共通のカラムを持たせたり、共通の振る舞いをさせたりしたいということが起こると思います。
そのような場合は、各モデルに対して同じような実装を施すのではなく、Abstract Model を定義して各モデルがそれを継承するようにするのが自然でしょう。
例えば以下の様な感じです。
from django.db import models class CommonAbstractModel(models.Model): created_datetime = models.DateTimeField(auto_now_add=True) updated_datetime = models.DateTimeField(auto_now=True) class Meta: abstract = True
from common.models import CommonAbstractModel class User(CommonAbstractModel): name = models.models.CharField(max_length=100)
このように実装することによって、User
モデルに直接 created_datetime
, updated_datetime
を定義する必要がなくなるので便利です。
ではテストをどうするか
CommonAbstractModel
を継承したモデルが確実に created_datetime
, updated_datetime
を持っているかということをテストした気持ちになるのが自然ですよね。
ただ abstract = True
なモデルは manage.py makemigrations
でマイグレーションが作成されないため、通常のモデルのように普通にテストを書くことがかないません。
とはいえ、子クラスである User
に対してそれらテストを行うのは、あくまで User
のテストであって CommonAbstractModel
をテストするということにはならないです(なるかも知れないけど、例えば CommonAbstractModel
に論理削除の実装が入ったりしたらそれも子クラスでテストするんですか?という話になりますね) 。
py.test
を使った例
実はこの例(継承したモデルが確実に created_datetime
, updated_datetime
を持っているかというテスト)だと、擬似的なマイグレーションを行う必要はまったくなく、擬似的な子クラスだけがあれば良かったりします。。。
Abstract Model に論理削除とかを実装したくなったときには必要ですが。
import pytest import datetime from common.models import CommonAbstractModel from django.db import connection from django.core.management.color import no_style @pytest.fixture(scope='module') def fx_TestInheritedModel(): class TestInheritedModel(CommonAbstractModel): class Meta: app_label = 'common' return TestInheritedModel @pytest.yield_fixture(scope='function') @pytest.mark.django_db def fx_test_model_cls(request, fx_TestInheritedModel): cursor = connection.cursor() statements, pending = connection.creation.sql_create_model(fx_TestInheritedModel, no_style()) for sql in statements: cursor.execute(sql) yield fx_TestInheritedModel statements = connection.creation.sql_destroy_model(fx_TestInheritedModel, (), no_style()) for sql in statements: cursor.execute(sql) @pytest.mark.django_db class TestCommonAbstractModel: @pytest.mark.parametrize(('attr_name'), [ 'created_datetime', 'updated_datetime', ]) def test_inherited_model_has_proper_fields(self, fx_TestInheritedModel, attr_name): inherited_model = fx_TestInheritedModel() assert hasattr(inherited_model, attr_name), 'the inherited model must have %s field' % (attr_name, )
ちょっとだけ解説
テスト内部で擬似クラスを作成してそれに CommonAbstractModel
を継承させて、それを擬似マイグレーションをさせてテストしてしまおうという戦略です。
擬似クラス
フィクスチャをこのように定義します。
app_label = 'common'
がめっちゃ重要で、これを定義しておかないと擬似マイグレーションさせることが出来ません。
@pytest.fixture(scope='module') def fx_TestInheritedModel(): class TestInheritedModel(CommonAbstractModel): class Meta: app_label = 'common' return TestInheritedModel
擬似マイグレーション
各テストメソッドが実行される前にテーブルが作成され、終わったら消されます。
yield_fixture
を使うのがポイントです(scope='function'
はデフォルトなのであえて指定する必要はないかもしれませんが、Explicit is better than implicit.
です。)
@pytest.yield_fixture(scope='function') @pytest.mark.django_db def fx_test_model_cls(request, fx_TestInheritedModel): cursor = connection.cursor() statements, pending = connection.creation.sql_create_model(fx_TestInheritedModel, no_style()) for sql in statements: cursor.execute(sql) yield fx_TestInheritedModel statements = connection.creation.sql_destroy_model(fx_TestInheritedModel, (), no_style()) for sql in statements: cursor.execute(sql)
あとは...
実際に fx_test_model_cls
を利用するテストをガシガシ書いていくだけです!
django.test.TestCase
を使いたい場合
普通に setUp
, tearDown
を使って同じようなことすれば良さそう。
EOF
Python でオブジェクト内部の dict に直接アクセスする
- Ruby でいうとこのこういうやつ。
class Hage def initialize() @hage = { bozu: 1, hage: 2 } end def [](key) @hage[key] end def []=(key, value) @hage[key] = value end end h = Hage.new() p h #=> #<Hage:0x007f94428a2c20 @hage={:bozu=>1, :hage=>2}> p h[:bozu] #=> 1 h[:fusa] = 3 p h[:fusa] #=> 3
- Python でやるとこう。
class Hage: def __init__(self): self.hage = { 'bozu': 1, 'hage': 2 } def __getitem__(self, key): return self.hage[key] def __setitem__(self, key, value): self.hage[key] = value h = Hage() print h #=> <__main__.Hage instance at 0x109f6aef0> print h['hage'] #=> 2 h['fusa'] = 3 print h['fusa'] #=> 3