# Exercise 10

Create .go files as described below. Each should declare itself to be in package exer10.

## Concurrent Fibonacci

In fibonacci.go, write a function that calculates Fibonacci numbers concurrently. The function:

func Fib(n uint, cutoff uint) uint { … }


… should calculate the n-th Fibonacci number. It should do this (using the worst algorithm in the world which is) recursively using the identities:

$$f(0) = 0$$

$$f(1) = 1$$

$$f(n) = f(n-1) + f(n-2)$$

The recursive steps should be concurrent if n > cutoff and sequential otherwise.

Test values for cutoff and choose something good as a default in this function (and include it in your code). It should definitely be larger than zero:

func Fibonacci(n uint) uint {
return Fib(n, 0)
}


## Go Interfaces

In the last exercises, we have created the Point struct, including .Rotate and .Scale methods. Copy your points.go to this exercise (and change the package to exer10).

Let's create another struct to represent a geometric thing where we could do similar operations:

type Triangle struct {
A, B, C Point
}
func (t Triangle) String() string {
return fmt.Sprintf("[%s %s %s]", t.A, t.B, t.C)
}


In triangle.go, copy this code and add methods .Scale and .Rotate that have similar behaviour to the ones on Point. [Hint: you can likely just call the Point methods on the three corner points.]

Create an interface Transformable that includes any struct that has .Scale and .Rotate methods like these structs do.

Write a function TurnDouble(transf, angle) that takes a Transformable instance and and angle.

func TurnDouble(t Transformable, angle float64) { … }


It should double the size (scale 2) and rotate by the given angle in-place. Then this code:

pt := Point{3, 4}
TurnDouble(&pt, 3*math.Pi/2)
fmt.Println(pt)
tri := Triangle{Point{1, 2}, Point{-3, 4}, Point{5, -6}}
TurnDouble(&tri, math.Pi)
fmt.Println(tri)


Should output (probably with some numerical error that I edited out for simplicity):

(8, -6)
[(-2, -4) (6, -8) (-10, 12)]


## Images

In this question, we will explore some of the Go built-in pacakges. In image.go, write a function:

func DrawCircle(outerRadius, innerRadius int, outputFile string) { … }


In that function, draw a 200×200 PNG image with a circle. The circle should inner- and outer-radius as specified. That is, if a pixel is between innerRadius and outerRadius pixels from the point (100,100), colour it black; else colour it white.

1. Create an image.Rectangle from (0,0) to (200,200) to describe the bounds of the image.
2. Use image.newRGBA to create a grid of pixels to draw on.
3. Iterate through each pixel and colour it appropriately. Always set the alpha (A) value to 255, so the pixel is opaque.
4. Use os.Create to create the file handle to write.
5. Ensure that the file handle is always closed (defer).
6. Use png.Encode to write the image.
7. Handle all of the errors that might be returned (from the file writing) and deal with them. It's okay for this exercise to panic, but you should at least acknowledge errors if they occur.

You will need things from the image, image/png, and os packages for this.

The format of the RGBA struct might not be obvious: the pixel data is flattened into a one-dimensional slice of uint8 values. The first four values in the array specify the first pixel's R, G, B, A (alpha channel) values. The next four are the second pixel, etc.

The first 4×width values describe the first row of the image, and so on. The struct's .Stride value gives the number of slice elements needed to describe one row (4×width). The docs give a formula for the position (of the R component) of a specific pixel.

You can compare my output for DrawCircle(40, 20, "out.png").

## GoDoc (optional)

The convention for documentation in Go is to include a comment on the line(s) before the definition, like this:

// Do a thing that takes s seconds.
func doThing(s uint) { … }


Then automated tools like GoDoc can produce documentation from source code.

If you add a short documentation comment to each function and struct created for this exercise, they will appear in GoDoc results.

Once you have done that, you can try:

godoc -http :8080


…and visit http://localhost:8080, or more specifically http://localhost:8080/pkg/exer10/ to see the documented package.

## Submitting

Submit your files through CourSys for Exercise 10.

Updated Mon Oct. 12 2020, 20:08 by ggbaker.