Dick Moores said unto the world upon 2004-12-05 15:03:Thanks, Brian. I looked at your code a long time, and also read the 11/26 thread you started. I can see how I could use datetime() and your t2 - t1 to get the seconds for time.sleep(), but the resulting code I have in mind is more convoluted than the heart of my timer3.py, which I quote below. (I don't need the alarm time to be more than 24 hours from current time--therefore I want to ignore the year, month, and day.)
=======================================
import time
alarm = raw_input("Enter alarm time as hhmm: ")
now = time.strftime("%X") # produces current time in format hh:mm:ss
nowSecond = int(now[6:])
nowMinute = int(now[3:5])
nowHour = int(now[0:2])
alarmMinute = int(alarm[2:4])
alarmHour = int(alarm[0:2])
hoursDiff = alarmHour - nowHour
minutesDiff = alarmMinute - nowMinute
if hoursDiff < 0 or (hoursDiff == 0 and minutesDiff <= 0):
hoursDiff = hoursDiff + 24 # add a day
sleepSeconds = hoursDiff*3600 + minutesDiff*60 - nowSecond
time.sleep(sleepSeconds)
====================================
If I'm wrong, could someone please set me right?
Dick
Hi Dick and all,
sorry I was too lazy to follow your link before, Dick. Thanks for posting the relevant portions.
I took another run, but my code is a lot longer as I put in some error checking on the input request -- hope you don't mind ;-) (I might have gone overboard -- I did it to learn how as much as anything else.)
I suspect that my way is easier than yours. (I don't know about Liam's. His came in as I was writing mine, and I've not read his closely yet.)
In mine, the key bit is that if you have two datetime objects, d1 and d2, d1 - d2 gives a timedelta object expressing the time difference between them in the form (days, seconds, microseconds). So, the datetime module seems to do the work you want -- just make the current time a datetime object, use the user input to get a datetime object in the future and then find their timedelta and ask it for its seconds attribute. This disregards any difference in days and gives only the hour + minute + seconds difference expressed in seconds.
That logic is near the bottom, though, as first you've got to read through my error checking code ;-)
I tested it pretty well, but as always, undetected errors entitle you to a full refund of purchase price. (Minus a reasonable handling fee, of course.)
I hope this is of some use to you.
Best to all,
Brian vdB
CODE:
import datetime import time
def get_alarm_time(): '''Asks user for a time in the form 'hh:mm' and return tuple of ints.
Includes error checking to make sure user input really is of form 'hh:mm' where the values of 'hh' and 'mm' are appropriate. ''' while True: alarm_time = raw_input("Enter alarm time as hh:mm") er_msg = ''' An alarm time must be entered in the format 'hh:mm' where 'hh' is a number between 0 and 23 inclusive and mm is a number between 0 and 59 inclusive. You entered: '%s', which is not of that form. Please try again. ''' %alarm_time alarm_time_list = alarm_time.split(':') # yields a list with first element the characters from before # the ':' and second from after.
try: alarm_hour, alarm_minute = (int(alarm_time_list[0]), int(alarm_time_list[1]) ) except ValueError: # raised if the user entered something like "silly:input" print er_msg continue if len(str(alarm_minute)) == 1: alarm_minute_string = '0' + str(alarm_minute) # if the user entered, say, 12:05, str(alarm_minute) would # give '5' rather than the needed '05'. else: alarm_minute_string = str(alarm_minute) if ( (alarm_hour > 24 or alarm_hour < 0) or (alarm_minute > 59 or alarm_minute < 0) or str(alarm_hour) + ':' + alarm_minute_string != alarm_time): # The first two clauses check that minutes and hours are # within the expected ranges. The final clause checks that # the inputs were string representations of integers. # (Without it, the user could have entered something like # 16.845:57.0000343.) print er_msg else: return alarm_hour, alarm_minute
alarm_hour, alarm_minute = get_alarm_time() now = datetime.datetime.now() alarm_datetime = datetime.datetime(now.year + 4, now.month, now.day, alarm_hour, alarm_minute) # now.year + 4 to ensure that the alarm_datetime represents a time in # the future. I used a multiple of 4 to avoid leap year issues. + 44 # would work equally well. (This ignores the additional correction every # 100 or 400 years -- I forget which. But what do you want for free ;-)
alarm_in_seconds = (alarm_datetime - now).seconds # a_datetime_object - another_datetime_object gives a_timedelta_object. # a_timedelta_object.seconds returns only the hour and minute difference # (discarding days) expressed in seconds. It has to be the future time # minus the current time for the .seconds to give the wanted result.
print "I should wake up in %d seconds" %alarm_in_seconds time.sleep(alarm_in_seconds) print "I'm awake!"
Brian,
So yours can be boiled down to
==========Begin code==================
alarm_time = raw_input("Enter alarm time as hh:mm")
alarm_time_list = alarm_time.split(':')
alarm_hour, alarm_minute = (int(alarm_time_list[0]),
int(alarm_time_list[1]))
now = datetime.datetime.now()
alarm_datetime = datetime.datetime(now.year + 4, now.month, now.day,
alarm_hour, alarm_minute)
print alarm_datetime
alarm_in_seconds = (alarm_datetime - now).seconds
print "I should wake up in %d seconds" % alarm_in_seconds
time.sleep(alarm_in_seconds)
print "I'm awake!"
============End code==================Yes, I think yours is shorter, but not simpler. Mine doesn't need to consider the year or month, or leap years. On the other hand, mine doesn't take care of crossing the daylight time change borderline.
But thanks very much. It gives me some understanding of the datetime module. As does Liam's code.
BTW I found one omission in your error checking. The case where the user enters the time without a colon, e.g., 1234 instead of 12:34.
Dick
_______________________________________________ Tutor maillist - [EMAIL PROTECTED] http://mail.python.org/mailman/listinfo/tutor
