helper

package
v2.0.0-beta.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 8, 2024 License: AGPL-3.0 Imports: 17 Imported by: 0

README

helper

import "github.com/cinar/indicator/v2/helper"

Package helper contains the helper functions.

This package belongs to the Indicator project. Indicator is a Golang module that supplies a variety of technical indicators, strategies, and a backtesting framework for analysis.

License
Copyright (c) 2021-2024 Onur Cinar.
The source code is provided under GNU AGPLv3 License.
https://github.com/cinar/indicator
Disclaimer

The information provided on this project is strictly for informational purposes and is not to be construed as advice or solicitation to buy or sell any security.

Index

Constants

const (
    // CsvHeaderTag represents the parameter name for the column header.
    CsvHeaderTag = "header"

    // CsvFormatTag represents the parameter name for the column format.
    CsvFormatTag = "format"

    // DefaultDateTimeFormat denotes the default format of a date and time column.
    DefaultDateTimeFormat = "2006-01-02 15:04:05"
)

func Abs

func Abs[T Number](c <-chan T) <-chan T

Abs calculates the absolute value of each value in a channel of float64.

Example:

abs := helper.Abs(helper.SliceToChan([]int{-10, 20, -4, -5}))
fmt.Println(helper.ChanToSlice(abs)) // [10, 20, 4, 5]

func Add

func Add[T Number](ac, bc <-chan T) <-chan T

Add adds each pair of values from the two input channels of float64 and returns a new channel containing the sums.

Example:

ac := helper.SliceToChan([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
bc := helper.SliceToChan([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})

actual := helper.ChanToSlice(helper.Add(ac, bc))

fmt.Println(actual) // [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

func AppendOrWriteToCsvFile

func AppendOrWriteToCsvFile[T any](fileName string, hasHeader bool, rows <-chan *T) error

AppendOrWriteToCsvFile writes the provided rows of data to the specified file, appending to the existing file if it exists or creating a new one if it doesn't. In append mode, the function assumes that the existing file's column order matches the field order of the given row struct to ensure consistent data structure.

func Apply

func Apply[T Number](c <-chan T, f func(T) T) <-chan T

Apply applies the given transformation function to each element in the input channel and returns a new channel containing the transformed values. The transformation function takes a float64 value as input and returns a float64 value as output.

Example:

timesTwo := helper.Apply(c, func(n int) int {
	return n * 2
})

func Buffered

func Buffered[T any](c <-chan T, size int) <-chan T

Buffered takes a channel of any type and returns a new channel of the same type with a buffer of the specified size. This allows the original channel to continue sending data even if the receiving end is temporarily unavailable.

Example:

func ChanToJSON

func ChanToJSON[T any](c <-chan T, w io.Writer) error

ChanToJSON converts a channel of values into JSON format and writes it to the specified writer.

Example:

input := helper.SliceToChan([]int{2, 4, 6, 8})

var buffer bytes.Buffer
err := helper.ChanToJSON(input, &buffer)

fmt.Println(buffer.String())
// Output: [2,4,6,8,9]

func ChanToSlice

func ChanToSlice[T any](c <-chan T) []T

ChanToSlice converts a channel of float64 to a slice of float64.

Example:

c := make(chan int, 4)
c <- 1
c <- 2
c < -3
c <- 4
close(c)

fmt.Println(helper.ChanToSlice(c)) // [1, 2, 3, 4]

func Change

func Change[T Number](c <-chan T, before int) <-chan T

Change calculates the difference between the current value and the value N before.

Example:

input := []int{1, 2, 5, 5, 8, 2, 1, 1, 3, 4}
output := helper.Change(helper.SliceToChan(input), 2)
fmt.Println(helper.ChanToSlice(output)) // [4, 3, 3, -3, -7, -1, 2, 3]

func ChangePercent

func ChangePercent[T Number](c <-chan T, before int) <-chan T

ChangePercent calculates the percentage change between the current value and the value N positions before.

Example:

c := helper.ChanToSlice([]float64{1, 2, 5, 5, 8, 2, 1, 1, 3, 4})
actual := helper.ChangePercent(c, 2))
fmt.Println(helper.ChanToSlice(actual)) // [400, 150, 60, -60, -87.5, -50, 200, 300]

func ChangeRatio

func ChangeRatio[T Number](c <-chan T, before int) <-chan T

ChangeRatio calculates the ratio change between the current value and the value N positions before.

Example:

c := helper.ChanToSlice([]float64{1, 2, 5, 5, 8, 2, 1, 1, 3, 4})
actual := helper.ChangeRatio(c, 2))
fmt.Println(helper.ChanToSlice(actual)) // [400, 150, 60, -60, -87.5, -50, 200, 300]

func CheckEquals

func CheckEquals[T comparable](inputs ...<-chan T) error

CheckEquals determines whether the two channels are equal.

func Count

func Count[T Number, O any](from T, other <-chan O) <-chan T

Count generates a sequence of numbers starting with a specified value, from, and incrementing by one until the given other channel continues to produce values.

Example:

other := make(chan int, 4)
other <- 1
other <- 1
other <- 1
other <- 1
close(other)

c := Count(0, other)

fmt.Println(<- s) // 1
fmt.Println(<- s) // 2
fmt.Println(<- s) // 3
fmt.Println(<- s) // 4

func DecrementBy

func DecrementBy[T Number](c <-chan T, d T) <-chan T

DecrementBy decrements each element in the input channel by the specified decrement value and returns a new channel containing the decremented values.

Example:

input := helper.SliceToChan([]int{1, 2, 3, 4})
substractOne := helper.DecrementBy(input, 1)
fmt.Println(helper.ChanToSlice(substractOne)) // [0, 1, 2, 3]

func Divide

func Divide[T Number](ac, bc <-chan T) <-chan T

