diff --git a/algs4/src/go/Makefile b/algs4/src/go/Makefile index 2206cbe..1ba1a92 100644 --- a/algs4/src/go/Makefile +++ b/algs4/src/go/Makefile @@ -8,7 +8,9 @@ TARGETS := \ $(REPO_BASE)/algs4-randomseq \ $(REPO_BASE)/algs4-average \ $(REPO_BASE)/algs4-interval2d \ - $(REPO_BASE)/algs4-date + $(REPO_BASE)/algs4-date \ + $(REPO_BASE)/algs4-test-accumulator + test: build go test -x $(TARGETS) diff --git a/algs4/src/go/algs4-test-accumulator/main.go b/algs4/src/go/algs4-test-accumulator/main.go new file mode 100644 index 0000000..fea140a --- /dev/null +++ b/algs4/src/go/algs4-test-accumulator/main.go @@ -0,0 +1,34 @@ +package main + +import ( + "errors" + "fmt" + "os" + "strconv" + + "github.com/meatballhat/box-o-sand/algs4/src/go/algs4" +) + +func die(err error) { + fmt.Fprintf(os.Stderr, "ERROR: %v\n", err) + os.Exit(1) +} + +func main() { + if len(os.Args) < 2 { + die(errors.New("We need an int!")) + } + + nValues, err := strconv.Atoi(os.Args[1]) + if err != nil { + die(err) + } + + a := algs4.NewAccumulator() + for t := 0; t < nValues; t++ { + a.AddDataValue(algs4.Random()) + } + + fmt.Println(a) + return +} diff --git a/algs4/src/go/algs4/accumulator.go b/algs4/src/go/algs4/accumulator.go new file mode 100644 index 0000000..62c2f01 --- /dev/null +++ b/algs4/src/go/algs4/accumulator.go @@ -0,0 +1,28 @@ +package algs4 + +import "fmt" + +type Accumulator struct { + total float64 + n int +} + +func NewAccumulator() *Accumulator { + return &Accumulator{ + float64(0.0), + 0, + } +} + +func (me *Accumulator) AddDataValue(val float64) { + me.n++ + me.total += val +} + +func (me *Accumulator) Mean() float64 { + return me.total / float64(me.n) +} + +func (me *Accumulator) String() string { + return fmt.Sprintf("Mean (%d values): %7.5f", me.n, me.Mean()) +} diff --git a/algs4/src/go/algs4/canvas.go b/algs4/src/go/algs4/canvas.go index 13c3602..d987a43 100644 --- a/algs4/src/go/algs4/canvas.go +++ b/algs4/src/go/algs4/canvas.go @@ -41,11 +41,6 @@ type Canvas struct { } func NewCanvas(height, width int, xmin, xmax, ymin, ymax float64) (*Canvas, error) { - window, err := x11.NewWindow() - if err != nil { - return nil, err - } - canvas := &Canvas{ Height: height, Width: width, @@ -55,12 +50,27 @@ func NewCanvas(height, width int, xmin, xmax, ymin, ymax float64) (*Canvas, erro Ymax: ymax, img: image.NewRGBA(image.Rect(0, 0, height, width)), - window: window, + window: nil, } return canvas, nil } +func (me *Canvas) ensureHasWindow() error { + if me.window != nil { + return nil + } + + window, err := x11.NewWindow() + if err != nil { + return err + } + + me.window = window + + return nil +} + func (me *Canvas) Image() *image.RGBA { return me.img } @@ -98,14 +108,26 @@ func (me *Canvas) Rectangle(x, y, halfWidth, halfHeight float64) error { return nil } -func (me *Canvas) Pixel(x, y float64) { +func (me *Canvas) Pixel(x, y float64) error { + err := me.ensureHasWindow() + if err != nil { + return err + } + originX, originY := int(me.scaleX(x)), int(me.scaleY(y)) draw.Draw(me.img, image.Rect(originX, originY, originX+1, originY+1), &image.Uniform{image.White}, image.ZP, draw.Src) me.window.FlushImage() + + return nil } func (me *Canvas) Draw() error { + err := me.ensureHasWindow() + if err != nil { + return err + } + draw.Draw(me.window.Screen(), me.window.Screen().Bounds(), me.img, image.ZP, draw.Src) me.window.FlushImage() diff --git a/algs4/src/go/algs4/random.go b/algs4/src/go/algs4/random.go index ce68830..8cb1708 100644 --- a/algs4/src/go/algs4/random.go +++ b/algs4/src/go/algs4/random.go @@ -12,3 +12,7 @@ func init() { func RandomUniform(min, max float64) float64 { return rand.Float64()*(max-min) + min } + +func Random() float64 { + return rand.Float64() +}