歩いたら休め

If the implementation is easy to explain, it may be a good idea.

【Python】仕事の依存関係を有向非巡回グラフ(Directed acyclic graph)として整理するツールを作りました

特にデータ分析周りの仕事で、

  • 「プログラムを書く」前に「設計」と「プログラミング言語の選定」が必要
  • プログラミング言語の選定」の前に「設計」が必要
  • 「設計」の前に「稟議を出す」「個人情報についての取扱を調べる」が必要

といったような、タスクの依存関係がひどくて整理のつかない状態に陥ってしまいがちなため、それを解消するために作ったツールです。

集合・位相入門の半順序集合の章を読んでいるときに思いつきました。 元々は、Haskellの練習として、Ord型クラスで半順序集合を表現するようなコードを書いていましたが、グラフの扱いが慣れた言語でないと案外難しかった(また、冗談みたいですがYamlのパース方法が分からなかった)のでPythonで書きました。

↑のようなタスクの依存関係をひたすら以下のようなyamlファイルに書き出して、

# tasks.yml
- name: write product code
  deps:
    - fix design
    - choose programing language
    - request for budget(ringi)
    - make a mock-up
- name: choose programing language
- name: request for budget(ringi)
    - talk to legal department
- name: talk to legal department
- name: releace
  deps:
    - write product code
    - code review
- name: code review
    - write product code
- name: make a mock-up
  deps:
    - choose programming language

コマンドを実行すれば、

# save as NetworkX graph
ordmap tasks.yml tasks.png

# save as pajek format
# see also https://networkx.github.io/documentation/networkx-1.9/reference/readwrite.html
ordmap tasks.yml tasks.net --save_as pajek

以下のような図や有向グラフを表したファイルが出力されます。

f:id:takeshi0406:20170625224803p:plain

*vertices 8
1 "write product code" 0.0 0.0 ellipse
2 "fix design" 0.0 0.0 ellipse
3 "choose programing language" 0.0 0.0 ellipse
4 "request for budget(ringi)" 0.0 0.0 ellipse
5 "make a mock-up" 0.0 0.0 ellipse
6 releace 0.0 0.0 ellipse
7 "code review" 0.0 0.0 ellipse
8 "choose programming language" 0.0 0.0 ellipse
*arcs
1 2 1.0
1 3 1.0
1 4 1.0
1 5 1.0
5 8 1.0
6 1 1.0
6 7 1.0

「このタスクの前にこのタスク」という関係を枝で繋いでいるだけではなく、「Cの前にB」「Bの前にA」「Cの前にA」という関係のときに「A→B→C」という関係まで簡略化されます(A→Cの枝が省略されます)。要するに、半順序集合のハッセ図をプロットしています。

この作業をtransitive reduction(推移簡約)というそうです。Pythonグラフ理論を扱うライブラリのNetworkXでは開発中のver2.0に実装されていたので、それを参考に実装しました。

また、NetworkX(と裏で動いているmatplotlib)でUTF-8をプロットする方法が案外面倒なようなので、いまのところ日本語を入れると文字化けするし、ハッセ図をそれなりによくプロットする方法が分からなかったので図示はかなり酷いと思います。

ただ、うまくいけば分析基盤周りのバッチ処理(このデータの前にこのデータを用意しなきゃいけないとかややこしいですよね?)を整理する際も、同じような発想でできるんじゃないかなと妄想しています。もうあるのかもしれないですけど。

github.com

順序集合(Ord型)で仕事のロードマップ(Loadmap)を作るという意味でordmapという名前にしたのですが、Haskellじゃなくなったので微妙かもしれません。