Skip to content

Commit

Permalink
Math (quii#201)
Browse files Browse the repository at this point in the history
* math chapter take one - v1

* Bit more done

* More about maths

Nice bit about float accuracy - pleasing

* Roughly equal

* adding images

* extra image of circle ray calculated from angle with y axis

* good enough float comparison

* a bit more clarity on radians

* Hours written and tests passing

* Refactor of radians logic

* bit further along - tests around second hand vector

* change of tack - changing the beginning

want to make the acceptance test skinnier

* new v1

* new v2

* v3

* v4

* should've been using float64 all this time...

* v5 in progress - just needs refactor

* v5 complete

* v6

* Get rid of a lot of crap at the bottom

* v7

* Ok, wasn't quite finished with v7

* something like v8

* done v9 - minute hand complete

* v10 - hour hand radians

* v11 and v12 - complete working svg - and the beginnings of a conclusion

* version 7b - introducing encoding/xml to the acceptance tests

* v7c - beautiful, beautiful acceptance test

* v8 and v9 get the updated acceptance test

* bit of tidying up

* updated v10 to use new AT

* New acceptance test in v11 now

* new acceptance test up to the end

* final version of clockface with API

* making a library of it

* oh even more edits lol so tired

* svg tidy

* small fixes

* attempt to please cj

* minor

* readthrough, fixup

* typos

* add docstring to SVGWriter

* no dot imports please

* doc comment for point in earlier versions

* doc comment for SecondHand

* use v10 in v10 main

* remove binaries

* change import path to use `github.com/quii/learn-go-with-tests/...`

* using key fields now

ARE YOU HAPPY OLD VET?
  • Loading branch information
gypsydave5 authored and quii committed Jul 13, 2019
1 parent a6be481 commit f0c6fce
Show file tree
Hide file tree
Showing 80 changed files with 5,664 additions and 0 deletions.
2,173 changes: 2,173 additions & 0 deletions math.md

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions math/clock.template.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions math/example_clock.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added math/images/unit_circle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added math/images/unit_circle_12_oclock.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added math/images/unit_circle_coords.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added math/images/unit_circle_params.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions math/v1/clockface/clockface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package clockface

import "time"

// A Point represents a two dimensional Cartesian coordinate
type Point struct {
X float64
Y float64
}

// SecondHand is the unit vector of the second hand of an analogue clock at time `t`
// represented as a Point.
func SecondHand(t time.Time) Point {
return Point{150, 60}
}
19 changes: 19 additions & 0 deletions math/v1/clockface/clockface_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package clockface_test

import (
"testing"
"time"

"github.com/quii/learn-go-with-tests/math/v1/clockface"
)

func TestSecondHandAtMidnight(t *testing.T) {
tm := time.Date(1337, time.January, 1, 0, 0, 0, 0, time.UTC)

want := clockface.Point{X: 150, Y: 150 - 90}
got := clockface.SecondHand(tm)

if got != want {
t.Errorf("Got %v, wanted %v", got, want)
}
}
41 changes: 41 additions & 0 deletions math/v10/clockface/clockface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package clockface

import (
"math"
"time"
)

// A Point represents a two dimensional Cartesian coordinate
type Point struct {
X float64
Y float64
}

func secondsInRadians(t time.Time) float64 {
return (math.Pi / (30 / float64(t.Second())))
}

func secondHandPoint(t time.Time) Point {
return angleToPoint(secondsInRadians(t))
}

func minutesInRadians(t time.Time) float64 {
return (secondsInRadians(t) / 60) +
(math.Pi / (30 / float64(t.Minute())))
}

func minuteHandPoint(t time.Time) Point {
return angleToPoint(minutesInRadians(t))
}

func hoursInRadians(t time.Time) float64 {
return (minutesInRadians(t) / 12) +
(math.Pi / (6 / float64(t.Hour()%12)))
}

func angleToPoint(angle float64) Point {
x := math.Sin(angle)
y := math.Cos(angle)

return Point{x, y}
}
7 changes: 7 additions & 0 deletions math/v10/clockface/clockface/clock.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions math/v10/clockface/clockface/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package main

import (
"os"
"time"

"github.com/quii/learn-go-with-tests/math/v10/clockface"
)

func main() {
t := time.Now()
clockface.SVGWriter(os.Stdout, t)
}
134 changes: 134 additions & 0 deletions math/v10/clockface/clockface_acceptance_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package clockface_test

import (
"bytes"
"encoding/xml"
"testing"
"time"

"github.com/quii/learn-go-with-tests/math/v10/clockface"
)

type SVG struct {
XMLName xml.Name `xml:"svg"`
Text string `xml:",chardata"`
Xmlns string `xml:"xmlns,attr"`
Width string `xml:"width,attr"`
Height string `xml:"height,attr"`
ViewBox string `xml:"viewBox,attr"`
Version string `xml:"version,attr"`
Circle Circle `xml:"circle"`
Line []Line `xml:"line"`
}

type Line struct {
X1 float64 `xml:"x1,attr"`
Y1 float64 `xml:"y1,attr"`
X2 float64 `xml:"x2,attr"`
Y2 float64 `xml:"y2,attr"`
}

type Circle struct {
Cx float64 `xml:"cx,attr"`
Cy float64 `xml:"cy,attr"`
R float64 `xml:"r,attr"`
}

func TestSVGWriterSecondHand(t *testing.T) {
cases := []struct {
time time.Time
line Line
}{
{
simpleTime(0, 0, 0),
Line{150, 150, 150, 60},
},
{
simpleTime(0, 0, 30),
Line{150, 150, 150, 240},
},
}

for _, c := range cases {
t.Run(testName(c.time), func(t *testing.T) {
b := bytes.Buffer{}
clockface.SVGWriter(&b, c.time)

svg := SVG{}
xml.Unmarshal(b.Bytes(), &svg)

if !containsLine(c.line, svg.Line) {
t.Errorf("Expected to find the second hand line %+v, in the SVG lines %+v", c.line, svg.Line)
}
})
}
}

func TestSVGWriterMinutedHand(t *testing.T) {
cases := []struct {
time time.Time
line Line
}{
{
simpleTime(0, 0, 0),
Line{150, 150, 150, 70},
},
}

for _, c := range cases {
t.Run(testName(c.time), func(t *testing.T) {
b := bytes.Buffer{}
clockface.SVGWriter(&b, c.time)

svg := SVG{}
xml.Unmarshal(b.Bytes(), &svg)

if !containsLine(c.line, svg.Line) {
t.Errorf("Expected to find the minute hand line %+v, in the SVG lines %+v", c.line, svg.Line)
}
})
}
}

func TestSVGWriterHourHand(t *testing.T) {
cases := []struct {
time time.Time
line Line
}{
// {
// simpleTime(6, 0, 0),
// Line{150, 150, 150, 200},
// },
}

for _, c := range cases {
t.Run(testName(c.time), func(t *testing.T) {
b := bytes.Buffer{}
clockface.SVGWriter(&b, c.time)

svg := SVG{}
xml.Unmarshal(b.Bytes(), &svg)

if !containsLine(c.line, svg.Line) {
t.Errorf("Expected to find the minute hand line %+v, in the SVG lines %+v", c.line, svg.Line)
}
})
}
}

func containsLine(l Line, ls []Line) bool {
for _, line := range ls {
if line == l {
return true
}
}
return false
}

func simpleTime(hours, minutes, seconds int) time.Time {
return time.Date(312, time.October, 28, hours, minutes, seconds, 0, time.UTC)
}

func testName(t time.Time) string {
return t.Format("15:04:05")
}
Loading

0 comments on commit f0c6fce

Please sign in to comment.