読者です 読者をやめる 読者になる 読者になる

Effective Python 読んだ

Python入門週間の続きでEffective Pythonをサラリと読んだ。

Effective Python ―Pythonプログラムを改良する59項目

Effective Python ―Pythonプログラムを改良する59項目

自分がおもしろいと思ったのは、入門 Python3にはあまり載っていない込み入ったPythonの機能の紹介ので、特に "4章 メタクラスと属性" では、Pythonのオブジェクトシステムの凝った使い方を知ることができて良かった。自分のコードでメタクラスを積極的に使うのは嫌な予感がするので、あまりないかなと思うものの、ライブラリコードを読むときなどには役立ちそう。

他にも、"6章 組み込みモジュール" では、デコレータやコンテキストオブジェクトの定義の仕方やコンテキスト、日付周りのイディオムや、"7章 協働作業(コラボレーション)"では循環参照の問題についてなど、実際のコードを書くときに役立ちそうな話題が総ざらいにできる内容で自分としては満足できた。

一方、サンプルコードが微妙に理解しづらくて、丁寧に読み込まないとよくわからない部分がちょいちょいあったように感じた(もちろん、自分の理解力の問題もあるとは思うものの)。あと、コードの設計の仕方に疑問を感じるところも少しあって("項目 34:クラスの存在をメタクラスで登録する", " 項目 50:モジュールの構成にパッケージを用い、安定な APIを提供する", 例外が好きそうなところ)、本の内容をそのまま鵜呑みにせずに、やり方の一つとして覚えておくのが良さそうかと思った。

総じては、Pythonのよくあるイディオムがコンパクトにまとまっていて良かったと思う。Python流のやり方が少しづつわかるようになってきた。この本の内容が実際のPythonコードではどれくらい採用されているのかは、特に知らないという状態なので、もう少し世の中のPythonのコードを読んだり、オフィシャルのドキュメントを眺めたりすると良さそうだった。

ゼルダの伝説 時のオカリナ3Dをクリアした

Nintendo Switch でリリースされる、ゼルダの伝説 ブレスオブザワイルドが楽しみすぎる今日このごろなのだけど、よく考えたらゼルダシリーズを一切プレイしたことなかった*1ので、時のオカリナをプレイすることにした(のが2週間くらい前)。3DSでのリメイク版を購入した。

64版はたぶん友達がプレイしているのを見たことがあるはずだけど、うろ覚えの記憶しかない。友達がオカリナの楽譜をだいたい覚えていて、すげーなって思ってたような。大乱闘スマッシュブラザーズはやっているので、主要キャラクターはだいたいわかるものの、物語的な背景は知らないという感じでスタート。

謎解きがむずいって聞いていたので、とりあえず初見でチャレンジして、はまりまくったら攻略サイトは見て良いというルールにした。クリアしてみて振り返ると、ダンジョンの攻略のために攻略サイトに頼ったのは2,3回くらいで、丁寧に取り組めばなんとかなるなという感じ。ダンジョン以外のサブクエストや隠しアイテムの入手には攻略サイトに頼りまくった。自由度高すぎて、気づけないみたいなパターンが多かったような(コッコジャンプでこの位置にとどくのまじか..とか)。試行錯誤しまくってるとブレスオブザワイルドが発売されそうなのであきらめた。

演出はそんなに多くはないし、めちゃくちゃグラフィックが綺麗ということもないんだけど、落ち着いた世界観と心にしみるストーリーでたいへん良かった。音楽が良かったのか。スマブラをやっていたことにより、ストーリー上の重要な事実を知らされていたために、途中できづいてあーーってなったりしたのだけど、やむなしである。

ゼルダ作品の時系列の上、重要作品らしい時のオカリナのストーリーを知ることができたし、基本的なゼルダのコンテキストを学ぶことはできたので、だいたい目的は達成できて良かった。意外と2週間くらいでストーリークリアはできたけど、やりこみ要素はいろいろ残っているので、もうちょっと楽しめそう。Nintendo Switchが発売される3/3までには少し時間があるので、トワイライトプリンセスかスカイウォードソードあたりをプレイしても良いかと思ったけど、時間を無限に消化しそうなので諦めたい..。

