Skip to content

Utility library for calculations for applying the "Laser Focus" priority strategy.

License

Notifications You must be signed in to change notification settings

FlineDev/LaserFocusKit-Swift

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Laser Focus Header

LaserFocusKit-Swift

Utility library for calculations when applying the Laser Focus priority strategy.

Usage

VECTOR

This library calculates the overall priority for a given graph of categorized actionable items, such as features or tasks. It supports any number of actionable item levels, e.g. you can provide an entire range of levels like "Epic", "Story", "Feature", "Task", "Sub-Task", "Step" as input. The main method takes just the top level ("Epic" in this case) and walks through the other children levels automatically.

For example, imagine you have the features "A", "B", and "C". Some of them have 3 tasks "1", "2", and "3". And some of the tasks have subtasks, "x", "y", and "z". So the input is this top level array with its children:

let inputs: [ActionableInput] = [
  .init(name: "A", localCategory: .vital, children: [
    .init(name: "A1", localCategory: .vital, children: [
      .init(name: "A1x", localCategory: .vital),
      .init(name: "A1y", localCategory: .essential),
      .init(name: "A1z", localCategory: .completing)]
    ),
    .init(name: "A2", localCategory: .essential),
    .init(name: "A3", localCategory: .completing, children: [
      .init(name: "A3x", localCategory: .vital),
      .init(name: "A3y", localCategory: .essential),
      .init(name: "A3z", localCategory: .completing)]
    )]
  ),
  .init(name: "B", localCategory: .optional, children: [
    .init(name: "B1", localCategory: .vital),
    .init(name: "B2", localCategory: .essential, children: [
      .init(name: "B2x", localCategory: .vital),
      .init(name: "B2y", localCategory: .retracting),
      .init(name: "B2z", localCategory: .completing)]
    )]
  ),
  .init(name: "C", localCategory: .completing)
]

What we want to know in the Laser Focus strategy, is the global category for each "leaf" element in the graph, or the elements without children, the "atomic" elements, so to say. These elements are not further split(table) and can directly be worked on. Just calling the LaserFocus.prioritizedAtoms(inputs:) gives us exactly these elements:

let outputs: [ActionableOutput] = LaserFocus.prioritizedAtoms(inputs: inputs)

Each element in ActionableOutput has a globalCategory which includes the overall category of the atomic actionable, which serves as the primary prioritization point. Additionally, each ActionableOutput also has an averageCategoryRawValue numeric property which can be used to prioritize tasks with the same globalCategory for improved precision.

The simplest way to get the list of tasks in the correct priority order is to just call sorted() on the outputs as ActionableOutput is Comparable:

let sortedOutputs: [ActionableOutput] = outputs.sorted()

print(sortedOutputs.map(\.name)) // => ["A1x", "A1y", "A2", "A1z", "A3x", "A3y", "A3z", "C", "B2x", "B1", "B2z", "B2y"]

Note that both the input ActionableInput and output type ActionableOutput are Codable and can therefore be easily read from & written to JSON.

About

Utility library for calculations for applying the "Laser Focus" priority strategy.

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published

Languages