micro:bitでポモドーロタイマーを作る

# はじめに
ポモドーロ・テクニックをご存知でしょうか。
25分間ひたすら集中して作業を行い、5分間の休憩を取った後にまた25分間集中・・・というのを繰り返しすことで、仕事効率を上げるテクニックです。
ポモドーロ・テクニックの実践にはタイマーが欠かせません。キッチン用の物理的なタイマーを使用したり、専用のアプリを使用したりするかと思います。
さて、手元のmicro:bitを眺めてみると、LEDが25個付いているではありませんか！
ということで、micro:bitでポモドーロタイマーを作ってみました。（Pythonで実装）

# 時間の計測方法
`running_time()` という関数が、デバイス起動後の経過時間（ミリ秒）を返してくれます。
ボタンクリック時の経過時間(t1)を退避しておけば、その時からの経過時間(t2)を計算することができます。

```Python
t2 = running_time() - t1
```

実際のソースコードからの抜粋です：

```Python
    def start(self):
        self.start_time = running_time()
    def seconds_elapsed(self):
        return (running_time() - self.start_time) // 1000
```

# 仕様
## 待受時
Aボタン：ポモドーロタイマー開始
Bボタン：計測時間を1分ずつ増やす（1-25分。デフォルトは25分）
## タイマー起動時
残り時間を点灯したLEDの数で知らせる。残り10秒を切ると数字でカウントダウン。
Bボタン：一時停止/再開
A+Bボタン：終了

# ソースコード
```Python:Pomodoro.py
from microbit import *

class Timer:
    def __init__(self, total_minutes):
        self.total_minutes = total_minutes
        self.is_paused = False
    def start(self):
        self.start_time = running_time()
    def pause(self):
        self.is_paused = True
        self.paused_time = running_time()
    def resume(self):
        period = running_time() - self.paused_time
        self.start_time = self.start_time + period
        self.is_paused = False
    def paused(self):
        return self.is_paused
    def done(self):
        return self.seconds_remaining() <= 0
    def seconds_elapsed(self):
        return (running_time() - self.start_time) // 1000
    def seconds_remaining(self):
        return self.total_minutes * 60 - self.seconds_elapsed()
    def minutes_elapsed(self):
        return self.seconds_elapsed() // 60
    def minutes_remaining(self):
        return self.total_minutes - self.minutes_elapsed()

class Displayer:
    PAUSED = Image("00000:09090:090909:090909:00000")
    def __init__(self, timer):
        self.timer = timer
    def show_remaining(self):
        if self.timer.paused():
            display.show(Displayer.PAUSED)
            return
        minutes = self.timer.minutes_remaining()
        seconds = self.timer.seconds_remaining()
        if seconds >= 0 and seconds < 10:
            self.countdown(seconds)
        else:
            self.show(minutes, seconds)
    def show(self, minutes, seconds):
        for cnt in range(25):
            y, x = divmod(cnt, 5)
            if cnt < minutes - 1:
                b = 9
            elif cnt == minutes - 1:
                # make it blink
                b = 9 if seconds % 2 == 0 else 0
            else:
                b = 0
            display.set_pixel(x, y, b)
    def countdown(self, seconds):
        display.show(str(seconds))

class Pomodoro:
    DEFAULT_DURATION = 25
    def __init__(self, duration):
        self.duration = duration
    def exec(self):
        timer = Timer(self.duration)
        displayer = Displayer(timer)
        timer.start()
        while True:
            if button_a.is_pressed() and button_b.is_pressed():
                display.clear()
                sleep(200)
                break
            elif button_b.is_pressed():
                if timer.paused():
                    timer.resume()
                else:
                    timer.pause()
            elif timer.done():
                display.show(Image.HAPPY)
                sleep(5000)
                display.clear()
                break
            else:
                displayer.show_remaining()
    
duration = Pomodoro.DEFAULT_DURATION
while True:
    if button_a.is_pressed():
        pomodoro = Pomodoro(duration)
        pomodoro.exec()
        duration = Pomodoro.DEFAULT_DURATION
    elif button_b.is_pressed():
        duration = 1 if duration == Pomodoro.DEFAULT_DURATION else duration + 1
        #display.scroll(str(duration))
        sleep(200)
        display.clear()
        for cnt in range(0, duration):
            y, x = divmod(cnt, 5)
            display.set_pixel(x, y, 9)
        sleep(200)

display.clear()
```

# 応用問題
25分経過後に、5分間の休憩時間の計測を自動で行うようにしてみてください。