Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lab1 - Generate Fibonacci Series #625

Merged
merged 14 commits into from
Sep 24, 2019
11 changes: 11 additions & 0 deletions 01_fib/jimbotech/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Fibonacci Number Generator
## Overview
As part of the ANZ "go" course the first lab is to produce a piece of software
that will produce the Fibonacci series for fib(7).
It was also an exercise in the tour.golang.org.

Generating the series was implemented as "closure" which was a requirement in
the tour-golang . There are other ways to solve this problem,
but I kept it as an example of closure for later reference.

The function maintains state and hence has to be called sequentially.
55 changes: 55 additions & 0 deletions 01_fib/jimbotech/ex_fibonacci.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package main

import (
"fmt"
"io"
"os"
)

var out io.Writer = os.Stdout

// fibonacci returns a function that returns
// an number in the fibonacci sequence.
// This is an implmentation of "closure".
// The inside function returns the current number
// in the fibonnacci sequence, starting at 1
// and sets up the next which will be returned
// in the subsequent call
func fibonacci() func() int {
secondLast, last := 0, 1

return func() int {
result := last
secondLast, last = last, secondLast+last
return result
}
}

func fibSeries(n int) []int {
counter := n
if n < 0 {
counter = -n
}
var fibSerial []int

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: stray blank line. unnecessarily spaces out the code, which matters on real code that does not fit on one screen. blank lines to separate "paragraphs" of code are good, but do think about what your "code paragraphs" are.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

f := fibonacci()
for i := 0; i < counter; i++ {
factor := 1
if n < 0 && i%2 != 0 {
factor = -1
}
fibSerial = append(fibSerial, f()*factor)
}
return fibSerial
}

func fib(n int) {
fibSer := fibSeries(n)
for _, v := range fibSer {
fmt.Fprintln(out, v)
}
}

func main() {
fib(7)
}
70 changes: 70 additions & 0 deletions 01_fib/jimbotech/ex_fibonacci_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package main

import (
"bytes"
"testing"
)

func TestFib(t *testing.T) {

fibResults := []int{1, 1, 2, 3, 5, 8, 13, 21, 34}

f := fibonacci()

for _, val := range fibResults {
if r := f(); r != val {
t.Errorf("returned value %v does not match %v", r, val)
}
}
}

func TestMain(t *testing.T) {

want := "1\n1\n2\n3\n5\n8\n13\n"
var buf bytes.Buffer
out = &buf
main()
result := buf.String()

if result != want {
t.Errorf("expected %v, got %v", want, result)
}
}

func TestNeg(t *testing.T) {

want := "1\n-1\n2\n-3\n5\n-8\n13\n"
var buf bytes.Buffer
out = &buf
fib(-7)
result := buf.String()

if result != want {
t.Errorf("expected %v, got %v", want, result)
}
}

func TestZero(t *testing.T) {

var buf bytes.Buffer
out = &buf
fib(0)
result := buf.String()

if len(result) > 0 {
t.Errorf("expected nothing to be printed, got %v", result)
}
}

func TestOne(t *testing.T) {

want := "1\n"
var buf bytes.Buffer
out = &buf
fib(1)
result := buf.String()

if result != want {
t.Errorf("expected %v, got %v", want, result)
}
}
19 changes: 19 additions & 0 deletions 05_stringer/harirakr/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package main

import (
"fmt"
"io"
"os"
)

var out io.Writer = os.Stdout

type IPAddr [4]byte

func (ip IPAddr) String() string {
return fmt.Sprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3])
}

func main() {
fmt.Fprintln(out, IPAddr{127, 0, 0, 1})
}
38 changes: 38 additions & 0 deletions 05_stringer/harirakr/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package main

import (
"bytes"
"testing"

"github.com/stretchr/testify/assert"
)

func TestMain(t *testing.T) {
var buf bytes.Buffer
out = &buf
main()
assert.Equal(t, "127.0.0.1\n", buf.String())
}

