僕とコードとブルーハワイ

omega (@equal_001) の日記

Lenovo ThinkPad X220i に Ubuntu16.04 LTS Desktop を入れた

最近は個人ではMacbook Proを使用していたのだけど、せっかくそこそこ良いThink Padを放置するのも宝の持ち腐れだと思い、Ubintu16.04 LTS Desktop を入れることにした。

中にはWindows7が入っていたのだけど、正直使わないのでまるっと削除してすべてをUbuntu色に染めた。


以下、使えるようにするまでの手順のメモ。



UbuntuライブメディアをUSBで作成する

用意するもの:PC, フォーマットしてもいいUSB (2Gあれば十分)

Ubuntuのインストール

  • マシンの再起動をして、BIOSからUSBデバイスを選択する。(私のThinkPadの場合、Enter押したらいけた)
  • 選択するとubuntuのインストールが始まって、セットアップ画面になるので、タイムゾーンとかもろもろ設定していく。セットアップ画面しっかりしてて綺麗。ubuntuめっちゃ頑張ってるなーという印象受けた。

日本語の設定

デフォルトだと日本語が使えなかったので設定変更する必要があった。幸いubuntuのセットアップ時にmozcなど日本語入力に必要なドライバが入ってきていたので、そのあたりは苦労しなかった。

  • desktop右上にあるキーボードアイコン -> 設定 -> 入力メソッドの設定 へ飛ぶ
  • 以下画像左下にあるプラスボタンを押したあと、入力メソッドを検索できるフォームにmozcと入力する
  • mozcを入力メソッドにしてメソッド追加したら、最初から入ってた入力メソッド「キーボード - 日本語」よりも上に持っていく
  • PC再起動する。すると英字/日本語の切り替えができて日本語入力可能になっている


f:id:equal_001:20160718192846p:plain

Chromeを使えるようにする

デフォルトだとFirefoxが入っているのだけど、個人的にChromeが使いたかったので入れた。

$ sudo apt install libappindicator1
$ sudo dpkg -i ダウンロード/google-chrome-stable_current_amd64.deb
  • /opt/google/chrome/ にchrome起動ファイルがあるので実行+Launcherに追加しとく

感想

  • 思ったよりメモリ消費しない。今使ってるノートPCのメモリが4Gなんだけど変に遅くなったりしないしサクサク動作してくれる。chromeにタブ5つくらい開いて、youtubeとか見ても2Gいくかいかないか。ニコ動はもうちょい食うけど許容範囲内。
  • Linuxファイルシステムが普通に使えて最高
  • 充電はMacより長持ちしないのがちょっとつらい
  • ThinkPad軽いなぁ...
  • Kindle for Desktopを頑張って入れないといけないのがちょいと面倒(Windows上なら動くらしいが、Linux版のは無いらしい)

Domain Driven Design Quickly Online を読んでいく。 その2

Domain Driven Design Quickly Online を読んでいく。 その1 - 僕とコードとブルーハワイ
の続き。

読んでいる本
www.infoq.com

ユビキタス言語

ユビキタス言語とは、ドメインの専門家とソフトウェアの専門家の両者が正しくドメインを理解/表現するための共通言語のこと、と捉えた。

例えば、ドメインモデルの作成の過程で、ドメインの専門家は自己の専門範囲である業務の専門用語を使い、ソフトウェアの専門はプログラミング脳でドメインを捉えてたり技術的な専門用語などで説明してしまったりする場合、両者の間で共通の認識を得ないまま、ドメインモデルを構築してしまう。
そうなってしまうと、

ドメインについての正しい表現は記録されず適切でない表現の中に埋もれてしまったり、
相手がわかるように簡単な(と思っている)言葉で説明することに消耗したり、
専門分野を理解しなければいけないがためにまた別の今回限りな専門用語を生み出してしまったり

する。
ドメインモデルの構築、そして設計が困難になってしまう。
これを回避するために、ユビキタス言語(共通言語)を使っていこうね、というお話。

では、ユビキタス言語(共通言語)はどのように構築するか。

監視システムの例を読むと、
ユビキタス言語というものはこれだ!と言って名付けるものではなく、ドメインモデルを構築していく過程のお互いの会話から発せられた、ある程度まとまった概念を持つ単語の持つ意味の認識をすり合わせていく、という作業に考えられた。
そして、すり合わせをした結果できた概念(ユビキタス言語で表現できるもの)をドメインモデルに反映してみて、齟齬をなくしていく、というのが理想なのだろう。

