lamar249
lamar249

Reputation: 27

How to capture data within a given time frame based on an hour basis?

I'm still learning Python and sometimes my coding is not very efficient. I'm looking for a more efficient way to adequately group data entry by "hourly basis". This is to measure production every hour not an average of hourly production (Yes, I know this would be much much simple. To give an example if I did something 32 times within 4:30-5:30 and between 5:30-6:30 I did 58 and that was it for the day these two time frames would not be an average of hourly production but would stay static which is what I need. The time frames in which it must fit within are (4:30-5:30, 5:30-6:30, 6:30-7:30, 7:30-8:30, 8:30-9:30, 9:30-10:30, 11:00-12:00, 12:00-1:00, 1:00-2:00, 2:00-3:00, 3:00-4:00, 4:00-5:00, 5:00-6:00, 6:00-7:00, 7:30-8:30, 8:30-9:30, 9:30-10:30, 10:30-11:30, 11:30-12:30, 12:30-1:30). I already have GUI for data entry into excel. I have two columns labeled as *"Time" and "Date", Time is where I manipulated hour and minute.

a_list = [2,3,4,5,6,7,8,9,10,11]
b_list = [11,12,13,14,15,16,17,18,19]
c_list = [19,20,21,22,23,0]
date = dt.datetime.now()
#hm =  float(date.strftime('%H.%M'))
#hour = float(date.strftime('%H'))
hour = float(5) #testing 
hm =  float(5.30) #testing
for i in a_list:
    if hour in a_list:
        if hour < 5:
            hour = 5
            a ="{:.2f}".format(hour) 
            print(f'Test 1:{a}')
            break
        if hour+.5 >= 5.5 and hour <10:
            if hm >= hour +.3:
                a ="{:.2f}".format(hour+1)
                print(f'Test 2: {a}')
            else: 
                a ="{:.2f}".format(hour) 
                print(f'Test 3: {a}')
        if hour >= 10: 
            hour = 10
            a ="{:.2f}".format(hour)
            print(f'Test 4: {a}')
    break

I have not yet added any code for the other list. I'm looking for better ideas then what I have here. I thought about date ranges but might run into complications. Here is a reference image of two of the columns:

enter image description here

enter image description here

Upvotes: 1

Views: 579

Answers (1)

blurryroots
blurryroots

Reputation: 382

Using the datetime module, it is certainly possible to avoid cumbersome if-else salads. To create time windows and register activity within these windows, let's consider the following:

import datetime

def calculate_slot(point_in_time, base, windows, length = datetime.timedelta(hours = 1)):
    '''Calculates the slot index of a given time relative to a base time and a list of time windows with a certain length.'''
    slot = -1
    # check if the time is further in the future than the end of the day.
    if (base + windows[-1] + length) <= point_in_time:
        return slot
    # increase the slot index, as long as the time is still bigger than the window time.
    while (slot+1) < len(windows) and (base + windows[slot+1]) < point_in_time:
        slot += 1

    return slot

def register_activity(activity_log, base, windows, point_in_time):
    '''Stores an entry in a slot depending on the point in time given.'''
    # in which window does the given time fit?
    slot = calculate_slot(point_in_time, base, windows)
    # only add if slot is valid.
    if -1 < slot:
        activity_log[slot].append(point_in_time)

def main():
    # when does the first time window start?
    base = datetime.datetime(2021, 1, 6)
    # what are the starting points of each window?
    windows = [
        datetime.timedelta(hours = 4, minutes = 30),
        datetime.timedelta(hours = 5, minutes = 30),
        datetime.timedelta(hours = 6, minutes = 30),
        datetime.timedelta(hours = 7, minutes = 30),
        datetime.timedelta(hours = 8, minutes = 30),
        datetime.timedelta(hours = 9, minutes = 30),
        datetime.timedelta(hours = 11, minutes = 00),
        datetime.timedelta(hours = 12, minutes = 00),
        datetime.timedelta(hours = 13, minutes = 00),
        datetime.timedelta(hours = 14, minutes = 00),
        datetime.timedelta(hours = 15, minutes = 00),
        datetime.timedelta(hours = 16, minutes = 00),
        datetime.timedelta(hours = 17, minutes = 00),
        datetime.timedelta(hours = 18, minutes = 00),
        datetime.timedelta(hours = 19, minutes = 30),
        datetime.timedelta(hours = 20, minutes = 30),
        datetime.timedelta(hours = 21, minutes = 30),
        datetime.timedelta(hours = 22, minutes = 30),
        datetime.timedelta(hours = 23, minutes = 30),
        datetime.timedelta(hours = 24, minutes = 30),
    ]

    # prepare the activity log with enought slots.
    activity_log = []
    for _ in range(0, len(windows)):
        activity_log.append([])

    # point in time to test against.
    search_time0 = datetime.datetime(2021, 1, 6, 8, 15)
    search_time1 = datetime.datetime(2021, 1, 6, 23, 42)
    search_time2 = datetime.datetime(2021, 1, 7, 1, 11)

    # register activity on specific times.
    register_activity(activity_log, base, windows, search_time0)
    register_activity(activity_log, base, windows, search_time1)
    register_activity(activity_log, base, windows, search_time2)

    # show activity log.
    print(activity_log)

if __name__ == '__main__':
    main()

The concept is, to define a base time (the day of consideration) and create a list of starting times for each window. Using timedelta a window is defined by the time distance relative to the start time.

To figure out, in which window / slot an activity at a certain time belongs, the windows are checked from earliest to latest.

For the activity log, a list of lists (with the number of inner lists equal to the number of windows / slots) is used. To register an activity, the slot of a given time is calculated and if a slot has been found, the time is inserted into the inner list.

Hope this serves as a source of inspiration for your application.

Upvotes: 1

Related Questions