Divide takes two channels of float64 and divides the values from the first channel with the values from the second one. It returns a new channel containing the results of the division.

Example:

ac := helper.SliceToChan([]int{2, 4, 6, 8, 10})
bc := helper.SliceToChan([]int{2, 1, 3, 2, 5})

divison := helper.Divide(ac, bc)

fmt.Println(helper.ChanToSlice(division)) // [1, 4, 2, 4, 2]

func DivideBy

func DivideBy[T Number](c <-chan T, d T) <-chan T

DivideBy divides each element in the input channel of float64 values by the given divider and returns a new channel containing the divided values.

Example:

half := helper.DivideBy(helper.SliceToChan([]int{2, 4, 6, 8}), 2)
fmt.Println(helper.ChanToSlice(half)) // [1, 2, 3, 4]

func Drain

func Drain[T any](c <-chan T)

Drain drains the given channel. It blocks the caller.

func Duplicate

func Duplicate[T any](input <-chan T, count int) []<-chan T

Duplicate duplicates a given receive-only channel by reading each value coming out of that channel and sending them on requested number of new output channels.

Example:

expected := helper.SliceToChan([]float64{-10, 20, -4, -5})
outputs := helper.Duplicates[float64](helper.SliceToChan(expected), 2)

fmt.Println(helper.ChanToSlice(outputs[0])) // [-10, 20, -4, -5]
fmt.Println(helper.ChanToSlice(outputs[1])) // [-10, 20, -4, -5]

func Echo

func Echo[T any](input <-chan T, last, count int) <-chan T

Echo takes a channel of numbers, repeats the specified count of numbers at the end by the specified count.

Example:

input := helper.SliceToChan([]int{2, 4, 6, 8})
output := helper.Echo(input, 2, 4))
fmt.Println(helper.ChanToSlice(output)) // [2, 4, 6, 8, 6, 8, 6, 8, 6, 8, 6, 8]

func Field

func Field[T, S any](c <-chan *S, name string) (<-chan T, error)

Field extracts a specific field from a channel of struct pointers and delivers it through a new channel.

func Filter

func Filter[T any](c <-chan T, p func(T) bool) <-chan T

Filter filters the items from the input channel based on the provided predicate function. The predicate function takes a float64 value as input and returns a boolean value indicating whether the value should be included in the output channel.

Example:

even := helper.Filter(c, func(n int) bool {
  return n%2 == 0
})

func First

func First[T any](c <-chan T, count int) <-chan T

First takes a channel of values and returns a new channel containing the first N values.

func Head

func Head[T Number](c <-chan T, count int) <-chan T

Head retrieves the specified number of elements from the given channel of float64 values and delivers them through a new channel.

Example:

c := helper.SliceToChan([]int{2, 4, 6, 8})
actual := helper.Head(c, 2)
fmt.Println(helper.ChanToSlice(actual)) // [2, 4]

func IncrementBy

func IncrementBy[T Number](c <-chan T, i T) <-chan T

IncrementBy increments each element in the input channel by the specified increment value and returns a new channel containing the incremented values.

Example:

input := []int{1, 2, 3, 4}
actual := helper.IncrementBy(helper.SliceToChan(input), 1)
fmt.Println(helper.ChanToSlice(actual)) // [2, 3, 4, 5]

func JSONToChan

func JSONToChan[T any](r io.Reader) <-chan T

JSONToChan reads values from the specified reader in JSON format into a channel of values.

Example:

func KeepNegatives

func KeepNegatives[T Number](c <-chan T) <-chan T

KeepNegatives processes a stream of float64 values, retaining negative values unchanged and replacing positive values with zero.

Example:

c := helper.SliceToChan([]int{-10, 20, 4, -5})
negatives := helper.KeepPositives(c)
fmt.Println(helper.ChanToSlice(negatives)) // [-10, 0, 0, -5]

func KeepPositives

func KeepPositives[T Number](c <-chan T) <-chan T

KeepPositives processes a stream of float64 values, retaining positive values unchanged and replacing negative values with zero.

Example:

c := helper.SliceToChan([]int{-10, 20, 4, -5})
positives := helper.KeepPositives(c)
fmt.Println(helper.ChanToSlice(positives)) // [0, 20, 4, 0]

func Last

func Last[T any](c <-chan T, count int) <-chan T

Last takes a channel of values and returns a new channel containing the last N values.

func Map

func Map[F, T any](c <-chan F, f func(F) T) <-chan T

Map applies the given transformation function to each element in the input channel and returns a new channel containing the transformed values. The transformation function takes a float64 value as input and returns a float64 value as output.

Example:

timesTwo := helper.Map(c, func(n int) int {
	return n * 2
})

func MapWithPrevious

func MapWithPrevious[F, T any](c <-chan F, f func(T, F) T, previous T) <-chan T

MapWithPrevious applies a transformation function to each element in an input channel, creating a new channel with the transformed values. It maintains a "memory" of the previous result, allowing the transformation function to consider both the current element and the outcome of the previous transformation. This enables functions that rely on accumulated state or sequential dependencies between elements.

Example:

sum := helper.MapWithPrevious(c, func(p, c int) int {
	return p + c
}, 0)

func Multiply

func Multiply[T Number](ac, bc <-chan T) <-chan T

Multiply takes two channels of float64 and multiples the values from the first channel with the values from the second channel. It returns a new channel containing the results of the multiplication.

Example:

ac := helper.SliceToChan([]int{1, 4, 2, 4, 2})
bc := helper.SliceToChan([]int{2, 1, 3, 2, 5})

multiplication := helper.Multiply(ac, bc)

fmt.Println(helper.ChanToSlice(multiplication)) // [2, 4, 6, 8, 10]

func MultiplyBy

func MultiplyBy[T Number](c <-chan T, m T) <-chan T

MultiplyBy multiplies each element in the input channel of float64 values by the given multiplier and returns a new channel containing the multiplied values.

