退職と入社

8年ほど勤務した株式会社ビープラウドを退職しました。

11月から株式会社オープンコレクターに入社します。 www.open-c.jp オープンコレクターという会社は、もりよしが代表で1人の組織でしたが、私とあおだぐが新しく加わって3人になります。

開発や技術支援の案件あればご相談ください。

Pythonでファイルディスクリプタをサブプロセスに渡す

Pythonのsubprocessモジュールでサブプロセスを実行するときに、親プロセス側で開いたファイルのファイルディスクリプタを渡す方法。

subprocess.Popenのpass_fds引数を指定すると、指定したファイルディスクリプタは閉じられないようだ。

試したPythonのバージョンは3.5。

コード

send_fd.py:

import sys
import subprocess

# ファイルを開く(readで全部読まれるのを避けるのでバッファをOFFにしとく)
input_file = open('spam.txt', 'rb', buffering=0)
# ファイルディスクリプタを取得
fd = input_file.fileno()
# 5バイト読む
print('send_fd: ', input_file.read(5))
# receive_fd.pyに引数でFDを渡して子プロセスとして実行
process = subprocess.Popen(
    [sys.executable, 'receive_fd.py', str(fd)],
    pass_fds=[fd])
# プロセスが終了するまで待つ
process.wait()
# ファイルを閉じる
input_file.close()
print('end')

receive_fd.py:

import os
import sys

# 引数で渡されたFDを取得
fd = int(sys.argv[1])
# FDからファイルオブジェクトを作る
input_file = os.fdopen(fd, 'rb')
# 最後まで読み込んで表示
print('receive_fd: ', input_file.read())
# ファイルを閉じる
input_file.close()

spam.txt:

Hello World!

実行結果

tokibito@ubuntu:~/sandbox$ python3.5 send_fd.py
send_fd:  b'Hello'
receive_fd:  b' World!\n'
end

親プロセス側で5バイト読んで、子プロセス側で残りを読んでいる。

参考

PyConJP 2016に参加しました

PyConJP 2016に参加してきました。 スピーカーとして、トーク1つ、ビギナーセッション1つ、オープンスペース2枠で話してきました。

ビギナーセッション(コードリーディング)

ビギナーセッションは、講師の応募がなかったそうで、お願いされたのを引き受けて話しました。

www.slideshare.net os.path、this、antigravityモジュールのコードを読んでみましょう、というものです。

Pythonコードの追いかけ方、pdbの使い方について話しました。 資料は6ページしかないですが、画面上で実際に操作しながら説明しました。

Pythonでpyftpdlibを使ってFTPサーバーを作る際に使ったテクニックの紹介 (トーク)

CfPを出して採用されたので話しました。

www.slideshare.net GitHub - tokibito/soloftpd: FTP server application. www.youtube.com

PythonでGitリポジトリをゴニョゴニョ (オープンスペース1日目)

オープンスペースは、1日目の午後の時点では、2日目の枠が半分ほど埋まっていたのですが、1日目はスカスカでした。

なにかやろうと思い、過去にブログに書いたネタを引っ張り出してきてやってました。

dulwichモジュールでgitリポジトリを読んでみたり、それをgitのサブコマンド化したりしてました。 tokibito.hatenablog.com

socketモジュールでHello, world! (オープンスペース2日目)

2日目でもオープンスペースの枠が埋まりきっておらず、空いてたので話しました。

今回はネットワーク周りの初心者向けのセッションはなかった?みたいだったので、socketでHello, world!でもやってみようと思い、話してました。

PythonのsocketモジュールでHello, world! · GitHub

こちらは5,6人ほど来てくれて盛り上がってました。

サーバーを起動してngrokを使ってインターネットからアクセスできるようにし、参加者からメッセージを投稿してもらったりしていました。 コードを変更して、HTTPのレスポンスを返すようにしてみたりもしました。

感想

  • 今回も他の人のトークはあまり聞いておらず、休憩スペースで駄弁ったりしていました。じっと座って聞くのは疲れてしまうので、自分にはこれが合ってる感じです。
  • 気になっていたトークはYouTubeにアップされてる動画を見ようと思います。動画がアップされてるのありがたい。
  • 何年かぶりに会えた方もいたので、とてもよかった。
  • 今回、朝ごはんがあったのは、結構嬉しかった。毎度のことながら、あのチケット価格で飲み食い全部込みということなので、かなり安いと思います。
  • オープンスペースは少人数で気軽に話せたりするので、次回のPyConJPでもあれば、何かしようと思います。
  • 楽しかった。来年もできれば参加したいと思います。

システムやアプリケーションの要件定義、設計から実装、完成まで

