ЁЯО▓ рдзрдбрд╛ 05 тАФ рдирд┐рдпреЛрдЬрди рдЖрдгрд┐ рдЕрдВрджрд╛рдЬ: Monte Carlo forecast рд╡рд┐рд░реБрджреНрдз рдПрдХрдЪ рддрд╛рд░реАрдЦ
ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 05 ┬╖ рдорд╛рдЧреЗ: lesson-04-hiring ┬╖ рдкреБрдвреЗ: lesson-06-prioritisation
ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ
рдзрдбрд╛ 04, рдЖрдгрд┐ "рд╣реЗ рдХрдзреА рдкреВрд░реНрдг рд╣реЛрдИрд▓?" рдпрд╛рдЪреЗ рдкреНрд░рд╛рдорд╛рдгрд┐рдХ рдЙрддреНрддрд░. рд╕рд░рд╛рд╕рд░реАрд╡рд░реВрди рдХрд╛рдврд▓реЗрд▓реА рдПрдХрдЪ рддрд╛рд░реАрдЦ
рдмрд╣реБрддреЗрдХ рд╡реЗрд│рд╛ рдирд╛рдгреЗрдлреЗрдХ рдХрд╛ рдЕрд╕рддреЗ, рдЖрдгрд┐ рдЯреАрдордЪреНрдпрд╛ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ рдорд╛рдЧреАрд▓ throughput рд╡рд░реВрди рдмрдирд╡рд▓реЗрд▓рд╛ Monte Carlo
forecast рд╕рдВрднрд╛рд╡реНрдпрддреЗрд╕рд╣ range рдХрд╢реА рджреЗрддреЛ: 50% рддрд╛рд░реАрдЦ, 85% рддрд╛рд░реАрдЦ рдЖрдгрд┐ 95% рддрд╛рд░реАрдЦ.
lead/demo.py рдордзрд▓реЗ forecast(); lead/models.py рдордзрд▓реЗ
monte_carlo() рдЖрдгрд┐ pct().
ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ
рдореБрдЦреНрдпрд╛рдзреНрдпрд╛рдкрд┐рдХрд╛ рдХрддрд░рд┐рдирд╛рд▓рд╛ рд╡рд┐рдЪрд╛рд░рддрд╛рдд: "рд╡рд┐рднрд╛рдЧ рд╕рдЧрд│реНрдпрд╛ 40 рдЙрддреНрддрд░рдкрддреНрд░рд┐рдХрд╛ рддрдкрд╛рд╕реВрди рдХрдзреА рдкреВрд░реНрдг рдХрд░реЗрд▓?" ЁЯУЪ
рдХрддрд░рд┐рдирд╛ рдорд╛рдЧрдЪреЗ рджрд╣рд╛ рдЖрдард╡рдбреЗ рдкрд╛рд╣рддреЗ. рдХрд╛рд╣реА рдЖрдард╡рдбреНрдпрд╛рдВрдд рд╡рд┐рднрд╛рдЧрд╛рдиреЗ 6 рдХрд┐рдВрд╡рд╛ 7 рддрдкрд╛рд╕рдгреАрдЪреА рдХрд╛рдореЗ рдкреВрд░реНрдг рдХреЗрд▓реА. рдПрдХрд╛ рдЖрдард╡рдбреНрдпрд╛рдд тАФ рдХреНрд░реАрдбрд╛ рд╕рдкреНрддрд╛рд╣рд╛рдд тАФ рдПрдХрд╣реА рдирд╛рд╣реА. рд╕рд░рд╛рд╕рд░реА, рдЖрдард╡рдбреНрдпрд╛рд▓рд╛ рдЬрд╡рд│рдкрд╛рд╕ 3.7.
рд╕реЛрдкреЗ рдЙрддреНрддрд░: "40 ├╖ 3.7 тЙИ 11 рдЖрдард╡рдбреЗ." рдкрдг рдпрд╛рдд рдЕрд╕реЗ рдЧреГрд╣реАрдд рдзрд░рд▓реЗ рдЖрд╣реЗ рдХреА рдкреНрд░рддреНрдпреЗрдХ рдЖрдард╡рдбрд╛ рд╕рд░рд╛рд╕рд░реА рдЖрдард╡рдбрд╛ рдЕрд╕реЗрд▓. рдХрд╛рд╣реА рдЖрдард╡рдбреЗ рд╕рдВрде рдЕрд╕рддреАрд▓. ЁЯРв
рдореНрд╣рдгреВрди рдХрддрд░рд┐рдирд╛ рдПрдХ рдЦреЗрд│ рдЦреЗрд│рддреЗ. ЁЯО▓ рддреА рдорд╛рдЧрдЪреЗ рджрд╣рд╛ рдЖрдард╡рдбреЗ рджрд╣рд╛ рдкрддреНрддреНрдпрд╛рдВрд╡рд░ рд▓рд┐рд╣рд┐рддреЗ. рддреА рдпрд╛рджреГрдЪреНрдЫрд┐рдХрдкрдгреЗ рдПрдХ рдкрддреНрддрд╛ рдХрд╛рдврддреЗ тАФ рддреЛ "рдкреБрдврдЪрд╛ рдЖрдард╡рдбрд╛". рддреА рддрдкрд╛рд╕рдгреАрдЪреА рдмреЗрд░реАрдЬ рдХрд░рддреЗ, рдкреБрдиреНрд╣рд╛ рдкрддреНрддрд╛ рдХрд╛рдврддреЗ, рдкреБрдиреНрд╣рд╛, 40 рдЙрддреНрддрд░рдкрддреНрд░рд┐рдХрд╛ рдкреВрд░реНрдг рд╣реЛрдИрдкрд░реНрдпрдВрдд. рддреА рдЖрдард╡рдбреЗ рдореЛрдЬрддреЗ. рдордЧ рддреА рд╕рдВрдкреВрд░реНрдг рдЦреЗрд│ 10,000 рд╡реЗрд│рд╛ рдЦреЗрд│рддреЗ (computer рдорджрдд рдХрд░рддреЛ!).
рдЕрд░реНрдзреЗ рдЦреЗрд│ 11 рдЖрдард╡рдбреНрдпрд╛рдВрдд рдХрд┐рдВрд╡рд╛ рдХрдореА рд╡реЗрд│рд╛рдд рд╕рдВрдкрддрд╛рдд. рдкрдг 100 рдкреИрдХреА 85 рдЦреЗрд│ 13 рдЖрдард╡рдбреНрдпрд╛рдВрдд рдХрд┐рдВрд╡рд╛ рдХрдореА рд╡реЗрд│рд╛рдд рд╕рдВрдкрддрд╛рдд. рдореНрд╣рдгреВрди рддреА рдореБрдЦреНрдпрд╛рдзреНрдпрд╛рдкрд┐рдХрд╛рдВрдирд╛ рд╕рд╛рдВрдЧрддреЗ: "11 рдЖрдард╡рдбреЗ рдореНрд╣рдгрдЬреЗ рдирд╛рдгреЗрдлреЗрдХ. рддреБрдореНрд╣рд╛рд▓рд╛ рдмрд▒реНрдпрд╛рдкреИрдХреА рдЦрд╛рддреНрд░реА рд╣рд╡реА рдЕрд╕реЗрд▓ рддрд░ 13 рдЪреЗ рдирд┐рдпреЛрдЬрди рдХрд░рд╛."
ЁЯЧ║я╕П рдЖрдХреГрддреА
flowchart LR
h["ЁЯУТ last 10 weeks<br/>2 6 1 4 7 0 5 3 6 3<br/>average 3.7"] --> g["ЁЯзо single guess<br/>40 ├╖ 3.7 тЙИ 11 weeks"]
g --> c["58% chance<br/>of finishing by then"]
h --> mc["ЁЯО▓ 10,000 seeded trials<br/>replay random past weeks"]
mc --> r["50%: 11 wk ┬╖ 85%: 13 wk ┬╖ 95%: 15 wk"]
r --> s["ЁЯУИ backlog +20% тЖТ 48 items<br/>50%: 13 wk ┬╖ 85%: 16 wk"]
ЁЯЧ║я╕П рдХрд╛рдврд▓реЗрд▓реА рдЖрд╡реГрддреНрддреА + рдПрдХ lab: https://school-edh.pages.dev/engineering-leadership/lesson-diagrams.html#l05
тЭУ рдХрд╛рдп
- Estimate рд╡рд┐рд░реБрджреНрдз forecast тАФ estimate рдХрд╛рдорд╛рдЪреНрдпрд╛ рдЖрдХрд╛рд░рд╛рдЪрд╛ рдЕрдВрджрд╛рдЬ рдХрд░рддреЛ ("рд╣реЗ 3 рджрд┐рд╡рд╕рд╛рдВрдЪреЗ рдЖрд╣реЗ"). Forecast рдкреБрд░рд╛рд╡реНрдпрд╛рд╡рд░реВрди, рд╕рд╛рдВрдЧрд┐рддрд▓реЗрд▓реНрдпрд╛ рд╕рдВрднрд╛рд╡реНрдпрддреЗрд╕рд╣, рддрд╛рд░реАрдЦ рд╡рд░реНрддрд╡рддреЛ. рдкреНрд░рддреНрдпреЗрдХ рдХрд╛рдо estimate рди рдХрд░рддрд╛рд╣реА рддреБрдореНрд╣реА forecast рдХрд░реВ рд╢рдХрддрд╛ тАФ рдХрд╛рдореЗ рдЬреНрдпрд╛ рджрд░рд╛рдиреЗ рдкреВрд░реНрдг рд╣реЛрдд рдЖрд▓реА рдЖрд╣реЗрдд рддреНрдпрд╛рд╡рд░реВрди.
- Throughput тАФ рдЯреАрдо рджрд░ рдЖрдард╡рдбреНрдпрд╛рд▓рд╛ рдХрд┐рддреА рдХрд╛рдореЗ рдкреВрд░реНрдг рдХрд░рддреЗ. рд╣реЗ рдореЛрдЬрд▓реЗ рдЬрд╛рддреЗ, рдЕрдВрджрд╛рдЬрд▓реЗ рдЬрд╛рдд рдирд╛рд╣реА, рдореНрд╣рдгреВрди рддреНрдпрд╛рдд meetings, рдЖрдЬрд╛рд░рдкрдгрд╛рдЪреЗ рджрд┐рд╡рд╕, bugs рдЖрдгрд┐ рд╡реНрдпрддреНрдпрдп рдЖрдзреАрдЪ рд╕рдорд╛рд╡рд┐рд╖реНрдЯ рдЕрд╕рддрд╛рдд.
- Monte Carlo simulation тАФ рдПрдЦрд╛рджреА рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЕрдиреЗрдХ рд╡реЗрд│рд╛ рдЪрд╛рд▓рд╡рд╛ рдЖрдгрд┐ рдирд┐рдХрд╛рд▓рд╛рдВрдЪрд╛ рдкрд╕рд╛рд░рд╛ рдкрд╛рд╣рд╛. рдЗрдереЗ: backlog рдкреВрд░реНрдг рд╣реЛрдИрдкрд░реНрдпрдВрдд рдкреНрд░рддреНрдпреЗрдХ рднрд╛рд╡реА рдЖрдард╡рдбреНрдпрд╛рд╕рд╛рдареА рдорд╛рдЧреАрд▓ рдПрдЦрд╛рджреНрдпрд╛ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдЖрдард╡рдбреНрдпрд╛рдЪрд╛ throughput рдирд┐рд╡рдбрд╛; рд╣реЗ 10,000 рд╡реЗрд│рд╛ рдХрд░рд╛. рдпрд╛ рдкрджреНрдзрддреАрдЪреЗ рд╡рд░реНрдгрди Troy Magennis рдЖрдгрд┐ Daniel Vacanti рдпрд╛рдВрд╕рд╛рд░рдЦреНрдпрд╛ practitioners рдиреА рдХреЗрд▓реЗ рдЖрд╣реЗ.
- Percentile dates тАФ 50% рддрд╛рд░реАрдЦ рдореНрд╣рдгрдЬреЗ median: рддреЛрдкрд░реНрдпрдВрдд рдЕрд░реНрдзреЗ trials рдкреВрд░реНрдг рдЭрд╛рд▓реЗ. 85% рддрд╛рд░реАрдЦ: рддреЛрдкрд░реНрдпрдВрдд 100 рдкреИрдХреА 85 trials рдкреВрд░реНрдг рдЭрд╛рд▓реЗ. рдкрд░рд┐рд╕реНрдерд┐рддреАрд▓рд╛ рдХрд┐рддреА рдЦрд╛рддреНрд░реА рд╣рд╡реА рддреЗ lead рдирд┐рд╡рдбрддреЗ тАФ рдард░рд▓реЗрд▓реНрдпрд╛ рдкрд░реАрдХреНрд╖реЗрдЪреНрдпрд╛ рддрд╛рд░рдЦреЗрд▓рд╛ рдЕрдВрддрд░реНрдЧрдд target рдкреЗрдХреНрд╖рд╛ рдЬрд╛рд╕реНрдд рдЦрд╛рддреНрд░реА рд▓рд╛рдЧрддреЗ.
- рдПрдХрд╛рдЪ рддрд╛рд░рдЦреЗрдЪрд╛ рд╕рд╛рдкрд│рд╛ тАФ backlog рд▓рд╛ рд╕рд░рд╛рд╕рд░реА throughput рдиреЗ рднрд╛рдЧрд▓реНрдпрд╛рд╕ рд╕рд╛рдзрд╛рд░рдг median рдорд┐рд│рддреЛ: рдЬрд╡рд│рдкрд╛рд╕ 50/50 рд╢рдХреНрдпрддрд╛. рддреЗ "рддреА рддрд╛рд░реАрдЦ" рдореНрд╣рдгреВрди рдорд╛рдВрдбрд▓реНрдпрд╛рдиреЗ рдирд╛рдгреЗрдлреЗрдХ рд▓рдкрддреЗ.
- рдЧреГрд╣реАрддрдХреЗ (рджрд░ рд╡реЗрд│реА рд▓рд┐рд╣реВрди рдареЗрд╡рд╛): рднрд╡рд┐рд╖реНрдп рдЕрд▓реАрдХрдбрдЪреНрдпрд╛ рднреВрддрдХрд╛рд│рд╛рд╕рд╛рд░рдЦреЗ рдЕрд╕реЗрд▓; рдХрд╛рдореЗ рд╕рд╛рдзрд╛рд░рдг рд╕рд╛рд░рдЦреНрдпрд╛ рдЖрдХрд╛рд░рд╛рдЪреА рдЖрд╣реЗрдд, рдХрд┐рдВрд╡рд╛ рдХрд┐рдорд╛рди рддреНрдпрд╛рдЪ рдкреНрд░рдХрд╛рд░реЗ рдорд┐рд╕рд│рд▓реЗрд▓реА; рдЖрдард╡рдбреЗ рдПрдХрдореЗрдХрд╛рдВрд╡рд░ рдЕрд╡рд▓рдВрдмреВрди рдирд╛рд╣реАрдд; backlog рдЪреА рд╕рдВрдЦреНрдпрд╛ рдкреНрд░рд╛рдорд╛рдгрд┐рдХ рдЖрд╣реЗ. рдХрд╛рдо рд╕рдордЬрдд рдЬрд╛рддреЗ рддрд╕реЗ backlog рд╕рд╣рд╕рд╛ рд╡рд╛рдврддреЛ тАФ рддрд╕реЗ рдЭрд╛рд▓реНрдпрд╛рд╡рд░ рдкреБрдиреНрд╣рд╛ forecast рдХрд░рд╛.
ЁЯдФ рдХрд╛
рдХрд╛рд░рдг рдПрдХрдЪ рддрд╛рд░реАрдЦ рд╡рдЪрди рдореНрд╣рдгреВрди рдРрдХрд▓реА рдЬрд╛рддреЗ, рдЖрдгрд┐ рд╕рд░рд╛рд╕рд░реАрд╡рд░ рдЖрдзрд╛рд░рд▓реЗрд▓реЗ рд╡рдЪрди рдЬрд╡рд│рдкрд╛рд╕ рдЕрд░реНрдзреНрдпрд╛ рд╡реЗрд│рд╛ рдЪреБрдХрддреЗ тАФ рдЬреНрдпрд╛рдореБрд│реЗ рд╕рдЧрд│реЗ рд╢рд┐рдХрддрд╛рдд рдХреА рдЕрдВрджрд╛рдЬ рдирд┐рд░реБрдкрдпреЛрдЧреА рдЕрд╕рддрд╛рдд. рд╕рдВрднрд╛рд╡реНрдпрддреЗрд╕рд╣ range рддреБрдордЪреНрдпрд╛рд╡рд░ рдЕрд╡рд▓рдВрдмреВрди рдЕрд╕рд▓реЗрд▓реНрдпрд╛рдВрдирд╛ рдирд┐рдпреЛрдЬрди рдХрд░реВ рджреЗрддреЗ: "рдЖрдард╡рдбрд╛ 13 рдкрд░реНрдпрдВрдд 85%" рд╣реЗ рдореБрдЦреНрдпрд╛рдзреНрдпрд╛рдкрд┐рдХрд╛рдВрдирд╛ рддреНрдпрд╛ рдХрд┐рддреА рдзреЛрдХрд╛ рдмрд╛рд│рдЧрдд рдЖрд╣реЗрдд рддреЗ рд╕рд╛рдВрдЧрддреЗ. рдЖрдгрд┐ forecast рдореЛрдЬрд▓реЗрд▓реНрдпрд╛ throughput рд╡рд░реВрди рдмрдирдд рдЕрд╕рд▓реНрдпрд╛рдиреЗ, рддреНрдпрд╛рд▓рд╛ рд▓рд╛рдВрдмрд▓рдЪрдХ estimation meetings рд▓рд╛рдЧрдд рдирд╛рд╣реАрдд.
ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)
lead/models.py рдордзрд▓реЗ monte_carlo(history, backlog, trials=10000, seed=42)
рдЫреЛрдЯрд╛ seeded random generator Rng рд╡рд╛рдкрд░рддреЗ, рдореНрд╣рдгреВрди рдкреНрд░рддреНрдпреЗрдХ run рддреЗрдЪ рдЖрдХрдбреЗ print рдХрд░рддреЛ. рдкреНрд░рддреНрдпреЗрдХ trial
рд╕рд╛рдареА рддреЗ рдкреВрд░реНрдг рдЭрд╛рд▓реЗрд▓реА рдХрд╛рдореЗ backlog рдкрд░реНрдпрдВрдд рдкреЛрд╣реЛрдЪреЗрдкрд░реНрдпрдВрдд history рдордзреВрди рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдЖрдард╡рдбреЗ рдХрд╛рдврддреЗ, рдЖрдгрд┐
рдЖрдард╡рдбреНрдпрд╛рдВрдЪреА рд╕рдВрдЦреНрдпрд╛ рдиреЛрдВрджрд╡рддреЗ. рддреЗ sorted list рдкрд░рдд рджреЗрддреЗ; pct(runs, p) рддреНрдпрд╛рддреВрди percentile рд╡рд╛рдЪрддреЗ.
lead/demo.py рдордзрд▓реЗ forecast() рдПрдХрд╛рдЪ рдЕрдВрджрд╛рдЬрд╛рдЪреА 50/85/95% рддрд╛рд░рдЦрд╛рдВрд╢реА рдЖрдгрд┐ 20% рдиреЗ
рд╡рд╛рдврдгрд╛рд▒реНрдпрд╛ backlog рд╢реА рддреБрд▓рдирд╛ рдХрд░рддреЗ. рд╡рд┐рдЪрд╛рд░ рдХрд░рдгреНрдпрд╛рдЪреЗ рд╕рд╛рдзрди, рдорд╛рдгрд╕рд╛рдВрд╕рд╛рдареАрдЪреЗ рд╕реВрддреНрд░ рдирд╛рд╣реА: рддреЗ рдХрд╛рдорд╛рдЪреНрдпрд╛
system рдЪрд╛ forecast рдХрд░рддреЗ, рдЖрдгрд┐ рддреНрдпрд╛рдЪреЗ рдХрдзреАрд╣реА рд╡реНрдпрдХреНрддреАрдВрд╕рд╛рдареАрдЪреНрдпрд╛ target рдордзреНрдпреЗ рд░реВрдкрд╛рдВрддрд░ рд╣реЛрддрд╛ рдХрд╛рдорд╛ рдирдпреЗ.
ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛
python3 lead/demo.py forecast
python3 - <<'EOF'
import sys; sys.path.insert(0, "lead"); from models import monte_carlo, pct
hist = [2, 6, 1, 4, 7, 0, 5, 3, 6, 3]
for backlog in (20, 40, 60):
r = monte_carlo(hist, backlog)
print(f"backlog {backlog:>2} тЖТ 50%: {pct(r, .5):>2} wk ┬╖ 85%: {pct(r, .85):>2} wk ┬╖ 95%: {pct(r, .95):>2} wk ┬╖ single guess {round(backlog / 3.7):>2} wk")
for seed in (1, 2, 3):
r = monte_carlo(hist, 40, seed=seed)
print(f"seed {seed} тЖТ 50%: {pct(r, .5)} ┬╖ 85%: {pct(r, .85)}")
steady = monte_carlo([4, 4, 3, 4, 4, 3, 4, 4, 3, 4], 40)
print(f"a steadier team, same 3.7 average тЖТ 50%: {pct(steady, .5)} ┬╖ 85%: {pct(steady, .85)} ┬╖ 95%: {pct(steady, .95)}")
EOF
тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ
forecast рдЕрд╕реЗ print рдХрд░рддреЗ:
тФАтФА the last 10 weeks' throughput (items finished): [2, 6, 1, 4, 7, 0, 5, 3, 6, 3] ┬╖ average 3.7/week ┬╖ backlog 40 items
the single-date guess: 40 ├╖ 3.7 тЙИ 11 weeks
Monte Carlo, 10,000 seeded trials replaying random past weeks тЖТ 50%: 11 weeks ┬╖ 85%: 13 weeks ┬╖ 95%: 15 weeks
chance of finishing within the guess (11 weeks): 58%
тФАтФА the backlog grows 20% (40 тЖТ 48 items) тЖТ 50%: 13 weeks ┬╖ 85%: 16 weeks
рддреБрдордЪрд╛ snippet рдЕрд╕реЗ print рдХрд░рддреЛ:
backlog 20 тЖТ 50%: 6 wk ┬╖ 85%: 7 wk ┬╖ 95%: 9 wk ┬╖ single guess 5 wk
backlog 40 тЖТ 50%: 11 wk ┬╖ 85%: 13 wk ┬╖ 95%: 15 wk ┬╖ single guess 11 wk
backlog 60 тЖТ 50%: 17 wk ┬╖ 85%: 19 wk ┬╖ 95%: 21 wk ┬╖ single guess 16 wk
seed 1 тЖТ 50%: 11 ┬╖ 85%: 13
seed 2 тЖТ 50%: 11 ┬╖ 85%: 13
seed 3 тЖТ 50%: 11 ┬╖ 85%: 13
a steadier team, same 3.7 average тЖТ 50%: 11 ┬╖ 85%: 12 ┬╖ 95%: 12
ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ
рдПрдХрдЪ рдЕрдВрджрд╛рдЬ (11 рдЖрдард╡рдбреЗ) median рд╡рд░ рдмрд╕рддреЛ: рддреЛ рдкрд╛рд│рд▓рд╛ рдЬрд╛рдгреНрдпрд╛рдЪреА рдлрдХреНрдд 58% рд╢рдХреНрдпрддрд╛. 85% рддрд╛рд░реАрдЦ 13 рдЖрдард╡рдбреЗ рдЖрдгрд┐ 95% рддрд╛рд░реАрдЦ 15 рдЖрд╣реЗ. рд╡реЗрдЧрд╡реЗрдЧрд│реЗ seeds рддреЗрдЪ рдЙрддреНрддрд░ рджреЗрддрд╛рдд, рдореНрд╣рдгреВрди рдпрд╛ history рд╕рд╛рдареА 10,000 trials рдкреБрд░реЗрд╕реЗ рдЖрд╣реЗрдд. рддреНрдпрд╛рдЪ рд╕рд░рд╛рд╕рд░реАрдЪреА рдЕрдзрд┐рдХ рд╕реНрдерд┐рд░ рдЯреАрдо рдЦреВрдк рдЕрд░реБрдВрдж range рджреЗрддреЗ (рдЖрдард╡рдбрд╛ 12 рдкрд░реНрдпрдВрдд 85%) тАФ рдЕрдВрджрд╛рдЬ рд╡рд░реНрддрд╡рддрд╛ рдпреЗрдгреЗ рдХрдореА рдЪрдврдЙрддрд╛рд░рд╛рддреВрди рдпреЗрддреЗ, рдЬрд╛рд╕реНрдд рд╕рд░рд╛рд╕рд░реАрддреВрди рдирд╛рд╣реА. рдЖрдгрд┐ 20% рдореЛрдареНрдпрд╛ backlog рдиреЗ 85% рддрд╛рд░реАрдЦ 13 рд╡рд░реВрди 16 рдЖрдард╡рдбреНрдпрд╛рдВрд╡рд░ рдиреЗрд▓реА.
тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛
- рд╕рдВрднрд╛рд╡реНрдпрддреЗрд╢рд┐рд╡рд╛рдп рдПрдХрдЪ рддрд╛рд░реАрдЦ рджреЗрдгреЗ, рдЖрдгрд┐ рддреА рд╡рдЪрди рдореНрд╣рдгреВрди рдкреБрдиреНрд╣рд╛ рдкреБрдиреНрд╣рд╛ рдРрдХрдгреЗ
- рдореЛрдЬрд▓реЗрд▓реНрдпрд╛ throughput рдРрд╡рдЬреА рдЖрджрд░реНрд╢ рдХреНрд╖рдорддреЗрд╡рд░реВрди forecast рдХрд░рдгреЗ ("5 рд▓реЛрдХ ├Ч 5 рджрд┐рд╡рд╕")
- рдЦреВрдк рд╡реЗрдЧрд╡реЗрдЧрд│реНрдпрд╛ рдЖрдХрд╛рд░рд╛рдВрдЪреА рдХрд╛рдореЗ (рдПрдХ рддрд╛рд╕рд╛рдЪрд╛ fix рдЖрдгрд┐ рджреЛрди рдорд╣рд┐рдиреНрдпрд╛рдВрдЪрд╛ project) рдПрдХрд╛рдЪ рдореЛрдЬрдгреАрдд рдорд┐рд╕рд│рдгреЗ
- рдПрдХрджрд╛рдЪ forecast рдХрд░рдгреЗ рдЖрдгрд┐ рдкреБрдиреНрд╣рд╛ рдХрдзреАрдЪ рдирд╛рд╣реА тАФ history рдЖрдгрд┐ backlog рдмрджрд▓рддрд╛рдд рддрд╕рд╛ рддреЛ рджрд░ рдЖрдард╡рдбреНрдпрд╛рд▓рд╛ рдкреБрдиреНрд╣рд╛ рдЪрд╛рд▓рд╡рд╛
- forecast рдЪреЗ рд╡реНрдпрдХреНрддреАрдВрд╕рд╛рдареАрдЪреНрдпрд╛ target рдордзреНрдпреЗ рд░реВрдкрд╛рдВрддрд░ рдХрд░рдгреЗ (targets рдХрд╛рдп рдХрд░рддрд╛рдд рддреЗ рдзрдбрд╛ 08 рджрд╛рдЦрд╡рддреЛ)
- backlog рд╡рд╛рдвреЗрд▓ рд╣реЗ рд╡рд┐рд╕рд░рдгреЗ: рдХрд╛рдо рд╕рдордЬрдд рдЬрд╛рддреЗ рддрд╢реА рдирд╡реА рдХрд╛рдореЗ рджрд┐рд╕рддрд╛рдд
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд
Throughput рдореНрд╣рдгрдЬреЗ рджрд░ рдЖрдард╡рдбреНрдпрд╛рд▓рд╛ рдкреВрд░реНрдг рдЭрд╛рд▓реЗрд▓реНрдпрд╛ рдХрд╛рдорд╛рдВрдЪреА рд╕рдВрдЦреНрдпрд╛, рдЬреА рдмрд╣реБрддреЗрдХ trackers export рдХрд░реВ рд╢рдХрддрд╛рдд. рдЦрд▒реНрдпрд╛ repository рд╡рд░, рджрд░ рдЖрдард╡рдбреНрдпрд╛рд▓рд╛ merge рдЭрд╛рд▓реЗрд▓реЗ pull requests рд╣рд╛ рдвреЛрдмрд│ рдкрд░реНрдпрд╛рдп рдЖрд╣реЗ (рдПрдХ рдХрд╛рдо рдореНрд╣рдгрдЬреЗ рдЕрдиреЗрдХ PRs рдЕрд╕реВ рд╢рдХрддрд╛рдд тАФ рд╣реЗ рдЧреГрд╣реАрддрдХ рдиреЛрдВрджрд╡рд╛):
gh pr list --state merged --limit 200 --json mergedAt \
--jq '.[].mergedAt[0:10]' | sort | uniq -c | tail -20
рд╕рдВрдкреВрд░реНрдг forecast рддреБрдордЪреНрдпрд╛ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ script рдЪреНрдпрд╛ рдХрд╛рд╣реА рдУрд│реАрдВрдд, рдХрд┐рдВрд╡рд╛ spreadsheet рдордзреНрдпреЗ рдмрд╕рддреЛ:
import random
def forecast(history, backlog, trials=10_000):
runs = []
for _ in range(trials):
done = weeks = 0
while done < backlog:
done += random.choice(history); weeks += 1
runs.append(weeks)
runs.sort()
return {p: runs[int(p / 100 * trials) - 1] for p in (50, 85, 95)}
рд▓реЛрдХрд╛рдВрдирд╛ рдЕрд╕реЗ рд╕рд╛рдВрдЧрд╛:
Gradebook migration тАФ forecast, week 14
40 items left ┬╖ based on the last 10 weeks' throughput
50%: week 25 ┬╖ 85%: week 27 ┬╖ 95%: week 29
Assumptions: similar item mix; no new scope; Leela joins on-call in week 18.
Next re-forecast: Monday.
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ рдЖрд╣реЗ: "рд╣реЗ 14 рддрд╛рд░рдЦреЗрд▓рд╛ рдкреВрд░реНрдг рд╣реЛрдИрд▓" рдРрд╡рдЬреА "21 рддрд╛рд░рдЦреЗрдкрд░реНрдпрдВрдд 85%, рджрд░ рдЖрдард╡рдбреНрдпрд╛рд▓рд╛ рдкреБрдиреНрд╣рд╛ forecast" рдЕрд╕реЗ рдореНрд╣рдгрд╛. рд▓реЛрдХ range рднреЛрд╡рддреА рдирд┐рдпреЛрдЬрди рдХрд░реВ рд╢рдХрддрд╛рдд; рдЕрд░реНрдзреНрдпрд╛ рд╡реЗрд│рд╛ рдмрд░реЛрдмрд░ рдард░рдгрд╛рд▒реНрдпрд╛ рддрд╛рд░рдЦреЗрднреЛрд╡рддреА рддреЗ рдирд┐рдпреЛрдЬрди рдХрд░реВ рд╢рдХрдд рдирд╛рд╣реАрдд.
тПня╕П рдкреБрдвреЗ
Forecast рдиреЗ рдЕрд╕реЗ рдЧреГрд╣реАрдд рдзрд░рд▓реЗ рдХреА рдЖрдзреА рдХрд╛рдп рдХрд░рд╛рдпрдЪреЗ рд╣реЗ рддреБрдореНрд╣рд╛рд▓рд╛ рдЖрдзреАрдЪ рдорд╛рд╣реАрдд рдЖрд╣реЗ. рдкреБрдвреЗ: рдХреНрд░рдо рдард░рд╡рдгреЗ тАФ prioritisation, рдЧреГрд╣реАрддрдХреЗ рджреГрд╢реНрдп рдХрд░реВрди.
git checkout lesson-06-prioritisation