Example:

c := helper.SliceToChan([]int{1, 2, 3, 4})
twoTimes := helper.MultiplyBy(c, 2)
fmt.Println(helper.ChanToSlice(twoTimes)) // [2, 4, 6, 8]

func Operate

func Operate[A any, B any, R any](ac <-chan A, bc <-chan B, o func(A, B) R) <-chan R

Operate applies the provided operate function to corresponding values from two numeric input channels and sends the resulting values to an output channel.

Example:

add := helper.Operate(ac, bc, func(a, b int) int {
  return a + b
})

func Operate3

func Operate3[A any, B any, C any, R any](ac <-chan A, bc <-chan B, cc <-chan C, o func(A, B, C) R) <-chan R

Operate3 applies the provided operate function to corresponding values from three numeric input channels and sends the resulting values to an output channel.

Example:

add := helper.Operate3(ac, bc, cc, func(a, b, c int) int {
  return a + b + c
})

func Pipe

func Pipe[T any](f <-chan T, t chan<- T)

Pipe function takes an input channel and an output channel and copies all elements from the input channel into the output channel.

Example:

input := helper.SliceToChan([]int{2, 4, 6, 8})
output := make(chan int)
helper.Pipe(input, output)
fmt.println(helper.ChanToSlice(output)) // [2, 4, 6, 8]

func Pow

func Pow[T Number](c <-chan T, y T) <-chan T

Pow takes a channel of float64 values and returns the element-wise base-value exponential of y.

Example:

c := helper.SliceToChan([]int{2, 3, 5, 10})
squared := helper.Pow(c, 2)
fmt.Println(helper.ChanToSlice(squared)) // [4, 9, 25, 100]

func ReadFromCsvFile

func ReadFromCsvFile[T any](fileName string, hasHeader bool) (<-chan *T, error)

ReadFromCsvFile creates a CSV instance, parses CSV data from the provided filename, maps the data to corresponding struct fields, and delivers it through the channel.

func RoundDigit

func RoundDigit[T Number](n T, d int) T

RoundDigit rounds the given float64 number to d decimal places.

Example:

n := helper.RoundDigit(10.1234, 2)
fmt.Println(n) // 10.12

func RoundDigits

func RoundDigits[T Number](c <-chan T, d int) <-chan T

RoundDigits takes a channel of float64 numbers and rounds them to d decimal places.

Example:

c := helper.SliceToChan([]float64{10.1234, 5.678, 6.78, 8.91011})
rounded := helper.RoundDigits(c, 2)
fmt.Println(helper.ChanToSlice(rounded)) // [10.12, 5.68, 6.78, 8.91]

func Seq

func Seq[T Number](from, to, increment T) <-chan T

Seq generates a sequence of numbers starting with a specified value, from, and incrementing by a specified amount, increment, until a specified value, to, is reached or exceeded. The sequence includes both from and to.

Example:

s := Seq(1, 5, 1)
defer close(s)

fmt.Println(<- s) // 1
fmt.Println(<- s) // 2
fmt.Println(<- s) // 3
fmt.Println(<- s) // 4

func Shift

func Shift[T any](c <-chan T, count int, fill T) <-chan T

Shift takes a channel of numbers, shifts them to the right by the specified count, and fills in any missing values with the provided fill value.

Example:

input := helper.SliceToChan([]int{2, 4, 6, 8})
output := helper.ChanToSlice(input, 4, 0))
fmt.Println(helper.ChanToSlice(output)) // [0, 0, 0, 0, 2, 4, 6, 8]

func Sign

func Sign[T Number](c <-chan T) <-chan T

Sign takes a channel of float64 values and returns their signs as -1 for negative, 0 for zero, and 1 for positive.

Example:

c := helper.SliceToChan([]int{-10, 20, -4, 0})
sign := helper.Sign(c)
fmt.Println(helper.ChanToSlice(sign)) // [-1, 1, -1, 0]

func Since

func Since[T comparable, R Number](c <-chan T) <-chan R

Since counts the number of periods since the last change of value in a channel of numbers.

func Skip

func Skip[T any](c <-chan T, count int) <-chan T

Skip skips the specified number of elements from the given channel of float64.

Example:

c := helper.SliceToChan([]int{2, 4, 6, 8})
actual := helper.Skip(c, 2)
fmt.Println(helper.ChanToSlice(actual)) // [6, 8]

func SliceToChan

func SliceToChan[T any](slice []T) <-chan T

SliceToChan converts a slice of float64 to a channel of float64.

Example:

slice := []float64{2, 4, 6, 8}
c := helper.SliceToChan(slice)
fmt.Println(<- c)  // 2
fmt.Println(<- c)  // 4
fmt.Println(<- c)  // 6
fmt.Println(<- c)  // 8

func Sqrt

func Sqrt[T Number](c <-chan T) <-chan T

Sqrt calculates the square root of each value in a channel of float64.

Example:

c := helper.SliceToChan([]int{9, 81, 16, 100})
sqrt := helper.Sqrt(c)
fmt.Println(helper.ChanToSlice(sqrt)) // [3, 9, 4, 10]

func Subtract

func Subtract[T Number](ac, bc <-chan T) <-chan T

Subtract takes two channels of float64 and subtracts the values from the second channel from the first one. It returns a new channel containing the results of the subtractions.

Example:

ac := helper.SliceToChan([]int{2, 4, 6, 8, 10})
bc := helper.SliceToChan([]int{1, 2, 3, 4, 5})
actual := helper.Subtract(ac, bc)
fmt.Println(helper.ChanToSlice(actual)) // [1, 2, 3, 4, 5]

func Waitable

func Waitable[T any](wg *sync.WaitGroup, c <-chan T) <-chan T

Waitable increments the wait group before reading from the channel and signals completion when the channel is closed.

type Bst

Bst represents the binary search tree.