ゼルダの伝説 ブレス オブ ザ ワイルド

ゼルダの伝説 ブレス オブ ザ ワイルド

*1:よくよく思い出すとリンクのボウガントレーニングだけ持っていた

レガシーソフトウェア改善ガイドを読んだ

めっちゃ似た名前の"レガシコード改善ガイド"とは別の本。レガシーコード改善ガイドは結構前の本だけど、このレガシーソフトウェア改善ガイドは去年刊行されたばかりだ。hitodeくんと会話してて気運が高まったので読んだ。

レガシーソフトウェア改善ガイド (Object Oriented Selection)

レガシーソフトウェア改善ガイド (Object Oriented Selection)

この本は、レガシーソフトウェアがメインのテーマにしているけれど、古びてどうにもならなくないソフトウェアプロジェクトへの対処のみにフォーカスしているのではなく、普段から開発しているコードをどうやって継続して進化させられるかといった内容が主で、どんなソフトウェアエンジニアにも勧められそう。

この本の章の構成をみると、大きくはリファクタリングに関する章と、プロジェクトのワークフローと基盤整理に関する章に分けられる。

リファクタリングに関する章では、プロジェクトのコードの状態が悪くなった時に対処する作戦として、リファクタリング/リアークテクティング/ビッグリライトの3つを紹介しながら、何を基準にどの作戦を採用すればよいかを教えてくれる。

リアーキテクティングのゴールの一つとして、マイクロサービスのような流行のアーキテクチャについても言及があるが、実際的なメリットとデメリットがまとめられていて(デメリットのほうがリストが長い)、技術的なおしゃれさに引きずられない、バランスの良い解説が読める。

技術的なテクニックだけでなく、リファクタリングを"開発者のための開発"のみに陥らせずに、プロジェクトの成功に結びついた活動にするためのポイントも、逐一丁寧に言及されているのも落ち着きがある。例えば、リファクタリング自体を目的にせずに、機能Xを実現するために必要なタスクとしてリファクタリングをとらえることで、チームにも説明可能になるし、リファクタリングのスコープをまちがえずに済むといったことが紹介されている。しかたないので、自分のメインの仕事のじゃまにならない範囲で手をつけてみるみたいな作戦も載っていて生々しい。

"もし価値のないソフトウェアを作ってしまったら、コードがどうだろうと誰も気にしない" のようなフレーズがちょいちょい現れて心に刺さる。

プロジェクトのワークフローと基盤整理に関する章については、手元の開発環境やテスト環境、プロダクション環境構築の自動化についてかなり具体的な手順が載っているので、これからやりたいけどイメージがついていない人には良さそうな内容だった。

最近の本だからか、銀行の決済システムとかではなく、Web開発者になじみのありそうなECのWebサイトが例として取り上げられていたり、登場する技術セット比較的なじみのあるものだったりで、読みやすかった。作者の開発のスタイルや、置かれているチームの状況が自分と結構似ているというのもあったかもしれない(お前は俺かみたいなエピソードが何個もあった)。

まったく新しい内容はそんなにはないけれども、継続開発可能なコードベースや開発体制を目指しているときに、漠然と気をつけていることがコンパクトにまとまっていて良い本だと思う。第一章のはじめのあたりの文章が結構ささるので気になる人は立ち読みしてみても良さそう。

PythonでWebアプリケーション作る練習をした

最近流行っている雰囲気があるPythonだけど、僕も年末にふと気分が高まったので、練習をしてみた。

自分にとってはPerlやRubyよりも先に勉強した、初めてのスクリプト言語がPythonだったので、ちょっとだけ思い入れがある。とはいえ、何年も前に初めてのPythonで勉強した後は、稀に使うくらいだったのでPythonならではの良い書き方とか、良いライブラリの知見とかは全然持ってなかった。

