Getting Values ​​for Time Periods

I am writing a program in Python3, and one of the functions that I need is to calculate the value by reference to two datetime values, as described below.

Imagine a day divided into 8 three-hour pieces, always starting at 0000 UTC. Each of these pieces will have a value of x, which will vary from piece to piece, but will not change inside the fragment itself.

I need to pass the initial datetime object and the final datetime object to the function, and return the value for the function, which is the product of x and the number of minutes in this fragment between the starting datetime object and the datetime end object.

So, for example, if the start time is 0100 UTC, and the end time was 0200 UTC, and the x value for 0000 UTC is 0300 UTC chunk was 20, then this is easy, the value is 60 * 20 = 1200.

If the start time was 0100 UTC and the end time was 0400 UTC, and the x value for 0000 UTC - 0300 UTC chunk was 20, and the x value for 0300 UTC - 0600 UTC chunk was 30, then the sum is be (20 * 120) + ( 60 * 30) = 4200

Start and end times can span several pieces, or even several days.

What I propose to do is set the "day_list" of the dictionaries, where each dictionary {"startchunk_time": # (for example, 0000 UTC), "endchunk_time": # (for example, 0300 UTC), "x": value}. Then the pseudo code will be:

def find_value(start_time, end_time):
    test_time = start_time
    while test_time < end_time:
        for item in day_list:
            if test_time > itemstartchunk_time and test_time < endchunk_time:
                #code to add the current x value and increase the test_time by one minute

This means that the whole day_list is repeated each time, even if the corresponding value is found, and the next one, as a rule, will be in one fragment.

: (i) for , ; (ii) ?

+4
2

, [a, b] - f(t). f(t) - . calculus:

$$ \ int_a ^ bf (t) \, dt = F (b) - F (a) $$

t[i] - ( ) i -th piece f[i] - . , F(a) F(b). f[i] , . , i , O(1) .

t[i], i s O(log n) , ( bisect). , , 3 , i ( O (1) ):

assert s >= t[0]
i = (s - t[0]) // timedelta(hours=3)

:

  • , , 03..06
  • , [a, b), , .

, find_value() :

#!/usr/bin/env python3
from datetime import datetime, timedelta

slot_size = timedelta(hours=3)
slot_size_minutes = slot_size // timedelta(minutes=1)
f = [20, 30] # x values from the question
min_time = datetime(2015, 9, 29) # the time corresponding to f[0]
max_time = min_time + slot_size * len(f)

# compute F[i]
F = [0] * (len(f) + 1)
for i in range(len(f)):
    F[i+1] = F[i] + slot_size_minutes * f[i]

def find_value(start_time, end_time):
    return indefinite_integral(end_time) - indefinite_integral(start_time)

def indefinite_integral(t):
    if min_time <= t <= max_time:
        i = (t - min_time) // slot_size
        t_i = min_time + i * slot_size # i-th transition point
        minutes_in_ith_slot = (t - t_i) // timedelta(minutes=1)  # complete minutes
        return F[i] + f[i] * minutes_in_ith_slot if i < len(f) else F[i]
    else:
        raise ValueError('%r is not in [%s, %s] time range' % (
                         t, min_time, max_time))

:

def tt(hhmm):
    hour, minute = divmod(int(hhmm), 100)
    return min_time.replace(hour=hour, minute=minute)

assert find_value(tt("0100"), tt("0200")) == 1200
assert find_value(tt("0100"), tt("0400")) == 4200
0

! , ;) - Python. (.. if, elif, else), else ( "else" , ). , :

ctr = 1
while True:
    print "CTR: {0}".format(ctr)
    for x in xrange(10):
        print '\t{0}'.format(x)
        if x == 5:
            print "break FOR loop"
            break
    else:
        print "The FOR loop has completed and no break was hit."
        # do something when a breakpoint hasn't been hit
        break       # break WHILE loop

    print "Break was hit in the FOR loop. Kill the WHILE loop"
    # do something when the FOR loop breaks
    break       # break WHILE loop

, , . , :

if x == 5:
    print "break FOR loop"
    break

, . .

-1

Source: https://habr.com/ru/post/1609344/


All Articles