【python】睡眠時間管理するプログラム作った話
この記事は Aizu Advent Calendar 2017 の11日目の記事です
あぶすとらくと
pythonを使って日々の睡眠時間と起床時間を記録してグラフ化するシステムを作ってみたよ!
なぜ作ったの?
理由としては、
ここ数ヶ月ぐらい3時から4時就寝の生活が続いており、睡眠時間が死んでるのと単位がやばいので何とかしないとと思っていた
睡眠時間を見える化して自分にプレッシャーを与えると結構いいらしい
自分の使ってる睡眠管理アプリが2度寝した時に正確に記録できない
ということでじゃ自分で睡眠時間を記録できるもの作っちゃおうと思い立ち作ってみました
機能
具体的にはこんな機能を作成します
標準入力からその日の就寝時間と起床時間を受け取る
「8時30分」や「0:30」などどんなフォーマットで入力が来ても時間を取得できるようにする
取得した就寝時間と起床時間を日付とともにcsvファイルに記録する
csvファイルから就寝時間と起床時間の推移をグラフイメージにプロットする
使ったもの
環境
開発言語
- Python (3.6.1)
主なライブラリ
datetime (日付と時間のデータを扱うため)
pandas (データのcsvファイルへの読み書き)
matplotlib (グラフイメージ作成)
など
準備
pipでpandas,matplotlibライブラリをインストールしておく
実装
入力から時間を取得する関数
import re ERROR = 0 # テキストから時間を抽出 def get_time(text): m = re.findall('[\d]+', text) if len(m) == 2: return m; return [ERROR,'何時かわかんないよ〜\nもう一度入力し直してね']
正規表現を使って文字列から数字を抽出します
import re
で正規表現を使うモジュールを読み込み、文字列の中のパターンとマッチする部分をすべてリストとして返すfindall関数を呼びます
引数[\d]+
でtext
から1つ以上の連続した数字を検出します
時、分をリストの要素として受け取るため、取得したリストの長さが2以外ならエラーを返します
csvファイルに日付、就寝時間、起床時間を記録する関数
import os import pandas as pd from datetime import date CSV_PATH = "./timedata.csv" today = date.today() # csvファイルに時間を記録 def write_csv(sleep_time, wakeup_time): if not os.path.exists(CSV_PATH): # データフレームを作成 df = pd.DataFrame( [[today, sleep_time, wakeup_time]], columns=['Date', 'Sleep_Time', 'Wake_Up_time'] ) df.to_csv(CSV_PATH, index=False, encoding="utf-8") else: w = pd.DataFrame([[today, sleep_time, wakeup_time]]) w.to_csv(CSV_PATH, index=False, encoding="utf-8", mode='a', header=False)
最初にdatetimeモジュールのdate.today()
で記録日の日付を取得しておきます
csvファイルが存在していない場合は新規作成します
その場合、データフレームを作成し、列のindexとして日付(Date)、就寝時間(Sleep_Time)、起床時間(Wake_Up_time)を指定し、to_csv関数でデータフレームをcsvファイルとして書き込みます
既にcsvファイルがあれば、データフレームに取得した日付、就寝時間、起床時間のデータを入れ、csvファイルに追記します
追記する場合はオプションでmode='a'
header=False
を追加します
csvファイルからグラフイメージを作成する関数
import pandas as pd import matplotlib.pyplot as plt CSV_PATH = "./timedata.csv" # グラフイメージをプロット def plot_graph(): csv = pd.read_csv(CSV_PATH) plt.plot(csv.Date, csv.Sleep_Time, label='sleep time') plt.plot(csv.Date, csv.Wake_Up_time, label='wake up time') plt.legend() plt.savefig("./graph.png")
read_csv関数でcsvファイルをデータフレームとして読み込み、plot関数のx軸に日付、y軸に就寝時間と起床時間を指定し、分かりやすいように凡例名(label)を指定しました
余談ですが、このplot関数に日付を入れる時にdatetimeオブジェクトを作成して指定するとなぜか日付が小数値で出力されるという現象が起こり、半日ぐらいハマってました...
最終的にcsvの日付をとりあえず突っ込んでみたらちゃんと表示されてるし、なぜだろう...
話を戻して、次のlegend関数でグラフの凡例をつけています
最後にsavefig関数でグラフイメージを保存します
全体の実装
import os from datetime import date import datetime import re import pandas as pd import numpy as np import matplotlib.pyplot as plt CSV_PATH = "./timedata.csv" ERROR = 0 today = date.today() # csvファイルに時間を記録 def write_csv(sleep_time, wakeup_time): if not os.path.exists(CSV_PATH): # データフレームを作成 df = pd.DataFrame( [[today, sleep_time, wakeup_time]], columns=['Date', 'Sleep_Time', 'Wake_Up_time'] ) df.to_csv(CSV_PATH, index=False, encoding="utf-8") else: w = pd.DataFrame([[today, sleep_time, wakeup_time]]) w.to_csv(CSV_PATH, index=False, encoding="utf-8", mode='a', header=False) # テキストから時間を抽出 def get_time(text): m = re.findall('[\d]+', text) if len(m) == 2: return m; return [ERROR,'何時かわかんないよ〜\nもう一度入力し直してね'] # グラフイメージをプロット def plot_graph(): csv = pd.read_csv(CSV_PATH) plt.plot(csv.Date, csv.Sleep_Time, label='sleep time') plt.plot(csv.Date, csv.Wake_Up_time, label='wake up time') plt.legend() plt.savefig("./graph.png") if __name__ == '__main__': count = 0 sleep_time = datetime.datetime.now() wakeup_time = datetime.datetime.now() while count < 2: if count == 0: print('昨日の就寝時間を入力してください') input_str = str(input()) time = get_time(input_str) else: print('今日の起床時間を入力してください') input_str = str(input()) time = get_time(input_str) if not time[0]: print(time[1]) continue #時間を整形 if len(time[0]) == 1: time[0] = '0' + time[0] if len(time[1]) == 1: time[1] = '0' + time[1] if count == 0: str_time = time[0] + ':' + time[1] + ':00' sleep_time = datetime.datetime.strptime(str_time, '%H:%M:%S') sleep_time = sleep_time.time() else: str_time = time[0] + ':' + time[1] + ':00' wakeup_time = datetime.datetime.strptime(str_time, '%H:%M:%S') wakeup_time = wakeup_time.time() count+=1 write_csv(sleep_time, wakeup_time) plot_graph()
全体として上記のような実装になっています
mainのコードでは主に就寝時間と起床時間の入力を施し、時間を取得してフォーマットを整形ののちcsvファイルにデータを保存する関数とグラフイメージを作成する関数を呼ぶという流れになっています
結果
Date | Sleep_Time | Wake_Up_time |
---|---|---|
2017-12-04 | 03:27:00 | 09:10:00 |
2017-12-05 | 02:44:00 | 08:24:00 |
2017-12-06 | 03:48:00 | 09:14:00 |
2017-12-07 | 04:44:00 | 09:55:00 |
現状ひどいですね...😅😅
おわりに
pandasやmatplotlibはデータ解析用のライブラリで今回は触りぐらいしか使ってませんが、調べてみるとかなり奥が深かったです
現状のプログラムだと多分飽きて使わなくなるだろうと思うので、現在開発中のTwitter Botからリプがくるようにするようなシステムを考案中です
カムバック!!朝型生活!!