AT's Blog

趣味のプログラミング、ギター、音楽とかとか

とりあえずPythonで何か作ってみる「サイクルシステムを用いたタスク管理ツール」(1)

はじめに

勉強ばかりでアウトプット不足が否めないので、タイトルの通り一念発起してショボくてもいいから何か作ってみようと思います。 とりあえず、普段テキストエディタで行っているタスク管理をPythonでツール化してみます。 飽きっぽい性格なので、いつまで続くかわかりませんが、楽しんでコーディングしていきたいと思います。

サイクルシステム

新入社員の頃、残業が嫌でなんとか業務を効率化できないかと思っていました。 慢性的に人手不足の部署で、新人の私も即実戦投入でそれなりの量のタスクをこなさなければならなかったので、 タスク管理が課題でした。 そんなときに書店で見つけたのが、オライリーの「エンジニアのための時間管理術」です。

エンジニアのための時間管理術

エンジニアのための時間管理術

この本に「サイクルシステム」というタスク管理システムが紹介されています。 どういったシステムかというと、まずタスクをA・B・Cの3つにクラス分けします。

  • A : その日のうちに処理する必要があるタスク
  • B : 締め切りが近いがその日のうちに処理する必要はないタスク
  • C : とくに締め切りがないタスク

タスクの管理自体は、私はテキストエディタで行っています。

* [ ] [A] レビュー資料作成(2017/10/01)

こんな感じで、Markdown書式でチェックボックス、タスクのクラス、タスク名、期日の順で書き出していきます。

タスクがリストアップできたら、A>B>Cの優先順位で、タスクを処理するスケジュールを時間単位で決めていきます。 会社でグループウェアを運用しているのなら、自分のスケジュール欄にタスク処理を予定として突っ込んでしまうのがいいと思います。 会議の予定を入れようとする者に対する牽制の意味で(笑)

定時になって、Aクラスのタスクが全て片付いていたらさっさと退社しましょう! まあ、たいてい差し迫ったBクラスのタスクがたまっていて帰れないのですが…。

ここでは紹介しきれませんが、サイクルシステムをはじめ時間管理の具体的なノウハウがかかれていて面白いので、 興味がある方はご一読ください。 精神論や一般論ばかりのよくあるハウツー本と違って、エンジニア視点で書かれているので即役に立つ内容が多いと思います。

タスクのデータ構造を考えてJSON形式で表してみる

タスクを管理するデータ構造を考えていきます。

サイクルシステムにおいて、1つのタスクが持つ要素は以下になります。

  • タスクの内容
  • クラス(A・B・Cのいずれか)
  • 期日

とりあえず、Pythonの辞書を利用してタスクを表してみます。 辞書を利用するのは、タスクをJSON形式で管理していこうと考えているからです。

import datetime
task = {'task':u'牛乳を買う', 'class':'A', 'due':datetime.date(2017, 9, 23)}
print(task)
# {'task_name': '牛乳を買う', 'class': 'A', 'due': datetime.date(2017, 9, 23)}

期日はdateオブジェクトで表現します。1つのタスクは表現できたので、今度は複数のタスクをまとめていきます。

task1 = {'task':u'牛乳を買う', 'class':'A', 'due':datetime.date(2017, 9, 23)}
task2 = {'task':u'美容室を予約する', 'class':'B', 'due':datetime.date(2017, 9, 24)}
tasks = {'root':[task1, task2]}
print(tasks['root'])
# [{'task': '牛乳を買う', 'class': 'B', 'due': datetime.date(2017, 9, 23)}, {'task': '美容室を予約する', 'class': 'B', 'due': datetime.date(2017, 9, 24)}]

‘root'キーにタスクのリストを割り当てています。 後々、JSON形式でファイルを読み書きする際に、単純にタスクを並列にして保存できないためこうしています。

さて、作成したtasksをjson.dumps()でエンコードします。 しかし、そのままだとdateオブジェクトが原因でTypeErrorが発生しエンコードに失敗します。 そこで、json.dumps()でTypeErrorがraiseされた際の処理を規定する関数を別途定義してやります。

def json_serial(obj):
    if isinstance(obj, (datetime.date)):
        return obj.isoformat()
    raise TypeError ("Type %s not serializable" % type(obj))

作成したjson_serial()を、json.dumps()のdefault引数に指定してやります。

print(json.dumps(tasks, indent=4, default=json_serial))
"""
{
    "root": [
        {
            "task": "\u725b\u4e73\u3092\u8cb7\u3046",
            "class": "B",
            "due": "2017-09-23"
        },
        {
            "task": "\u7f8e\u5bb9\u5ba4\u3092\u4e88\u7d04\u3059\u308b",
            "class": "B",
            "due": "2017-09-24"
        }
    ]
}
"""

無事にエンコードできるようになりました。

今回はこの辺で。次はデコードと、ファイルへの読み書き周辺を実装していこうと思います。