type Bst[T Number] struct {
    // contains filtered or unexported fields
}

func NewBst
func NewBst[T Number]() *Bst[T]

NewBst creates a new binary search tree.

func (*Bst[T]) Contains
func (b *Bst[T]) Contains(value T) bool

Contains checks whether the given value exists in the binary search tree.

func (*Bst[T]) Insert
func (b *Bst[T]) Insert(value T)

Insert adds a new value to the binary search tree.

func (*Bst[T]) Max
func (b *Bst[T]) Max() T

Max function returns the maximum value in the binary search tree.

func (*Bst[T]) Min
func (b *Bst[T]) Min() T

Min function returns the minimum value in the binary search tree.

func (*Bst[T]) Remove
func (b *Bst[T]) Remove(value T) bool

Remove removes the specified value from the binary search tree and rebalances the tree.

type BstNode

BstNode represents the binary search tree node.

type BstNode[T Number] struct {
    // contains filtered or unexported fields
}

type Csv

Csv represents the configuration for CSV reader and writer.

type Csv[T any] struct {
    // contains filtered or unexported fields
}

func NewCsv
func NewCsv[T any](hasHeader bool) (*Csv[T], error)

NewCsv function initializes a new CSV instance. The parameter hasHeader indicates whether the CSV contains a header row.

func (*Csv[T]) AppendToFile
func (c *Csv[T]) AppendToFile(fileName string, rows <-chan *T) error

AppendToFile appends the provided rows of data to the end of the specified file, creating the file if it doesn't exist. In append mode, the function assumes that the existing file's column order matches the field order of the given row struct to ensure consistent data structure.

func (*Csv[T]) ReadFromFile
func (c *Csv[T]) ReadFromFile(fileName string) (<-chan *T, error)

ReadFromFile parses the CSV data from the provided file name, maps the data to corresponding struct fields, and delivers the resulting rows through the channel.

func (*Csv[T]) ReadFromReader
func (c *Csv[T]) ReadFromReader(reader io.Reader) <-chan *T

ReadFromReader parses the CSV data from the provided reader, maps the data to corresponding struct fields, and delivers the resulting it through the channel.

func (*Csv[T]) WriteToFile
func (c *Csv[T]) WriteToFile(fileName string, rows <-chan *T) error

WriteToFile creates a new file with the given name and writes the provided rows of data to it, overwriting any existing content.

type Float

Float refers to any float type.

type Float interface {
    // contains filtered or unexported methods
}

type Integer

Integer refers to any integer type.

type Integer interface {
    // contains filtered or unexported methods
}

type Number

Number refers to any numeric type.

type Number interface {
    // contains filtered or unexported methods
}

type Report

Report generates an HTML file containing an interactive chart that visually represents the provided data and annotations.

The generated HTML file can be opened in a web browser to explore the data visually, interact with the chart elements, and view the associated annotations.

type Report struct {
    // contains filtered or unexported fields
}

func NewReport
func NewReport(title string, date <-chan time.Time) *Report

NewReport takes a channel of time as the time axis and returns a new instance of the Report struct. This instance can later be used to add data and annotations and subsequently generate a report.

func (*Report) AddChart
func (r *Report) AddChart() int

AddChart adds a new chart to the report and returns its unique identifier. This identifier can be used later to refer to the chart and add columns to it.

func (*Report) AddColumn
func (r *Report) AddColumn(column ReportColumn, charts ...int)

AddColumn adds a new data column to the specified charts. If no chart is specified, it will be added to the main chart.

func (*Report) WriteToFile
func (r *Report) WriteToFile(fileName string) error

WriteToFile writes the generated report content to a file with the specified name. This allows users to conveniently save the report for later viewing or analysis.

func (*Report) WriteToWriter
func (r *Report) WriteToWriter(writer io.Writer) error

WriteToWriter writes the report content to the provided io.Writer. This allows the report to be sent to various destinations, such as a file, a network socket, or even the standard output.

type ReportColumn

ReportColumn defines the interface that all report data columns must implement. This interface ensures that different types of data columns can be used consistently within the report generation process.

type ReportColumn interface {
    // Name returns the name of the report column.
    Name() string

    // Type returns the data type of the report column.
    Type() string

    // Role returns the role of the report column.
    Role() string

    // Value returns the next data value for the report column.
    Value() string
}

func NewAnnotationReportColumn
func NewAnnotationReportColumn(values <-chan string) ReportColumn

NewAnnotationReportColumn returns a new instance of a annotation column for a report.

func NewNumericReportColumn
func NewNumericReportColumn[T Number](name string, values <-chan T) ReportColumn

NewNumericReportColumn returns a new instance of a numeric data column for a report.

type Ring

Ring represents a ring structure that can be instantiated using the NewRing function.

Example:

ring := helper.NewRing[int](2)

fmt.Println(ring.Insert(1)) // 0
fmt.Println(ring.Insert(2)) // 0
fmt.Println(ring.Insert(3)) // 1
fmt.Println(ring.Insert(4)) // 2
type Ring[T any] struct {
    // contains filtered or unexported fields
}

func NewRing
func NewRing[T any](size int) *Ring[T]

NewRing creates a new ring instance with the given size.

func (*Ring[T]) At
func (r *Ring[T]) At(index int) T

At returns the value at the given index.

func (*Ring[T]) Get
func (r *Ring[T]) Get() (T, bool)

Get retrieves the available value from the ring buffer. If empty, it returns the default value (T) and false.

func (*Ring[T]) IsEmpty
func (r *Ring[T]) IsEmpty() bool

IsEmpty checks if the current ring buffer is empty.

func (*Ring[T]) IsFull
func (r *Ring[T]) IsFull() bool

IsFull checks if the current ring buffer is full.

func (*Ring[T]) Put
func (r *Ring[T]) Put(t T) T

