diff --git a/go.mod b/go.mod
index 184b9ef0c896f3343e0f718c91a4578af2d83321..2ac83b2c429b939cf7aea7a747c6119eedc4c6c3 100644
--- a/go.mod
+++ b/go.mod
@@ -2,4 +2,7 @@ module pi
 
 go 1.16
 
-require gonum.org/v1/plot v0.9.0
+require (
+	github.com/gizak/termui/v3 v3.1.0
+	gonum.org/v1/plot v0.9.0
+)
diff --git a/go.sum b/go.sum
index 4104d696ba080123894d85ee44f408d3ec2cacf2..bed3ecc344170309930ede4d6845cf855345865c 100644
--- a/go.sum
+++ b/go.sum
@@ -8,6 +8,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
 github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
 github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
 github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
+github.com/gizak/termui/v3 v3.1.0 h1:ZZmVDgwHl7gR7elfKf1xc4IudXZ5qqfDh4wExk4Iajc=
+github.com/gizak/termui/v3 v3.1.0/go.mod h1:bXQEBkJpzxUAKf0+xq9MSWAvWZlE7c+aidmyFlkYTrY=
 github.com/go-fonts/dejavu v0.1.0 h1:JSajPXURYqpr+Cu8U9bt8K+XcACIHWqWrvWCKyeFmVQ=
 github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g=
 github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks=
@@ -21,6 +23,12 @@ github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF0
 github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
 github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
 github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
+github.com/mattn/go-runewidth v0.0.2 h1:UnlwIPBGaTZfPQ6T1IGzPI0EkYAQmT9fAEJ/poFC63o=
+github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
+github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM=
+github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
+github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d h1:x3S6kxmy49zXVVyhcnrFqxvNVCBPb2KZ9hV2RBdS840=
+github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
 github.com/phpdave11/gofpdf v1.4.2 h1:KPKiIbfwbvC/wOncwhrpRdXVj2CZTCFlw4wnoyjtHfQ=
 github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY=
 github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=
@@ -35,6 +43,7 @@ golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL
 golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3 h1:n9HxLrNxWWtEb1cA950nuEEj3QnKbtsCJ6KjcgisNUs=
 golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE=
 golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
 golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
@@ -64,6 +73,7 @@ golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGm
 golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
+gonum.org/v1/gonum v0.8.2 h1:CCXrcPKiGGotvnN6jfUsKk4rRqm7q09/YbKb5xCEvtM=
 gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0=
 gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
 gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=
diff --git a/pi.go b/pi.go
index f1f72255628eabbe78f35563dbd3fc9b8d49d6db..6b12771fa3503d3ece14df368cbb4c00058ba4b0 100644
--- a/pi.go
+++ b/pi.go
@@ -2,19 +2,28 @@
 // If I get time, it would be fun to do the second uebung in go.
 // For the sake of speed, we can do all the numbers at once, put
 // them in arrays, rather than doing i/o on every step.
