Как рассчитать эффективность полезного времени из заданного временного диапазона в Python? - PullRequest
0 голосов
/ 28 января 2019

Я имею дело с несколькими временными диапазонами.Я должен рассчитать эффективность (то есть, часть) полезного времени.Эту проблему можно сравнить с любой бюрократией.

Я просто использовал несколько операторов 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 голосов
/ 28 января 2019

Если бы я понял это правильно, я бы упростил код, введя несколько более простых операций 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

РЕДАКТИРОВАТЬ: добавлена ​​дополнительная проверка ввода.

0 голосов
/ 28 января 2019

Я бы сделал это, обойдя все временные интервалы и добавив эффективные часы:

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 является отсортированным спискомКстати, иначе это ужасно испортится.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...