-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmain.ts
More file actions
61 lines (49 loc) · 2.98 KB
/
main.ts
File metadata and controls
61 lines (49 loc) · 2.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import { Test } from "./Experiment/Test";
import {KanbanTest} from "./Experiment/KanbanTest"
import {ScrumTest} from "./Experiment/ScrumTest"
import {WaterfallExperiment} from "./Experiment/WaterfallExperiment"
import {SmallTeamTest} from "./Experiment/SmallTeamTest"
import {ScrumPartialStackTest} from "./Experiment/ScrumPartialStackTest"
import { Statistics } from "./Simulation/Statistics";
import { Result } from "./Experiment/Result";
const experiments = new Array<Test>(new SmallTeamTest(), new ScrumTest(), new KanbanTest(), new ScrumPartialStackTest(), new WaterfallExperiment());
console.log(`
Experiments search for:
1) Shortest lead time
2) Follows as close uniform distribution as possible
3) Delivers biggest amount of stories (value), this is a given as under the experiment everyone needs to deliver set amount of stories.
As a starting point experiment will be setup to have a bias towards delivering work right at the end the cycle.
All lower ▼ the better.
`);
experiments.forEach((experiment) => {
const results = experiment.Run();
console.log(`
##############################START###################################
### ${experiment.Name} Experiment
${experiment.Description}
# Assumptions
${results.Assumptions.reduce((s,a,i) => s+((i+1) + ": " + a[0] + " => " + a[1] + "\n"), "")}
# Control
${resultView(results.Control, results.EffortPerTick)}
# Experiment
${resultView(results.Experiment, results.EffortPerTick)}
# Control vs Experiment (Null Hypothesis): ${results.NullHypothesis ? "No difference (Not Rejected)" : "Significant difference (Rejected)"}
##############################END###################################
`);
});
function resultView(result : Result, tickSize : number) {
return ` Total mean man-days: original ${Statistics.ToDecimalPlace(result.WorkSizeOriginalMean)}, actual ${Statistics.ToDecimalPlace(result.WorkSizeActualMean)}
Conditions:
${result.Conditions.map((c) => " " + c[0] + " : " + c[1]).join("\n")}
## Lead Time
Days Deviation: ${result.LeadTime.Frequency}
*When* delivered:
First 25% delivered on day ${result.LeadTime.Quartiles[0] * tickSize}, 50% ${result.LeadTime.Quartiles[1] * tickSize}, 75% ${result.LeadTime.Quartiles[2] * tickSize}, last 25% ${result.LeadTime.Max * tickSize}
## Cycle Time
*Time taken* to deliver once started:
25% has taken ${result.CycleTime.Quartiles[0] * tickSize} day(s), 50% ${result.CycleTime.Quartiles[1] * tickSize}, 75% ${result.CycleTime.Quartiles[2] * tickSize}, last 25% ${result.CycleTime.Max * tickSize}
## Constraint
Member: ${result.Constraint}, Idle Deviation: ${Statistics.ToDecimalPlace(result.TeamMembersIdleFrequency)}
## Team Members
${result.TeamMembers.reduce((s,m) => s+(" "+ m.Name + " => idle days " + Statistics.ToDecimalPlace(m.TimeIdle.Median,0) + ", turn count: waiting " + Statistics.ToDecimalPlace(m.SkipNotMyTurn.Median,1) + ", preq " + Statistics.ToDecimalPlace(m.SkipPrerequisite.Median,1) + ", feedback " + Statistics.ToDecimalPlace(m.GivenFeedback.Median,1) + "\n"), "")}`;
}