ðãPythonã¯ã©ã¹ãäœæ¥çšãã¢ããŒãã¿ã€ããŒã®ãã©ãŠã¶ãŒãœãŒã¹ãäœã£ãŠYouTubeåç»ãäœã£ãŠã¿ã
ãã¢ããŒããã¯ããã¯ãšã¯ïŒ
ã³ããçŠåæã®2020幎ã«åºãŸã£ãæé管çææ³ã§ããæ£ç¢ºã«ã¯1980幎åŸåã«ãã©ã³ãã§ã¹ã³ã»ããªãããã«ãã£ãŠéçºãããææ³ã§ãããã³ãããè延ãåŠæ ¡ãè·å Žãééãããªã¢ãŒãå€åã«ãªã£ã2020幎以éã«äžæ°ã«ãã®ææ³ã泚ç®ãããYouTubeãTwitchãªã©ã®ãªã³ã©ã€ã³åç»é ä¿¡ãã©ãããã©ãŒã ã§ãã¢ããŒãã¿ã€ããŒãçšããã³ã³ãã³ããå€ãäžãããŸãããããã¢ããŒãããšããèšèã¯ã€ã¿ãªã¢èªã§ããããæå³ããããã§ããã®ææ³ã¯æ¬§ç±³ã®ãããã³ã§ã¯ããèŠããããããåã®ã¿ã€ããŒã«ç±æ¥ããŠããããã§ãã
ð ãã¢ããŒãææ³ã®ç¹åŸŽã¯äž»ã«ä»¥äžã®ããã«æ©èœããŸãïŒ
ã¿ã¹ã¯ã®éžæïŒäœæ¥ãããã¿ã¹ã¯ãéžæããŸãã
ã¿ã€ããŒã®èšå®ïŒåºæ¬ã¯ïŒïŒåã§ãããã äœæ¥å 容ã«ãã£ãŠïŒïŒåãïŒæéã«èšå®ããã人ããããèªç±ã§ãã
ã¿ã¹ã¯ã«éäžïŒã¿ã€ããŒããªããŸã§éžæããã¿ã¹ã¯ã«éäžããŸãã
çãäŒæ©ïŒåºæ¬ã¯ïŒåã§ãã
ç¹°ãè¿ãïŒä»¥äžã®ããã»ã¹ãç¹°ãè¿ããŸããåºæ¬ã¯ïŒã»ããã®ãã¢ããŒããå®äºãããé·ãäŒæ©ïŒéåžžã¯ïŒïŒåããïŒïŒåïŒãåããŸãã
ð ãã¢ããŒãææ³ã®å©ç¹ã¯ïŒ
æé管çïŒæéãå¹ççã«ç®¡çããæå©ããããŸãã
éäžãšçç£æ§ïŒçãäœæ¥æéãé«ãéäžåãšçç£æ§ãç¶æããäºãå©ããŸãã
ããŒã³ã¢ãŠãïŒçãå°œãïŒã®é²æ¢ïŒå®æçãªäŒæ©ã¯ããŒã³ã¢ãŠããé²ããæç¶å¯èœãªäœæ¥ããŒã¹ãä¿ã¡ãŸãã
ã¢ãããŒã·ã§ã³ã®åäžïŒã¿ã€ããŒã¯ã¢ãããŒã·ã§ã³ãé«ããã¿ã¹ã¯ãå®äºããããã®ããçš®ã®ç·æ¥æãçã¿åºããŸãã
ãã¢ããŒãã®äœ¿çšäŸ
YouTubeã§ã¯ãã®ãããªåç»ãèŠãããšãã人ãããããšæããŸãããããïŒïŒåã®äœæ¥æéãšïŒåéã®äŒæ©ãïŒã»ãããããªãåç»ã§ãã
ç§èªèº«ãæ°å¹Žåã¯ãã¢ããŒãææ³ãçšããããã°ã©ãã³ã°ã»ãã·ã§ã³ãã©ã€ãé
ä¿¡ãããããŠããŸãããããã°ã©ãã³ã°ã®å Žåã¯ïŒïŒåã ãšããªãçãã®ã§å€§äœã¯ïŒïŒåã®äœæ¥æéãšïŒïŒåã®äŒæ©ãæãã§ïŒïŒïŒã»ãããããªããŠããŸããã
ãã®æã«äœ¿ã£ãŠãããã¢ããŒãã¿ã€ããŒã¯ä»ã®ãããããŒãæ§ç¯ãããã®ã䜿ãããŠããã£ãŠããã®ã§ããã€ãèªåã§ãã·ã³ãã«ãªãã®ã§ãããããäœã£ãŠã¿ãããšæã£ãŠããŸããã
å æãå°ãæéã空ããã®ã§Flaskã䜿ã£ãã·ã³ãã«ãªãã¢ããŒãã¿ã€ããŒãäœã£ãŠã¿ãŸããã
ã³ãŒãã®æ§ç¯
ãŸã倧ããåããŠïŒã€ã®ãã¡ã€ã«ããæãç«ã£ãŠããŸãã
ããã¯ãšã³ãã¯Pythonèšèªãããã³ããšã³ãã¯FlaskãšåŒã°ããPython ã®Webãã¬ãŒã ã¯ãŒã¯ããããŠã¿ã€ããŒãç§ããšã«ã¢ããããŒãããããã¡ã€ã«ã«ã¯JavaScriptã䜿ã£ãŠããŸãã
ãã®Noteèšäºã§ã¯ããã¯ãšã³ãã®ãã€ãœã³èšèªã³ãŒãã玹ä»ããŠãããŸãã
幟ã€ãã®ã»ã¯ã·ã§ã³ã«åããŠåœ¹å²ãªã©ã解説ããŠãããŸãã
ã©ã€ãã©ãªãŒã®åŒã³èŸŒã¿
from flask import Flask, render_template
import time
import threading
import winsound
app = Flask(__name__)
å¿ èŠãªã©ã€ãã©ãªãŒãåŒã³èŸŒã¿ãFlaskãŠã§ãã¢ããªã±ãŒã·ã§ã³ã®ã€ã³ã¹ã¿ã³ã¹ãäœæããŸãã
ãã³ã¬ãŒã¿ãŒã®äœ¿çš
# define decorator
def log_method_call(func) -> callable:
"""
A decorator that logs the method call and arguments.
Parameters:
func (function): The function to decorate.
Returns:
function: The decorated function.
"""
def wrapper(*args, **kwargs) -> any:
"""
Wrapper function that logs the method call and arguments.
Parameters:
*args (tuple): The positional arguments.
**kwargs (dict): The keyword arguments.
Returns:
The result of the decorated function.
"""
print(f"Calling {func.__name__} with arguments {args} and keywork arguments {kwargs}")
return func(*args, **kwargs)
return wrapper
ãŸãäžçªæåã«ãã³ã¬ãŒã¿ãŒãå®çŸ©ããŸããããã³ã¬ãŒã¿ãŒãšã¯ããã§ã«å®çŸ©ãããŠããé¢æ°ã«åŠçã®å€æŽãè¿œå ãè¡ãçºã®ãã€ãœã³ç¹èã®æ©èœã§ãã
ããã§ã¯ã³ãŒããããŒãåãããããããããããã°ãããããããã°æ©èœãä»ãå ãããã³ã¬ãŒã¿ãŒãå®çŸ©ããŠããŸãã
ãã®å
ã®ã³ãŒãã«@log_method_callãæ°ãæã«åºãŠããŸãããããããã³ã¬ãŒã¿ãŒã®æ©èœãããŠããŸãã
Pythonã¯ã©ã¹
class PomodoroTimer():
def __init__(self):
# Initialize timer-related variables
self.timer_message = ""
self.remaining_time = 0
self.timer_lock = threading.Lock() # Add a lock for thread safety
self.cycles = 4
self.current_session = 0
@log_method_call
def update_timer(self, message, time_remaining) -> None:
"""
Update the timer message and remaining time.
Parameters:
message (str): The message to display in the timer.
time_remaining (int): The remaining time in seconds.
Returns:
None.
"""
with self.timer_lock:
self.timer_message = message
self.remaining_time = time_remaining
# print(f"Timer Updated: {self.timer_message}, Remaining Time: {self.remaining_time} seconds")
@log_method_call
def play_bell_sound(self) -> None:
"""
Play bell sound
"""
winsound.PlaySound("bell.wav", winsound.SND_ASYNC)
@log_method_call
def format_time(self, seconds) -> str:
"""
Format time in seconds as MM:SS
Parameters:
seconds (int): The time in seconds.
Returns:
str: The formatted time as MM:SS.
"""
minutes, seconds = divmod(seconds, 60) # python built-in
formatted_time = f"{minutes:02d}:{seconds:02d}"
# print(f"Formatted Time: {formatted_time}")
return formatted_time
@log_method_call
def countdown(self, phase, duration) -> None:
"""
Run the countdown timer for the specified phase and duration.
Parameters:
phase (str): The phase of the timer (e.g. "Work Time" or "Break Time").
duration (int): The duration of the timer in seconds.
This method updates the timer display with the current phase, session couint,
and remaining time every second during the countdown.
Returns:
None.
"""
start_time = time.time()
while time.time() - start_time < duration:
elapsed_time = time.time() - start_time
time_remaining = max(0, int(duration - elapsed_time))
# Update the timer with the current phase and remaining time
session_info = f"Session {self.current_session} of {self.cycles}"
self.update_timer(f"{phase} : {session_info} - {self.format_time(time_remaining)}", time_remaining)
time.sleep(1) # Update every second
# print(f"Phase: {phase}, Elapsed Time: {elapsed_time}, Remaining Time: {time_remaining}")
@log_method_call
def pomodoro_timer(self) -> None:
"""
Run the entire Pomo timer logic, including work and break phases alternating.
Returns:
None.
It iterates through the specified numbe of cycles, executing the work and break phases,
along with brief pauses and bell sounds between each cycle.
"""
# Display Welcome Message
self.update_timer("Welcome to Pomo Code Sessions", 0)
time.sleep(20) # Add a pause for the welcome message
self.play_bell_sound()
# Iterate through the specified number of cycles
for i in range(self.cycles):
self.current_session = i + 1
# Work Time
work_phase, work_duration = "Work Time", 25 * 60
self.countdown(work_phase, work_duration)
if i < self.cycles - 1:
self.play_bell_sound()
# Add a brief pause before starting Break Time
time.sleep(1)
# Break Time
break_phase, break_duration = "Break Time", 5 * 60
self.countdown(break_phase, break_duration)
if i < self.cycles - 1:
self.play_bell_sound()
# Display a message when the timer is finished
self.update_timer("Great Job!", 0)
Classãšããã³ã³ã»ããã¯ãªããžã§ã¯ãæåããã°ã©ãã³ã°ã®åºç€ãšãã£ãŠãéèšã§ã¯ãããŸãããClassã¯æ°ããããŒã¿ã®åãæ§ç¯ããéã®èšèšå³ïŒãã«ãŒããªã³ãïŒã§ãããããŠClassããäœãããã¢ãïŒãªããžã§ã¯ãïŒãã€ã³ã¹ã¿ã³ã¹ãšåŒã°ããŸãã
ã³ã³ã¹ãã©ã¯ã¿ãŒ
ã¯ã©ã¹å ã®äžçªæåã«ã¯å¿ ã
def __init__(self):
ããããŸããããã¯ã³ã³ã¹ãã©ã¯ã¿ãŒãšåŒã°ãããã®ã§ãç¹æ®ã¡ãœããã®äžã€ã§ããäž»ã«Classã®åæèšå®ãè¡ããŸããååã®Noteèšäºã§ã°ããŒãã«å€æ°ã«ã€ããŠè©±ããŸããããã°ããŒãã«å€æ°ãšäŒŒãŠããŸããClasså ã«å ¥ããšã°ããŒãã«å€æ°ã§ã¯ãªãã€ã³ã¹ã¿ã³ã¹å€æ°ã«å€ãããŸãã
def __init__(self):
# Initialize timer-related variables
self.timer_message = ""
self.remaining_time = 0
self.timer_lock = threading.Lock() # Add a lock for thread safety
self.cycles = 4
self.current_session = 0
äžã®äŸã§ã¯ïŒã€ã®ã€ã³ã¹ã¿ã³ã¹å€æ°ãåæåããŠããŸãããã®å€æ°ãç§ããšã«ããããã¯ãã¢ããŒãã®ãµã€ã¯ã«ãè¿œãããšã«ã¢ããããŒããããŠãããŸãã
ã¡ãœãã
Classã®äžã«ã¯ä»¥äžã®é¢æ°ãå®çŸ©ãããããªéšåãæ°ãæèŠããããšæããŸãã
@log_method_call
def update_timer(self, message, time_remaining) -> None:
"""
Update the timer message and remaining time.
Parameters:
message (str): The message to display in the timer.
time_remaining (int): The remaining time in seconds.
Returns:
None.
"""
with self.timer_lock:
self.timer_message = message
self.remaining_time = time_remaining
# print(f"Timer Updated: {self.timer_message}, Remaining Time: {self.remaining_time} seconds")
Classã®äžã«ããdefã¯é¢æ°ïŒFunctionïŒã§ã¯ãªãã¡ãœãããšåŒã°ããŸããã¡ãœããã¯ããŒã¿ãäœæããéã®å®éã®åäœã®ä»æ¹ãå®çŸ©ããŸãããã®ãã¢ããŒãã¿ã€ããŒã®Classå ã«ã¯ïŒã€ã®ã¡ãœãããäœããŸããã
@log_method_call
def play_bell_sound(self) -> None:
"""
Play bell sound
"""
winsound.PlaySound("bell.wav", winsound.SND_ASYNC)
äŸãã°äžã®ã¡ãœããã¯ã·ã³ãã«ã«ãã«é³ã鳎ããçºã ãã®ã¡ãœããã§ãã
ãã®ããã«åäœã«ãã£ãŠæ¯ãåããŠã¡ãœããã幟ã€ãèšå®ããããšã«ãã£ãŠClassãšãããã«ãŒããªã³ããæ§æããŠããŸãã
ãã¢ããŒãã¿ã€ããŒã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãäœæ
# Create an instance of the PomodoroTimer class
pomodoro_time_instance = PomodoroTimer()
ãã®è¡ã¯ PomodoroTimer ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãäœæããããã©ã«ãã®å€ã§åæåããŸãã
Flask ã«ãŒã ('/') ãå®çŸ©
# Route definition using the Flask web framework
@app.route('/')
def index():
with pomodoro_time_instance.timer_lock:
return render_template("index.html", timer_message=pomodoro_time_instance.timer_message)
ããã§ã¯ Flask ãŠã§ããã¬ãŒã ã¯ãŒã¯ã䜿çšããŠã«ãŒã URL ('/') ãå®çŸ©ããŠããŸãããŠãŒã¶ãŒããã® URL ã«ã¢ã¯ã»ã¹ãããšãindex é¢æ°ãåŒã³åºãããŸããé¢æ°ã¯ pomodoro_time_instance.timer_lock ã䜿çšããŠã¿ã€ããŒé¢é£ã®ããŒã¿ã«å¯Ÿããã¹ã¬ããã»ãŒãã確ä¿ããããŠå¥ã«çšæããŠãã"index.html" ãšããååã® HTML ãã³ãã¬ãŒããã¬ã³ããªã³ã°ãã衚瀺ãããã¹ãã¿ã€ããŒã¡ãã»ãŒãž (timer_message) ãæž¡ããŸãã
ã¡ã€ã³ããã㯠(if __name__ == '__main__':)
if __name__ == '__main__':
# Start the timer thread
timer_thread = threading.Thread(target=pomodoro_time_instance.pomodoro_timer)
timer_thread.start()
# Run the Flask app in debug mode during development mode
# Disable it in a production environment for security reasons
app.run(debug=True)
ãã®ãããã¯ã¯ã¹ã¯ãªãããã¡ã€ã³ããã°ã©ã ãšããŠå®è¡ãããŠãããã確èªããŸããpomodoro_timer ã¡ãœãããå®è¡ããæ°ããã¹ã¬ãã (timer_thread) ãäœæãããŸãããã®ã¡ãœããã¯ãã¢ããŒãã¿ã€ããŒããžãã¯å šäœãå¶åŸ¡ããŸããFlask ãŠã§ãã¢ã㪠(app) ã¯ãããã°ã¢ãŒãã§å®è¡ãã (app.run(debug=True))ããŠã§ããã©ãŠã¶ãä»ããŠã¢ã¯ã»ã¹ã§ããããã«ãªããŸããã¿ã€ããŒããžãã¯ã¯ããã¯ã°ã©ãŠã³ãã§å®è¡ãããŸãã
å®éã«åç»ã«åæ ãããŠã¿ã
äœæ¥çšã«ãã²äœ¿ã£ãŠã¿ãŠãã ããã
ðïžäœãæ°ã¥ããããšããæèŠãªã©ãããã°ã³ã¡ã³ãæ¬ãããé¡ãããŸãããã£ã³ãã«ãã©ããŒããããããé¡ãããŸãã
ð çåã«æã£ãäºã¯ããŒã¿åããŠèªåãªãã®çããæ¢ããŠããããšæããŸãããããŠãã®çããã©ããã«ãã誰ãã®çºã«ãªãäºãé¡ã£ãŠããŸãã
ãã®èšäºãæ°ã«å ¥ã£ãããµããŒããããŠã¿ãŸãããïŒ