prattom
prattom

Reputation: 1743

code hangs up after some period while comparing datetime

I have the following code which hangs after some period while comparing datetime. Following is my code.

def worker():
flag = True
while True:
    s1 = '101:35:00'
    e1 = '101:36:00'
    s2 = '101:37:00'
    e2 = '101:38:00'
    s3 = '101:39:00'
    e3 = '101:40:00'

    if int(s1[0]) == 1:
        start1 = str(datetime.datetime.now().date()) + ' ' + s1[1:9]
    else:
        start1 = str(datetime.datetime.now().date() + datetime.timedelta(days=1)) + ' ' + s1[1:9]

    if int(s2[0]) == 1:
        start2 = str(datetime.datetime.now().date()) + ' ' + s2[1:9]
    else:
        start2 = str(datetime.datetime.now().date() + datetime.timedelta(days=1)) + ' ' + s2[1:9]

    if int(s3[0]) == 1:
        start3 = str(datetime.datetime.now().date()) + ' ' + s3[1:9]
    else:
        start3 = str(datetime.datetime.now().date() + datetime.timedelta(days=1)) + ' ' + s3[1:9]

    if int(e1[0]) == 1:
        end1 = str(datetime.datetime.now().date()) + ' ' + e1[1:9]
    else:
        end1 = str(datetime.datetime.now().date() + datetime.timedelta(days=1)) + ' ' + e1[1:9]

    if int(e2[0]) == 1:
        end2 = str(datetime.datetime.now().date()) + ' ' + e2[1:9]
    else:
        end2 = str(datetime.datetime.now().date() + datetime.timedelta(days=1)) + ' ' + e2[1:9]

    if int(e3[0]) == 1:
        end3 = str(datetime.datetime.now().date()) + ' ' + e3[1:9]
    else:
        end3 = str(datetime.datetime.now().date() + datetime.timedelta(days=1)) + ' ' + e3[1:9]

    s1t = datetime.datetime.strptime(start1, '%Y-%m-%d %H:%M:%S')
    s2t = datetime.datetime.strptime(start2, '%Y-%m-%d %H:%M:%S')
    s3t = datetime.datetime.strptime(start3, '%Y-%m-%d %H:%M:%S')
    e1t = datetime.datetime.strptime(end1, '%Y-%m-%d %H:%M:%S')
    e2t = datetime.datetime.strptime(end2, '%Y-%m-%d %H:%M:%S')
    e3t = datetime.datetime.strptime(end3, '%Y-%m-%d %H:%M:%S')

    cur = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    curr = datetime.datetime.strptime(cur, '%Y-%m-%d %H:%M:%S')

    if e1t < curr <= s2t or e2t < curr <= s3t:
        flag = False

    else: pass

    while not flag:
        print 'iwashereghgj'
        print str(curr) #line1
        if s2t <= curr < e2t or s3t <= curr < e3t:          
            q1.put(True)

            flag = True
        else:
            flag = True

For example in this case the code just hangs up after curr reaches '2014-01-06 01:37:00' at line1. Anyone can help me out why it is happening like this?

Upvotes: 0

Views: 299

Answers (1)

jonrsharpe
jonrsharpe

Reputation: 122107

All of that duplication makes your code very difficult to debug. Start with some encapsulation:

def process_time(timestring):
    today = datetime.date.today()
    tomorrow = today + datetime.timedelta(days=1)
    h, m, s = map(int, timestring[1:9].split(':'))
    time = datetime.time(hour=h, minute=m, second=s)
    if timestring[0] == '1':
        return datetime.datetime.combine(today, time)
    return datetime.datetime.combine(tomorrow, time)

Now it is clear what the function is actually doing and you can skip straight to

s1t = process_time(s1) # and so on

Plus it feels like you could shorten

cur = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
curr = datetime.datetime.strptime(cur, '%Y-%m-%d %H:%M:%S')

to

curr = datetime.datetime.now()

As for your problem, it's that you don't update curr in your loop, so it remains the time at which you started doing your task. You need to keep checking the current time.

To implement:

# process time strings once, outside loop
timeslots = [(s1t, e1t), ...]
while True:
##    starting = True
    while any(s <= datetime.datetime.now() < e for s, e in timeslots):
##        if starting:
##            print("Starting:", datetime.datetime.now())
##            starting = False
        q1.put(True) # do task in timeslots
    if all(datetime.datetime.now() >= e for s, e in timeslots):
##        print("All timeslots done:", datetime.datetime.now())
        break
# whatever happens afterwards

Note: lines starting ## are for demo purposes, leave commented out for "production" use.

Upvotes: 3

Related Questions