Added self adjustment minLow and maxHigh values. Renamed Get method to GetIntervals. Removed Report method, moved functionality to the Intervals Springer implementation. Added GetMinLow and GetMaxHigh methods.
This commit is contained in:
parent
1d6fd664fa
commit
217eb78ab4
20
add.go
20
add.go
@ -1,5 +1,7 @@
|
|||||||
package interval
|
package interval
|
||||||
|
|
||||||
|
import "math"
|
||||||
|
|
||||||
func (intvls *intervals) Add(low, high int, obj interface{}) error {
|
func (intvls *intervals) Add(low, high int, obj interface{}) error {
|
||||||
itvl := &Interval{
|
itvl := &Interval{
|
||||||
Low: low,
|
Low: low,
|
||||||
@ -10,6 +12,17 @@ func (intvls *intervals) Add(low, high int, obj interface{}) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (intvls *intervals) AddInterval(itvl *Interval) error {
|
func (intvls *intervals) AddInterval(itvl *Interval) error {
|
||||||
|
|
||||||
|
// the first time an interval is added, we check if a self adjustment is programmed to update some control variables
|
||||||
|
if len(intvls.Intervals) == 0 {
|
||||||
|
if intvls.SelfAdjustMinLow {
|
||||||
|
intvls.MinLow = math.MaxInt64
|
||||||
|
}
|
||||||
|
if intvls.SelfAdjustMaxHigh {
|
||||||
|
intvls.MaxHigh = math.MinInt64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
low := intvls.getInclusiveLow(itvl.Low)
|
low := intvls.getInclusiveLow(itvl.Low)
|
||||||
high := intvls.getInclusiveHigh(itvl.High)
|
high := intvls.getInclusiveHigh(itvl.High)
|
||||||
|
|
||||||
@ -18,6 +31,13 @@ func (intvls *intervals) AddInterval(itvl *Interval) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if intvls.SelfAdjustMaxHigh && high > intvls.MaxHigh {
|
||||||
|
intvls.MaxHigh = high
|
||||||
|
}
|
||||||
|
if intvls.SelfAdjustMinLow && low < intvls.MinLow {
|
||||||
|
intvls.MinLow = low
|
||||||
|
}
|
||||||
|
|
||||||
intvls.Intervals = append(intvls.Intervals, itvl)
|
intvls.Intervals = append(intvls.Intervals, itvl)
|
||||||
intvls.reset()
|
intvls.reset()
|
||||||
return nil
|
return nil
|
||||||
|
485
demo_test.go
485
demo_test.go
File diff suppressed because it is too large
Load Diff
@ -91,7 +91,14 @@ func readData(path string) ([]xy, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func initIntervals(xys []xy) interval.Intervals {
|
func initIntervals(xys []xy) interval.Intervals {
|
||||||
intervals := interval.NewIntervals(MinX, MaxX, true, true)
|
// initialize Intervals
|
||||||
|
minLow := MinX
|
||||||
|
maxHigh := MaxX
|
||||||
|
lowInclusive = true
|
||||||
|
highInclusive = true
|
||||||
|
selfAdjustMinLow := false
|
||||||
|
selfAdjustMaxHigh := true
|
||||||
|
intervals := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh)
|
||||||
|
|
||||||
if intervals.IsLowInclusive() {
|
if intervals.IsLowInclusive() {
|
||||||
intervalOpening = "["
|
intervalOpening = "["
|
||||||
@ -110,7 +117,7 @@ func initIntervals(xys []xy) interval.Intervals {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, xy := range xys {
|
for _, xy := range xys {
|
||||||
err := intervals.Add(&interval.Interval{Low: xy.x, High: xy.y})
|
err := intervals.AddInterval(&interval.Interval{Low: xy.x, High: xy.y})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("invalid interval discarded: %v\n", err)
|
fmt.Printf("invalid interval discarded: %v\n", err)
|
||||||
}
|
}
|
||||||
@ -127,7 +134,7 @@ func convertToPlotterXYs(intervals []*interval.Interval) plotter.XYs {
|
|||||||
return pxys
|
return pxys
|
||||||
}
|
}
|
||||||
|
|
||||||
func alignPlots(plotItems []*Superplot) *vgimg.Canvas {
|
func alignPlots(plotItems []*Superplot, minLow, maxHigh int) *vgimg.Canvas {
|
||||||
rows, cols := len(plotItems), 1
|
rows, cols := len(plotItems), 1
|
||||||
plots := make([][]*plot.Plot, rows)
|
plots := make([][]*plot.Plot, rows)
|
||||||
for j := 0; j < rows; j++ {
|
for j := 0; j < rows; j++ {
|
||||||
@ -136,8 +143,8 @@ func alignPlots(plotItems []*Superplot) *vgimg.Canvas {
|
|||||||
p := plotItems[j]
|
p := plotItems[j]
|
||||||
|
|
||||||
// make sure the horizontal scales match
|
// make sure the horizontal scales match
|
||||||
p.Plot.X.Min = MinX
|
p.Plot.X.Min = float64(minLow) // MinX
|
||||||
p.Plot.X.Max = MaxX
|
p.Plot.X.Max = float64(maxHigh) //MaxX
|
||||||
|
|
||||||
plots[j][i] = p.Plot
|
plots[j][i] = p.Plot
|
||||||
}
|
}
|
||||||
@ -232,7 +239,7 @@ func plotData(path string, intervals interval.Intervals) error {
|
|||||||
plots = append(plots, p4)
|
plots = append(plots, p4)
|
||||||
|
|
||||||
// join all plots, align them
|
// join all plots, align them
|
||||||
canvas := alignPlots(plots)
|
canvas := alignPlots(plots, intervals.GetMinLow(), intervals.GetMaxHigh())
|
||||||
err = createFileFromCanvas("out.png", canvas)
|
err = createFileFromCanvas("out.png", canvas)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -13,7 +13,9 @@ func initIntervalsForDemo001() interval.Intervals {
|
|||||||
maxHigh := 100
|
maxHigh := 100
|
||||||
lowInclusive := true
|
lowInclusive := true
|
||||||
highInclusive := true
|
highInclusive := true
|
||||||
itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive)
|
selfAdjustMinLow := false
|
||||||
|
selfAdjustMaxHigh := true
|
||||||
|
itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh)
|
||||||
|
|
||||||
// add new intervals
|
// add new intervals
|
||||||
if err := itvls.AddInterval(&interval.Interval{Low: 5, High: 7}); err != nil {
|
if err := itvls.AddInterval(&interval.Interval{Low: 5, High: 7}); err != nil {
|
||||||
|
@ -20,6 +20,9 @@ func TestGaps(t *testing.T) {
|
|||||||
demo010 := buildIntervalsDemo010()
|
demo010 := buildIntervalsDemo010()
|
||||||
demo011 := buildIntervalsDemo011()
|
demo011 := buildIntervalsDemo011()
|
||||||
demo012 := buildIntervalsDemo012()
|
demo012 := buildIntervalsDemo012()
|
||||||
|
demo013 := buildIntervalsDemo013()
|
||||||
|
demo014 := buildIntervalsDemo014()
|
||||||
|
demo015 := buildIntervalsDemo015()
|
||||||
|
|
||||||
// tests for low/high exclusive
|
// tests for low/high exclusive
|
||||||
demo101 := buildIntervalsDemo101()
|
demo101 := buildIntervalsDemo101()
|
||||||
@ -79,6 +82,9 @@ func TestGaps(t *testing.T) {
|
|||||||
{name: "demo010", intvls: demo010.Intervals, expectedGaps: demo010.ExpectedGaps},
|
{name: "demo010", intvls: demo010.Intervals, expectedGaps: demo010.ExpectedGaps},
|
||||||
{name: "demo011", intvls: demo011.Intervals, expectedGaps: demo011.ExpectedGaps},
|
{name: "demo011", intvls: demo011.Intervals, expectedGaps: demo011.ExpectedGaps},
|
||||||
{name: "demo012", intvls: demo012.Intervals, expectedGaps: demo012.ExpectedGaps},
|
{name: "demo012", intvls: demo012.Intervals, expectedGaps: demo012.ExpectedGaps},
|
||||||
|
{name: "demo013", intvls: demo013.Intervals, expectedGaps: demo013.ExpectedGaps},
|
||||||
|
{name: "demo014", intvls: demo014.Intervals, expectedGaps: demo014.ExpectedGaps},
|
||||||
|
{name: "demo015", intvls: demo015.Intervals, expectedGaps: demo015.ExpectedGaps},
|
||||||
|
|
||||||
{name: "demo101", intvls: demo101.Intervals, expectedGaps: demo101.ExpectedGaps},
|
{name: "demo101", intvls: demo101.Intervals, expectedGaps: demo101.ExpectedGaps},
|
||||||
{name: "demo102", intvls: demo102.Intervals, expectedGaps: demo102.ExpectedGaps},
|
{name: "demo102", intvls: demo102.Intervals, expectedGaps: demo102.ExpectedGaps},
|
||||||
@ -122,6 +128,9 @@ func TestGaps(t *testing.T) {
|
|||||||
|
|
||||||
for _, tc := range tt {
|
for _, tc := range tt {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
// if tc.name == "demo014" {
|
||||||
|
// fmt.Printf("stop point")
|
||||||
|
// }
|
||||||
gaps := tc.intvls.Gaps()
|
gaps := tc.intvls.Gaps()
|
||||||
unexpectedLength := false
|
unexpectedLength := false
|
||||||
if len(gaps) != len(tc.expectedGaps) {
|
if len(gaps) != len(tc.expectedGaps) {
|
||||||
|
2
get.go
2
get.go
@ -1,6 +1,6 @@
|
|||||||
package interval
|
package interval
|
||||||
|
|
||||||
func (intvls *intervals) Get() []*Interval {
|
func (intvls *intervals) GetIntervals() []*Interval {
|
||||||
// sort intervals (if necessary)
|
// sort intervals (if necessary)
|
||||||
intvls.Sort()
|
intvls.Sort()
|
||||||
|
|
||||||
|
72
intervals.go
72
intervals.go
@ -5,10 +5,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultMinLow = 0
|
defaultMinLow = 0
|
||||||
defaultMaxHigh = math.MaxInt64
|
defaultMaxHigh = math.MaxInt64
|
||||||
defaultLowInclusive = true
|
defaultLowInclusive = true
|
||||||
defaultHighInclusive = true
|
defaultHighInclusive = true
|
||||||
|
defaultSelfAdjustMinLow = false
|
||||||
|
defaultSelfAdjustMaxHigh = true
|
||||||
)
|
)
|
||||||
|
|
||||||
// Intervals is an interface to handle Interval structures discovering the existence of gaps or overlays
|
// Intervals is an interface to handle Interval structures discovering the existence of gaps or overlays
|
||||||
@ -26,7 +28,7 @@ type Intervals interface {
|
|||||||
HasGaps() bool
|
HasGaps() bool
|
||||||
|
|
||||||
// Get returns the interval list
|
// Get returns the interval list
|
||||||
Get() []*Interval
|
GetIntervals() []*Interval
|
||||||
|
|
||||||
// Gaps returns the interval gaps
|
// Gaps returns the interval gaps
|
||||||
Gaps() []*Interval
|
Gaps() []*Interval
|
||||||
@ -43,43 +45,55 @@ type Intervals interface {
|
|||||||
// FindIntervalsForValue returns all the intervals which contains the passed value
|
// FindIntervalsForValue returns all the intervals which contains the passed value
|
||||||
FindIntervalsForValue(value int) []*Interval
|
FindIntervalsForValue(value int) []*Interval
|
||||||
|
|
||||||
// Report creates a report of the interval sequence
|
|
||||||
Report() string
|
|
||||||
|
|
||||||
// IsLowInclusive indicates if the Low part of the interval is included, e. g. (3,5) --> the 3 is included as part of the interval
|
// IsLowInclusive indicates if the Low part of the interval is included, e. g. (3,5) --> the 3 is included as part of the interval
|
||||||
IsLowInclusive() bool
|
IsLowInclusive() bool
|
||||||
|
|
||||||
// IsHighInclusive indicates if the High part of the interval is included, e. g. (3,5) --> the 5 is included as part of the interval
|
// IsHighInclusive indicates if the High part of the interval is included, e. g. (3,5) --> the 5 is included as part of the interval
|
||||||
IsHighInclusive() bool
|
IsHighInclusive() bool
|
||||||
|
|
||||||
|
// GetMinLow returns the minimal Low, either the one configured in the constructor, or the self-adjusted calculated if SelfAdjustMinLow=true
|
||||||
|
GetMinLow() int
|
||||||
|
|
||||||
|
// GetMaxHigh returns the maximal High, either the one configured in the constructor, or the self-adjusted calculated if SelfAdjustMaxHigh=true
|
||||||
|
GetMaxHigh() int
|
||||||
}
|
}
|
||||||
|
|
||||||
// intervals implements Intervals interface
|
// intervals implements Intervals interface
|
||||||
type intervals struct {
|
type intervals struct {
|
||||||
Intervals []*Interval
|
Intervals []*Interval
|
||||||
GapsList []*Interval
|
GapsList []*Interval
|
||||||
OverlappedList []*Interval
|
OverlappedList []*Interval
|
||||||
MergeList []*Interval
|
MergeList []*Interval
|
||||||
MinLow int
|
MinLow int
|
||||||
MaxHigh int
|
MaxHigh int
|
||||||
Sorted bool
|
Sorted bool
|
||||||
LowInclusive bool
|
LowInclusive bool
|
||||||
HighInclusive bool
|
HighInclusive bool
|
||||||
|
SelfAdjustMinLow bool // set the minLow to the minimal Low value passed in Add or AddInterval methods
|
||||||
|
SelfAdjustMaxHigh bool // set the maxHigh to the maximal High value passed in Add or AddInterval methods
|
||||||
|
}
|
||||||
|
|
||||||
|
// String implements Stringer.Interface Interval
|
||||||
|
func (itvls *intervals) String() string {
|
||||||
|
return itvls.report()
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewIntervalsDefault is a constructor that returns an instance of the Intervals interface with default values
|
// NewIntervalsDefault is a constructor that returns an instance of the Intervals interface with default values
|
||||||
func NewIntervalsDefault() Intervals {
|
func NewIntervalsDefault() Intervals {
|
||||||
return NewIntervals(defaultMinLow, defaultMaxHigh, defaultLowInclusive, defaultHighInclusive)
|
return NewIntervals(defaultMinLow, defaultMaxHigh, defaultLowInclusive, defaultHighInclusive, defaultSelfAdjustMinLow, defaultSelfAdjustMaxHigh)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewIntervals is a constructor that returns an instance of the Intervals interface
|
// NewIntervals is a constructor that returns an instance of the Intervals interface
|
||||||
func NewIntervals(minLow int, maxHigh int, lowInclusive bool, highInclusive bool) Intervals {
|
func NewIntervals(minLow, maxHigh int, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh bool) Intervals {
|
||||||
return &intervals{
|
return &intervals{
|
||||||
MinLow: minLow,
|
MinLow: minLow,
|
||||||
MaxHigh: maxHigh,
|
MaxHigh: maxHigh,
|
||||||
Intervals: []*Interval{},
|
Intervals: []*Interval{},
|
||||||
Sorted: false,
|
Sorted: false,
|
||||||
LowInclusive: lowInclusive,
|
LowInclusive: lowInclusive,
|
||||||
HighInclusive: highInclusive,
|
HighInclusive: highInclusive,
|
||||||
|
SelfAdjustMinLow: selfAdjustMinLow,
|
||||||
|
SelfAdjustMaxHigh: selfAdjustMaxHigh,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,3 +104,11 @@ func (intvls *intervals) IsLowInclusive() bool {
|
|||||||
func (intvls *intervals) IsHighInclusive() bool {
|
func (intvls *intervals) IsHighInclusive() bool {
|
||||||
return intvls.HighInclusive
|
return intvls.HighInclusive
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (intvls *intervals) GetMinLow() int {
|
||||||
|
return intvls.MinLow
|
||||||
|
}
|
||||||
|
|
||||||
|
func (intvls *intervals) GetMaxHigh() int {
|
||||||
|
return intvls.MaxHigh
|
||||||
|
}
|
||||||
|
@ -20,6 +20,9 @@ func TestMerge(t *testing.T) {
|
|||||||
demo010 := buildIntervalsDemo010()
|
demo010 := buildIntervalsDemo010()
|
||||||
demo011 := buildIntervalsDemo011()
|
demo011 := buildIntervalsDemo011()
|
||||||
demo012 := buildIntervalsDemo012()
|
demo012 := buildIntervalsDemo012()
|
||||||
|
demo013 := buildIntervalsDemo013()
|
||||||
|
demo014 := buildIntervalsDemo014()
|
||||||
|
demo015 := buildIntervalsDemo015()
|
||||||
|
|
||||||
// tests for low/high exclusive
|
// tests for low/high exclusive
|
||||||
demo101 := buildIntervalsDemo101()
|
demo101 := buildIntervalsDemo101()
|
||||||
@ -79,6 +82,9 @@ func TestMerge(t *testing.T) {
|
|||||||
{name: "demo010", intvls: demo010.Intervals, expectedMerges: demo010.ExpectedMerges},
|
{name: "demo010", intvls: demo010.Intervals, expectedMerges: demo010.ExpectedMerges},
|
||||||
{name: "demo011", intvls: demo011.Intervals, expectedMerges: demo011.ExpectedMerges},
|
{name: "demo011", intvls: demo011.Intervals, expectedMerges: demo011.ExpectedMerges},
|
||||||
{name: "demo012", intvls: demo012.Intervals, expectedMerges: demo012.ExpectedMerges},
|
{name: "demo012", intvls: demo012.Intervals, expectedMerges: demo012.ExpectedMerges},
|
||||||
|
{name: "demo013", intvls: demo013.Intervals, expectedMerges: demo013.ExpectedMerges},
|
||||||
|
{name: "demo014", intvls: demo014.Intervals, expectedMerges: demo014.ExpectedMerges},
|
||||||
|
{name: "demo015", intvls: demo015.Intervals, expectedMerges: demo015.ExpectedMerges},
|
||||||
|
|
||||||
{name: "demo101", intvls: demo101.Intervals, expectedMerges: demo101.ExpectedMerges},
|
{name: "demo101", intvls: demo101.Intervals, expectedMerges: demo101.ExpectedMerges},
|
||||||
{name: "demo102", intvls: demo102.Intervals, expectedMerges: demo102.ExpectedMerges},
|
{name: "demo102", intvls: demo102.Intervals, expectedMerges: demo102.ExpectedMerges},
|
||||||
|
@ -20,6 +20,9 @@ func TestOverlapped(t *testing.T) {
|
|||||||
demo010 := buildIntervalsDemo010()
|
demo010 := buildIntervalsDemo010()
|
||||||
demo011 := buildIntervalsDemo011()
|
demo011 := buildIntervalsDemo011()
|
||||||
demo012 := buildIntervalsDemo012()
|
demo012 := buildIntervalsDemo012()
|
||||||
|
demo013 := buildIntervalsDemo013()
|
||||||
|
demo014 := buildIntervalsDemo014()
|
||||||
|
demo015 := buildIntervalsDemo015()
|
||||||
|
|
||||||
// tests for low/high exclusive
|
// tests for low/high exclusive
|
||||||
demo101 := buildIntervalsDemo101()
|
demo101 := buildIntervalsDemo101()
|
||||||
@ -79,6 +82,9 @@ func TestOverlapped(t *testing.T) {
|
|||||||
{name: "demo010", intvls: demo010.Intervals, expectedOverlaps: demo010.ExpectedOverlaps},
|
{name: "demo010", intvls: demo010.Intervals, expectedOverlaps: demo010.ExpectedOverlaps},
|
||||||
{name: "demo011", intvls: demo011.Intervals, expectedOverlaps: demo011.ExpectedOverlaps},
|
{name: "demo011", intvls: demo011.Intervals, expectedOverlaps: demo011.ExpectedOverlaps},
|
||||||
{name: "demo012", intvls: demo012.Intervals, expectedOverlaps: demo012.ExpectedOverlaps},
|
{name: "demo012", intvls: demo012.Intervals, expectedOverlaps: demo012.ExpectedOverlaps},
|
||||||
|
{name: "demo013", intvls: demo013.Intervals, expectedOverlaps: demo013.ExpectedOverlaps},
|
||||||
|
{name: "demo014", intvls: demo014.Intervals, expectedOverlaps: demo014.ExpectedOverlaps},
|
||||||
|
{name: "demo015", intvls: demo015.Intervals, expectedOverlaps: demo015.ExpectedOverlaps},
|
||||||
|
|
||||||
{name: "demo101", intvls: demo101.Intervals, expectedOverlaps: demo101.ExpectedOverlaps},
|
{name: "demo101", intvls: demo101.Intervals, expectedOverlaps: demo101.ExpectedOverlaps},
|
||||||
{name: "demo102", intvls: demo102.Intervals, expectedOverlaps: demo102.ExpectedOverlaps},
|
{name: "demo102", intvls: demo102.Intervals, expectedOverlaps: demo102.ExpectedOverlaps},
|
||||||
|
@ -25,7 +25,7 @@ func newSymbols() symbols {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (intvls *intervals) Report() string {
|
func (intvls *intervals) report() string {
|
||||||
intvls.Sort()
|
intvls.Sort()
|
||||||
symbols := newSymbols()
|
symbols := newSymbols()
|
||||||
intro := intvls.buildHeading()
|
intro := intvls.buildHeading()
|
||||||
|
@ -8,7 +8,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestReport(t *testing.T) {
|
func TestReport(t *testing.T) {
|
||||||
itvls := interval.NewIntervals(0, 100, true, true)
|
minLow := 0
|
||||||
|
maxHigh := 100
|
||||||
|
lowInclusive := true
|
||||||
|
highInclusive := true
|
||||||
|
selfAdjustMinLow := false
|
||||||
|
selfAdjustMaxHigh := true
|
||||||
|
itvls := interval.NewIntervals(minLow, maxHigh, lowInclusive, highInclusive, selfAdjustMinLow, selfAdjustMaxHigh)
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
err = itvls.AddInterval(&interval.Interval{Low: 5, High: 7})
|
err = itvls.AddInterval(&interval.Interval{Low: 5, High: 7})
|
||||||
@ -49,7 +55,8 @@ func TestReport(t *testing.T) {
|
|||||||
|
|
||||||
for _, tc := range tt {
|
for _, tc := range tt {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
t.Log(tc.itvls.Report())
|
// this will call report() which implements Springer interface
|
||||||
|
t.Log(tc.itvls)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user