Reputation: 27
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:
Upvotes: 1
Views: 579
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