MATLABでポモドーロタイマーを作ってみた
はじめに
私は制御工学の研究者です。あるとき気づきました。一番制御できていないのは自分自身であることを。
作業時間管理の有名な方法の一つとしてポモドーロテクニックというものが知られています。簡単にご説明しますと、作業時間を区切って適度に休憩を取ることで作業効率を上げようというものです。この時間の管理に使われるツールをポモドーロタイマーといいます。
この読者であられる皆様方におきましては、MATLABを常に起動されていると思われますので、このポモドーロタイマーをコマンド一つで起動できるようにしておきましょう。
仕様
ポモドーロテクニックとは作業時間を区切って適度に休憩を取ることで作業効率を上げる方法です。
概念としては以下のように作業時間と休憩時間を繰り返します。
ポモドーロテクニックの説明をWikipediaから引用します[1]。
具体的な手順は以下の通りである。
- 達成しようとするタスクを選ぶ
- キッチンタイマーで25分を設定する
- タイマーが鳴るまでタスクに集中する
- 少し休憩する(5分程度)
- ステップ2 - 4を4回繰り返したら、少し長めに休憩する(15分 - 30分)
また注意として以下も記載されております。
注意点
- ポモドーロ(上図でいうとサイクルのこと)の途中で急用が入りタスクが中断された場合は、そのポモドーロは終了とみなし、はじめから新しいポモドーロを開始する。
- 25分間の作業の中では、一つの作業に没頭する。
- タイマーは音が鳴るものが良い。音が鳴らないタイマーだと、常にタイマーに注意を払う必要があり、集中の妨げとなる。
ここから、時間の一時停止などの機能を省略してよいことと、アラーム音が鳴らせると良いことが読み取れます。
インストール
MATLABのホームタブのアドオン(Add-Ons)からAdd-On Explorerを開いてください。pomodoro-timer
と検索していただけますと引っかかると思いますのでAdd
-> Add to MATLAB
の順にクリックすれば完了です。
もしAdd-On Explorerが使えない場合には、File Exchangeから直接ダウンロードしてください。
アンインストールしたい場合には、コマンドパレットに以下のコマンドを入力してください。
matlab.addons.uninstall("pomodoro timer");
実行
MATLABのコマンドウィンドウで以下のコマンドを入力してください。
pomodoroTimer
起動するとまずは25分のタイマーがスタートします。作業を始めましょう。
タイマースタート時にはゴングの音がなります。
25分のタイマーが終わると、ピヨピヨという音とともに5分のタイマーがスタートします。短い休憩を取りましょう。
5分のタイマーが終わると25分タイマーに戻ります。
特殊なケースとして4回目の25分のタイマーが終わると、ハレルヤとともに30分のタイマーがスタートします。長い休憩を取りましょう。
30分のタイマーが終わった場合も25分タイマーに戻ります。
以上が繰り返されます。
実装
ソースコードはGitHubで公開しております。
以下では、その実装の詳細を解説していきます。
状態管理に構造体を使う
ポモドーロタイマーは「作業中」「短い休憩」「長い休憩」の3つの状態を持ちます。また、それぞれの状態は「状態名」「設定時間」「画面の色」「アラーム音」の情報を持つため、それらを構造体で管理することで可読性の高いコードとなります。
現在の状態はcurrentStatus
という変数で保持します。状態の切り替わり先の状態は、現在の状態currentStatus.Name
と現在のサイクル数currentCycle
に応じて決まります。
状態の切り替わりの際に行われる共通の動作をcurrentStatus
に対して行う形でまとめることが可能です。
このswitchStatus
関数の続きは以下のとおりです。
switchStatus
関数は、現在のタイマーの値が0になる度に呼び出されます。残り時間がある場合には時刻の表示を更新します。
時間の取り扱い
つぎに、updataTimer
関数の呼び出しと残り時間の計算について説明します。timer
を用いて、1秒に1回画面の時刻を書き換える処理を実装しました。
この設定を行うことで、一定時間(1秒)おきにupdateTimer
関数が動作します。
updateTimer
で最初に行う残り時間の計算ですが、MATLABの変数型としてdatetime
とduration
があることに注意が必要です。
datetime
はある一点の時刻を格納する変数の型であり、duration
は時間の間隔を格納する変数の型です。MathWorksが提供するdurationのドキュメントページの説明がわかりやすいです。
durationのドキュメントページより
初期設定としてタイマーがスタートした時刻を基準時刻と定義してbaseTime
にdatetime
として格納しておきます。また、各状態が継続する時間を設定時間と定義してwork.duration
などにduration
として格納しておきます。
以上を踏まえて、残り時間の計算は以下のように計算しています。
remainingTime = currentStatus.duration - (datetime("now") - baseTime);
% 残り時間 = 現在状態の設定時間 - (現在時刻 - 基準時刻)
ここで、
- 残り時間
remainingTime
はduration
。 - 現在の状態の設定時間
currentStatus.duration
はduration
。 - 現在時刻
datetime("now")
はdatetime
。 - 基準時刻
baseTime
はdatetime
。
となります。
感覚的には当たり前ですが型の概念から混乱しそうな点として、datetime
の和や差はduration
の型になるということにご留意ください。
timer
はバックグラウンドで実行されておりますので、timer
を止める前にこのプログラムを終了してしまうと、変数にアクセスできなくなることから、
Error while evaluating TimerFcn for timer 'timer-1'
というエラーメッセージが出てしまいます。
Figureを閉じる際にtimerを停止してから終了するように、コールバック関数で終了時の動作を拡張しました。
表示について
一般的なfigure
ではなくuifigure
とuilabel
を使用しました。上記のcloseRequest
関数の紐付けも、timer
のときと類似の書き方です。
uifigure
の良い点としては、デフォルトでメニューバーやナンバータイトルなどがないためスッキリとした見た目であることと、figure
と別管理がされているため、本筋の開発でclose all
などをしてしまっても閉じることがありません。
イマイチな点としては、uifigure
が表示されるまでの時間がfigure
に比べると若干遅い(3秒くらい?かかる)ことです。MathWorks様の今後のアップデートに期待しております。
サイズの指定はマジックナンバーとなってしまいましたが、3桁の分数まで表示されることを想定して"000:00"という表示がされたときに収まるように、フォントサイズをfigureサイズの「横幅の0.3倍」または「縦の高さの0.7倍」の小さい方に合わせて適当に調整しました。
この処理がupdateTimer
関数の中にあることにより、動作中にウィンドウサイズをドラッグなどで変更されても表示が崩れないように制御されます。
アラーム音
MATLABで音を出すことはsound
関数を使えば簡単です。
一例をあげると
として、currentStatus = work
であったとすると、
これでゴングの音を鳴らせます。
今回は、アラーム音を途中で止めることはなく単発を垂れ流しますが、より柔軟に制御したい場合にはaudioplayer
関数を使用するとよいでしょう。
MATLABに標準搭載されている音の種類ですが、上記らの関数のドキュメントには記載されておりませんが、以下のページを見るとchirp
, gong
, handel
, laughter
, splat
, train
の6つオーディオファイルが存在していることがわかります。
引数
25分作業5分休憩のポモドーロテクニックに類似したものとして、作業時間と休憩時間を52分と17分とする52/17ルールと言うものもあるようです。
いずれにしても時間を設定できた方が嬉しい人も多そうということで、MATLAB関数のオプション引数を設定しました。
後で説明しますが通常の引数Cycles
に加えて、options
という構造体引数を設定します。
これにより、options
の要素の引数はコマンドウィンドウやエディターウィンドウで補完が効くようになります。
また以下で、引数のデフォルト値とスカラー値かつ正の整数で来ているかもチェックも記述していきます。
引数なしで実行した場合にはここで定義された値で実行され、引数ありで実行された場合には誤った引数を入れるとエラーとして弾いてくれるため、とても便利です。
options
引数の与え方は、plot
やfigure
などと同じようにpomodoroTimer(引数名, 値, ...)
で実行する形となります。具体例は以下の通りです。
pomodoroTimer("WorkTime", 52, "ShortBreakTime", 17)
つぎにCycles
という引数ですが、こちらは作業と休憩を何サイクル繰り返したら長い休憩をとるかという値も引数として設定したものです。これは通常引数であるため
pomodoroTimer(3)
のような実行のさせ方をします。options
引数と組み合わせることも可能です。
pomodoroTimer(3, "WorkTime", 52, "ShortBreakTime", 17, "LongBreakTime", 60)
まとめ
ポモドーロテクニックを使うことで、作業時間を制御、もとい自分自身が制御されることができるでしょう。ポモドーロテクニックは強力な方法ではありますが、作業内容や人によって向き不向きがあるため、適材適所に取り入れていただければと思います。一方でマトラーボテクニックは、研究・開発・MATLAB芸のためになんぼあっても困りませんので、ぜひ体得してください。皆様の今後の作品に期待しております。
- MATLABで動くポモドーロタイマーで自分の作業を制御しよう。
- 構造体を活用しましょう。
- timerを使うときには注意が必要。
-
uifigure
でGUIを作ってみよう。 - 音を出すのは簡単です。
- 引数定義は便利です。
参考
類似でよりシンプルなものを作られている先駆者が居られましたのでご紹介します。コールバック関数周りコードを参考にさせていただき、非常にスッキリ書き直すことができました。
Discussion