Put inserts the specified value into the ring and returns the value that was previously stored at that index.

Generated by gomarkdoc

Documentation

Overview

Package helper contains the helper functions.

This package belongs to the Indicator project. Indicator is a Golang module that supplies a variety of technical indicators, strategies, and a backtesting framework for analysis.

License

Copyright (c) 2021-2024 Onur Cinar.
The source code is provided under GNU AGPLv3 License.
https://github.com/cinar/indicator

Disclaimer

The information provided on this project is strictly for informational purposes and is not to be construed as advice or solicitation to buy or sell any security.

Index

Constants

View Source
const (
	// CsvHeaderTag represents the parameter name for the column header.
	CsvHeaderTag = "header"

	// CsvFormatTag represents the parameter name for the column format.
	CsvFormatTag = "format"

	// DefaultDateTimeFormat denotes the default format of a date and time column.
	DefaultDateTimeFormat = "2006-01-02 15:04:05"
)

Variables

This section is empty.

Functions

func Abs

func Abs[T Number](c <-chan T) <-chan T

Abs calculates the absolute value of each value in a channel of float64.

Example:

abs := helper.Abs(helper.SliceToChan([]int{-10, 20, -4, -5}))
fmt.Println(helper.ChanToSlice(abs)) // [10, 20, 4, 5]

func Add

func Add[T Number](ac, bc <-chan T) <-chan T

Add adds each pair of values from the two input channels of float64 and returns a new channel containing the sums.

Example:

ac := helper.SliceToChan([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
bc := helper.SliceToChan([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})

actual := helper.ChanToSlice(helper.Add(ac, bc))

fmt.Println(actual) // [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

func AppendOrWriteToCsvFile

func AppendOrWriteToCsvFile[T any](fileName string, hasHeader bool, rows <-chan *T) error

AppendOrWriteToCsvFile writes the provided rows of data to the specified file, appending to the existing file if it exists or creating a new one if it doesn't. In append mode, the function assumes that the existing file's column order matches the field order of the given row struct to ensure consistent data structure.

func Apply

func Apply[T Number](c <-chan T, f func(T) T) <-chan T

Apply applies the given transformation function to each element in the input channel and returns a new channel containing the transformed values. The transformation function takes a float64 value as input and returns a float64 value as output.

Example:

timesTwo := helper.Apply(c, func(n int) int {
	return n * 2
})

func Buffered

func Buffered[T any](c <-chan T, size int) <-chan T

Buffered takes a channel of any type and returns a new channel of the same type with a buffer of the specified size. This allows the original channel to continue sending data even if the receiving end is temporarily unavailable.

Example:

func ChanToJSON

func ChanToJSON[T any](c <-chan T, w io.Writer) error

ChanToJSON converts a channel of values into JSON format and writes it to the specified writer.

Example:

input := helper.SliceToChan([]int{2, 4, 6, 8})

var buffer bytes.Buffer
err := helper.ChanToJSON(input, &buffer)

fmt.Println(buffer.String())
// Output: [2,4,6,8,9]

func ChanToSlice

func ChanToSlice[T any](c <-chan T) []T

ChanToSlice converts a channel of float64 to a slice of float64.

Example:

c := make(chan int, 4)
c <- 1
c <- 2
c < -3
c <- 4
close(c)

fmt.Println(helper.ChanToSlice(c)) // [1, 2, 3, 4]

func Change

func Change[T Number](c <-chan T, before int) <-chan T

Change calculates the difference between the current value and the value N before.

Example:

input := []int{1, 2, 5, 5, 8, 2, 1, 1, 3, 4}
output := helper.Change(helper.SliceToChan(input), 2)
fmt.Println(helper.ChanToSlice(output)) // [4, 3, 3, -3, -7, -1, 2, 3]

func ChangePercent

func ChangePercent[T Number](c <-chan T, before int) <-chan T

ChangePercent calculates the percentage change between the current value and the value N positions before.

Example:

c := helper.ChanToSlice([]float64{1, 2, 5, 5, 8, 2, 1, 1, 3, 4})
actual := helper.ChangePercent(c, 2))
fmt.Println(helper.ChanToSlice(actual)) // [400, 150, 60, -60, -87.5, -50, 200, 300]

func ChangeRatio

func ChangeRatio[T Number](c <-chan T, before int) <-chan T

ChangeRatio calculates the ratio change between the current value and the value N positions before.

Example:

c := helper.ChanToSlice([]float64{1, 2, 5, 5, 8, 2, 1, 1, 3, 4})
actual := helper.ChangeRatio(c, 2))
fmt.Println(helper.ChanToSlice(actual)) // [400, 150, 60, -60, -87.5, -50, 200, 300]

func CheckEquals

func CheckEquals[T comparable](inputs ...<-chan T) error

CheckEquals determines whether the two channels are equal.

func Count

func Count[T Number, O any](from T, other <-chan O) <-chan T

Count generates a sequence of numbers starting with a specified value, from, and incrementing by one until the given other channel continues to produce values.

Example:

other := make(chan int, 4)
other <- 1
other <- 1
other <- 1
other <- 1
close(other)

c := Count(0, other)

fmt.Println(<- s) // 1
fmt.Println(<- s) // 2
fmt.Println(<- s) // 3
fmt.Println(<- s) // 4

func DecrementBy

func DecrementBy[T Number](c <-chan T, d T) <-chan T

DecrementBy decrements each element in the input channel by the specified decrement value and returns a new channel containing the decremented values.

Example:

input := helper.SliceToChan([]int{1, 2, 3, 4})
substractOne := helper.DecrementBy(input, 1)
fmt.Println(helper.ChanToSlice(substractOne)) // [0, 1, 2, 3]

func Divide

func Divide[T Number](ac, bc <-chan T) <-chan T

Divide takes two channels of float64 and divides the values from the first channel with the values from the second one. It returns a new channel containing the results of the division.