そこで、Pythonに入門しなおしてPython流を思い出した後、自分が気になっているWeb開発をやってみてどういうもんなのかを一通りやってみた。

このエントリは、GoでWebアプリケーション作る練習をしたの続編です(さらに続きはないでしょう)。

入門 Python3 を読んだ

入門 Python 3

入門 Python 3

一通りの文法を思い出そうということでとりあえず読んでみた。他の言語を一通りやっていれば新しい概念はほとんどないのでサクサク読める。僕は3,4日くらいでだいたい目を通せた。

ざっと読んだことで、Pythonならではのリスト内包表記とか、関数デコレータの話題とかを思い出せることが出来てよかった。PythonってリテラルにSet型があるんだなーとか。

Pythonの文法の話題だけにとどまらず、テストやデータベースへのアクセス、HTTPクライアントやサーバ(WSGI)の話題について一通り教えてくれるのも良い。最近の本らしく、NoSQL(Redis)やメッセージングキュー(ZeroMQ)あたりの話題も取り上げられていた。各章に練習問題がついてるので実際に手を動かすこともできる。

はてなインターンの事前課題

はてなインターン参加者は、はてなオフィスにやってくるまでの予習として、事前課題というのをやることになっている。ちょっと古いけど公開されていて、Perl版とScala版がある。その課題をPythonで解いた。ソースコードの python-Intern-Exercise はこちら

この事前課題は、プログラムの基本的な書き方、ファイルI/O、テストなどを網羅しているので、同じ内容の課題をPerlやScala以外の言語でやると良い練習になっておすすめ。ちょっと前に id:shiba_yu36 さんがやっていた、 Java版はこちら

Webアプリケーションの実装

さらに練習として、PythonでWebアプリケーションを作ってみることにした。あれこれ調べながら、自分がよくやるスタイルでWebアプリケーションを書くとどういう感じになるかを調べてみた。

github.com

結論としては、Pythonでどういう書き方をすると良いのかとか、どのライブラリを使うのかといったことを調べるのには時間がかかったものの、それさえわかれば、だいたいやりたいことはできるということがわかった。

普段はPerlを使っているのだけど、Perlで使っているテクニックやライブラリはだいたい対応するものがあって同じやり方が通用する感じ。例えば、テストの感じとかは、いつも書いているPerlのコードに近いインターフェースのサポート関数を利用できるようにできた。

もしかすると何かの参考になるかもしれないので、実装の方針を紹介しておいてみる。

PerlでWebアプリケーションを作るときにもよくやっている、薄いフレームワークの上になるべくシンプルにアプリケーションを構築するという方針でつくっている。複雑なしくみは使わず見通しの良さを重視してる。使っているライブラリは最低限で以下の様な感じ。

  • Webフレームワーク: Flask
  • データベース: ORMは使わずに mysqlclient をそのまま利用
  • テスト: nose (追記: 識者によると今開発止まってるのであんまり使わないほうがいいらしかった!)

ファイルツリーは以下のような感じになっていて、それぞれの役割も書いた。

.
├── db/
│   └── schema.sql
├── hakoblog/
│   ├── config.py  # アプリケーション設定用のクラス定義
│   ├── model/     # アプリケーションのモデル定義(BlogやEntryなど)
│   ├── loader/    # モデルオブジェクトをデータベースから取得するクラスが入ってる
│   ├── action/    # アプリケーションに対して破壊的な操作を行うクラスが入ってる
│   ├── db.py      # データベース接続を抽象化したクラスの定義
│   └── web.py     # Webアプリケーションのルーティングとコントローラ
│   ├── templates/ # HTMLテンプレート
└── tests

ORMは使わないので、modelの定義は単純なPythonのクラスになっている(例: Entryクラス)。

