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!"
_______________________________________________
Tutor maillist  -  [EMAIL PROTECTED]
http://mail.python.org/mailman/listinfo/tutor

Reply via email to