Example:

ac := helper.SliceToChan([]int{2, 4, 6, 8, 10})
bc := helper.SliceToChan([]int{2, 1, 3, 2, 5})

divison := helper.Divide(ac, bc)

fmt.Println(helper.ChanToSlice(division)) // [1, 4, 2, 4, 2]

func DivideBy

func DivideBy[T Number](c <-chan T, d T) <-chan T

DivideBy divides each element in the input channel of float64 values by the given divider and returns a new channel containing the divided values.

Example:

half := helper.DivideBy(helper.SliceToChan([]int{2, 4, 6, 8}), 2)
fmt.Println(helper.ChanToSlice(half)) // [1, 2, 3, 4]

func Drain

func Drain[T any](c <-chan T)

Drain drains the given channel. It blocks the caller.

func Duplicate

func Duplicate[T any](input <-chan T, count int) []<-chan T

Duplicate duplicates a given receive-only channel by reading each value coming out of that channel and sending them on requested number of new output channels.

Example:

expected := helper.SliceToChan([]float64{-10, 20, -4, -5})
outputs := helper.Duplicates[float64](helper.SliceToChan(expected), 2)

fmt.Println(helper.ChanToSlice(outputs[0])) // [-10, 20, -4, -5]
fmt.Println(helper.ChanToSlice(outputs[1])) // [-10, 20, -4, -5]

func Echo

func Echo[T any](input <-chan T, last, count int) <-chan T

Echo takes a channel of numbers, repeats the specified count of numbers at the end by the specified count.

Example:

input := helper.SliceToChan([]int{2, 4, 6, 8})
output := helper.Echo(input, 2, 4))
fmt.Println(helper.ChanToSlice(output)) // [2, 4, 6, 8, 6, 8, 6, 8, 6, 8, 6, 8]

func Field

func Field[T, S any](c <-chan *S, name string) (<-chan T, error)

Field extracts a specific field from a channel of struct pointers and delivers it through a new channel.

func Filter

func Filter[T any](c <-chan T, p func(T) bool) <-chan T

Filter filters the items from the input channel based on the provided predicate function. The predicate function takes a float64 value as input and returns a boolean value indicating whether the value should be included in the output channel.

Example:

even := helper.Filter(c, func(n int) bool {
  return n%2 == 0
})

func First

func First[T any](c <-chan T, count int) <-chan T

First takes a channel of values and returns a new channel containing the first N values.

func Head[T Number](c <-chan T, count int) <-chan T

Head retrieves the specified number of elements from the given channel of float64 values and delivers them through a new channel.

Example:

c := helper.SliceToChan([]int{2, 4, 6, 8})
actual := helper.Head(c, 2)
fmt.Println(helper.ChanToSlice(actual)) // [2, 4]

func IncrementBy

func IncrementBy[T Number](c <-chan T, i T) <-chan T

IncrementBy increments each element in the input channel by the specified increment value and returns a new channel containing the incremented values.

Example:

input := []int{1, 2, 3, 4}
actual := helper.IncrementBy(helper.SliceToChan(input), 1)
fmt.Println(helper.ChanToSlice(actual)) // [2, 3, 4, 5]

func JSONToChan

func JSONToChan[T any](r io.Reader) <-chan T

JSONToChan reads values from the specified reader in JSON format into a channel of values.

Example:

func KeepNegatives

func KeepNegatives[T Number](c <-chan T) <-chan T

KeepNegatives processes a stream of float64 values, retaining negative values unchanged and replacing positive values with zero.

Example:

c := helper.SliceToChan([]int{-10, 20, 4, -5})
negatives := helper.KeepPositives(c)
fmt.Println(helper.ChanToSlice(negatives)) // [-10, 0, 0, -5]

func KeepPositives

func KeepPositives[T Number](c <-chan T) <-chan T

KeepPositives processes a stream of float64 values, retaining positive values unchanged and replacing negative values with zero.

Example:

c := helper.SliceToChan([]int{-10, 20, 4, -5})
positives := helper.KeepPositives(c)
fmt.Println(helper.ChanToSlice(positives)) // [0, 20, 4, 0]

func Last

func Last[T any](c <-chan T, count int) <-chan T

Last takes a channel of values and returns a new channel containing the last N values.

func Map

func Map[F, T any](c <-chan F, f func(F) T) <-chan T

Map applies the given transformation function to each element in the input channel and returns a new channel containing the transformed values. The transformation function takes a float64 value as input and returns a float64 value as output.

Example:

timesTwo := helper.Map(c, func(n int) int {
	return n * 2
})

func MapWithPrevious

func MapWithPrevious[F, T any](c <-chan F, f func(T, F) T, previous T) <-chan T

MapWithPrevious applies a transformation function to each element in an input channel, creating a new channel with the transformed values. It maintains a "memory" of the previous result, allowing the transformation function to consider both the current element and the outcome of the previous transformation. This enables functions that rely on accumulated state or sequential dependencies between elements.

Example:

sum := helper.MapWithPrevious(c, func(p, c int) int {
	return p + c
}, 0)

func Multiply

func Multiply[T Number](ac, bc <-chan T) <-chan T

Multiply takes two channels of float64 and multiples the values from the first channel with the values from the second channel. It returns a new channel containing the results of the multiplication.

Example:

ac := helper.SliceToChan([]int{1, 4, 2, 4, 2})
bc := helper.SliceToChan([]int{2, 1, 3, 2, 5})

multiplication := helper.Multiply(ac, bc)

fmt.Println(helper.ChanToSlice(multiplication)) // [2, 4, 6, 8, 10]

func MultiplyBy

func MultiplyBy[T Number](c <-chan T, m T) <-chan T

MultiplyBy multiplies each element in the input channel of float64 values by the given multiplier and returns a new channel containing the multiplied values.

Example:

