Reputation: 29
I am writing a simple command-line program that shows the current time and let user set the alarm. However, the alarm did not ring as the raw_input was blocking it. I have even implement multithreading but it didn't work as well. Here's the full code:
import datetime, time, thread, os
program_running = True
now = datetime.datetime.now()
alarm_status = 0
alarm_hour = 0
alarm_minute = 0
def clock():
now = datetime.datetime.now()
print now.strftime('%H:%M')
def set_alarm():
global alarm_hour, alarm_minute, alarm_status
alarm_time = raw_input('Set Alarm (XX:XX) : ')
alarm_hour = alarm_time[:alarm_time.find(':')]
alarm_minute = alarm_time[alarm_time.find(':')+1:]
alarm_status = 1
def alert_thread():
global alarm_hour, alarm_minute, alarm_status
while True:
if(alarm_status):
if (str(now.hour) == str(alarm_hour) and str(now.minute) == str(alarm_minute)):
print 'Ring.. Ring..'
alarm_status = 0
#program start here
thread.start_new_thread(alert_thread,())
while(program_running):
now = datetime.datetime.now()
print '1) Clock'
print '2) Alarm'
print '3) Quit'
choice = input('Choose (1-6) : ')
if(choice==1):
clock()
elif(choice==2):
set_alarm()
elif(choice==3):
program_running = False
Upvotes: 0
Views: 3563
Reputation: 414235
raw_input()
doesn't prevent other threads to print. Here's a small example:
from threading import Timer
def ring():
print "\nRing.. Ring.."
t = Timer(3, ring) # ring in 3 seconds
t.start()
s = raw_input("wait for the ring, press enter afterwards")
Output:
wait for the ring, press enter afterwards..
Ring.. Ring..
Upvotes: 0
Reputation: 4224
2 Things
Just before the inner if of thread, do
now = datetime.datetime.now()
Upvotes: 0
Reputation: 1116
I find the implementation with globals and only a single thread for alarms a little strange. This way you can always only have set one alarm at a time and there will always be an alarm thread running even without any alarm being set. Also your now is never being updated to the alarm shouldn't run at all. Maybe consider doing it like this. This isjust a quick refactor, not saying this is perfect but it should help you get on:
import datetime, time, threading, os
def clock():
now = datetime.datetime.now()
print now.strftime('%H:%M')
def set_alarm():
alarm_time = raw_input('Set Alarm (XX:XX) : ')
alarm_hour = alarm_time[:alarm_time.find(':')]
alarm_minute = alarm_time[alarm_time.find(':')+1:]
alarm_thread = threading.Thread(target=alert_thread, args=(alarm_time, alarm_hour, alarm_minute))
alarm_thread.start()
def alert_thread(alarm_time, alarm_hour, alarm_minute):
print "Ringing at {}:{}".format(alarm_hour, alarm_minute)
while True:
now = datetime.datetime.now()
if str(now.hour) == str(alarm_hour) and str(now.minute) == str(alarm_minute):
print ("Ring.. Ring..")
break
#program start here
while True:
now = datetime.datetime.now()
print '1) Clock'
print '2) Alarm'
print '3) Quit'
choice = input('Choose (1-6) : ')
if(choice==1):
clock()
elif(choice==2):
set_alarm()
elif(choice==3):
break
Upvotes: 1