package mathUtil

import (
	"errors"
	"math"
	"sort"
)

//同时计算上中下四分位数
func Quartile_Int(intList []int) (lowerquartile, midquartile, upperquartile float64, err error) {
	n := len(intList)

	if n == 0 {
		err = errors.New("List is empty")
		return
	}

	//长度大于等于2的情况
	//排序 升序
	sort.Ints(intList)
	lowerquartile, err = Quartile_Int_Lower(intList, true)
	if err != nil {
		return
	}
	midquartile, err = Quartile_Int_Mid(intList, true)
	if err != nil {
		return
	}
	upperquartile, err = Quartile_Int_Upper(intList, true)
	if err != nil {
		return
	}
	return
}

// 计算整数数组下四分为数据
func Quartile_Int_Lower(intList []int, isSorted bool) (lowerquartile float64, err error) {
	n := len(intList)

	if n == 0 {
		err = errors.New("List is empty")
		return
	}
	//如果长度为1，则上、中、下四分为数都等于该值
	if n == 1 {
		lowerquartile = float64(intList[0])
		return
	}
	//长度大于等于2的情况
	//排序 升序 ,如果数据没有排序，则排序
	if !isSorted {
		sort.Ints(intList)
	}
	//计算下四分位数位置
	lowerPosition := 1 + float64(n-1)*0.25
	intPart, deciPart := math.Modf(lowerPosition)
	//将整数部分转换为int类型，成为取数据的索引
	index := int(intPart)
	if index < 1 || index > n-1 {
		err = errors.New("Quartile_Int_Lower Index Out of Range")
		return
	}
	lowerquartile = float64(intList[index-1])*(1-deciPart) + float64(intList[index])*deciPart

	return
}

// 计算整数数组中四分为数据
func Quartile_Int_Mid(intList []int, isSorted bool) (midquartile float64, err error) {
	n := len(intList)

	if n == 0 {
		err = errors.New("List is empty")
		return
	}
	//如果长度为1，则上、中、下四分为数都等于该值
	if n == 1 {
		midquartile = float64(intList[0])
		return
	}
	//长度大于等于2的情况
	//排序 升序 ,如果数据没有排序，则排序
	if !isSorted {
		sort.Ints(intList)
	}
	//计算下四分位数位置
	lowerPosition := 1 + float64(n-1)*0.5
	intPart, deciPart := math.Modf(lowerPosition)
	//将整数部分转换为int类型，成为取数据的索引
	index := int(intPart)
	if index < 1 || index > n-1 {
		err = errors.New("Quartile_Int_Mid Index Out of Range")
		return
	}
	midquartile = float64(intList[index-1])*(1-deciPart) + float64(intList[index])*deciPart

	return
}

// 计算整数数组上四分为数据
func Quartile_Int_Upper(intList []int, isSorted bool) (upperquartile float64, err error) {
	n := len(intList)

	if n == 0 {
		err = errors.New("List is empty")
		return
	}
	//如果长度为1，则上、中、下四分为数都等于该值
	if n == 1 {
		upperquartile = float64(intList[0])
		return
	}
	//长度大于等于2的情况
	//排序 升序 ,如果数据没有排序，则排序
	if !isSorted {
		sort.Ints(intList)
	}
	//计算下四分位数位置
	lowerPosition := 1 + float64(n-1)*0.75
	intPart, deciPart := math.Modf(lowerPosition)
	//将整数部分转换为int类型，成为取数据的索引
	index := int(intPart)
	if index < 1 || index > n-1 {
		err = errors.New("Quartile_Int_Upper Index Out of Range")
		return
	}
	upperquartile = float64(intList[index-1])*(1-deciPart) + float64(intList[index])*deciPart

	return
}