+// The plotting library I used does not draw to the screen. Bummer. One could
+// use the canvas in vggio, although that pulls in all of fyne.
+
 
 package main
 
 import (
+	"bufio"
 	"errors"
 	"flag"
 	"fmt"
+	"math"
 	"math/rand"
 	"os"
 	"strconv"
 
 	"gonum.org/v1/plot"
+	"gonum.org/v1/plot/font"
+	"gonum.org/v1/plot/plotter"
 	"gonum.org/v1/plot/vg"
+	"gonum.org/v1/plot/vg/draw"
+	"gonum.org/v1/plot/vg/vgimg"
 )
 
 const (
@@ -22,6 +31,12 @@ const (
 	exitFailure
 )
 
+const (
+	sizeHrznt  font.Length = 15 * vg.Centimeter
+	sizeVert   font.Length = 10 * vg.Centimeter
+	nPointPlot             = 1000
+)
+
 // usage prints out anything the caller gives us then bails.
 func usage(e string) {
 	u := "usage: pi seed nsteps nstep_nprint"
@@ -30,7 +45,7 @@ func usage(e string) {
 }
 
 // getnums does the work of filling out the arrays of results
-func getnums(cmdArgs cmdArgs) {
+func getnums(cmdArgs cmdArgs) ([]float32, []float32) {
 	rand.Seed(cmdArgs.seed)
 	inCnt := make([]uint32, cmdArgs.nstep)
 	{ // The braces limit the lifetime of inPoint, to save a bit of memory
@@ -51,20 +66,57 @@ func getnums(cmdArgs cmdArgs) {
 				inCnt[i]++
 			}
 		}
+	} // We have the counts. Now calculate the errors and standard error
+	pi := make([]float32, cmdArgs.nstep)     // estimated pi
+	stdErr := make([]float32, cmdArgs.nstep) // standard error
+
+	for i := range inCnt {
+		ptmp := float64(inCnt[i]) / float64(i+1) // do we need more precision ?
+		qtmp := 1 - ptmp
+		pi[i] = float32(4 * ptmp)
+		stdErr[i] = float32(4 * math.Sqrt((ptmp*qtmp)/(float64(i+1))))
 	}
+	return pi, stdErr
+}
+
+// wrtTable prints out the table, as per the Uebung instructions
+func wrtTable(cmdArgs cmdArgs, pi, stdErr []float32) {
+	b := bufio.NewWriter(os.Stdout)
+	b.WriteString(fmt.Sprintf("%8s %7s %7s %7s\n", "step", "pi", "err", "stderr"))
+	defer b.Flush()
 	for i := 0; i < cmdArgs.nstep; i = i + cmdArgs.nstepPrint {
-		pi := 4 * float32(inCnt[i]) / float32(i+1)
-		fmt.Println(i, inCnt[i], pi)
+		e := math.Pi - pi[i]
+		b.WriteString(fmt.Sprintf("%8d %.5f %.5f %.5f\n", i+1, pi[i], e, stdErr[i]))
 	}
 }
 
 // doplot makes a primitive plot without any interesting options
-func doplot(plotName string) error {
+// If no plotname is given, it means no plot is wanted. We have to rewrite the data
+// to fit to the plot function's expectations (x/y pairs).
+func doplot(pi, stdErr []float32, plotName string) error {
+	if plotName == "" {
+		return nil
+	}
 	p := plot.New()
-	p.Title.Text = "ugly plot"
-	if err := p.Save(15*vg.Centimeter, 10*vg.Centimeter, plotName); err != nil {
+	p.Title.Text = ""
+	cnvs := draw.New(vgimg.New(vg.Points(10), vg.Points(16)))
+	points := make (plotter.XYs, len(pi))
+	for i, piV := range pi {
+		points[i] = plotter.XY{X: float64(i+1), Y:float64(piV)}
+	}
+	line, err := plotter.NewLine(points)
+	if err != nil {
 		return err
 	}
+	p.X.Label.Text = "step"
+	p.Y.Label.Text = "π estimate"
+	p.Add(line)
+	p.Draw(cnvs)
+	if plotName != "" {
+		if err := p.Save(sizeHrznt, sizeVert, plotName); err != nil {
+			return fmt.Errorf("Plotting, opening \"%s\": %w", plotName, err)
+		}
+	}
 	return nil
 }
 
@@ -108,10 +160,16 @@ func main() {
 	if err := cmdline(&cmdArgs); err != nil {
 		usage(err.Error())
 	}
-	fmt.Println("doStdout is", cmdArgs.doStdout)
-	getnums(cmdArgs)
-	if err := doplot(cmdArgs.plotName); err != nil {
+	pi, stdErr := getnums(cmdArgs)
+	wrtTable(cmdArgs, pi, stdErr)
+	if err := doplot(pi, stdErr, cmdArgs.plotName); err != nil {
+		fmt.Fprintln(os.Stderr, err)
+		os.Exit(exitFailure)
+	}
+	if err := scrnPlt(pi, stdErr); err != nil {
 		fmt.Fprintln(os.Stderr, err)
 		os.Exit(exitFailure)
 	}
+		
+	os.Exit(exitSuccess)
 }