I've had this experience one to many times. And in self defence my code doesn't look ugly even when I've just written it; I don't have to come back and "clean it up".
I am exploring two new languages and a Distributed VCS. Go and Node.js. Go has Goroutines (sorta evented, sorta threaded) and Node.js is intrinsically event driven. Git is a VCS born of Linus Torvalds mind (tried Mercuria[hg] but git has won me and the majority over).
Sunday, June 19, 2016
Wednesday, February 10, 2016
I wrote my solutions to tour.golang.org at gist.github.com
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Exercise: Web Crawler http://tour.golang.org/concurrency/10 | |
package main | |
import ( | |
"fmt" | |
"sync" | |
) | |
type Fetcher interface { | |
// Fetch returns the body of URL and | |
// a slice of URLs found on that page. | |
Fetch(url string) (body string, urls []string, err error) | |
} | |
type syncStringSet struct { | |
set map[string]bool | |
mux sync.Mutex | |
} | |
// set.add(string) returns true if it does not have string in set, but has now inserted | |
// the string into the set. | |
// set.add(url) returns false if it has the url in its cache | |
func (ss *syncStringSet) add(str string) bool { | |
ss.mux.Lock() | |
defer ss.mux.Unlock() | |
if _, hasEntry := ss.set[str]; hasEntry { | |
return false | |
} | |
ss.set[str] = true | |
return true | |
} | |
type result struct { | |
url string | |
body string | |
err error | |
} | |
type crawlError struct { | |
error | |
} | |
func crawl( | |
url string, | |
depth int, | |
fetcher Fetcher, | |
results chan result, | |
seen *syncStringSet, | |
crawlers *sync.WaitGroup, | |
) { | |
defer crawlers.Done() | |
if depth < 1 { | |
results <- result{ | |
url: url, | |
err: crawlError{fmt.Errorf("depth exceeded (%d)", depth)}, | |
} | |
return | |
} | |
if !seen.add(url) { | |
results <- result{ | |
url: url, | |
err: crawlError{fmt.Errorf("seen.add(%q) == false", url)}, | |
} | |
return | |
} | |
body, urls, err := fetcher.Fetch(url) | |
for _, u := range urls { | |
crawlers.Add(1) | |
go crawl(u, depth-1, fetcher, results, seen, crawlers) | |
} | |
results <- result{url, body, err} | |
} | |
func Crawl(url string, depth int, fetcher Fetcher) { | |
seen := &syncStringSet{set: make(map[string]bool)} | |
crawlers := &sync.WaitGroup{} | |
results := make(chan result) | |
//expected_msgs.inc() | |
crawlers.Add(1) | |
go crawl(url, depth, fetcher, results, seen, crawlers) | |
go func() { | |
crawlers.Wait() | |
close(results) | |
}() | |
for res := range results { | |
_, isCrawlError := res.err.(crawlError) | |
switch { | |
case isCrawlError: | |
//fmt.Println(res.err) | |
case res.err != nil: | |
fmt.Println(res.err) | |
default: | |
fmt.Printf("found: %s %q\n", res.url, res.body) | |
} | |
} | |
} | |
func main() { | |
Crawl("http://golang.org/", 4, fetcher) | |
} | |
// fakeFetcher is Fetcher that returns canned results. | |
type fakeFetcher map[string]*fakeResult | |
type fakeResult struct { | |
body string | |
urls []string | |
} | |
func (f fakeFetcher) Fetch(url string) (string, []string, error) { | |
if res, ok := f[url]; ok { | |
return res.body, res.urls, nil | |
} | |
return "", nil, fmt.Errorf("not found: %s", url) | |
} | |
// fetcher is a populated fakeFetcher. | |
var fetcher = fakeFetcher{ | |
"http://golang.org/": &fakeResult{ | |
"The Go Programming Language", | |
[]string{ | |
"http://golang.org/pkg/", | |
"http://golang.org/cmd/", | |
}, | |
}, | |
"http://golang.org/pkg/": &fakeResult{ | |
"Packages", | |
[]string{ | |
"http://golang.org/", | |
"http://golang.org/cmd/", | |
"http://golang.org/pkg/fmt/", | |
"http://golang.org/pkg/os/", | |
}, | |
}, | |
"http://golang.org/pkg/fmt/": &fakeResult{ | |
"Package fmt", | |
[]string{ | |
"http://golang.org/", | |
"http://golang.org/pkg/", | |
}, | |
}, | |
"http://golang.org/pkg/os/": &fakeResult{ | |
"Package os", | |
[]string{ | |
"http://golang.org/", | |
"http://golang.org/pkg/", | |
}, | |
}, | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Exercise: Equivalent Binary Trees http://tour.golang.org/concurrency/8 | |
// | |
// 1. Implement the Walk function. | |
// | |
// 2. Test the Walk function. | |
// | |
// The function tree.New(k) constructs a randomly-structured binary tree | |
// holding the values k, 2k, 3k, ..., 10k. | |
// | |
// Create a new channel ch and kick off the walker: | |
// | |
// go Walk(tree.New(1), ch) | |
// | |
// Then read and print 10 values from the channel. It should be the numbers | |
// 1, 2, 3, ..., 10. | |
// | |
// 3. Implement the Same function using Walk to determine whether t1 and t2 | |
// store the same values. | |
// | |
// 4. Test the Same function. | |
// | |
// Same(tree.New(1), tree.New(1)) should return true, and Same(tree.New(1), | |
// tree.New(2)) should return false. | |
package main | |
import ( | |
"fmt" | |
"golang.org/x/tour/tree" | |
) | |
// Walk walks the tree t sending all values | |
// from the tree to the channel ch. | |
func Walk(t *tree.Tree, ch chan int) { | |
if t.Left != nil { | |
Walk(t.Left, ch) | |
} | |
ch <- t.Value | |
if t.Right != nil { | |
Walk(t.Right, ch) | |
} | |
} | |
// Same determines whether the trees | |
// t1 and t2 contain the same values. | |
func Same(t1, t2 *tree.Tree) bool { | |
ch1 := make(chan int) | |
ch2 := make(chan int) | |
go Walk(t1, ch1) | |
go Walk(t2, ch2) | |
for i:=0; i<10; i++ { | |
v1 := <- ch1 | |
v2 := <- ch2 | |
if v1 != v2 { | |
return false | |
} | |
} | |
return true | |
} | |
func main() { | |
if Same(tree.New(1), tree.New(1)) { | |
fmt.Println("The trees are the same.") | |
} else { | |
fmt.Println("The trees are NOT the same.") | |
} | |
} | |
/* | |
func main() { | |
ch := make(chan int) | |
go Walk(tree.New(1), ch) | |
for i := 0; i < 10; i++ { | |
fmt.Println(<-ch) | |
} | |
} | |
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Exercise: Loops and Functions http://tour.golang.org/flowcontrol/8 | |
// Next, change the loop condition to stop once the value has stopped changing | |
// (or only changes by a very small delta). See if that's more or fewer | |
// iterations. How close are you to the math.Sqrt? | |
package main | |
import ( | |
"fmt" | |
"math" | |
) | |
func Sqrt(x float64) float64 { | |
delta := 0.0001 //terminates at i=7 | |
//delta := 0.00001 //terminates at i=9 | |
//delta := 0.000001 //terminates at i=11 | |
z := float64(1) | |
for i := 0; i < 100; i++ { | |
z0 := z | |
z = z - ((z*z - x) / (2*x)) | |
if math.Abs(z-z0) < delta { | |
fmt.Printf("small enough i=%d, delta=%f\n", i, delta) | |
break | |
} | |
} | |
return z | |
} | |
func main() { | |
fmt.Println(Sqrt(2)) | |
fmt.Println("math.Sqrt(2) =", math.Sqrt(2)) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Exercise: Loops and Functions http://tour.golang.org/flowcontrol/8 | |
package main | |
import ( | |
"fmt" | |
) | |
func Sqrt(x float64) float64 { | |
z := float64(1) | |
for i := 0; i < 10; i++ { | |
z = z - ((z*z - x) / (2*x)) | |
} | |
return z | |
} | |
func main() { | |
fmt.Println(Sqrt(2)) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Exercise: Stringers http://tour.golang.org/methods/18 | |
package main | |
import "fmt" | |
type IPAddr [4]byte | |
// TODO: Add a "String() string" method to IPAddr. | |
func (ip IPAddr) String() string { | |
return fmt.Sprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]) | |
} | |
func main() { | |
addrs := map[string]IPAddr{ | |
"loopback": {127, 0, 0, 1}, | |
"googleDNS": {8, 8, 8, 8}, | |
} | |
for n, a := range addrs { | |
fmt.Printf("%v: %v\n", n, a) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Exercise: Errors http://tour.golang.org/methods/20 | |
package main | |
import ( | |
"fmt" | |
"math" | |
) | |
type ErrNegativeSqrt float64 | |
func (err ErrNegativeSqrt) Error() string { | |
return fmt.Sprintf("cannot Sqrt negative number: %d", err) | |
} | |
func Sqrt(x float64) (float64, error) { | |
if x < 0 { | |
return math.NaN(), ErrNegativeSqrt(x) | |
} | |
z := float64(1) | |
for i :=1; i<10; i++ { | |
z = z - ((z*z)-x)/(2*x) | |
} | |
return z, nil | |
} | |
func main() { | |
fmt.Println(Sqrt(2)) | |
fmt.Println(Sqrt(-2)) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Exercise: Readers http://tour.golang.org/methods/22 | |
package main | |
import "golang.org/x/tour/reader" | |
type MyReader struct{} | |
func (m MyReader) Read(b []byte) (n int, err error) { | |
for n = range b { | |
b[n] = 'A' | |
} | |
return | |
} | |
func main() { | |
reader.Validate(MyReader{}) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Exercise: rot13Reader http://tour.golang.org/methods/23 | |
package main | |
import ( | |
"io" | |
"os" | |
"strings" | |
) | |
type rot13Reader struct { | |
r io.Reader | |
} | |
func (rot *rot13Reader) Read(b []byte) (n int, err error) { | |
n, err = rot.r.Read(b) | |
for i, v := range b { | |
switch { | |
case v >= 'A' && v <= 'Z': | |
if v < 'N' { | |
b[i] += 13 | |
} else { | |
b[i] -= 13 | |
} | |
case v >= 'a' && v <= 'z': | |
if v < 'n' { | |
b[i] += 13 | |
} else { | |
b[i] -= 13 | |
} | |
} | |
} | |
return | |
} | |
func main() { | |
s := strings.NewReader("Lbh penpxrq gur pbqr!") | |
r := rot13Reader{s} | |
io.Copy(os.Stdout, &r) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Exercise: Images http://tour.golang.org/methods/25 | |
package main | |
import ( | |
"golang.org/x/tour/pic" | |
"image" | |
"image/color" | |
) | |
type Image struct{} | |
func (i Image) ColorModel() color.Model { | |
return color.RGBAModel | |
} | |
func (i Image) Bounds() image.Rectangle { | |
return image.Rect(0, 0, 256, 256) | |
} | |
func (i Image) At(x, y int) color.Color { | |
return color.RGBA{72, 72, uint8(x^y), 255} | |
} | |
func main() { | |
m := Image{} | |
pic.ShowImage(m) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Exercise: Slices http://tour.golang.org/moretypes/15 | |
package main | |
import "golang.org/x/tour/pic" | |
func Pic(dx, dy int) [][]uint8 { | |
var p = make([]([]uint8), dy) | |
for y := 0; y < len(p); y++ { | |
p[y] = make([]uint8, dx) | |
for x := 0; x < len(p[y]); x++ { | |
//p[y][x] = uint8((y + x) / 2) | |
//p[y][x] = uint8(y * x) | |
p[y][x] = uint8(y ^ x) | |
} | |
} | |
return p | |
} | |
func main() { | |
pic.Show(Pic) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Exercise: Maps http://tour.golang.org/moretypes/20 | |
package main | |
import ( | |
"golang.org/x/tour/wc" | |
"strings" | |
) | |
func WordCount(s string) map[string]int { | |
wordcount := make(map[string]int) | |
for _, w := range strings.Fields(s) { | |
wordcount[w]++ | |
} | |
return wordcount | |
} | |
func main() { | |
wc.Test(WordCount) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Exercise: Fibonacci closure http://tour.golang.org/moretypes/23 | |
package main | |
import "fmt" | |
// fibonacci is a function that returns | |
// a function that returns an int. | |
func fibonacci() func() int { | |
prev, curr := 0, 1 | |
return func() int { | |
ret := prev | |
prev, curr = curr, prev+curr | |
return ret | |
} | |
} | |
func main() { | |
f := fibonacci() | |
for i := 0; i < 10; i++ { | |
fmt.Println(f()) | |
} | |
} |
How quickly I've picked up Go
I started writing Go with the cononical hello_world.go program on Jan 11, 2016.
I wrote a working B+Tree implementation in Go on Feb 11, 2016.
So I would say it took me 4 weeks to become "productive" in Go. I still need to use the Playground to work out small issues with Go syntax every now and again.
I wrote a working B+Tree implementation in Go on Feb 11, 2016.
So I would say it took me 4 weeks to become "productive" in Go. I still need to use the Playground to work out small issues with Go syntax every now and again.
Sunday, February 7, 2016
Testing Gist & Go Playground
The Gist:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import "fmt" | |
func showArgs(args ...int) { | |
fmt.Println(args) | |
} | |
func main() { | |
//n := []byte{0, 1, 2, 3, 4} //odd | |
n := []byte{0, 1, 2, 3} //even | |
l := n[:len(n)/2] | |
r := n[len(n)/2:] | |
fmt.Println(n) | |
fmt.Println(len(n)/2) | |
fmt.Println(l) | |
fmt.Println(r) | |
showArgs(1,2,3) | |
} |
The iframe embed of Go Playground heigh=500
Subscribe to:
Posts (Atom)