はじめに
暇だったので,その日の勤務時間に応じて今日何円稼いでいるかをリアルタイムで表示するようなCLIアプリを書きました.
バイト中のモチベになるかなと思って作っただけなので,税金などは考慮せず,正確さも適当です.
アイデア・気づいたこと
- 小さい数字を単位にする方が楽しい
最初は1秒ごとに稼いだ金額を更新していましたが,あまり楽しくない.
1円稼ぐごとに更新しても,時給が十分高ければ楽しいかもしれませんが,バイト程度の賃金だとそこまで楽しくない.
0.01円稼ぐごとに表示し,少数第二位の数字が荒ぶっているくらいが見ていて楽しいです.
- 一日の途中でアプリを起動しても,その時点でその日に稼いだ金額がわかるようにしたほうが良い
PC起動時にアプリも勝手に起動するようにするのを前提として作成しましたが,やはり間違ってウィンドウを閉じてしまったり,PC再起動することはよくあります.
一度起動しても問題ないようにする必要があります.
コード解説
import time
import sys
from datetime import datetime
import pyfiglet
一週間の勤務時間を書きます.休憩がある場合はその前後で2つ以上に分けて.
# schedule
timer_schedule = {
"Monday": [["9:00", "12:00"], ["13:00", "18:00"]],
"Tuesday": [["9:00", "12:00"], ["13:00", "18:00"]],
"Wednesday": [["13:00", "18:00"]],
"Thursday": [],
"Friday": [],
"Saturday": [],
"Sunday": []
}
その日,その時点までで稼いだ金額を計算します.
勤務秒数を計算し,それに時給/3600 (秒給) をかけて金額を返します.
def get_current_count(schedule, current_time, payment):
total_seconds = 0
for period in schedule:
start_time = datetime.strptime(period[0], "%H:%M").time()
end_time = datetime.strptime(period[1], "%H:%M").time()
if start_time <= current_time.time() <= end_time:
total_seconds += (current_time - datetime.combine(current_time.date(), start_time)).seconds
elif current_time.time() > end_time:
total_seconds += (datetime.combine(current_time.date(), end_time) - datetime.combine(current_time.date(), start_time)).seconds
return total_seconds * (payment / 3600)
現在時刻が勤務中かどうかを判定する関数.
def is_within_schedule(schedule, current_time):
for period in schedule:
start_time = datetime.strptime(period[0], "%H:%M").time()
end_time = datetime.strptime(period[1], "%H:%M").time()
if start_time <= current_time.time() <= end_time:
return True
return False
main関数.
その時点までの賃金を取得した後,0.01円稼ぐのにかかる秒数を計算.
while文ではアスキーアートのライブラリを使って,0.01円稼ぐごとに数字を更新・表示しています.
勤務時間外はストップです.
def timer(payment, time_slice):
current_time = datetime.now()
weekday = current_time.strftime("%A")
if weekday in timer_schedule:
count = get_current_count(timer_schedule[weekday], current_time, payment)
else:
count = 0
interval = time_slice * 3600 / payment # time of 0.01 yen
try:
while True:
sys.stdout.write("\033[H\033[J")
ascii_art = pyfiglet.figlet_format(f"{count:.2f}")
sys.stdout.write(f"\r{ascii_art}")
sys.stdout.flush()
current_time = datetime.now()
if is_within_schedule(timer_schedule[weekday], current_time):
time.sleep(interval)
count += time_slice
else:
time.sleep(1) # when its not working time
except KeyboardInterrupt:
print("\n timer stopped.")
if __name__ == "__main__":
payment = 1064 # yen per hour
time_slice = 0.01 # seconds
timer(payment, time_slice)
おわりに
ちょっと気を抜いた時にこのタイマーが見えると,ちょっとモチベが上がりますね.……本当に?
ちなみにこのタイマー,0.01円ごとの時間を浮動小数点にしているので精度が悪く,一日が終わるころには500円くらいずれます.
30分おきくらいにget_current_countを使ってリセットを入れると良さそう.