循环逻辑通过查看将来的点值来标记一系列数据点的趋势类型

I'm using a for loop that goes through a series of datapoints and works out how to class the trend that the data is showing

Here's the logic to flag the points:

  • If 6 points in a row have a decreasing/increasing trend, flag as "Decreasing Trend"/"Increasing Trend"
  • else if 7 points in a row are below/above the mean, flag as "Below Mean"/"Above Mean"

We prioritising the increasing/decreasing trend over below or above the mean

I think the logic i'm using is incorrect, but i'm unsure why. This is some of the logic in a sentence for the series:

"For each point, if the next 5 points are below this and then their previous partner, mark all those points as 'Decreasing Trend'. Else if a point isn't trend marked, see if the following 6 points from this point are all above or below the mean"

You can copy and paste this in in totality:

package main

import (
"bufio"
"fmt"
"os"
"strings"
)

type points struct {
    quantity   float64
    lowerBound float64
    upperBound float64
    mean       float64
    pattern    string
}

func main() {

var pointsToUse = []points{
    points{quantity: 3.5, lowerBound: 1, upperBound: 4.8,, mean: 4, pattern: "Common Variation"},

    points{
        quantity:   3.4,
        lowerBound: 3,
        upperBound: 4.8,
        mean:       4,
        pattern:    "Common Variation",
    },

    points{
        quantity:   3.2,
        lowerBound: 3,
        upperBound: 4.8,
        mean:       4,
        pattern:    "Common Variation",
    },

    points{
        quantity:   3.19,
        lowerBound: 3,
        upperBound: 4.8,
        mean:       4,
        pattern:    "Common Variation",
    },

    points{
        quantity:   3.17,
        lowerBound: 3,
        upperBound: 4.8,
        mean:       4,
        pattern:    "Common Variation",
    },

    points{
        quantity:   3.14,
        lowerBound: 3,
        upperBound: 4.8,
        mean:       4,
        pattern:    "Common Variation",
    },

    points{
        quantity:   3.12,
        lowerBound: 3,
        upperBound: 4.8,
        mean:       4,
        pattern:    "Common Variation",
    },

    points{
        quantity:   3.09,
        lowerBound: 3,
        upperBound: 4.8,
        mean:       4,
        pattern:    "Common Variation",
    },

    points{
        quantity:   4.1,
        lowerBound: 3,
        upperBound: 4.8,
        mean:       4,
        pattern:    "Common Variation",
    },

    points{
        quantity:   3.16,
        lowerBound: 3,
        upperBound: 4.8,
        mean:       4,
        pattern:    "Common Variation",
    },

    points{
        quantity:   3,
        lowerBound: 3,
        upperBound: 4.8,
        mean:       4,
        pattern:    "Common Variation",
    },
    points{
        quantity:   3,
        lowerBound: 3,
        upperBound: 4.8,
        mean:       4,
        pattern:    "Common Variation",
    },
    points{
        quantity:   3.11,
        lowerBound: 3,
        upperBound: 4.8,
        mean:       4,
        pattern:    "Common Variation",
    },
    points{
        quantity:   3.12,
        lowerBound: 3,
        upperBound: 4.8,
        mean:       4,
        pattern:    "Common Variation",
    },
    points{
        quantity:   3.14,
        lowerBound: 3,
        upperBound: 4.8,
        mean:       4,
        pattern:    "Common Variation",
    },
    points{
        quantity:   3.13,
        lowerBound: 3,
        upperBound: 4.8,
        mean:       4,
        pattern:    "Common Variation",
    },
    points{
        quantity:   3.17,
        lowerBound: 3,
        upperBound: 4.8,
        mean:       4,
        pattern:    "Commons Variation",
    },
}

for i, point := range pointsToUse {

    if len(pointsToUse) >= 6 && len(pointsToUse)-(i+1) >= 5 {
        if point.quantity > pointsToUse[i+1].quantity && pointsToUse[i+1].quantity > pointsToUse[i+2].quantity && pointsToUse[i+2].quantity > pointsToUse[i+3].quantity && pointsToUse[i+3].quantity > pointsToUse[i+4].quantity && pointsToUse[i+4].quantity > pointsToUse[i+5].quantity {
            point.pattern = "Decreasing Trend"
            pointsToUse[i+1].pattern = "Decreasing Trend"
            pointsToUse[i+2].pattern = "Decreasing Trend"
            pointsToUse[i+3].pattern = "Decreasing Trend"
            pointsToUse[i+4].pattern = "Decreasing Trend"
            pointsToUse[i+5].pattern = "Decreasing Trend"
            continue
        } else if point.quantity < pointsToUse[i+1].quantity && pointsToUse[i+1].quantity < pointsToUse[i+2].quantity && pointsToUse[i+2].quantity < pointsToUse[i+3].quantity && pointsToUse[i+3].quantity < pointsToUse[i+4].quantity && pointsToUse[i+4].quantity < pointsToUse[i+5].quantity {
            point.pattern = "Increasing Trend"
            pointsToUse[i+1].pattern = "Increasing Trend"
            pointsToUse[i+2].pattern = "Increasing Trend"
            pointsToUse[i+3].pattern = "Increasing Trend"
            pointsToUse[i+4].pattern = "Increasing Trend"
            pointsToUse[i+5].pattern = "Increasing Trend"
            continue
        }
    }
    if (point.pattern != "Decreasing Trend" || point.pattern != "Increasing Trend") && len(pointsToUse)-(i+1) >= 6 {
        if point.quantity < pointsToUse[i].mean && pointsToUse[i+1].quantity < pointsToUse[i].mean && pointsToUse[i].quantity < pointsToUse[i].mean && pointsToUse[i+3].quantity < pointsToUse[i].mean && pointsToUse[i+4].quantity < pointsToUse[i].mean && pointsToUse[i+5].quantity < pointsToUse[i].mean && pointsToUse[i+6].quantity < pointsToUse[i].mean {
            pointsToUse[i].pattern = "Below Mean"
            pointsToUse[i+1].pattern = "Below Mean"
            pointsToUse[i+2].pattern = "Below Mean"
            pointsToUse[i+3].pattern = "Below Mean"
            pointsToUse[i+4].pattern = "Below Mean"
            pointsToUse[i+5].pattern = "Below Mean"
            pointsToUse[i+6].pattern = "Below Mean"
        } else if point.quantity > pointsToUse[i].mean && pointsToUse[i+1].quantity > pointsToUse[i].mean && pointsToUse[i].quantity > pointsToUse[i].mean && pointsToUse[i+3].quantity > pointsToUse[i].mean && pointsToUse[i+4].quantity > pointsToUse[i].mean && pointsToUse[i+5].quantity < pointsToUse[i].mean && pointsToUse[i+6].quantity < pointsToUse[i].mean {
            pointsToUse[i].pattern = "Above Mean"
            pointsToUse[i+1].pattern = "Above Mean"
            pointsToUse[i+2].pattern = "Above Mean"
            pointsToUse[i+3].pattern = "Above Mean"
            pointsToUse[i+4].pattern = "Above Mean"
            pointsToUse[i+5].pattern = "Above Mean"
            pointsToUse[i+6].pattern = "Above Mean"
        }
    }
}

fmt.Println(pointsToUse)
}

