Skip to content

Repository files navigation

Precedence Diagram Method for Go

This is a Go package that provides an implementation to help plan dependencies of a project via the Precedence Diagram Method.

CI Status codecov Docs

Table of Contents

Install

Install via go get. Note that Go 1.23 or newer is required.

# After: go mod init ...
go get -u github.com/gtantech/pdm

Features

  • 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

Example

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())
	}

}

Error Handling

CycleDetectedError

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())
	}
}

License

Licensed under MIT License

Acknowledgements

  • Engineer4Free youtube playlist
    • A big thank you to Engineer4Free (youtube) for their amazing course in project management. Most of the test cases used in this project were from their worked examples in their project management playlist.

Thanks!

Thanks for reading and happy coding! Add a star to the project if you find it useful!

About

A precedence diagram method package for project management

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages