From 8660dd4b88e5ec76d1d2d7583970ba1b1dbc11a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Schr=C3=B6pfer?= Date: Sat, 2 Jan 2021 17:10:54 +0100 Subject: [PATCH] first simple test for positive aspects --- .gitignore | 1 + MatrixBerechnung.ods | Bin 16283 -> 16027 bytes matrix.go | 47 ++++++++++++++++++++++++-- matrix_test.go | 76 +++++++++++++++++++++++++++++++++++++++++++ stakeholder.go | 13 ++++++++ theme.go | 35 ++++++++++++++++++-- 6 files changed, 168 insertions(+), 4 deletions(-) create mode 100644 matrix_test.go diff --git a/.gitignore b/.gitignore index 426169a..0a1dce3 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ # vendor/ .~lock.*.ods# +out.txt diff --git a/MatrixBerechnung.ods b/MatrixBerechnung.ods index f212f511372523049a6c71d1418e1f447ed0e8e8..8d819c0cb79410025bf628e91c07b0bda051c08f 100644 GIT binary patch delta 14079 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" + } + var s string + s += fmt.Sprintf("MaxPoints: %d\n", m.MaxPoints) + s += fmt.Sprintf("MaxValuationPoints: %d\n", m.MaxValuationPoints) + s += fmt.Sprintf("MaxNegValuationPoints: %d\n", m.MaxNegValuationPoints) + s += fmt.Sprintf("NegPointsFactor: %d\n", m.NegPointsFactor) + s += fmt.Sprintf("Calculation: %#v\n", m.Calculation) + s += fmt.Sprintf("Stakeholders: {\n%s\n}\n", m.Stakeholders) + return s +} + +func (m *Matrix) BalancePoints() int { + var balancePoints float64 + m.calcWeightFactor() + m.setMaxValuationPoints() + m.forall(func(t *Theme) { + t.Calc.calcMaxPoints() + t.calcNrPosAspects() + t.calcValPoints() + t.calcEstPercentage() + t.calcBalancePoints() + balancePoints += float64(t.Calc.BalancePoints) + balancePoints += float64(t.Calc.NegativeBlancePoints) + }) + balancePoints = math.Round(balancePoints) + return int(balancePoints) } // MatrixCalc contains calculated values @@ -34,7 +70,14 @@ func (m *Matrix) forall(f func(t *Theme)) { } } +// sumCalcWeight sums all the calculated weights of +// the matrix. func (m *Matrix) sumCalcWeight() { + // calculate the stakeholder weight to each + // theme + for _, s := range m.Stakeholders { + s.calcWeight() + } m.Calculation.SumCalcWeight = 0 m.forall(func(t *Theme) { m.Calculation.SumCalcWeight += t.Calc.CalcWeight @@ -63,7 +106,7 @@ func (m *Matrix) setMaxValuationPoints() { maxThemeValPoints := 0 for _, a := range t.Aspects { a.MaxValuationPoints = m.MaxValuationPoints * int(a.Weight) - maxThemeValPoints += m.MaxNegValuationPoints * int(a.Weight) + maxThemeValPoints += m.MaxValuationPoints * int(a.Weight) } t.Calc.MaxValuationPoints = maxThemeValPoints for _, na := range t.NegativeAspects { diff --git a/matrix_test.go b/matrix_test.go new file mode 100644 index 0000000..2a80471 --- /dev/null +++ b/matrix_test.go @@ -0,0 +1,76 @@ +package goodcalc + +import ( + "fmt" + "testing" +) + +func emptyMatrix() *Matrix { + m := Matrix{ + MaxPoints: 1000, + MaxValuationPoints: 10, + MaxNegValuationPoints: -200, + NegPointsFactor: 50, + Stakeholders: []*Stakeholder{}, + Calculation: &MatrixCalc{ + SumCalcWeight: 0, + WeightFactor: 0, + }, + } + + stakeholderDefault := []Stakeholder{ + {"A", 1.5, []*Theme{}}, + {"B", 0.5, []*Theme{}}, + {"C", 0.5, []*Theme{}}, + {"D", 1, []*Theme{}}, + {"E", 1, []*Theme{}}, + } + + themeDefault := []string{"1", "2", "3", "4"} + for _, st := range stakeholderDefault { + s := st + for _, th := range themeDefault { + t := Theme{ + No: st.No + th, + Weight: 1, + Aspects: []Aspect{}, + NegativeAspects: []NegativeAspect{}, + NegPointsFactor: 0, + Calc: &ThemeCalc{}, + } + for i := 1; i <= 2; i++ { + a := Aspect{ + No: fmt.Sprintf("%s.%d", t.No, i), + Weight: 1, + ValuationPoints: 5, + } + t.Aspects = append(t.Aspects, a) + } + s.Themes = append(s.Themes, &t) + } + m.Stakeholders = append(m.Stakeholders, &s) + } + return &m +} + +func TestMatrix_BalancePoints(t *testing.T) { + tests := []struct { + name string + m *Matrix + want int + }{ + { + "", + emptyMatrix(), + 500, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.m.BalancePoints(); got != tt.want { + t.Errorf("Matrix.BalancePoints() = %v, want %v", got, tt.want) + } + //fmt.Printf("%s", tt.m) + }) + } +} diff --git a/stakeholder.go b/stakeholder.go index 3b766b8..c9a068f 100644 --- a/stakeholder.go +++ b/stakeholder.go @@ -1,5 +1,7 @@ package goodcalc +import "fmt" + // Stakeholder can define a weight, which is calculated to // all containing themes. // No is the id like in the excel @@ -10,6 +12,17 @@ type Stakeholder struct { Themes []*Theme `json:"themes"` } +func (s *Stakeholder) String() string { + var str string + str += fmt.Sprintf("\n No: %s\n", s.No) + str += fmt.Sprintf(" Weight: %.1f\n", s.Weight) + str += fmt.Sprintf(" Themes: %v\n", s.Themes) + return str +} + +// calcWeight takes the weight of the stakeholder level +// and calculates that weight for each theme +// iteration 1 inside the example table func (s *Stakeholder) calcWeight() { for _, t := range s.Themes { t.Calc.CalcWeight = s.Weight * t.Weight diff --git a/theme.go b/theme.go index 73ba742..ec065f2 100644 --- a/theme.go +++ b/theme.go @@ -1,5 +1,7 @@ package goodcalc +import "fmt" + // Theme is the basic element of the matrix. // No defines the id of the excel balance. // A1 for Human dignity in the supply chain @@ -12,6 +14,17 @@ type Theme struct { Calc *ThemeCalc `json:"calculation"` } +func (t *Theme) String() string { + var s string + s += fmt.Sprintf(" No: %s\n", t.No) + s += fmt.Sprintf(" Weight: %.1f\n", t.Weight) + s += fmt.Sprintf(" Aspects: %v\n", t.Aspects) + s += fmt.Sprintf(" NegativeAspects: %v\n", t.NegativeAspects) + s += fmt.Sprintf(" NegPointsFactor: %v\n", t.NegPointsFactor) + s += fmt.Sprintf(" Calc: %s\n", t.Calc) + return s +} + func (t *Theme) calcNrPosAspects() { t.Calc.NrPositiveAspects = len(t.Aspects) } @@ -28,10 +41,10 @@ func (t *Theme) calcValPoints() { } func (t *Theme) calcEstPercentage() { - t.Calc.EstPercentage = 0 + t.Calc.EstPercentage = 1 if t.Calc.MaxValuationPoints != 0 { t.Calc.EstPercentage = - float32(t.Calc.ValuationPoints / t.Calc.MaxValuationPoints) + float32(t.Calc.ValuationPoints) / float32(t.Calc.MaxValuationPoints) } } @@ -57,6 +70,24 @@ type ThemeCalc struct { NegativeBlancePoints float32 `json:"negative_blance_points"` } +func (tc *ThemeCalc) String() string { + if tc == nil { + return "" + } + var s string + s += fmt.Sprintf("\t\tCalcWeight: %.1f\n", tc.CalcWeight) + s += fmt.Sprintf("\t\tWeightFactor: %.1f\n", tc.WeightFactor) + s += fmt.Sprintf("\t\tMaxBalancePoints: %.1f\n", tc.MaxBalancePoints) + s += fmt.Sprintf("\t\tNrPositiveAspects: %d\n", tc.NrPositiveAspects) + s += fmt.Sprintf("\t\tValuationPoints: %d\n", tc.ValuationPoints) + s += fmt.Sprintf("\t\tMaxValuationPoints: %d\n", tc.MaxValuationPoints) + s += fmt.Sprintf("\t\tEstPercentage: %.1f\n", tc.EstPercentage) + s += fmt.Sprintf("\t\tBalancePoints: %.1f\n", tc.BalancePoints) + s += fmt.Sprintf("\t\tNegativeValuationPoints: %d\n", tc.NegativeValuationPoints) + s += fmt.Sprintf("\t\tNegativeBlancePoints: %.1f\n", tc.NegativeBlancePoints) + return s +} + // calcMaxPoints // Stakeholder.calcWeight needs to run first func (c *ThemeCalc) calcMaxPoints() {