モデルオブジェクトをデータベースから取得するにはloader内で定義されたクラスを使う。クラスはただのネームスペースで、クラスメソッドとして処理を定義する。例えば、UserLoaderは以下のような雰囲気になる。

from hakoblog.model.user import User


class UserLoader():
    @classmethod
    def find_by_name(cls, db, name):
        with db.cursor() as cursor:
            cursor.execute(
                '''
                SELECT id, name
                FROM user
                WHERE name = %s
                LIMIT 1
                ''',
                (name, )
            )
            row = cursor.fetchone()

            if row is None:
                return None

        return User(**row)

SQL内に%sが出て来るのでドキッとするけど、これでちゃんとplaceholderになっている(mysqlclientの仕様で%sを使う)。

破壊的な操作をするときはactionに同様のクラスを定義することに、ざっくり責任をわけておく。こうすることでデータを読み込みつつ破壊的な操作を定義しにくくなる狙いがあったりする。

db.pyはDBクラスが定義してあってmysqlclientライブラリを薄くラップしてある。接続のための設定を読み込んだり、ちょっとしたユーティリティ関数(例: uuid_short関数)を定義するのに便利。

web.pyでは、HTTPのルーティングとコントローラを定義してある。アプリケーションのエントリポイントはここになる。

実装を試すのが主目的なので実用性はまったくない。記事書いたり記事を読んだりはできるけど、ユーザ認証などはないし、スタイルも書いてなくてみためは限界に近くしょぼい。

感想

ちょっとPythonに入門したあと、あれこれ調べながらPythonでWebアプリを0から書いてみた。

当然、普通にWebアプリケーションは書けるわけだけど、Perlでいつもよく使う設計スタイルも無理なく採用することができることがわかったのは良かった。コードを書いてみると、標語*1のとおりで、一つのことをやるやり方がだいたい決まっているので、迷わずにどんどん書き進められるのは心地よかった。

あんまり凝ったことをしない文化っぽいけど、必要になったらやっていくという感じがあるのもなんとなくわかってきた。例えば、テストのために時間をとめるライブラリ(freezegun)とかはちゃんとあったりして、柔軟性も大事にされていそう。

スクリプト言語としてなかなか良いバランスだし、Web開発がうまくできそうなことも体験できた。そうでなくても、機械学習やデータサイエンス分野で勢いのある言語だと思うので、もうちょっと練習して使えるようにしておいても良さそう。

*1:There should be one-- and preferably only one --obvious way to do it.

無線機を購入した

9月ごろに第一級アマチュア無線技士の資格を取得したのだけど、今の今まで無線機を持ってなかった。資格を取ったのが引越をした直後のお金を使いまくっていた時期だったので、しばらく高価なものを買う気になれなかった...。

引越後の生活も落ち着き、せっかく資格をとったのだからちゃんと実際の電波の送受信をやってみたいという気持ちも復活してきたので、ついに昨日、自分へのクリスマスプレゼントとして無線機を購入した。

購入したのは 八重洲無線のFT-817NDという機種。

自分の家の電波の状況は今のところわからないので、最悪まったく電波が受信できないない可能性がある。なので、まずは移動運用できる機種にしておいて、最悪電波が受信できなくても、野外の広いところにいって使うという選択肢を残して起きたかった。また、技術的にもコミュニティの層的にもおもしろいと聞く、HF帯に出れる機種にはしたかった。

この条件に見合う機種はほとんどなくて、購入したお店の人によると今回買ったFT-817NDくらいとのこと。自分で調べたところだとKX3も候補にあげられるのだけど、こっちは高価だし、技適に通ってないので開局の手続きのハードルが高そうであったのでやめておいた。

前に一度覗いたアマチュア無線の専門店に出向いて、FT-817NDほしいんですと言うとお店のおじさんがおすすめのアンテナなんかも教えてくれて、あれこれ一式をスムーズに購入できた。結構値引きもしていただいて、古き良き電化製品購入プロセスの体験をしてきたという感じ。