func TestStringer(t *testing.T) {
tcs := map[string]struct {
want string
ip IPAddr
}{
"null": {want: "0.0.0.0", ip: IPAddr{}},
"zero": {want: "0.0.0.0", ip: IPAddr{0}},
"classA": {want: "10.0.0.0", ip: IPAddr{10}},
"classB": {want: "192.168.0.0", ip: IPAddr{192, 168}},
"classC": {want: "172.16.100.0", ip: IPAddr{172, 16, 100}},
"classD": {want: "8.8.8.8", ip: IPAddr{8, 8, 8, 8}},
"mask": {want: "255.255.255.255", ip: IPAddr{255, 255, 255, 255}},
}

for name, tc := range tcs {
output := tc.ip.String()
want := tc.want
t.Run(name, func(t *testing.T) {
assert.Equal(t, want, output)
})
}
}
52 changes: 52 additions & 0 deletions 08_project/kasunfdo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Puppy Store - An in-memory store for puppies

<!-- MarkdownTOC -->

- [Overview](#overview)
- [Prerequisites](#prerequisites)
- [Build, execute, test, lint](#betl)
- [Build](#build)
- [Execute](#execute)
- [Test](#test)
- [Format and Lint](#lint)
- [Review unit test coverage](#coverage)

<!-- /MarkdownTOC -->

## Overview

Puppy Store is a simple in-memory store for [Puppy](pkg/puppy/types.go) objects. Puppy Store
is implemented with CRUD methods for creating, reading, updating, and deleting puppies in puppy store.


## Prerequisites

- Install `go 1.12` according to [official installation instruction](https://golang.org/doc/install)
- Clone this project outside your `$GOPATH` to enable [Go Modules](https://github.com/golang/go/wiki/Modules)
- Install `golangci-lint` according to [instructions](https://github.com/golangci/golangci-lint#local-installation)

## Build, execute, test, lint <a name="betl"></a>

#### Build

go build -o puppystore cmd/puppy-server/main.go

#### Execute

./puppystore


#### Test

go test ./...


#### Format and lint <a name="lint"></a>

gofmt -w .
goimports -w .
golangci-lint run

#### Review unit test coverage <a name="coverage"></a>

go test -coverprofile=coverage.out ./... && go tool cover -html=coverage.out
19 changes: 19 additions & 0 deletions 08_project/kasunfdo/cmd/puppy-server/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package main

import (
"fmt"
"io"
"os"

"github.com/anz-bank/go-course/08_project/kasunfdo/pkg/puppy"
"github.com/anz-bank/go-course/08_project/kasunfdo/pkg/puppy/store"
)

var out io.Writer = os.Stdout

func main() {
store := store.NewMapStore()
p := puppy.Puppy{Breed: "Husky", Colour: "White", Value: 4999.98}
id, _ := store.CreatePuppy(p)
fmt.Fprintf(out, "Puppy(%d) added to store\n", id)
}
19 changes: 19 additions & 0 deletions 08_project/kasunfdo/cmd/puppy-server/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package main

import (
"bytes"
"testing"

"github.com/stretchr/testify/assert"
)

func TestMainOutput(t *testing.T) {
var buf bytes.Buffer
out = &buf

main()

expected := "Puppy(1) added to store\n"
actual := buf.String()
assert.Equal(t, expected, actual)
}
37 changes: 37 additions & 0 deletions 08_project/kasunfdo/pkg/puppy/error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package puppy

import "fmt"

type ErrCode uint32

type Error struct {
Message string
Code ErrCode
}

const (
ErrInvalid ErrCode = 400
ErrNotFound ErrCode = 404
)

func (e ErrCode) String() string {
switch e {
case ErrInvalid:
return "invalid input: %v"
case ErrNotFound:
return "not found: %v"
default:
return "error occurred"
}
}

func (e *Error) Error() string {
return e.Message
}

func NewError(code ErrCode, args ...interface{}) *Error {
return &Error{
Message: fmt.Sprintf(code.String(), args...),
Code: code,
}
}
20 changes: 20 additions & 0 deletions 08_project/kasunfdo/pkg/puppy/error_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package puppy

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestErrCodeString(t *testing.T) {
assert.Equal(t, "invalid input: %v", ErrInvalid.String())
assert.Equal(t, "not found: %v", ErrNotFound.String())

var ErrFoo ErrCode = 900
assert.Equal(t, "error occurred", ErrFoo.String())
}

func TestError(t *testing.T) {
err := NewError(ErrNotFound, "error message")
assert.Equal(t, "not found: error message", err.Error())
}
Loading