В прошлом я столкнулся с несколькими проблемами, связанными с тем, как среднее время цикла рассчитывается в виджете времени цикла, поэтому я решил проанализировать его с помощью 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.
Я пытаюсь выполнить запрос 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
), когда настраиваю виджет времени цикла с теми же настройками, что и ваши.
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
}
]
}
Sum/CompletedCount
".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 дней.
Для пояснения я хочу знать, как мне достичь значения в среднем по дням, например, в среднем 99+ дней, которое показано на вашем экране печати.
@fcoalcantarajr, как настроить виджет времени цикла? Можете показать подробности?
@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.
Я настраиваю виджет времени цикла аналогично запросу OData. Полученный тип рабочего элемента — «Проблема», а выбранный период — 30 дней.
@fcoalcantarajr, можете ли вы показать скриншоты с подробными настройками виджета времени цикла?
Вот оно: imgur.com/a/1fodWSS
@fcoalcantarajr, я обновил свой ответ выше, добавив дополнительную информацию (см. РЕДАКТИРОВАНИЕ). Проверьте и попробуйте с ним.
Привет, ваш ответ помог! Изначально мне еще не удавалось достичь того же значения, что показано в виджете, но после перехвата запросов OData с помощью журналов трассировки сети я заметил, что виджет начинает отсчитывать не с 30 дней точно, а с 35. дни. Моя функцияcalcular_janela_n точно рассчитывает, сколько дней мне следует добавить к уже определенному скользящему периоду. На 30 дней тянет с 35 дня, на 60 дней тянет с 71 дня и так далее.
Не могли бы вы добавить эту информацию в свой ответ? Так что могу отметить как правильное.
@fcoalcantarajr, Да, я действительно заметил разницу в значениях дат CompletedDateSK
в запросах OData, когда пытался использовать виджет времени цикла. Однако из журналов трассировки сети я не увидел, как он вычисляет значения дат на основе дней Rolling period
, указанных в виджете. Я думаю, это может быть связано с тем, что average days
рассчитывается на основе рабочих дней, не содержащих выходных. См. EDIT_2 для получения дополнительной информации.
Я тестировал разные периоды чередования, и использование функцииcalcular_janela_n для создания CompletedDateSK на 100% соответствовало тому, что показано в моих журналах трассировки сети.
Я обновил свой код, чтобы он был максимально приближен к вашему запросу OData, но мне все еще не удается достичь того же значения для среднего числа дней в виджете времени цикла. Текущее значение, показанное там, в среднем составляет 14 дней, но мой код Python возвращает 13.
url = https://analytics.dev.azure.com/hidden/hidden/_odata/v4.0-preview/WorkItems?$select=WorkItemId,WorkItemType,Title,CycleTimeDays,ClosedDate&$expand=Area($select=AreaPath)&$filter=(WorkItemType eq 'Issue' AND StateCategory eq 'Completed' AND CompletedDate ge {dia_formatado} AND startswith(Area/AreaPath,'hidden\hidden'))"