購入しただけではまだ自由に使うことはできなくて、無線機から電波を出すには、総務省に無線局の開局の申請をして免許される必要がある。手続きも時間がかかるのでのんびり取り組んでみようと思ってる。気の長い感じだけど趣味としてはじっくり楽しめて良いと思う。

第一電波工業 ダイヤモンド  7-50MHz帯ポータブル無線機用ハンディアンテナ コネクターBNC-P RHM8B

第一電波工業 ダイヤモンド 7-50MHz帯ポータブル無線機用ハンディアンテナ コネクターBNC-P RHM8B

次に何を勉強するかを決めるための作戦

Webエンジニアが学ぶべき技術範囲はとても広く、いったい何をどこから勉強していくかは難しい問題です。僕も試行錯誤を繰り返しています。

そんな試行錯誤の中で、新しく何を勉強するか決めるときに使ってる作戦がいくつかありそうだなと思うようになりました。そこでこの記事では、僕が次に勉強すべきテーマに困ったときに使っている作戦を紹介してみようと思います。

各作戦の例のコーナーでは実際に僕がその作戦を使って勉強したトピックなどを紹介しています。

このエントリは、はてなエンジニアアドベントカレンダー2016の20日目の記事で、担当はid:hakobe932です。昨日の担当は id:masayoshi さんでLinuxのARPとL2スイッチのお話という記事でした。

作戦1: 新しいプログラミング言語を学ぶ

新しいプログラミング言語を学ぶのは、比較的手を出しやすい作戦です。プログラミング言語を学ぶことで自分が使えるプログラミング言語が増えるのはもちろんですが、これまでとは違ったプログラムの捉え方や考え方も学ぶことができます。

また、プログラミング言語を学ぶ過程で様々な技術をつまみ食いできるのがお得なポイントです。例えば、ファイルの扱い方、プロセスやスレッド、ネットワーク、正規表現、リストや辞書などのデータ構造などの話題は言語の入門本にはよく登場します。詳細に学ぶことはできませんが、とっかかりには悪くありません。複数の言語を学ぶことで、これらの技術を多様な角度から学ぶこともできます。

勉強用の資料には分量が多くて詳しく書いてありそうなものを選ぶのがおすすめです。著者が言語の作者やそれに準ずる人である資料であればなお良いと思います。そのほうが表面的な文法や使い方だけでない考え方や背景についても教えてくれますし、いろんな技術がつまみ食いできます。

例: Scalaスケーラブルプログラミング第3版 / すごいErlangゆかいに学ぼう! / 初めてのPerl 第6版 / 続・初めてのPerl 改訂第2版 / すごいHaskellたのしく学ぼう! など

Scalaスケーラブルプログラミング第3版

Scalaスケーラブルプログラミング第3版

  • 作者: Martin Odersky,Lex Spoon,Bill Venners,長尾高弘,羽生田栄一,水島宏太
  • 出版社/メーカー: インプレス
  • 発売日: 2016/09/20
  • メディア: Kindle版
  • この商品を含むブログを見る

Dave Thomas先生も一年に一個は新しい言語を学ぶべしとおっしゃってるので、丁度良いんではないでしょうか。この作戦ではいろんな技術をつまみ食いできるのが良いのですがつまみ食いでは満足できなくなってきたら作戦2に移りましょう。

作戦2: 計算機科学分野からテーマを選んで勉強する

計算機科学の分野にあげられるような比較的基礎的な技術を学ぶという作戦です。計算機科学の分野といっても幅広いですが、Webエンジニアに関係が深いのは例えば、OSやネットワークの仕組み、アルゴリズムや、計算理論、ソフトウェア設計、並行プログラミング、データベースなどでしょうか。計算機科学の分野はWikipediaにざっくり載っているので、これを眺めたりしてもいいかもしれません。この中から必要性や自分の興味のバランスで分野を選びましょう。得意分野から攻めていくとモチベーションが続きやすい気がします。