はじめに

普段システムやアプリケーションを作るのに、どういう手順でやるっけかなーというのを書き出してみた、というものです。

必ずしもこの通りにすればうまくいく、というものではなく、一例だと考えてください。

流れ

大雑把に次のような流れになります。

  1. 何をしたいのか、まとめる(企画、要件定義)
  2. 要件を満たすシステムの入力や出力の詳細、データの流れやシステムの処理をまとめる(仕様策定)
  3. 要件、仕様をどうやって実現するのか考えてまとめる(設計)
  4. 設計に対応する実装をする、システムを構築する(実装)
  5. 実装、構築して出来上がったものが、要件や仕様を満たしているか確認する(試験)
  6. 完成

各工程で、アウトプットしたものを後工程で使ったりします。

1. 何をしたいのか、まとめる(企画、要件定義)

f:id:nullpobug:20160731235726p:plain

システムやアプリケーションに限らないですが、そもそも何をするのか決めていないと、始まらないので、やりたいことをまとめます。

システムが解決したい課題は何か、文章や図でまとめます。

次のようなことを書き出してみればいいです:

  • どういう背景(ストーリー)があってシステムを作るのか
    • システムが無い場合、どような課題があるのか
    • 既存の作業や仕組みを置き換えるのであれば、その流れ
    • 誰がシステムを使うのか
  • システムでは何をするのか
    • 課題のうち、システムが扱う範囲、扱わない範囲
    • システムに入力されるデータは何か
      • 人間の操作、外部のデータ、システムによって取得されるデータ
  • システムはどのぐらいの性能が必要か(性能要件)
    • 利用者の数(延べ人数、同時に操作する人数など)
    • 扱うデータ量(入出力のデータ量、保存するデータ量)
    • システムの処理時間(入力から出力までの時間、画面の応答速度)
  • システムはどのような環境で動作させるか(動作環境の制限、要件)
    • 特定のハードウェアやクラウド、プラットフォームを使わないといけないなどの制約はあるか

この工程でのアウトプット:

  • 企画書、要件定義書などに相当する資料(読んだら何をしたいのかがわかる資料)

ポイント:

  • 長い文章よりも、箇条書きで整理されたものがわかりやすい
  • 文章だけではなく、図もあるとわかりやすい
  • 具体的な画面のイメージや処理の流れがあるなら絵を書いておくとよい
  • やりたいことがまとまらない、という場合、課題がはっきりしていない可能性があります。現状何が問題なのか、整理するとよさそう。

2. 要件を満たすシステムの入力や出力の詳細、データの流れやシステムの処理をまとめる(仕様策定)

f:id:nullpobug:20160731235723p:plain

前工程で何をしたいのかを明らかにしたので、システムが扱う部分をもう少し具体的にします。

次のようなことを書き出してみればいいです:

  • システムを機能毎に分けたもの
    • 入力、出力、処理など
    • 機能数が多い場合は大中小などのまとまりを作って、ツリー状にして整理するとわかりやすい
      • 最上位階層が10~20程度になる場合は、やりたいことが多すぎるので、サブシステム化(別のシステムに分割して、システム間で連携させる)も検討したほうがよい
  • 入出力されるデータのフォーマット
    • 各機能毎の入力と出力
      • 外部のデータを取り込むor送信する、ファイルを読み込むor書き込む、データベースを読み込むor書き込む など
    • 利用者の具体的な操作(何を使って、どのように操作するのか)
    • 画面上の入出力

この工程でのアウトプット:

  • 仕様書に相当する資料(各機能と入出力がわかる資料)

ポイント:

  • 箇条書きを使って、できるだけ簡潔に説明する。仕様が複雑だと後の工程が大変です。

3. 要件、仕様をどうやって実現するのか考えてまとめる(設計)

f:id:nullpobug:20160731235725p:plain

前工程で機能と入出力を明らかにしたので、この工程では具体的にどうやって作るのかを考えます。

機能、入出力をつないで、1つのシステムとして整合性のとれた状態にする必要があります。

次のようなことを書き出してみればいいです:

この工程でのアウトプット:

  • 設計書に相当する資料(各機能毎に、入力から出力までの間に何をするのか、どのように構築するのか、がわかる資料)

ポイント:

  • 箇条書きや図を使って説明する。
  • 実装や構築が困難な設計を避ける(後の工程が大変になります)
    • 必要以上に複雑にしない(要件を満たす以上のことは、実装が終わってから余力でやるぐらいのほうがいい)
  • 実装に着手するには、すべての機能の設計が終わってないとダメ、ということはないです。並行作業で進められることもあります。
    • しかし、並行作業で進めると、「実装中の機能に設計変更が必要になった」というのもよくある話です。システム全体の整合性のためにも、設計は早めに終わらせといたほうがよさそうです。

