* feat: add configurable SMTP HELO hostname Allow the SMTP HELO/EHLO hostname to be configured separately from the SMTP server hostname. This is useful when the SMTP server requires clients to identify themselves with a fully qualified hostname different from the server address. * chore: remove vendored dependency changes * Bump go-pkgz/notify to v1.4.0 and document SMTP_HELO_HOST The HELOHost field lands in go-pkgz/notify v1.4.0, so the branch needs the bump to compile; v1.3.0 in master has no such field. The example module is tidied alongside, as any change to backend/go.mod requires. Documents the parameter in the parameters table and, separately, in the email setup page: what it does, that leaving it unset keeps the previous `localhost` greeting, and the case it exists for, a relay refusing the greeting under Postfix `reject_non_fqdn_helo_hostname`. Also records the current limit: verification emails for email authentication go through go-pkgz/auth's own sender, which has no equivalent setting, so the greeting there is unchanged. * Bump go-pkgz/auth to v2.2.0 and apply SMTP_HELO_HOST to verification email The verification email sender had no way to set the greeting, so a relay that refuses the HELO would accept notifications and still reject sign-in emails. EmailParams gains HELOHost in go-pkgz/auth v2.2.0, so the same SMTP_HELO_HOST now drives both paths. The example module is tidied alongside, as any change to backend/go.mod requires. --------- Co-authored-by: oli <someone@somewhere.tld> Co-authored-by: Dmitry Verkhoturov <paskal.07@gmail.com>
86 lines
2.7 KiB
Go
86 lines
2.7 KiB
Go
package stats
|
|
|
|
import "fmt"
|
|
|
|
// Holds information about the dataset provided to Describe
|
|
type Description struct {
|
|
Count int
|
|
Mean float64
|
|
Std float64
|
|
Max float64
|
|
Min float64
|
|
Range float64
|
|
DescriptionPercentiles []descriptionPercentile
|
|
AllowedNaN bool
|
|
}
|
|
|
|
// Specifies percentiles to be computed
|
|
type descriptionPercentile struct {
|
|
Percentile float64
|
|
Value float64
|
|
}
|
|
|
|
// Describe generates descriptive statistics about a provided dataset, similar to python's pandas.describe()
|
|
func Describe(input Float64Data, allowNaN bool, percentiles *[]float64) (*Description, error) {
|
|
return DescribePercentileFunc(input, allowNaN, percentiles, Percentile)
|
|
}
|
|
|
|
// Describe generates descriptive statistics about a provided dataset, similar to python's pandas.describe()
|
|
// Takes in a function to use for percentile calculation
|
|
func DescribePercentileFunc(input Float64Data, allowNaN bool, percentiles *[]float64, percentileFunc func(Float64Data, float64) (float64, error)) (*Description, error) {
|
|
var description Description
|
|
description.AllowedNaN = allowNaN
|
|
description.Count = input.Len()
|
|
|
|
if description.Count == 0 && !allowNaN {
|
|
return &description, ErrEmptyInput
|
|
}
|
|
|
|
// Disregard error, since it cannot be thrown if Count is > 0 and allowNaN is false, else NaN is accepted
|
|
description.Std, _ = StandardDeviation(input)
|
|
description.Max, _ = Max(input)
|
|
description.Min, _ = Min(input)
|
|
description.Range, _ = Range(input)
|
|
description.Mean, _ = Mean(input)
|
|
|
|
if percentiles != nil {
|
|
for _, percentile := range *percentiles {
|
|
if value, err := percentileFunc(input, percentile); err == nil || allowNaN {
|
|
description.DescriptionPercentiles = append(description.DescriptionPercentiles, descriptionPercentile{Percentile: percentile, Value: value})
|
|
}
|
|
}
|
|
}
|
|
|
|
return &description, nil
|
|
}
|
|
|
|
/*
|
|
Represents the Description instance in a string format with specified number of decimals
|
|
|
|
count 3
|
|
mean 2.00
|
|
std 0.82
|
|
max 3.00
|
|
min 1.00
|
|
range 2.00
|
|
25.00% NaN
|
|
50.00% 1.50
|
|
75.00% 2.50
|
|
NaN OK true
|
|
*/
|
|
func (d *Description) String(decimals int) string {
|
|
var str string
|
|
|
|
str += fmt.Sprintf("count\t%d\n", d.Count)
|
|
str += fmt.Sprintf("mean\t%.*f\n", decimals, d.Mean)
|
|
str += fmt.Sprintf("std\t%.*f\n", decimals, d.Std)
|
|
str += fmt.Sprintf("max\t%.*f\n", decimals, d.Max)
|
|
str += fmt.Sprintf("min\t%.*f\n", decimals, d.Min)
|
|
str += fmt.Sprintf("range\t%.*f\n", decimals, d.Range)
|
|
for _, percentile := range d.DescriptionPercentiles {
|
|
str += fmt.Sprintf("%.2f%%\t%.*f\n", percentile.Percentile, decimals, percentile.Value)
|
|
}
|
|
str += fmt.Sprintf("NaN OK\t%t", d.AllowedNaN)
|
|
return str
|
|
}
|