ちなみにユビキタス言語を構築することで得られるコードを書くときの恩恵はこの文章に集約されていた。

ドメインモデルの概念をクラスへと実装することで、ドメインモデルとコードを対応づけることができます。そして、それは共通言語とコードを対応づけることでもあります。しっかり対応づけられていると、コードが読みやすくなり、コードからドメインモデルを再作成できるようになるのでとても役に立ちます。

ふむふむ。
今の仕事でユビキタス言語っぽいものがwikiにまとまっていたりしていて、コードにもそれらが反映されているんだなーというのがなんとなくわかって、それって仕様把握に一役買っていて私は結構助かった記憶がある。
ただ、この本にも書いてあったけどユビキタス言語はどんどん変化していくものだからwikiと同期しないといけないよねという話がある。
それを怠ると、なんでこの名称になったんだっけどか、この部分何に使ってんの?もういらないやつだっけ?とかなったりして、チャットのログやチケットから経緯を追ったりしないといけなくて、結構辛くなってしまうんだよなこれが。(†戒め†



では、ユビキタス言語はどう表現すればよいのか。

UMLは、クラスやその属性、クラス間の関係を表現するのが得意です。 しかし、クラスの振る舞いや制約を表現するのは簡単ではありません。そのた め、UMLでは図のなかにメモを入れて文章で補足します。したがって、UML ではモデルについての2つの重要な側面、つまりモデルがあらわす概念の意味 とオブジェクトがするべきことを伝えられません。

UMLは全体像を把握するには良いけど、実際のところどういう働きをするの?って部分を表現するのは不得意だよねーという話。
では、「モデルがあらわす概念の意味とオブジェクト」をどう表現したら良いかというと、
この本では、モデルをあらわすクラスたちの関係やその説明文や画像などを図に起こすといいよ、と書いてある。
雑にいうと、各ドメインについて理解できるように、膨大なクラス群を適切なモデル単位の概念に集約・区切っていこう、という話だと思われる。

すなわち、ソフトウエアアーキテクト、開発者、ドメインの専門家を含む設計チームに必要なのは、作業を統一し、モデルの作成とコーディングを助ける共通言語だということです。

上記の言葉で第2章は締め括られている。
しかし、ユビキタス言語の構築は思っているより難しいところだなぁと感じる。


今日はここまで。

Django1.9 admin get_urlsのoverrideでハマってた

get_urlsで正しいっぽいurlpattern渡してるのに、なんでそんなパターン見つからないって怒られるんじゃーとなって先輩とデバッグしてたら、1.9から追加されたという以下のコードに遭遇した。

urlpatterns = [
url(r'^$', wrap(self.changelist_view), name='%s_%s_changelist' % info),
         :
# For backwards compatibility (was the change url before 1.9)
url(r'^(.+)/$', wrap(RedirectView.as_view(
pattern_name='%s:%s_%s_change' % ((self.admin_site.name,) + info)
))),
]

django.contrib.admin.options | Django documentation | Django


つまり、カスタムURLが先に来るように繋げないとで死ぬという感じだった。

    def get_urls(self):
        from django.conf.urls import url

        urlpatterns = super().get_urls()

        urlpatterns = [
            url(r'^somepattern/$', self.admin_site.admin_view(self.my_view), name=''),
        ] + urlpatterns  # ここのリストに入れる順番が今回の問題
        return urlpatterns

    def my_view(self, request):
        return TemplateResponse(request, template , {})

1.9にバージョンアップするときは注意が必要だなぁーと思った。


というかまずよくコード読めという話でした、先輩すみませんでした。。

Domain Driven Design Quickly Online を読んでいく。 その1

先に分厚いDDD本を読んでいたが、読み進めていてもどうも霧の中を歩いている感覚から抜け出せずにいるということで、まずは友人の勧めにより「Domain Driven Design Quickly」を読むこととし、そのメモを書いていく。

www.infoq.com

イントロ〜第1章 ドメイン駆動設計とは何か

ソフトウエアを開発する目的は、実世界の作業を自動化したり、ビジネス上の 問題を解決することです。つまりソフトウエアは、業務の自動化や現実世界の問題など、具体的なドメインのためのソフトウエアなのです。

ドメインとは、実世界で解決したい問題、要求の解決方の枠組みの集合またはそれ自体、ということだろうか。
もう少し雑にいうと、ドメインとはつまりソフトウェアが行う業務の範囲?内容?指していると思われる。


ドメイン駆動設計とは、ソフトウェア設計手法の一つ。
ドメインを明らかにするためには、ドメインを詳細に把握している人物からヒアリングするべきである。例えば、銀行業務システムであれば、業務流れや潜在的な問題を熟知している銀行員である(担当者および依頼者が問題を認識していない場合もあるけど)。
そうしてドメインを探り出していきつつ、ドメインの抽象化をしていく。
ドメインの抽象化とは、ドメインのモデル化のこと。
ドメインは多くの情報を含み、かつ複雑なものであるため、通常は全てをモデルに落とし込むことはできないと考えて良い。この取捨選択が設計作業であり、ソフトウェア作成でもある。

なお、ドメインモデルについては本文中にあったこの一文がわかりやすかった。

ドメインモデルとは特定の図で表されるものではなく、そのような図が表そうとする概念である。

ドメインの知識を構築する

次に、飛行機の飛行制御システム開発を例にドメイン設計を考える。

さらに議論すると、あなたは興味深い単語を聞きます。それ は「航路」です。あなたがこの単語にすぐに着目したのはそれなりの理由があ ります。航路は飛行行程の重要な概念を含んでいるからです。航路にしたがう。 これが飛行機が飛行中におこなうことです。飛行機の出発地と目的地は航路の 始点と終点でもあることが明らかになります。したがって、飛行機を出発地と 目的地に関連させるよりも、航路と関連させた方が自然な気がします。この場 合、航路は出発地と発着地に関連します。

飛行機の航路、つまり問題(飛行機)の遷移/あるいは状態に着目するというのが一つのポイントだと思われる。
例では、飛行機を出発地と目的地に関連させるよりも、飛行機ー航路ー出発地/目的地と関連付ける方が自然、とある。構成する出発地/目的地というものを抽象的に考えて飛行機と関連付ける見方ができるかどうかが第一歩。
抽象化なので、考えているとプログラムでいうクラスのようなイメージを持つ。

私たちソフトウエアの専門 家(アーキテクトと開発者)とドメインの専門家はドメインモデルを一緒に作成します。ドメインモデルはこの2つの専門領域が出会う場所でもあるあります。これは多くの時間を費やさなければならない作業に思えるでしょう。そして、実際その通りです。そうするべきです。なぜなら、ソフトウエアの最終的な目的は実際の生きたドメインでの業務上の問題を解決することであり、そのためにはソフトウエアはドメインと完璧に一体になる必要があるのですから。

アーキテクトと開発者とドメインエキスパートが揃ってドメインの抽象化を行い、ソフトウェアが本来行うべき業務のための設計をしていく、という流れなのだろう。
大雑把だが、DDDの概念は把握した。


今日はここまで。

zencoding-vim から emmet-vim へ

リポジトリが移動してた。

GitHub - mattn/emmet-vim: emmet for vim: http://emmet.io/


そういえばzen-codingというPluginがemacsにあったなーVimのもあるだろうなと思って調べたらやっぱり存在して、NeoBundleしたのだけど、Vimを起動したところ以下のエラーが出た。

Unfortunately, zencoding-vim was moved to emmet-vim, please use it.

ということで、NeoBundle 'mattn/emmet-vim' し直したのだった。

python の doctest

26.3. doctest — 対話的な実行例をテストする — Python 3.5.1 ドキュメント

そういえば使ったことがなかったので触ってみたのと、使い道とかの個人的な感想メモ。

pythonでテストするときはunittest, pytest, pylintあたりしか使ったことがなかった。


demo.py

"""
>>> test("omega")
'Hello, omega!'
"""

def test(name):
    return "Hello, {}!".format(name)

if __name__ == "__main__":
    import doctest
    doctest.testmod()

実行結果

~$ python demo.py -v  # -vすると実行詳細がみれる

"""
>>> test("omega")
'Hello, omega!'
"""

def test(name):
    return "Hello, {}!".format(name)

if __name__ == "__main__":
    import doctest
    doctest.testmod()
OMEGA:~$ python test.py
OMEGA:~$ python test.py -v
Trying:
    test("omega")
Expecting:
    'Hello, omega!'
ok
1 items had no tests:
    __main__.test
1 items passed all tests:
   1 tests in __main__
1 tests in 2 items.
1 passed and 0 failed.
Test passed.

こんな感じ。
ちなみにdocstringの気分で書いて、Expectingにシングルクォートで囲まないHello, omega!を記述していたら見事にfailedになった。

上記ではdemo,pyでdoctestをimportしてるけど、コマンドラインからdemo,pyを単体モジュールとしてimportしてテスト実行することもできる。

~$ python -m doctest -v demo.py

テストしたい内容が増えたりするとpythonファイルが肥大化するので、そういうときは testmod()の代わりにtestfile()と使うとよい。
doctest.testfile("test_list.txt") と書いてtest_list.txtの中にTrying/Expectingをガシガシ書いていけばいい。

test_list.txtの中身はこんな感じ。

>>> from demo import test
>>> test("omega")
'Hello, omega!'

なおこれもコマンドラインから実行できる。

~$ python -m doctest -v test_list.txt

例外について思ったところ

例外については公式ドキュメントにも書いてあった。
トレースバックを貼ればいいだけらしいけど、filepathとか変更されやすいものだったりrandom的なもので毎回値が変化するようなものには向いていない。
そもそもあまり例外でテストするのは良くないと思うけど。
例外に関して評価される部分としては、例外の型からそれ以降だけらしい。
以下の場合、最初の二行はスルーされる。

Traceback (most recent call last):
    ... 
ValueError: multi
    line
detail

やっぱり例外を扱うのはよろしくないと思う。なってほしい結果の一例としてのwikiのようなものくらいのほうが良いと思う。

単体テストAPI

多分使わないと思うけど、doctestをunittest.TestSuite に変換することができる機能を持っている。

デバッグ

使わないと思うけど使いそうなところを挙げるとpdbが使える、 TestCaseのdebug()が使える。以上。

感想

doctestはexampleとして記述しておくのが良いのかなと思った。私の中では今のところ、docstringをより良いものにするためのという位置付け。
あと、モジュールの方針・本当に実現したい機能を思い出させてくれるものとしても良いかも。
ガシガシコード書いてると、よく方向性見失ったりするので、、

ExDOS を動かしてみた

天才あらわる 14歳の少年プログラマが作った64ビットOS「ExDOS」が凄い という記事を見て、何やらOSを自作した人がいてそれが公開されているという情報を得たので実際に動かしてみた。

ダウンロード

ExDOS -- Downloads
ここからダウンロードしてくる。
現時点ではdemo状態のものだけが公開されている。
今回はdemo2.zipを手元に持ってきた。

ExDOSを動かす

ExDOS -- Tested Hardware を読むと、VirtualBox5.0上でならいい感じに動くぜ!と書いてたのでVirtualBox5.0上で動かした。
仮想ハードディスクを追加しない設定で作成して、ストレージからHDD選択でdemo2.vmdkを指定するだけ。

Runしたらこんな画面になった。
ウィンドウが二つ。こやつらはマウス操作で位置を動かせた。拡大縮小とかはできなかった。
f:id:equal_001:20160408020221p:plain

右下にDEBUGというボタンみたいなのあったのでクリックしたら、ターミナルっぽくなった。
helpと入力すると使えるコマンド一覧でてくる。
コマンドミスしてるのは、英数字切り替えボタンを押す癖が抜けなくて無意識に「 ` 」を入力していたというオチ。
f:id:equal_001:20160408020513p:plain

とりあえず手当たり次第にコマンド打って遊んだ。
無知すぎてportコマンド群の意味がよくわからなかった。
f:id:equal_001:20160408020549p:plain

感想

  • とにかく起動が早かった。まだそんなに機能ないからだとは思うけど、サクサク。
  • たまにカーソル操作がおかしくなって左側にぴょんと飛んだりするトリッキーな動きもして翻弄された。
  • ターミナルの履歴機能はまだなかったけど、ここまで作れた人にとってもそういう機能の導入って難しいのかな。(OS作ったことないのに生意気言ってごめんなさいでもあるとコマンドの動作確認とか便利だろうなって思ったんですごめんなさい)
  • まだドキュメントはcomming soonだったのでできるの楽しみ。


ソースコードはGihubで公開されている。
GitHub - omarrx024/exdos64: Extensible Disk Operating System (64-bit version)

アセンブラ力がゼロなので特になにも解読できませんでした。
でもこういうモジュール(と言っていいのかわからないけど)の切り方するんだなとか、kernel.asmを起点に眺めているとなんとなーくだけど、中でやってることがが見えてきた。
keyboard.asmにはhelpで出したコマンドの関数定義があったり(アセンブラは読めないけど)。

面白かったので真面目にUnixカーネルのコード読もうかなという気持ちにちょっとなった。