一度勉強すれば長く役立つ、基礎的な技術を学ぶのが目的です。特定のソフトウェアやライブラリの使い方のような知識はある瞬間はとても役立ちますが、ライブラリのバージョンが変化してしまったり、そのライブラリが廃れてしまうと役に立たなくなります。「寿命が長い技術」を学ぶのが費用対効果が良い作戦です*1

本を探すときには、自分の得意分野ではちょっとがんばって一番分厚いバイブル的な本を読むと効率が良いと思います。不慣れな分野では、近くのひとに聞いたりインターネットを探したりして、がんばって良い入門書を見つけましょう。

例: オブジェクト指向入門 / エリック・エヴァンスのドメイン駆動設計 / アルゴリズムイントロダクション / プログラミング言語の基礎概念 / スクリプト言語の作り方 / Java並行処理プログラミング / アジャイルサムライ / データベース技術実践入門 / マスタリングTCP/IP 入門編 第5版 など

オブジェクト指向入門 第2版 原則・コンセプト (IT Architect’Archive クラシックモダン・コンピューティング)

オブジェクト指向入門 第2版 原則・コンセプト (IT Architect’Archive クラシックモダン・コンピューティング)

さらなる基礎を抑えるという意味で、数学の復習をしてみたりも良いでしょうが、深みにハマっていくときりはなさそうです。

作戦3: お隣の分野に入門する

自分の専門ではないけれど、近い領域で役立ちそうな技術を見繕って勉強してみるという作戦です。僕の場合は、機械学習や電子工学といった技術は今すぐには必要になってはいませんが、そのうち役立つだろうと、ちょっと入門してみたりします。最近はこの作戦3を使っていることが多いです。

例: 機械学習 / 電子工学 / など

ちょっと別の話題として、作戦1や作戦2を繰り返していると、徐々に自分がもっている知識が増えてきて学習曲線が緩やかになってきます。それ自体は結構なことですが、やっぱり勉強をはじめたところの、高速に成長してる感覚を取り戻したくなるときがあります。そういうときは作戦3で勉強ネタを選ぶと、成長している感が得られて楽しかったりします(ちょっと逃避っぽい側面ですが)。

番外編: 自分がやりたい仕事ができそうな技術を学ぶ

純粋に技術的ではないですが、ある意味王道の作戦です。おもしろい仕事ができそうな技術を学びます。

技術をもっていないとその技術を使う仕事ができませんから、当然学ぶ必要があります。加えて、自分が勉強しているトピックというのものは、なんだかんだで会社の人にも見られていますから、その技術に関係ある仕事を任せられる可能性があったりなかったりするかもしれません。

高難易度の技としてはイケてる技術学んで、その技術を使った仕事を自分で作りだすというやりかたもありそうです。これはできたらかっこいいですね。

まとめ

僕が新しく何を学ぶかを決めるときに使っている作戦を紹介しました。勉強し続けるモチベーションを維持するには、常に勉強したいことをストックしておくのも大事です。Webエンジニアとして勉強をしていく上で、このエントリで紹介した作戦が何かの役にたてばうれしいです。

明日のアドベントカレンダーは id:syou6162 さんです!

*1:このあたりはid:stanakaさんの受け売りです

AtomからPerlのテストを直接実行するくん

チームで流行ってるので最近はAtomを使ってる。普段仕事ではPerl書くのでAtom上からテストをサクッと実行できるくんを作った。

atom.io

既存のscriptの拡張として動作する。本家のscriptでもPerlのファイルの実行はできるけど、以下のような点で便利に使えるようになっている。

  • carton exec -- proveしてくれる
  • カーソルがある位置が含まれている Test::Class 形式のテストケースを個別に実行できる

手元だけで使ってたんだけど、最近 hitode くんにも使ってもらって、ちゃんと動いてそうということが判明したので、apmにあげた。どうぞご利用ください。そこそこ雑。

このときにscriptの不具合発見してdiff 1byteのPullRequestに成功して笑顔です。