この記事では、Pythonのtime
モジュールとsubprocess
モジュールを使い、指定した秒数をカウントダウンし、終了時にアラーム音を鳴らすコマンドラインタイマーの作成方法を解説します。
1. プロジェクトの概要と準備
このスクリプトは、以下の2つの主要な機能を持っています。
- 設定された秒数から1秒ずつ減らしながら、残り時間を表示する。
- カウントがゼロになったら、外部コマンドを実行して音声ファイルを再生する。
このプログラムを実行するには、time
とsubprocess
という2つの標準ライブラリが必要です。また、再生したい音声ファイル(例: alarm.wav
)を、作成するPythonスクリプトと同じフォルダに配置しておく必要があります。
2. カウントダウンのロジック
カウントダウンの核となるのは、while
ループとtime.sleep(1)
です。ループの各回で1秒間プログラムを停止させ、残り秒数を1ずつ減らしていきます。
表示を見やすくするために、print
関数のend='\r'
引数を使います。これにより、改行する代わりにカーソルを行頭に戻し、同じ場所に残り時間を上書き表示させることができます。
import time
seconds_left = 10
while seconds_left > 0:
# f-stringで表示を整形し、\rでカーソルを行頭に戻す
print(f"残り時間: {seconds_left} 秒 ", end='\r')
time.sleep(1)
seconds_left -= 1
print("カウントダウン終了!")
3. アラーム音を再生する
カウントダウンが終了したら、subprocess
モジュールを使って音声ファイルを再生する外部コマンドを実行します。音声ファイルを再生するコマンドはOSによって異なるため、sys.platform
を使って実行環境を判定し、適切なコマンドを呼び出します。
- Windows:
start
コマンド - macOS:
afplay
コマンド - Linux:
aplay
コマンド
import subprocess
import sys
def play_sound(filename):
try:
if sys.platform == "win32":
# Windows
subprocess.Popen(['start', filename], shell=True)
elif sys.platform == "darwin":
# macOS
subprocess.Popen(['afplay', filename])
else:
# Linux
subprocess.Popen(['aplay', filename])
except FileNotFoundError:
print("エラー: 音声再生コマンドが見つからないか、ファイルが存在しません。")
4. 完成したコード全体
これまでの要素をすべて統合した、完全なカウントダウンタイマースクリプトを以下に示します。
import time
import subprocess
import sys
from pathlib import Path
# --- 設定 ---
COUNTDOWN_SECONDS = 10
ALARM_FILE = 'alarm.wav' # スクリプトと同じフォルダにある音声ファイル
# --- アラーム再生関数の定義 ---
def play_sound(filename):
if not Path(filename).is_file():
print(f"アラームファイル '{filename}' が見つかりません。")
return
try:
if sys.platform == "win32":
subprocess.Popen(['start', filename], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
elif sys.platform == "darwin":
subprocess.Popen(['afplay', filename])
else: # Linuxを想定
subprocess.Popen(['aplay', filename])
except FileNotFoundError:
print("エラー: 音声再生コマンド(afplayまたはaplay)が見つかりません。")
# --- メイン処理 ---
print(f"{COUNTDOWN_SECONDS}秒のカウントダウンを開始します。")
# カウントダウンループ
while COUNTDOWN_SECONDS > 0:
print(f"残り時間: {COUNTDOWN_SECONDS} 秒 ", end='\r')
time.sleep(1)
COUNTDOWN_SECONDS -= 1
# カウントダウン終了後の処理
print("\n時間です!")
play_sound(ALARM_FILE)
まとめ
このスクリプトは、time.sleep()
で正確な時間を待機し、while
ループでカウントダウン処理を実装し、そしてsubprocess
モジュールでOS固有のコマンドを呼び出して音を鳴らすという、複数のモジュールを連携させた実用的な例です。sys.platform
によるOS判定を加えることで、異なる環境でも動作する、より汎用性の高いプログラムを作成できます。