Среднее время цикла в моем коде Python и виджете «Время цикла» различается

В прошлом я столкнулся с несколькими проблемами, связанными с тем, как среднее время цикла рассчитывается в виджете времени цикла, поэтому я решил проанализировать его с помощью Python, чтобы посмотреть, найду ли я какой-либо способ рассчитать среднее время цикла и получить то же самое. значение, отображаемое в виджете времени цикла.

Моя проблема заключается в том, что я не могу достичь того же значения среднего времени цикла, которое отображается в виджете времени цикла.

Ребята, вы можете помочь мне разобраться в этом?

На момент написания этой статьи значение среднего времени цикла, отображаемое в виджете «Время цикла», составляет 12 дней.

Однако, используя Python, Pandas и подключаясь к Feed OData API, я никогда не достигаю того же значения. Я достиг значения 11 дней, а используя другие методы расчета, например, скользящие средние, я достиг либо 9 дней, либо 11 дней. Код я привел в своем посте.

При использовании Power BI и подключении к Feed OData API, как описано здесь , значение среднего времени цикла по-прежнему равно 11.

На момент написания этой темы целевое значение, на которое я ориентировался, составляло 12 дней.

Вот мой код, изначально написанный в блокноте Jupyter:

# %%
import pandas as pd
import requests
import json
import base64
import math
from datetime import datetime, timedelta

# %%
token_do_azure = '{hidden}'
pat_encoded = base64.b64encode((":" + token_do_azure).encode()).decode()
headers = {
    'Content-Type': 'application/json',
    'Authorization': f'Basic {pat_encoded}'
}

# %%
hoje = datetime.today()

delta = timedelta(days=90)
dia_resultante = hoje - delta

dia_formatado = dia_resultante.strftime('%Y-%m-%dT00:00:00.00000Z')

print(dia_formatado)

url = rf"https://analytics.dev.azure.com/{hidden}/_odata/v4.0-preview/WorkItems?$select=WorkItemId,WorkItemType,Title,CycleTimeDays,ClosedDate&$filter=(Project/ProjectName eq 'Suporte_Torres' AND (WorkItemType eq 'Issue') AND State eq 'Done' AND ClosedOn/Date ge {dia_formatado})"

# %%
req = requests.get(url, headers=headers)
req_tabela = json.loads(req.text)
req_valores = req_tabela["value"]

# %%
df = pd.DataFrame(req_valores)
df['ClosedDate'] = pd.to_datetime(df['ClosedDate'], format='ISO8601').dt.date

# %%
print(round(df['CycleTimeDays'].mean(), 0))
# Returns 11.0, instead of 12.0.

# %%
# The moving average part of the code was written based on the moving average content of this page: https://learn.microsoft.com/en-us/azure/devops/report/dashboards/cycle-time-and-lead-time?view=azure-devops
def calcular_janela_n(n_dias):
    n = int(0.2 * n_dias)
    n = math.floor(n)
    if n % 2 == 0:
        n -= 1
    if n < 1:
        n = 1
    return n

janela_n = calcular_janela_n(90)

# %%
df['SMA_n'] = df['CycleTimeDays'].rolling(window=janela_n, min_periods=1).mean()
print(round(df['SMA_n'].tail(1).iloc[0], 0))
# Returns 9.0, instead of 12.0.
print(round(df['SMA_n'].mean(), 0))
# Returns 11.0, instead of 12.0.
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
68
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я пытаюсь выполнить запрос OData, как показано ниже, и он может вернуть то же самое CycleTimeDays, что и в виджете времени цикла.

https://analytics.dev.azure.com/myOrg/myProj/_odata/v4.0-preview/WorkItems?
    $filter=WorkItemType eq 'Task'
        and StateCategory eq 'Completed'
        and CompletedDate ge 2024-01-20Z
        and startswith(Area/AreaPath,'myProj\myArea')
    &$select=WorkItemId,WorkItemType,Title,State,ClosedDate,CycleTimeDays,LeadTimeDays
    &$expand=Iteration($select=IterationPath),Area($select=AreaPath)

Примечание:

Значения CycleTimeDays, возвращаемые запросом OData, являются числами с плавающей запятой, а не целыми числами. Значения, отображаемые в виджете времени цикла, обычно округлены.


Обновлено:

Ниже приведены запросы OData, которые я получаю из журналов трассировки сети браузера (Developer tools), когда настраиваю виджет времени цикла с теми же настройками, что и ваши.

  1. Query #1:

    https://analytics.dev.azure.com/{organizationName}/{ProjectName}/_odata/v4.0-preview/WorkItems?
        $apply=filter(CompletedDateSK ge 20240618 and Teams/any(t:(t/TeamSK eq {teamId} and (WorkItemType eq 'Issue'))))/groupby((CompletedDateSK, WorkItemType),aggregate($count as CompletedCount,CycleTimeDays with sum as Sum,CycleTimeDays mul CycleTimeDays with sum as SumOfSquares))
    

    Example of the response.

    {
        "@odata.context": "https://analytics.dev.azure.com/{organizationName}/{ProjectId}/_odata/v4.0-preview/$metadata#WorkItems(CompletedDateSK,WorkItemType,CompletedCount,Sum,SumOfSquares)",
        "value": [
            {
                "@odata.id": null,
                "WorkItemType": "Issue",
                "CompletedDateSK": 20240717,
                "SumOfSquares": 2394586.3654467259,
                "Sum": 2425.1853354,
                "CompletedCount": 4
            }
        ]
    }
    
    • The value of "Sum" is the sum of cycle time for all the completed work items within the specified Time period.
    • The value of "CompletedCount" is the count of for all the completed work items within the specified Time period.
    • The value of "Days on average" displayed on Widget is calculated by "Sum/CompletedCount".

  2. Query #2: Similar as the first query I posted above last time, it will return a list of cycle time for each completed work items within the specified Time period.

    https://analytics.dev.azure.com/{organizationName}/{ProjectName}/_odata/v4.0-preview/WorkItems?
        $filter=CompletedDateSK ge 20240623
            and (Teams/any(t:t/TeamSK eq {teamId}))
            and WorkItemType eq 'Issue'
        &$select=WorkItemId,Title,WorkItemType,CompletedDateSK,CycleTimeDays
    