The output that I need to show is this:

3.50 | Decreasing Trend
3.40 | Decreasing Trend
3.20 | Decreasing Trend
3.19 | Decreasing Trend
3.17 | Decreasing Trend
3.14 | Decreasing Trend
3.12 | Decreasing Trend
3.09 | Decreasing Trend
4.1 | Common Variation
3.16 | Below Mean
3.00 | Below Mean
3.00 | Below Mean
3.11 | Below Mean
3.12 | Below Mean
3.14 | Below Mean
3.13 | Below Mean
3.17 | Below Mean

Can someone identify where i'm going wrong?

this line: if (point.pattern != "Decreasing Trend" || point.pattern != "Increasing Trend") && len(pointsToUse)-(i+1) >= 6 {

equals to: if true && len(pointsToUse)-(i+1) >= 6 {

additionaly, you need to use pointsToUse[i].pattern = "Decreasing Trend" instead of point.pattern = "Decreasing Trend" because point is your loop value and does not get assigned in your slice.

Why for _,a := range b references a copy, check out Change values while iterating in Golang (stackoverflow question)

Thanks to icza and sHartmann for pointing me in the right direction:

The full loop is here:

    for i, point := range pointsToUse {

        if len(pointsToUse)-(i+1) >= 5 {
            if point.quantity > pointsToUse[i+1].quantity && pointsToUse[i+1].quantity > pointsToUse[i+2].quantity && pointsToUse[i+2].quantity > pointsToUse[i+3].quantity && pointsToUse[i+3].quantity > pointsToUse[i+4].quantity && pointsToUse[i+4].quantity > pointsToUse[i+5].quantity {
                pointsToUse[i].pattern = "Decreasing Trend"
                pointsToUse[i+1].pattern = "Decreasing Trend"
                pointsToUse[i+2].pattern = "Decreasing Trend"
                pointsToUse[i+3].pattern = "Decreasing Trend"
                pointsToUse[i+4].pattern = "Decreasing Trend"
                pointsToUse[i+5].pattern = "Decreasing Trend"
                continue
            } else if point.quantity < pointsToUse[i+1].quantity && pointsToUse[i+1].quantity < pointsToUse[i+2].quantity && pointsToUse[i+2].quantity < pointsToUse[i+3].quantity && pointsToUse[i+3].quantity < pointsToUse[i+4].quantity && pointsToUse[i+4].quantity < pointsToUse[i+5].quantity {
                pointsToUse[i].pattern = "Increasing Trend"
                pointsToUse[i+1].pattern = "Increasing Trend"
                pointsToUse[i+2].pattern = "Increasing Trend"
                pointsToUse[i+3].pattern = "Increasing Trend"
                pointsToUse[i+4].pattern = "Increasing Trend"
                pointsToUse[i+5].pattern = "Increasing Trend"
                continue
            }
        }

        if pointsToUse[i].pattern == "Decreasing Trend" || pointsToUse[i].pattern == "Increasing Trend" {
            continue
        } else if len(pointsToUse)-(i+1) >= 6 {
            if point.quantity < pointsToUse[i].mean && pointsToUse[i+1].quantity < pointsToUse[i].mean && pointsToUse[i].quantity < pointsToUse[i].mean && pointsToUse[i+3].quantity < pointsToUse[i].mean && pointsToUse[i+4].quantity < pointsToUse[i].mean && pointsToUse[i+5].quantity < pointsToUse[i].mean && pointsToUse[i+6].quantity < pointsToUse[i].mean {
                pointsToUse[i].pattern = "Below Mean"
                pointsToUse[i+1].pattern = "Below Mean"
                pointsToUse[i+2].pattern = "Below Mean"
                pointsToUse[i+3].pattern = "Below Mean"
                pointsToUse[i+4].pattern = "Below Mean"
                pointsToUse[i+5].pattern = "Below Mean"
                pointsToUse[i+6].pattern = "Below Mean"
            } else if point.quantity > pointsToUse[i].mean && pointsToUse[i+1].quantity > pointsToUse[i].mean && pointsToUse[i].quantity > pointsToUse[i].mean && pointsToUse[i+3].quantity > pointsToUse[i].mean && pointsToUse[i+4].quantity > pointsToUse[i].mean && pointsToUse[i+5].quantity < pointsToUse[i].mean && pointsToUse[i+6].quantity < pointsToUse[i].mean {
                pointsToUse[i].pattern = "Above Mean"
                pointsToUse[i+1].pattern = "Above Mean"
                pointsToUse[i+2].pattern = "Above Mean"
                pointsToUse[i+3].pattern = "Above Mean"
                pointsToUse[i+4].pattern = "Above Mean"
                pointsToUse[i+5].pattern = "Above Mean"
                pointsToUse[i+6].pattern = "Above Mean"
            }
        }
}

One of the key changes that I had to make was making an else statement for the Below/Above mean categorisation that follows from this statement that stops this increment in the loop:

        if pointsToUse[i].pattern == "Decreasing Trend" || pointsToUse[i].pattern == "Increasing Trend" {
        continue
    }