c := helper.SliceToChan([]int{1, 2, 3, 4})
twoTimes := helper.MultiplyBy(c, 2)
fmt.Println(helper.ChanToSlice(twoTimes)) // [2, 4, 6, 8]

func Operate

func Operate[A any, B any, R any](ac <-chan A, bc <-chan B, o func(A, B) R) <-chan R

Operate applies the provided operate function to corresponding values from two numeric input channels and sends the resulting values to an output channel.

Example:

add := helper.Operate(ac, bc, func(a, b int) int {
  return a + b
})

func Operate3

func Operate3[A any, B any, C any, R any](ac <-chan A, bc <-chan B, cc <-chan C, o func(A, B, C) R) <-chan R

Operate3 applies the provided operate function to corresponding values from three numeric input channels and sends the resulting values to an output channel.

Example:

add := helper.Operate3(ac, bc, cc, func(a, b, c int) int {
  return a + b + c
})

func Pipe

func Pipe[T any](f <-chan T, t chan<- T)

Pipe function takes an input channel and an output channel and copies all elements from the input channel into the output channel.

Example:

input := helper.SliceToChan([]int{2, 4, 6, 8})
output := make(chan int)
helper.Pipe(input, output)
fmt.println(helper.ChanToSlice(output)) // [2, 4, 6, 8]

func Pow

func Pow[T Number](c <-chan T, y T) <-chan T

Pow takes a channel of float64 values and returns the element-wise base-value exponential of y.

Example:

c := helper.SliceToChan([]int{2, 3, 5, 10})
squared := helper.Pow(c, 2)
fmt.Println(helper.ChanToSlice(squared)) // [4, 9, 25, 100]

func ReadFromCsvFile

func ReadFromCsvFile[T any](fileName string, hasHeader bool) (<-chan *T, error)

ReadFromCsvFile creates a CSV instance, parses CSV data from the provided filename, maps the data to corresponding struct fields, and delivers it through the channel.

func RoundDigit

func RoundDigit[T Number](n T, d int) T

RoundDigit rounds the given float64 number to d decimal places.

Example:

n := helper.RoundDigit(10.1234, 2)
fmt.Println(n) // 10.12

func RoundDigits

func RoundDigits[T Number](c <-chan T, d int) <-chan T

RoundDigits takes a channel of float64 numbers and rounds them to d decimal places.

Example:

c := helper.SliceToChan([]float64{10.1234, 5.678, 6.78, 8.91011})
rounded := helper.RoundDigits(c, 2)
fmt.Println(helper.ChanToSlice(rounded)) // [10.12, 5.68, 6.78, 8.91]

func Seq

func Seq[T Number](from, to, increment T) <-chan T

Seq generates a sequence of numbers starting with a specified value, from, and incrementing by a specified amount, increment, until a specified value, to, is reached or exceeded. The sequence includes both from and to.

Example:

s := Seq(1, 5, 1)
defer close(s)

fmt.Println(<- s) // 1
fmt.Println(<- s) // 2
fmt.Println(<- s) // 3
fmt.Println(<- s) // 4

func Shift

func Shift[T any](c <-chan T, count int, fill T) <-chan T

Shift takes a channel of numbers, shifts them to the right by the specified count, and fills in any missing values with the provided fill value.

Example:

input := helper.SliceToChan([]int{2, 4, 6, 8})
output := helper.ChanToSlice(input, 4, 0))
fmt.Println(helper.ChanToSlice(output)) // [0, 0, 0, 0, 2, 4, 6, 8]

func Sign

func Sign[T Number](c <-chan T) <-chan T

Sign takes a channel of float64 values and returns their signs as -1 for negative, 0 for zero, and 1 for positive.

Example:

c := helper.SliceToChan([]int{-10, 20, -4, 0})
sign := helper.Sign(c)
fmt.Println(helper.ChanToSlice(sign)) // [-1, 1, -1, 0]

func Since

func Since[T comparable, R Number](c <-chan T) <-chan R

Since counts the number of periods since the last change of value in a channel of numbers.

func Skip

func Skip[T any](c <-chan T, count int) <-chan T

Skip skips the specified number of elements from the given channel of float64.

Example:

c := helper.SliceToChan([]int{2, 4, 6, 8})
actual := helper.Skip(c, 2)
fmt.Println(helper.ChanToSlice(actual)) // [6, 8]

func SliceToChan

func SliceToChan[T any](slice []T) <-chan T

SliceToChan converts a slice of float64 to a channel of float64.

Example:

slice := []float64{2, 4, 6, 8}
c := helper.SliceToChan(slice)
fmt.Println(<- c)  // 2
fmt.Println(<- c)  // 4
fmt.Println(<- c)  // 6
fmt.Println(<- c)  // 8

func Sqrt

func Sqrt[T Number](c <-chan T) <-chan T

Sqrt calculates the square root of each value in a channel of float64.

Example:

c := helper.SliceToChan([]int{9, 81, 16, 100})
sqrt := helper.Sqrt(c)
fmt.Println(helper.ChanToSlice(sqrt)) // [3, 9, 4, 10]

func Subtract

func Subtract[T Number](ac, bc <-chan T) <-chan T

Subtract takes two channels of float64 and subtracts the values from the second channel from the first one. It returns a new channel containing the results of the subtractions.

Example:

ac := helper.SliceToChan([]int{2, 4, 6, 8, 10})
bc := helper.SliceToChan([]int{1, 2, 3, 4, 5})
actual := helper.Subtract(ac, bc)
fmt.Println(helper.ChanToSlice(actual)) // [1, 2, 3, 4, 5]

func Waitable

func Waitable[T any](wg *sync.WaitGroup, c <-chan T) <-chan T

Waitable increments the wait group before reading from the channel and signals completion when the channel is closed.

Types

type Bst

type Bst[T Number] struct {
	// contains filtered or unexported fields
}