РЕДАКТИРОВАТЬ_2:

Согласно заявлению о «В среднем дней» в документации «Настройка виджета времени выполнения/цикла»:

В среднем количество дней (среднее время выполнения или время цикла) для основных типов рабочих элементов, настроенных для диаграммы. Это число может не равняться среднему времени цикла/выполнения всех рабочих элементов. Это зависит от конфигураций, используемых для виджетов. Среднее число рассчитывается на основе каждого дня, в течение которого команда тратит время на рабочий элемент.

average days рассчитывается на основе рабочих дней, не содержащих выходных, поэтому sum days также следует рассчитывать на основе рабочих дней.

Я думаю, что если установить дни Rolling period как 30, виджет будет рассчитывать sum days и average days за последние 30 рабочих дней (не включая выходные дни).

Итак, в приведенном выше запросе #1 фактическое значение даты CompletedDateSK может составлять более 30 дней.


Я обновил свой код, чтобы он был максимально приближен к вашему запросу OData, но мне все еще не удается достичь того же значения для среднего числа дней в виджете времени цикла. Текущее значение, показанное там, в среднем составляет 14 дней, но мой код Python возвращает 13. url = https://analytics.dev.azure.com/hidden/hidden/_odata/v4.0-pr‌​eview/WorkItems?$sel‌​ect=WorkItemId,WorkI‌​temType,Title,CycleT‌​imeDays,ClosedDate&$‌​expand=Area($select=‌​AreaPath)&$filter=(W‌​orkItemType eq 'Issue' AND StateCategory eq 'Completed' AND CompletedDate ge {dia_formatado} AND startswith(Area/AreaPath,'hidden\hidden'))"

fcoalcantarajr 17.07.2024 23:08

Для пояснения я хочу знать, как мне достичь значения в среднем по дням, например, в среднем 99+ дней, которое показано на вашем экране печати.

fcoalcantarajr 17.07.2024 23:09

@fcoalcantarajr, как настроить виджет времени цикла? Можете показать подробности?

Bright Ran-MSFT 18.07.2024 03:47

@fcoalcantarajr, возьмите описание из документации «Настройка виджета времени выполнения/цикла»: Days on average (average lead time or cycle time) for the main work item types configured for the chart. This number might not be equal to the average cycle/lead time of all work items. It depends on configurations used for widgets. The average number is calculated based on each day the team takes time for work item.

Bright Ran-MSFT 18.07.2024 03:53

Я настраиваю виджет времени цикла аналогично запросу OData. Полученный тип рабочего элемента — «Проблема», а выбранный период — 30 дней.

fcoalcantarajr 18.07.2024 20:42

@fcoalcantarajr, можете ли вы показать скриншоты с подробными настройками виджета времени цикла?

Bright Ran-MSFT 19.07.2024 05:00

Вот оно: imgur.com/a/1fodWSS

fcoalcantarajr 22.07.2024 15:16

@fcoalcantarajr, я обновил свой ответ выше, добавив дополнительную информацию (см. РЕДАКТИРОВАНИЕ). Проверьте и попробуйте с ним.

Bright Ran-MSFT 23.07.2024 10:56

Привет, ваш ответ помог! Изначально мне еще не удавалось достичь того же значения, что показано в виджете, но после перехвата запросов OData с помощью журналов трассировки сети я заметил, что виджет начинает отсчитывать не с 30 дней точно, а с 35. дни. Моя функцияcalcular_janela_n точно рассчитывает, сколько дней мне следует добавить к уже определенному скользящему периоду. На 30 дней тянет с 35 дня, на 60 дней тянет с 71 дня и так далее.

fcoalcantarajr 24.07.2024 17:16

Не могли бы вы добавить эту информацию в свой ответ? Так что могу отметить как правильное.

fcoalcantarajr 24.07.2024 17:17

@fcoalcantarajr, Да, я действительно заметил разницу в значениях дат CompletedDateSK в запросах OData, когда пытался использовать виджет времени цикла. Однако из журналов трассировки сети я не увидел, как он вычисляет значения дат на основе дней Rolling period, указанных в виджете. Я думаю, это может быть связано с тем, что average days рассчитывается на основе рабочих дней, не содержащих выходных. См. EDIT_2 для получения дополнительной информации.

Bright Ran-MSFT 25.07.2024 05:22

Я тестировал разные периоды чередования, и использование функцииcalcular_janela_n для создания CompletedDateSK на 100% соответствовало тому, что показано в моих журналах трассировки сети.

fcoalcantarajr 26.07.2024 19:58

Другие вопросы по теме