如何从Python中给定的时间范围计算可用时间的效率?

时间:2019-01-28 12:40:26

标签: python time

我正在处理多个时间范围。我必须计算可用时间的效率(即分数)。这个问题可以与任何官僚机构相提并论。

我只是使用了多个if-else语句,随着代码使用了这么长时间,是否有更好的方法来处理此类问题。 查询时间以元组的形式给出,开放时间以元组的列表形式给出。

    def efficiencyRatio(inquiryTime, openingHours):
       if len(openingHours) > 1:
         ----code remain-----
       else:
         if inquiryTime[0] >= openingHours[0][0] and inquiryTime[1] <= 
         openingHours[0][1]:
             return 1

         elif inquiryTime[0] >= openingHours[0][1] or inquiryTime[1] <= 
         openingHours[0][0]:
            return 0

        elif inquiryTime[0] < openingHours[0][0] and inquiryTime[1] <= 
        openingHours[0][1]:
           totalInquiryTime = inquiryTime[1] - inquiryTime[0]
           usableInquiryTime = inquiryTime[1] - openingHours[0][0]
           efficiency = usableInquiryTime / totalInquiryTime 

       elif inquiryTime[0] >= openingHours[0][0] and inquiryTime[1] > 
       openingHours[0][1]:
          totalInquiryTime = inquiryTime[1] - inquiryTime[0]
          usableInquiryTime = openingHours[0][1] -inquiryTime[0]  
          efficiency = usableInquiryTime / totalInquiryTime

      elif inquiryTime[0] <= openingHours[0][0] and inquiryTime[1] >= 
      openingHours[0][1]:
         totalInquiryTime = inquiryTime[1] - inquiryTime[0]
         usableInquiryTime = openingHours[0][1] - openingHours[0][0]  
         efficiency = usableInquiryTime / totalInquiryTime

我的问题的输入和输出如下。

    Inquiry Time       Opening Time        Answer
    (10, 18)       [(10, 12), (14, 16)]     0.50
    (10, 12)       [(09, 14)]               1.00
    (08, 12)       [(00, 10)]               0.50

2 个答案:

答案 0 :(得分:1)

我可以通过遍历所有时隙并添加有效时间来做到这一点:

def get_efficiency(inquiry_times, open_hours):
    usefull_hours = 0

    minimum_start_time = inquiry_times[0]
    max_end_time = inquiry_times[1]
    for times in open_hours:
        # the closing time cannot be later than the final end time
        # the start time cannot be earlier than the opening time/end of the previous time slot
        usefull_hours += min(max_end_time, times[1]) - max(minimum_start_time, times[0])
        minimum_start_time = times[1]

    total_hours = inquiry_times[1] - inquiry_times[0]

    return float(usefull_hours)/total_hours

print(get_efficiency((10, 18), [(10,12), (14, 16)]))
print(get_efficiency((10, 12), [(9, 14)]))
print(get_efficiency((8, 12), [(00, 10)]))

输出:

0.5
1.0
0.5

请确保您的open_hours是一个排序列表,否则,这会很麻烦。

答案 1 :(得分:0)

如果我正确理解了这一点,我将通过引入一些更简单的操作overlap来计算两个间隔之间的重叠,以及duration来计算一个间隔的(绝对)持续时间来简化代码。

def overlap(interval1, interval2):
    interval1 = sorted(interval1)
    interval2 = sorted(interval2)
    result = (
        max([interval1[0], interval2[0]]),
        min([interval1[1], interval2[1]]))
    if result[0] > result[1]:
        return (0, 0)
    else:
        return result

def duration(interval):
    return abs(interval[1] - interval[0])

def efficiency_ratio(inquiry_interval, open_intervals):
    assert(all(
        duration(overlap(interval1, interval2)) == 0
        for interval1, interval2 in itertools.combinations(open_intervals, 2)))
    effective_duration = sum([
        duration(overlap(inquiry_interval, open_interval))
        for open_interval in open_intervals])
    return effective_duration / duration(inquiry_interval)

请注意: -代码具有最大输入范围之外的逻辑,它们也适用于最大范围早于最小范围的输入间隔。 输出始终为(min_bound, max_bound)格式。 -open_intervals应该不重叠,这就是assert()

内部实现的附加逻辑的含义

要测试此功能是否适合您的用例,我们可以这样做:

print(efficiency_ratio((10, 18), [(10,12), (14, 16)]))
# 0.5
print(efficiency_ratio((10, 12), [(9, 14)]))
# 1.0
print(efficiency_ratio((8, 12), [(0, 10)]))
# 0.5

编辑:添加了更多输入检查。