Bst represents the binary search tree.

func NewBst

func NewBst[T Number]() *Bst[T]

NewBst creates a new binary search tree.

func (*Bst[T]) Contains

func (b *Bst[T]) Contains(value T) bool

Contains checks whether the given value exists in the binary search tree.

func (*Bst[T]) Insert

func (b *Bst[T]) Insert(value T)

Insert adds a new value to the binary search tree.

func (*Bst[T]) Max

func (b *Bst[T]) Max() T

Max function returns the maximum value in the binary search tree.

func (*Bst[T]) Min

func (b *Bst[T]) Min() T

Min function returns the minimum value in the binary search tree.

func (*Bst[T]) Remove

func (b *Bst[T]) Remove(value T) bool

Remove removes the specified value from the binary search tree and rebalances the tree.

type BstNode

type BstNode[T Number] struct {
	// contains filtered or unexported fields
}

BstNode represents the binary search tree node.

type Csv

type Csv[T any] struct {
	// contains filtered or unexported fields
}

Csv represents the configuration for CSV reader and writer.

func NewCsv

func NewCsv[T any](hasHeader bool) (*Csv[T], error)

NewCsv function initializes a new CSV instance. The parameter hasHeader indicates whether the CSV contains a header row.

func (*Csv[T]) AppendToFile

func (c *Csv[T]) AppendToFile(fileName string, rows <-chan *T) error

AppendToFile appends the provided rows of data to the end of the specified file, creating the file if it doesn't exist. In append mode, the function assumes that the existing file's column order matches the field order of the given row struct to ensure consistent data structure.

func (*Csv[T]) ReadFromFile

func (c *Csv[T]) ReadFromFile(fileName string) (<-chan *T, error)

ReadFromFile parses the CSV data from the provided file name, maps the data to corresponding struct fields, and delivers the resulting rows through the channel.

func (*Csv[T]) ReadFromReader

func (c *Csv[T]) ReadFromReader(reader io.Reader) <-chan *T

ReadFromReader parses the CSV data from the provided reader, maps the data to corresponding struct fields, and delivers the resulting it through the channel.

func (*Csv[T]) WriteToFile

func (c *Csv[T]) WriteToFile(fileName string, rows <-chan *T) error

WriteToFile creates a new file with the given name and writes the provided rows of data to it, overwriting any existing content.

type Float

type Float interface {
	float32 | float64
}

Float refers to any float type.

type Integer

type Integer interface {
	int | int8 | int16 | int32 | int64
}

Integer refers to any integer type.

type Number

type Number interface {
	Integer | Float
}

Number refers to any numeric type.

type Report

type Report struct {
	// contains filtered or unexported fields
}

Report generates an HTML file containing an interactive chart that visually represents the provided data and annotations.

The generated HTML file can be opened in a web browser to explore the data visually, interact with the chart elements, and view the associated annotations.

func NewReport

func NewReport(title string, date <-chan time.Time) *Report

NewReport takes a channel of time as the time axis and returns a new instance of the Report struct. This instance can later be used to add data and annotations and subsequently generate a report.

func (*Report) AddChart

func (r *Report) AddChart() int

AddChart adds a new chart to the report and returns its unique identifier. This identifier can be used later to refer to the chart and add columns to it.

func (*Report) AddColumn

func (r *Report) AddColumn(column ReportColumn, charts ...int)

AddColumn adds a new data column to the specified charts. If no chart is specified, it will be added to the main chart.

func (*Report) WriteToFile

func (r *Report) WriteToFile(fileName string) error

WriteToFile writes the generated report content to a file with the specified name. This allows users to conveniently save the report for later viewing or analysis.

func (*Report) WriteToWriter

func (r *Report) WriteToWriter(writer io.Writer) error

WriteToWriter writes the report content to the provided io.Writer. This allows the report to be sent to various destinations, such as a file, a network socket, or even the standard output.

type ReportColumn

type ReportColumn interface {
	// Name returns the name of the report column.
	Name() string

	// Type returns the data type of the report column.
	Type() string

	// Role returns the role of the report column.
	Role() string

	// Value returns the next data value for the report column.
	Value() string
}

ReportColumn defines the interface that all report data columns must implement. This interface ensures that different types of data columns can be used consistently within the report generation process.

func NewAnnotationReportColumn

func NewAnnotationReportColumn(values <-chan string) ReportColumn

NewAnnotationReportColumn returns a new instance of a annotation column for a report.

func NewNumericReportColumn

func NewNumericReportColumn[T Number](name string, values <-chan T) ReportColumn

NewNumericReportColumn returns a new instance of a numeric data column for a report.

type Ring

type Ring[T any] struct {
	// contains filtered or unexported fields
}

Ring represents a ring structure that can be instantiated using the NewRing function.

Example:

ring := helper.NewRing[int](2)

fmt.Println(ring.Insert(1)) // 0
fmt.Println(ring.Insert(2)) // 0
fmt.Println(ring.Insert(3)) // 1
fmt.Println(ring.Insert(4)) // 2

func NewRing

func NewRing[T any](size int) *Ring[T]

NewRing creates a new ring instance with the given size.

func (*Ring[T]) At

func (r *Ring[T]) At(index int) T

At returns the value at the given index.

func (*Ring[T]) Get

func (r *Ring[T]) Get() (T, bool)

Get retrieves the available value from the ring buffer. If empty, it returns the default value (T) and false.

func (*Ring[T]) IsEmpty

func (r *Ring[T]) IsEmpty() bool

IsEmpty checks if the current ring buffer is empty.

func (*Ring[T]) IsFull

func (r *Ring[T]) IsFull() bool

IsFull checks if the current ring buffer is full.

func (*Ring[T]) Put

func (r *Ring[T]) Put(t T) T

Put inserts the specified value into the ring and returns the value that was previously stored at that index.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL