public (decimal utilization, int total, int assigned) MeasureUtilization() { var sources = this.Sources; if (sources.Count == 0) { return(1, 0, 0); } var total = sources.Count; var state = sources.ToDictionary(c => c.Id.Value, c => c.Name); foreach (var item in this.Features.SelectMany(c => c.Indicators)) { if (state.ContainsKey(item.SourceId)) { state.Remove(item.SourceId); } if (state.Count == 0) { break; } } var assigned = total - state.Count(); return(QualityUtils.CalculateProportion(total, assigned), total, assigned); }
) Measure() { var groups = this.Items.GroupBy(c => c.Target).OrderBy(c => c.Key).ToList(); var totals = groups.Select(c => c.Sum(d => d.Total.GetValueOrDefault())).ToArray(); var bad = groups.Select(c => c.Sum(d => d.Bad.GetValueOrDefault())).ToArray(); var dailyInteractions = new List <DateInteractionModel>(); foreach (var item in groups) { dailyInteractions.Add( new DateInteractionModel(item.Key, item.Sum(c => c.Total).GetValueOrDefault(), item.Sum(c => c.Good).GetValueOrDefault()) ); } var pairs = totals.Zip(bad).OrderBy(c => c.First); totals = pairs.Select(c => c.First).ToArray(); bad = pairs.Select(c => c.Second).ToArray(); double correlation = QualityUtils.MeasureCorrelation(totals, bad); var(b0, b1, r2) = QualityUtils.LinealRegression(totals, bad); return(correlation, totals, bad, b0, b1, r2, dailyInteractions); }
public double?MeasureDailyCorrelation(DatePeriodValue period = null) { if (this.SourceItems.Count == 0) { return(0); } else { if (period == null) { period = new DatePeriodValue( this.SourceItems.Min(c => c.Target), this.SourceItems.Max(c => c.Target) ); } var groups = this.SourceItems.Where(c => c.Target >= period.Start && c.Target <= period.End) .GroupBy(c => c.Target.Date).OrderBy(c => c.Key); var totals = groups.Select(c => c.Sum(c => (double)c.Total.GetValueOrDefault())).ToArray(); var bad = groups.Select(c => c.Sum(c => (double)(c.Bad.GetValueOrDefault()) )).ToArray(); var correlation = QualityUtils.MeasureCorrelation(totals, bad); return(correlation); } }
public void Update(int total, int good, DateTime target) { this.Total = total; this.Good = good; this.Measure = QualityUtils.CalculateProportion(total, good); this.Target = target; }
public async Task <DatetimeSerieModel> GetDailySeriesById(int journeyId, DatePeriodValue period) { var journey = await this._dbContext.GetJourney(journeyId); var sourceIds = journey.FeatureMap.SelectMany(c => c.Feature.Indicators) .Select(c => c.SourceId).Distinct(); var sourceItems = await this._dbContext.GetSourceItems(sourceIds, period.Start, period.End); foreach (var map in journey.FeatureMap) { foreach (var indicator in map.Feature.Indicators) { indicator.Source.SourceItems = sourceItems.Where(c => c.SourceId == indicator.SourceId).ToList(); } } var result = new DatetimeSerieModel { Start = period.Start, End = period.End, Name = journey.Name, Avatar = journey.Avatar, }; var aggregator = new JourneyDailyAggregate(journey, period); var(availability, features) = aggregator.MeasureQuality; result.Availability.AddItems( availability.OrderBy(c => c.Date).Select(c => (c.Date, c.Measure.Availability)).ToList() ); result.Latency.AddItems( availability.OrderBy(c => c.Date).Select(c => (c.Date, c.Measure.Latency)).ToList() ); result.Experience.AddItems( availability.OrderBy(c => c.Date).Select(c => (c.Date, c.Measure.Experience)).ToList() ); foreach (var(feature, avaValues) in features) { var pivotAvailability = new DatetimeSerieListModel(feature.Name, feature.Avatar); pivotAvailability.AddItems(avaValues.OrderBy(c => c.Date) .Select(c => (c.Date, QualityUtils.MeasureDebt(c.Measure.Availability, journey.AvailabilitySlo))).ToList()); result.AvailabilityDetail.Add(pivotAvailability); var pivotLatency = new DatetimeSerieListModel(feature.Name, feature.Avatar); pivotLatency.AddItems(avaValues.OrderBy(c => c.Date) .Select(c => (c.Date, QualityUtils.MeasureLatencyDebt(c.Measure.Latency, journey.LatencySlo))).ToList()); result.LatencyDetail.Add(pivotLatency); var pivotExperience = new DatetimeSerieListModel(feature.Name, feature.Avatar); pivotExperience.AddItems(avaValues.OrderBy(c => c.Date) .Select(c => (c.Date, QualityUtils.MeasureDebt(c.Measure.Experience, journey.ExperienceSlo))).ToList()); result.ExperienceDetail.Add(pivotExperience); } return(result); }
public (decimal coverage, int total, int assigned) MeasureCoverage() { var features = this.Features; if (features.Count == 0) { return(1, 0, 0); } var total = features.Count; var state = features.ToDictionary(c => c.Id.Value, c => c.Name); foreach (var item in this.Journeys.SelectMany(c => c.FeatureMap)) { if (state.ContainsKey(item.FeatureId)) { state.Remove(item.FeatureId); } if (state.Count == 0) { break; } } var coverage = total - state.Count(); return(QualityUtils.CalculateProportion(total, coverage), total, coverage); }
public void TestProportionToNumbers10() { decimal target = 0.8M; var(g, t) = QualityUtils.ProportionToNumbers(target); Assert.Equal(g, 80); Assert.Equal(t, 100); }
public async Task <GraphGetRp> GetGraphExperience(int productId, DatePeriodValue period) { GraphGetRp result = new GraphGetRp(); var product = await this._dbContext.FullLoadProductWithSourceItems(productId, period.Start, period.End); result.Name = product.Name; result.Id = product.Id.Value; result.Avatar = product.Avatar; foreach (var journey in product.Journeys) { var measure = journey.Measure(); var snode = new GraphNode { Id = string.Format("journey_{0}", journey.Id), Avatar = journey.Avatar, Name = string.Format("{0} [ {1} | {2} ]", journey.Name, Math.Round(journey.ExperienceSlo, 2), Math.Round(measure.Experience, 2)), Value = measure.Experience, Group = "journeys", Slo = journey.ExperienceSlo, Budget = measure.ExperienceErrorBudget }; result.Nodes.Add(snode); foreach (var map in journey.FeatureMap) { var featureMeasure = map.Feature.Measure(); var Id = string.Format("feature_{0}", map.Feature.Id); var fnode = result.Nodes.SingleOrDefault(c => c.Id == Id); if (fnode == null) { fnode = new GraphNode { Id = Id, Avatar = map.Feature.Avatar, Name = map.Feature.Name, Value = featureMeasure.Experience, Group = "features" }; result.Nodes.Add(fnode); } var fedge = new GraphEdge() { From = snode.Id, To = fnode.Id, Value = QualityUtils.MeasureBudget(fnode.Value, journey.ExperienceSlo), Tags = new Dictionary <string, object>() { { "Latency", fnode.Value } } }; result.Edges.Add(fedge); } } return(result); }
public DayPointValue(DateTime date, IEnumerable <DayPointValue> points) : this(date) { if (points.Count() > 0) { var minimun = points.Min(c => c.Minimun); var maximun = points.Max(c => c.Maximun); var average = QualityUtils.CalculateAverage(points.Select(c => c.Average)); } }
public DebtMeasureValue MeasureDebt(SLOValue slo) { return(new DebtMeasureValue() { Availability = QualityUtils.MeasureDebt(this.Availability, slo.Availability), Latency = QualityUtils.MeasureLatencyDebt(this.Latency, slo.Latency), Experience = QualityUtils.MeasureDebt(this.Experience, slo.Experience) }); }
public void ProportionToMinutesSuccess() { var(good, total) = QualityUtils.ProportionToMinutes(OwlveyCalendar.StartJanuary2019, OwlveyCalendar.EndJanuary2019, 0.94M); var target = (decimal)good / (decimal)(total); Assert.Equal(target, 0.94M); }
public void MeasureImpactSuccess() { var result = QualityUtils.MeasureImpact(0.90m); result = QualityUtils.MeasureImpact(0.95m); result = QualityUtils.MeasureImpact(0.99m); result = QualityUtils.MeasureImpact(0.999m); //Assert.Equal<decimal>(90.43821m, result); Assert.Equal(950m, result); }
public static SourceItemEntity CreateItem(SourceEntity source, DateTime target, int?good, int?total, decimal?measeure, DateTime on, string createdBy, SourceGroupEnum group) { if (measeure.HasValue) { if (measeure < 0) { throw new ApplicationException(string.Format("invalid value measure {0} ", measeure)); } if (group != SourceGroupEnum.Latency) { if (measeure > 1 || measeure < 0) { throw new ApplicationException(string.Format("proportion {0} must be between 0 and 1", measeure)); } } } else if (good.HasValue && total.HasValue) { if (good < 0 || total < 0) { throw new ApplicationException( string.Format("good {0} and total {1} must be greater equal than zero", good, total)); } if (total < good) { throw new ApplicationException( string.Format("good {0} is greater than total {1}", good, total)); } measeure = QualityUtils.CalculateProportion(total, good); } else { throw new ApplicationException($" no values for measures ${total}, ${good}, ${measeure}"); } var entity = new SourceItemEntity() { Target = target, Good = good, Total = total, Measure = measeure.Value, Source = source, CreatedBy = createdBy, ModifiedBy = createdBy, CreatedOn = on, ModifiedOn = on, Group = group }; return(entity); }
public GraphNode(string group, string key, int id, string avatar, string name, decimal availability, decimal slo) { this.Id = string.Format("{0}_{1}", key, id); this.Avatar = avatar; this.Name = name; this.Value = availability; this.Group = group; this.Slo = slo; this.Importance = QualityUtils.MeasureImpact(slo); this.Budget = availability - (decimal)slo; }
public async Task <JourneyGroupListRp> GetJourneyGroupReport(int productId, DatePeriodValue period) { var entity = await this._dbContext.FullLoadProductWithSourceItems(productId, period.Start, period.End); var result = new JourneyGroupListRp(); var days = period.ToDaysPeriods(); foreach (var group in entity.Journeys.GroupBy(c => c.Group)) { var serie = new MultiSerieItemGetRp() { Name = group.Key }; foreach (var day in days) { serie.Items.Add(new SeriesItemGetRp(day.Start, group.Select(c => c.Measure(day).AvailabilityDebt).Sum())); } var measures = group.Select(c => new { measure = c.Measure(period) }).ToList(); var temp = new JourneyGroupListRp.JourneyGrouptem { Name = group.Key, AvailabilitySloAvg = QualityUtils.CalculateAverage(group.Select(c => c.AvailabilitySlo)), AvailabilitySloMin = QualityUtils.CalculateMinimum(group.Select(c => c.AvailabilitySlo)), LatencySloAvg = QualityUtils.CalculateAverage(group.Select(c => c.LatencySlo)), LatencySloMin = QualityUtils.CalculateMinimum(group.Select(c => c.LatencySlo)), ExperienceSloAvg = QualityUtils.CalculateAverage(group.Select(c => c.ExperienceSlo)), ExperienceSloMin = QualityUtils.CalculateMinimum(group.Select(c => c.ExperienceSlo)) }; temp.AvailabilityAvg = QualityUtils.CalculateAverage(measures.Select(c => c.measure.Availability)); temp.AvailabilityMin = QualityUtils.CalculateMinimum(measures.Select(c => c.measure.Availability)); temp.LatencyAvg = QualityUtils.CalculateAverage(measures.Select(c => c.measure.Latency)); temp.LatencyMin = QualityUtils.CalculateMinimum(measures.Select(c => c.measure.Latency)); temp.ExperienceAvg = QualityUtils.CalculateAverage(measures.Select(c => c.measure.Experience)); temp.ExperienceMin = QualityUtils.CalculateMinimum(measures.Select(c => c.measure.Experience)); temp.Count = group.Count(); temp.AvailabilityDebt = measures.Sum(c => c.measure.AvailabilityDebt); temp.ExperienceDebt = measures.Sum(c => c.measure.ExperienceDebt); temp.LatencyDebt = measures.Sum(c => c.measure.LatencyDebt); result.Series.Add(serie); result.Items.Add(temp); } return(result); }
public void LoadMeasure(JourneyQualityMeasureValue measure) { this.Availability = measure.Availability; this.Latency = measure.Latency; this.Experience = measure.Experience; this.Deploy = QualityUtils.BudgetToAction(measure); this.AvailabilityErrorBudget = measure.AvailabilityErrorBudget; this.LatencyErrorBudget = measure.LatencyErrorBudget; this.ExperienceErrorBudget = measure.ExperienceErrorBudget; this.AvailabilityDebt = measure.AvailabilityDebt; this.LatencyDebt = measure.LatencyDebt; this.ExperienceDebt = measure.ExperienceDebt; }
public static QualityMeasureValue Merge(IEnumerable <QualityMeasureValue> measures) { var availability = QualityUtils.CalculateAverage(measures.Select(c => c.Availability)); var latency = QualityUtils.CalculateAverage(measures.Select(c => c.Latency)); var experience = QualityUtils.CalculateAverage(measures.Select(c => c.Experience)); var total = measures.Sum(c => c.Total); var good = measures.Sum(c => c.Good); return(new QualityMeasureValue(availability, latency, experience) { Total = total, Good = good }); }
public JourneyQualityMeasureValue Measure(DatePeriodValue period = null) { var resultAvailability = new List <decimal>(); var resultLatency = new List <decimal>(); var resultExperience = new List <decimal>(); foreach (var map in this.FeatureMap) { QualityMeasureValue measure; if (period != null) { measure = map.Feature.Measure(period); } else { measure = map.Feature.Measure(); } if (measure.HasData) { resultAvailability.Add(measure.Availability); resultLatency.Add(measure.Latency); resultExperience.Add(measure.Experience); } } if (resultAvailability.Count > 0 || resultExperience.Count > 0 || resultLatency.Count > 0) { return(new JourneyQualityMeasureValue( this.AvailabilitySlo, this.LatencySlo, this.ExperienceSlo, QualityUtils.CalculateMinimum(resultAvailability, round: 3), QualityUtils.CalculateMaximum(resultLatency, round: 3), QualityUtils.CalculateMinimum(resultExperience, round: 3))); } else { return(new JourneyQualityMeasureValue(this.AvailabilitySlo, this.LatencySlo, this.ExperienceSlo, false)); } }
private MeasureValue MeasureLatency(DatePeriodValue period = null) { IEnumerable <SourceItemEntity> data; if (period != null) { data = this.SourceItems.Where(c => c.Group == SourceGroupEnum.Latency && c.Target >= period.Start && c.Target <= period.End); } else { data = this.SourceItems.Where(c => c.Group == SourceGroupEnum.Latency); } if (data.Count() == 0) { return(new MeasureValue(101, false)); } var proportion = QualityUtils.CalculateAverage(data.Select(c => c.Measure)); return(new MeasureValue(proportion)); }
private MeasureValue MeasureExperience(DatePeriodValue period = null) { IEnumerable <SourceItemEntity> data; if (period != null) { data = this.SourceItems.Where(c => c.Group == SourceGroupEnum.Experience && c.Target >= period.Start && c.Target <= period.End); } else { data = this.SourceItems.Where(c => c.Group == SourceGroupEnum.Experience); } if (data.Count() == 0) { return(new InteractionMeasureValue(1, 0, 0, false)); } var good = data.Select(c => c.Good.GetValueOrDefault()).Sum(); var total = data.Select(c => c.Total.GetValueOrDefault()).Sum(); var measure = QualityUtils.CalculateAverage(data.Select(c => c.Measure)); return(new InteractionMeasureValue(measure, total, good)); }
public DebtMeasureValue MeasureDebt(DatePeriodValue period = null) { var measure = this.Measure(period); var maps = this.Indicators.Select(c => c.Feature.JourneyMaps).ToList(); var services = maps.SelectMany(c => c.Select(d => d.Journey)).Distinct(new JourneyEntityCompare()); decimal availabilityDebt = 0; decimal latencyDebt = 0; decimal experienceDebt = 0; foreach (var item in services) { availabilityDebt += QualityUtils.MeasureDebt(measure.Availability, item.AvailabilitySlo); latencyDebt += QualityUtils.MeasureLatencyDebt(measure.Latency, item.LatencySlo); experienceDebt += QualityUtils.MeasureDebt(measure.Experience, item.ExperienceSlo); } var result = new DebtMeasureValue(availabilityDebt, latencyDebt, experienceDebt); return(result); }
public (decimal ownership, int total, int assigned) Measure() { if (this.Features.Count() == 0) { return(1, 0, 0); } var total = this.Features.Count(); var state = this.Features.ToDictionary(c => c.Id.Value, c => c.Name); foreach (var item in this.Squads.SelectMany(c => c.FeatureMaps)) { if (state.ContainsKey(item.FeatureId)) { state.Remove(item.FeatureId); } if (state.Count == 0) { break; } } var assigned = total - state.Count(); return(QualityUtils.CalculateProportion(total, assigned), total, assigned); }
public async Task <OperationProductDashboardRp> GetProductDashboard(int productId, DateTime start, DateTime end) { var product = await this._dbContext.FullLoadProduct(productId); var squadsData = await this._dbContext.SquadFeatures .Include(c => c.Squad) .Where(c => c.Feature.ProductId == productId).ToListAsync(); var incidentsData = await this._dbContext.IncidentMaps .Include(c => c.Incident) .Where(c => c.Feature.ProductId == productId).ToListAsync(); var sourceItems = await this._dbContext.GetSourceItemsByProduct(productId, start, end); var result = new OperationProductDashboardRp(); foreach (var source in product.Sources) { source.SourceItems = sourceItems.Where(c => c.SourceId == source.Id).ToList(); var measure = source.Measure(); result.Sources.Add(new SourceGetListRp() { Id = source.Id.Value, Measure = measure, Avatar = source.Avatar, CreatedBy = source.CreatedBy, CreatedOn = source.CreatedOn.Value, AvailabilityDefinition = source.AvailabilityDefinition, LatencyDefinition = source.LatencyDefinition, ExperienceDefinition = source.ExperienceDefinition, Name = source.Name }); } foreach (var feature in product.Features) { foreach (var indicator in feature.Indicators) { indicator.Source = product.Sources.Single(c => c.Id == indicator.SourceId); } foreach (var squadMap in squadsData.Where(c => c.FeatureId == feature.Id).ToList()) { squadMap.Feature = feature; feature.Squads.Add(squadMap); } var tmp = this._mapper.Map <FeatureGetListRp>(feature); var measure = feature.Measure(); tmp.LoadMeasure(measure); result.Features.Add(tmp); var featureIncidents = incidentsData.Where(c => c.FeatureId == feature.Id) .Select(c => c.Incident).ToList(); var incidentAggregate = new IncidentMetricAggregate(featureIncidents); var aggIncident = incidentAggregate.Metrics(); result.IncidentInformation[feature.Id.Value] = new { count = featureIncidents.Count, mttd = aggIncident.mttd, mtte = aggIncident.mtte, mttf = aggIncident.mttf, mttm = aggIncident.mttm }; result.FeatureMaps[feature.Id.Value] = feature.Indicators.OrderBy(c => c.Id).Select(c => c.SourceId).ToList(); result.SquadMaps[feature.Id.Value] = squadsData.Where(c => c.FeatureId == feature.Id) .Select(c => c.SquadId) .Distinct().ToList(); } foreach (var squad in squadsData.Select(c => c.Squad).Distinct(new SquadCompare())) { var tmp = this._mapper.Map <SquadGetListRp>(squad); result.Squads.Add(tmp); } int sloFails = 0; foreach (var journey in product.Journeys) { foreach (var map in journey.FeatureMap) { map.Feature = product.Features.Single(c => c.Id == map.FeatureId); } var measure = journey.Measure(); if (measure.Availability < journey.AvailabilitySlo) { sloFails += 1; } var tmp = this._mapper.Map <JourneyGetListRp>(journey); result.Journeys.Add(tmp); result.JourneyMaps[journey.Id.Value] = journey.FeatureMap.OrderBy(c => c.Id).Select(c => c.FeatureId).ToList(); } result.Journeys = result.Journeys.OrderBy(c => c.Availability).ToList(); result.SLOFail = sloFails; result.SLOProportion = QualityUtils.CalculateFailProportion(product.Journeys.Count, sloFails); //TODO: change //result.SourceStats = new StatsValue(result.Sources.Select(c => c.Measure)); result.FeaturesStats = new StatsValue(result.Features.Select(c => c.Availability)); result.FeaturesCoverage = QualityUtils.CalculateProportion(product.Features.Count, squadsData.Select(c => c.FeatureId).Distinct().Count()); result.JourneysStats = new StatsValue(result.Journeys.Select(c => c.Availability)); return(result); }
public void LoadData(int month, int good, int total) { switch (month) { case 1: this.JanGood = good; this.JanTotal = total; this.JanProportion = QualityUtils.CalculateProportion(total, good); break; case 2: this.FebGood = good; this.FebTotal = total; this.FebProportion = QualityUtils.CalculateProportion(total, good); break; case 3: this.MarGood = good; this.MarTotal = total; this.MarProportion = QualityUtils.CalculateProportion(total, good); break; case 4: this.AprGood = good; this.AprTotal = total; this.AprProportion = QualityUtils.CalculateProportion(total, good); break; case 5: this.MayGood = good; this.MayTotal = total; this.MayProportion = QualityUtils.CalculateProportion(total, good); break; case 6: this.JunGood = good; this.JunTotal = total; this.JunProportion = QualityUtils.CalculateProportion(total, good); break; case 7: this.JulGood = good; this.JulTotal = total; this.JulProportion = QualityUtils.CalculateProportion(total, good); break; case 8: this.AugGood = good; this.AugTotal = total; this.AugProportion = QualityUtils.CalculateProportion(total, good); break; case 9: this.SepGood = good; this.SepTotal = total; this.SepProportion = QualityUtils.CalculateProportion(total, good); break; case 10: this.OctGood = good; this.OctTotal = total; this.OctProportion = QualityUtils.CalculateProportion(total, good); break; case 11: this.NovGood = good; this.NovTotal = total; this.NovProportion = QualityUtils.CalculateProportion(total, good); break; case 12: this.DecGood = good; this.DecTotal = total; this.DecProportion = QualityUtils.CalculateProportion(total, good); break; default: break; } }
public void MeasureFailProportion() { var proportion = QualityUtils.CalculateFailProportion(4, 3); Assert.Equal(0.25M, proportion); }