4. 設計に対応する実装をする、システムを構築する(実装)

f:id:nullpobug:20160731235722p:plain

前工程の設計に従い、システムの実装、構築をします。

設計が適切であれば、実装は楽に進められます。

この工程でのアウトプット:

  • 必要な機能が実装されたシステム

ポイント:

  • 設計や仕様に不備がある場合は、設計、仕様にフィードバックしつつ、実装を進めていくとよさそうです。

5. 実装、構築して出来上がったものが、要件や仕様を満たしているか確認する(試験)

f:id:nullpobug:20160731235724p:plain

実装が終わったら、最後に要件や仕様を満たしているのか、確認(試験)をします。

試験の方法は、要件と仕様を元に、試験項目書を作ってテストしたり、ざっくり動かしてみて問題なかったらOKとしたり、プロジェクト毎に異なります。

試験の結果、問題がある場合は修正して再試験します。問題がなければこの工程は終了します。

この工程でのアウトプット:

  • 試験結果
    • 問題の有無(要件や仕様に沿ってない場合は問題がある。)
  • 問題を修正したシステム

ポイント:

  • 試験項目書をつくる場合は、試験項目書に記入した結果がアウトプットとなる
  • 問題が致命的かそうではないか、などカテゴリ分けすると、わかりやすい

6. 完成

f:id:nullpobug:20160731235727p:plain

試験が完了したら、システムは完成となります。

必要であれば利用者向けのドキュメントを作成したり、納品物にまとめたりします。

まとめ

企画、要件定義→仕様策定→設計→実装→試験、という流れになります。

書いてから思ったけど、ウォーターフォール・モデルですね、これ。

自分の中で、開発の手順を意識できていれば、次に何をすればいいのかわからず戸惑う、という状況は減るのではないかと思います。

記事中のイラストは、いらすとやのものを使ってます。

ngrokというサービスを使ってLAN内のサーバーに外部から接続する

ngrokはNATやファイヤーウォール以下にあるローカルサーバーを、インターネット越しにアクセス可能にしてくれるサービス。 便利だよと教えてもらったので、試してました。

ngrok.com

無料版の機能はアカウント登録等不要で、ngrokコマンドをダウンロードして実行すると、すぐに使えました。 ngrokコマンドは依存ライブラリ等なしの単一バイナリで、Windows, MacOSX, Linux用のものが配布されています。

公開したいサーバー

お試しなので、とりあえずPython3に組み込みのhttp.serverを使ってみます。

$ python3.5 -m http.server

カレントディレクトリにはindex.htmlを配置済み。これでlocalhostの8000番ポートでHTTPサーバーが起動します。 このサーバーをngrokで外部から接続できるようにしてみます。

ngrokの起動

localhostの8000番ポートをhttpで公開するのであれば次の通り。

$ ngrok http 8000

起動すると、ngrokのサービスのサーバーと、公開対象のサーバーにクライアントが接続し、「bf9fddc6.ngrok.io」のようにドメイン名が割り当てられます。 表示されたURLにWebブラウザ等で接続すると、対象のサーバー(この例だとPythonのhttp.server)につながります。

f:id:nullpobug:20160713221459p:plain

開発中のWebアプリなどを、ちょっと外部に見せたりするのに便利そうな感じですね。 有料プランだとカスタムのドメインを使えたりするそうなので、そのあたりも試してみたいところです。

参考

英語ドキュメントが整備されていて、使い方もわかりやすかったです。

https://ngrok.com/docs

ちなみに「えん-ぐろっく」と読むらしい

https://ngrok.com/faq#name

pipでPythonパッケージのソースアーカイブをダウンロードする

PyPIに登録されているPythonパッケージのソースコードをダウンロードする際、毎回PyPIのページを開くのが面倒だなーと思ってたのだけど、pipでダウンロードできた。

pip download --no-binary :all: --no-deps <package>

参考

Raspberry Pi 2 Model B でPythonを使ってLチカ

Raspberry Piを買ったのはかなり前だったりするんですが、放置してたのを動かしてみました。

とりあえずはLチカ

youtu.be

コード

main.py

from RPi import GPIO
import time


def main():
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(12, GPIO.OUT)
    try:
        state = True
        while True:
            GPIO.output(12, state)
            time.sleep(1)
            state = not state
    finally:
        GPIO.cleanup()

if __name__ == '__main__':
    main()

実行

$ sudo python main.py

参考