This is a Go package that provides an implementation to help plan dependencies of a project via the Precedence Diagram Method.
Install via go get. Note that Go 1.23 or newer is required.
# After: go mod init ...
go get -u github.com/gtantech/pdm- Adding activities from a table of dependencies
- Critical activity identification
- Early Start, Early Finish, Late Start, Late Finish calculations of each activity
- Total Float and Free Float calculations of each activity
- Determining which activities are start, middle or final, or are isolated
- Cycle detection (circular dependencies)
- Project duration
package main
import (
"fmt"
"time"
"github.com/gtantech/pdm"
"github.com/gtantech/pdm/activity"
"github.com/gtantech/pdm/enums"
"github.com/gtantech/pdm/relationship"
)
type Attributes struct {
activity.Data
Name string
}
func main() {
project := pdm.New[Attributes]()
// add activities (optional)
A := project.AddActivity(activity.New(Attributes{Data: activity.NewData(5 * time.Hour), Name: "A"}))
B := project.AddActivity(activity.New(Attributes{Data: activity.NewData(4 * time.Hour), Name: "B"}))
C := project.AddActivity(activity.New(Attributes{Data: activity.NewData(5 * time.Hour), Name: "C"}))
D := project.AddActivity(activity.New(Attributes{Data: activity.NewData(6 * time.Hour), Name: "D"}))
E := project.AddActivity(activity.New(Attributes{Data: activity.NewData(3 * time.Hour), Name: "E"}))
F := project.AddActivity(activity.New(Attributes{Data: activity.NewData(4 * time.Hour), Name: "F"}))
// add dependencies to pdm
// // A has no dependencies
project.AddDependency(A, B, relationship.New(enums.FS)) // B depends on A
project.AddDependency(A, C, relationship.New(enums.FS)) // C depends on A
project.AddDependency(B, D, relationship.New(enums.FS)) // .
project.AddDependency(C, E, relationship.New(enums.FS)) // .
project.AddDependency(D, F, relationship.New(enums.FS)) // F depends on D and E
project.AddDependency(E, F, relationship.New(enums.FS))
// remember to call UpdateActivityTimestamps() to update the early/late start/finish of each activity
project.UpdateActivityTimestamps()
// print the early/late start/finish of each activity
for _, activity := range []activity.Activity[Attributes]{A, B, C, D, E, F} {
fmt.Printf("Activity %v:\n", activity.Data().Name)
fmt.Printf("Early Start:%-5v \tEarly Finish:%-5v\n",
activity.Early().Start(), activity.Early().Finish())
fmt.Printf("Late Start:%-5v \tLate Finish:%-5v\n\n",
activity.Late().Start(), activity.Late().Finish())
}
}pdm.UpdateActivityTimestamps() features cycle detection and will return a CycleDetectedError when encountering a cycle within the network of activities. Below is an error handling example, continued from the above example.
err := project.UpdateActivityTimestamps()
if err != nil {
var e *pdm.CycleDetectedError[activity.Activity[Attributes], relationship.Relationship]
if errors.As(err, &e) {
fmt.Printf("encountered cycle from %v to %v with relationship: %v",
e.Predecessor.Data().Name,
e.Successor.Data().Name,
e.Relationship.Type())
}
}Licensed under MIT License
- Engineer4Free youtube playlist
Thanks for reading and happy coding! Add a star to the project if you find it useful!