From 4abbfabb52fee0a6c03e75c1ce1b3d1957425dfc Mon Sep 17 00:00:00 2001 From: Bo-Yi Wu Date: Sat, 11 Feb 2017 12:32:16 +0800 Subject: [PATCH] fix: coding style and file format for chapter 11, 12, 13, 14 and 15. --- eBook/exercises/chapter_11/float_sort.go | 132 +++++------ eBook/exercises/chapter_11/float_sortmain.go | 50 ++-- eBook/exercises/chapter_11/interface_nil.go | 92 ++++---- eBook/exercises/chapter_11/interface_poly3.go | 137 +++++------ eBook/exercises/chapter_11/interfaces_ext.go | 103 ++++---- .../exercises/chapter_11/interfaces_poly2.go | 115 ++++----- eBook/exercises/chapter_11/main_stack.go | 59 ++--- eBook/exercises/chapter_11/main_stack_v2.go | 34 +-- .../chapter_11/map_function_interface.go | 125 +++++----- .../chapter_11/map_function_interface_var.go | 119 +++++----- eBook/exercises/chapter_11/min_interface.go | 58 ++--- eBook/exercises/chapter_11/minmain.go | 62 ++--- .../exercises/chapter_11/point_interfaces.go | 179 +++++++------- eBook/exercises/chapter_11/print.go | 93 ++++---- .../exercises/chapter_11/simple_interface.go | 69 +++--- .../exercises/chapter_11/simple_interface2.go | 123 +++++----- .../exercises/chapter_11/simple_interface3.go | 149 ++++++------ eBook/exercises/chapter_11/sort/sort.go | 120 +++++----- eBook/exercises/chapter_11/sort_persons.go | 72 +++--- .../chapter_11/stack/stack_general.go | 78 +++---- .../chapter_11/stack/stack_general_v2.go | 56 ++--- eBook/exercises/chapter_12/calculator.go | 110 ++++----- eBook/exercises/chapter_12/cat_numbered.go | 86 +++---- eBook/exercises/chapter_12/degob.go | 83 +++---- eBook/exercises/chapter_12/hash_md5.go | 41 ++-- eBook/exercises/chapter_12/hello_who.go | 32 +-- eBook/exercises/chapter_12/read_csv.go | 135 +++++------ .../exercises/chapter_12/remove_3till5char.go | 74 +++--- .../chapter_12/stack/stack_struct.go | 64 ++--- eBook/exercises/chapter_12/wiki_part1.go | 1 + .../exercises/chapter_12/word_letter_count.go | 73 +++--- eBook/exercises/chapter_13/panic_defer.go | 89 +++---- .../chapter_13/panic_defer_convint.go | 89 +++---- .../exercises/chapter_13/recover_divbyzero.go | 69 +++--- eBook/exercises/chapter_13/string_reverse.go | 36 +-- .../chapter_13/string_reverse_test.go | 80 +++---- eBook/exercises/chapter_14/blocking.go | 38 +-- eBook/exercises/chapter_14/channel_block3.go | 45 ++-- eBook/exercises/chapter_14/channel_buffer.go | 43 ++-- eBook/exercises/chapter_14/concurrent_pi.go | 91 ++++---- eBook/exercises/chapter_14/concurrent_pi2.go | 91 ++++---- .../chapter_14/general_lazy_evalution2.go | 119 +++++----- eBook/exercises/chapter_14/gofibonacci.go | 88 +++---- eBook/exercises/chapter_14/gofibonacci2.go | 71 +++--- eBook/exercises/chapter_14/gofibonacci3.go | 90 +++---- .../chapter_14/gofibonacci_select.go | 85 +++---- eBook/exercises/chapter_14/goroutine_close.go | 52 ++--- eBook/exercises/chapter_14/goroutine_panic.go | 44 ++-- .../exercises/chapter_14/goroutine_select.go | 61 +++-- eBook/exercises/chapter_14/gosum.go | 32 +-- .../exercises/chapter_14/multiplex_server3.go | 117 +++++----- .../chapter_14/polar_to_cartesian.go | 203 ++++++++-------- .../exercises/chapter_14/producer_consumer.go | 85 +++---- .../chapter_14/producer_consumer2.go | 59 ++--- eBook/exercises/chapter_14/random_bitgen.go | 46 ++-- eBook/exercises/chapter_15/client1.go | 92 ++++---- eBook/exercises/chapter_15/hello_server.go | 39 ++-- eBook/exercises/chapter_15/http_fetch2.go | 62 ++--- eBook/exercises/chapter_15/server1.go | 150 ++++++------ eBook/exercises/chapter_15/statistics.go | 220 +++++++++--------- .../chapter_15/template_validation_recover.go | 59 ++--- .../chapter_15/twitter_status_json.go | 67 +++--- eBook/exercises/chapter_15/webhello2.go | 48 ++-- 63 files changed, 2662 insertions(+), 2622 deletions(-) diff --git a/eBook/exercises/chapter_11/float_sort.go b/eBook/exercises/chapter_11/float_sort.go index 393e5ed..bd379a6 100755 --- a/eBook/exercises/chapter_11/float_sort.go +++ b/eBook/exercises/chapter_11/float_sort.go @@ -1,66 +1,66 @@ -package float64 - -import ( - "fmt" - "math/rand" - "time" -) - -type Sorter interface { - Len() int - Less(i, j int) bool - Swap(i, j int) -} - -func Sort(data Sorter) { - for pass := 1; pass < data.Len(); pass++ { - for i := 0; i < data.Len()-pass; i++ { - if data.Less(i+1, i) { - data.Swap(i, i+1) - } - } - } -} - -func IsSorted(data Sorter) bool { - n := data.Len() - for i := n - 1; i > 0; i-- { - if data.Less(i, i-1) { - return false - } - } - return true -} - -type Float64Array []float64 - -func (p Float64Array) Len() int { return len(p) } -func (p Float64Array) Less(i, j int) bool { return p[i] < p[j] } -func (p Float64Array) Swap(i, j int) { p[i], p[j] = p[j], p[i] } - -func NewFloat64Array() Float64Array { - return make([]float64, 25) -} - -func (p Float64Array) Fill(n int) { - rand.Seed(int64(time.Now().Nanosecond())) - for i := 0; i < n; i++ { - p[i] = 100 * (rand.Float64()) - } -} - -func (p Float64Array) List() string { - s := "{ " - for i := 0; i < p.Len(); i++ { - if p[i] == 0 { - continue - } - s += fmt.Sprintf("%3.1f ", p[i]) - } - s += " }" - return s -} - -func (p Float64Array) String() string { - return p.List() -} +package float64 + +import ( + "fmt" + "math/rand" + "time" +) + +type Sorter interface { + Len() int + Less(i, j int) bool + Swap(i, j int) +} + +func Sort(data Sorter) { + for pass := 1; pass < data.Len(); pass++ { + for i := 0; i < data.Len()-pass; i++ { + if data.Less(i+1, i) { + data.Swap(i, i+1) + } + } + } +} + +func IsSorted(data Sorter) bool { + n := data.Len() + for i := n - 1; i > 0; i-- { + if data.Less(i, i-1) { + return false + } + } + return true +} + +type Float64Array []float64 + +func (p Float64Array) Len() int { return len(p) } +func (p Float64Array) Less(i, j int) bool { return p[i] < p[j] } +func (p Float64Array) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +func NewFloat64Array() Float64Array { + return make([]float64, 25) +} + +func (p Float64Array) Fill(n int) { + rand.Seed(int64(time.Now().Nanosecond())) + for i := 0; i < n; i++ { + p[i] = 100 * (rand.Float64()) + } +} + +func (p Float64Array) List() string { + s := "{ " + for i := 0; i < p.Len(); i++ { + if p[i] == 0 { + continue + } + s += fmt.Sprintf("%3.1f ", p[i]) + } + s += " }" + return s +} + +func (p Float64Array) String() string { + return p.List() +} diff --git a/eBook/exercises/chapter_11/float_sortmain.go b/eBook/exercises/chapter_11/float_sortmain.go index e7b1922..e8f701b 100755 --- a/eBook/exercises/chapter_11/float_sortmain.go +++ b/eBook/exercises/chapter_11/float_sortmain.go @@ -1,25 +1,25 @@ -package main - -import ( - "fmt" - "./float64" -) - -func main() { - f1 := float64.NewFloat64Array() - f1.Fill(10) - fmt.Printf("Before sorting %s\n", f1) - float64.Sort(f1) - fmt.Printf("After sorting %s\n", f1) - if float64.IsSorted(f1) { - fmt.Println("The float64 array is sorted!") - } else { - fmt.Println("The float64 array is NOT sorted!") - } -} - -/* Output: -Before sorting { 55.0 82.3 36.4 66.6 25.3 82.7 47.4 21.5 4.6 81.6 } -After sorting { 4.6 21.5 25.3 36.4 47.4 55.0 66.6 81.6 82.3 82.7 } -The float64 array is sorted! -*/ \ No newline at end of file +package main + +import ( + "./float64" + "fmt" +) + +func main() { + f1 := float64.NewFloat64Array() + f1.Fill(10) + fmt.Printf("Before sorting %s\n", f1) + float64.Sort(f1) + fmt.Printf("After sorting %s\n", f1) + if float64.IsSorted(f1) { + fmt.Println("The float64 array is sorted!") + } else { + fmt.Println("The float64 array is NOT sorted!") + } +} + +/* Output: +Before sorting { 55.0 82.3 36.4 66.6 25.3 82.7 47.4 21.5 4.6 81.6 } +After sorting { 4.6 21.5 25.3 36.4 47.4 55.0 66.6 81.6 82.3 82.7 } +The float64 array is sorted! +*/ diff --git a/eBook/exercises/chapter_11/interface_nil.go b/eBook/exercises/chapter_11/interface_nil.go index b2a4d4d..f419736 100755 --- a/eBook/exercises/chapter_11/interface_nil.go +++ b/eBook/exercises/chapter_11/interface_nil.go @@ -1,46 +1,46 @@ -// interface_nil.go -package main - -import "fmt" - -type Any interface {} -type Anything struct {} - -func main() { - any := getAny() - if any == nil { - fmt.Println("any is nil") - } else { - fmt.Println("any is not nil") - } -/* - // to get the inner value: - anything := any.(*Anything) - if anything == nil { - fmt.Println("anything is nil") - } else { - fmt.Println("anything is not nil") - } -*/ -} - -func getAny() Any { - return getAnything() -} - -func getAnything() *Anything { - return nil -} - -/* Output: -any is not nil -WHY? -you would perhaps expect: any is nil,because getAnything() returns that -BUT: -the interface value any is storing a value, so it is not nil. -It just so happens that the particular value it is storing is a nil pointer. -The any variable has a type, so it's not a nil interface, -rather an interface variable with type Any and concrete value (*Anything)(nil). -To get the inner value of any, use: anything := any.(*Anything) -now anything contains nil ! -*/ +// interface_nil.go +package main + +import "fmt" + +type Any interface{} +type Anything struct{} + +func main() { + any := getAny() + if any == nil { + fmt.Println("any is nil") + } else { + fmt.Println("any is not nil") + } + /* + // to get the inner value: + anything := any.(*Anything) + if anything == nil { + fmt.Println("anything is nil") + } else { + fmt.Println("anything is not nil") + } + */ +} + +func getAny() Any { + return getAnything() +} + +func getAnything() *Anything { + return nil +} + +/* Output: +any is not nil +WHY? +you would perhaps expect: any is nil,because getAnything() returns that +BUT: +the interface value any is storing a value, so it is not nil. +It just so happens that the particular value it is storing is a nil pointer. +The any variable has a type, so it's not a nil interface, +rather an interface variable with type Any and concrete value (*Anything)(nil). +To get the inner value of any, use: anything := any.(*Anything) +now anything contains nil ! +*/ diff --git a/eBook/exercises/chapter_11/interface_poly3.go b/eBook/exercises/chapter_11/interface_poly3.go index f75b454..9c7d023 100755 --- a/eBook/exercises/chapter_11/interface_poly3.go +++ b/eBook/exercises/chapter_11/interface_poly3.go @@ -1,68 +1,69 @@ -// interface_poly3.go -package main - -import ( - "fmt" - "math" -) - -type Shaper interface { - Area() float32 -} - -type Shape struct {} -func (sh Shape) Area() float32 { - return -1 // the shape is indetermined, so we return something impossible -} - -type Square struct { - side float32 - Shape -} - -func (sq *Square) Area() float32 { - return sq.side * sq.side -} - -type Rectangle struct { - length, width float32 - Shape -} - -func (r *Rectangle) Area() float32 { - return r.length * r.width -} - -type Circle struct { - radius float32 - Shape -} - -func (c *Circle) Area() float32 { - return math.Pi * c.radius * c.radius -} - -func main() { - s := Shape{} - r := &Rectangle{5, 3, s} // Area() of Rectangle needs a value - q := &Square{5, s} // Area() of Square needs a pointer - c := &Circle{2.5, s} - shapes := []Shaper{r, q, c, s} - fmt.Println("Looping through shapes for area ...") - for n, _ := range shapes { - fmt.Println("Shape details: ", shapes[n]) - fmt.Println("Area of this shape is: ", shapes[n].Area()) - } -} -/* Output: -Looping through shapes for area ... -Shape details: {5 3} -Area of this shape is: 15 -Shape details: &{5} -Area of this shape is: 25 -Shape details: &{2.5} -Area of this shape is: 19.634954 -Shape details: {} -Area of this shape is: -1 -*/ - +// interface_poly3.go +package main + +import ( + "fmt" + "math" +) + +type Shaper interface { + Area() float32 +} + +type Shape struct{} + +func (sh Shape) Area() float32 { + return -1 // the shape is indetermined, so we return something impossible +} + +type Square struct { + side float32 + Shape +} + +func (sq *Square) Area() float32 { + return sq.side * sq.side +} + +type Rectangle struct { + length, width float32 + Shape +} + +func (r *Rectangle) Area() float32 { + return r.length * r.width +} + +type Circle struct { + radius float32 + Shape +} + +func (c *Circle) Area() float32 { + return math.Pi * c.radius * c.radius +} + +func main() { + s := Shape{} + r := &Rectangle{5, 3, s} // Area() of Rectangle needs a value + q := &Square{5, s} // Area() of Square needs a pointer + c := &Circle{2.5, s} + shapes := []Shaper{r, q, c, s} + fmt.Println("Looping through shapes for area ...") + for n := range shapes { + fmt.Println("Shape details: ", shapes[n]) + fmt.Println("Area of this shape is: ", shapes[n].Area()) + } +} + +/* Output: +Looping through shapes for area ... +Shape details: {5 3} +Area of this shape is: 15 +Shape details: &{5} +Area of this shape is: 25 +Shape details: &{2.5} +Area of this shape is: 19.634954 +Shape details: {} +Area of this shape is: -1 +*/ diff --git a/eBook/exercises/chapter_11/interfaces_ext.go b/eBook/exercises/chapter_11/interfaces_ext.go index 4391ebc..5a1db23 100755 --- a/eBook/exercises/chapter_11/interfaces_ext.go +++ b/eBook/exercises/chapter_11/interfaces_ext.go @@ -1,51 +1,52 @@ -package main - -import "fmt" - -type Square struct { - side float32 -} - -type Triangle struct { - base float32 - height float32 -} - -type AreaInterface interface { - Area() float32 -} - -type PeriInterface interface { - Perimeter() float32 -} -func main() { - var areaIntf AreaInterface - var periIntf PeriInterface - - sq1 := new(Square) - sq1.side = 5 - tr1 := new(Triangle) - tr1.base = 3 - tr1.height = 5 - - areaIntf = sq1 - fmt.Printf("The square has area: %f\n", areaIntf.Area()) - - periIntf = sq1 - fmt.Printf("The square has perimeter: %f\n", periIntf.Perimeter()) - - areaIntf = tr1 - fmt.Printf("The triangle has area: %f\n", areaIntf.Area()) -} - -func (sq *Square) Area() float32 { - return sq.side * sq.side -} - -func (sq *Square) Perimeter() float32 { - return 4 * sq.side -} - -func (tr *Triangle) Area() float32 { - return 0.5 * tr.base*tr.height -} +package main + +import "fmt" + +type Square struct { + side float32 +} + +type Triangle struct { + base float32 + height float32 +} + +type AreaInterface interface { + Area() float32 +} + +type PeriInterface interface { + Perimeter() float32 +} + +func main() { + var areaIntf AreaInterface + var periIntf PeriInterface + + sq1 := new(Square) + sq1.side = 5 + tr1 := new(Triangle) + tr1.base = 3 + tr1.height = 5 + + areaIntf = sq1 + fmt.Printf("The square has area: %f\n", areaIntf.Area()) + + periIntf = sq1 + fmt.Printf("The square has perimeter: %f\n", periIntf.Perimeter()) + + areaIntf = tr1 + fmt.Printf("The triangle has area: %f\n", areaIntf.Area()) +} + +func (sq *Square) Area() float32 { + return sq.side * sq.side +} + +func (sq *Square) Perimeter() float32 { + return 4 * sq.side +} + +func (tr *Triangle) Area() float32 { + return 0.5 * tr.base * tr.height +} diff --git a/eBook/exercises/chapter_11/interfaces_poly2.go b/eBook/exercises/chapter_11/interfaces_poly2.go index ce7ec97..4675bc7 100755 --- a/eBook/exercises/chapter_11/interfaces_poly2.go +++ b/eBook/exercises/chapter_11/interfaces_poly2.go @@ -1,57 +1,58 @@ -// interfaces_poly2.go -package main - -import ( - "fmt" - "math" -) - -type Shaper interface { - Area() float32 -} - -type Square struct { - side float32 -} - -func (sq *Square) Area() float32 { - return sq.side * sq.side -} - -type Rectangle struct { - length, width float32 -} - -func (r Rectangle) Area() float32 { - return r.length * r.width -} - -type Circle struct { - radius float32 -} - -func (c *Circle) Area() float32 { - return math.Pi * c.radius * c.radius -} - -func main() { - r := Rectangle{5, 3} // Area() of Rectangle needs a value - q := &Square{5} // Area() of Square needs a pointer - c := &Circle{2.5} - fmt.Println("Looping through shapes for area ...") - // shapes := []Shaper{Shaper(r), Shaper(q), Shaper(c)} - shapes := []Shaper{r, q, c} - for n, _ := range shapes { - fmt.Println("Shape details: ", shapes[n]) - fmt.Println("Area of this shape is: ", shapes[n].Area()) - } -} -/* Output: -Looping through shapes for area ... -Shape details: {5 3} -Area of this shape is: 15 -Shape details: &{5} -Area of this shape is: 25 -Shape details: &{2.5} -Area of this shape is: 19.634954 -*/ +// interfaces_poly2.go +package main + +import ( + "fmt" + "math" +) + +type Shaper interface { + Area() float32 +} + +type Square struct { + side float32 +} + +func (sq *Square) Area() float32 { + return sq.side * sq.side +} + +type Rectangle struct { + length, width float32 +} + +func (r Rectangle) Area() float32 { + return r.length * r.width +} + +type Circle struct { + radius float32 +} + +func (c *Circle) Area() float32 { + return math.Pi * c.radius * c.radius +} + +func main() { + r := Rectangle{5, 3} // Area() of Rectangle needs a value + q := &Square{5} // Area() of Square needs a pointer + c := &Circle{2.5} + fmt.Println("Looping through shapes for area ...") + // shapes := []Shaper{Shaper(r), Shaper(q), Shaper(c)} + shapes := []Shaper{r, q, c} + for n := range shapes { + fmt.Println("Shape details: ", shapes[n]) + fmt.Println("Area of this shape is: ", shapes[n].Area()) + } +} + +/* Output: +Looping through shapes for area ... +Shape details: {5 3} +Area of this shape is: 15 +Shape details: &{5} +Area of this shape is: 25 +Shape details: &{2.5} +Area of this shape is: 19.634954 +*/ diff --git a/eBook/exercises/chapter_11/main_stack.go b/eBook/exercises/chapter_11/main_stack.go index 1404db1..ecc14f0 100755 --- a/eBook/exercises/chapter_11/main_stack.go +++ b/eBook/exercises/chapter_11/main_stack.go @@ -1,29 +1,30 @@ -// main_stack.go -package main - -import ( - "fmt" - "./stack/stack" -) - -var st1 stack.Stack - -func main() { - st1.Push("Brown") - st1.Push(3.14) - st1.Push(100) - st1.Push([]string{"Java", "C++", "Python", "C#", "Ruby"}) - for { - item, err := st1.Pop() - if err != nil { - break - } - fmt.Println(item) - } -} -/* Output: -[Java C++ Python C# Ruby] -100 -3.14 -Brown -*/ \ No newline at end of file +// main_stack.go +package main + +import ( + "./stack/stack" + "fmt" +) + +var st1 stack.Stack + +func main() { + st1.Push("Brown") + st1.Push(3.14) + st1.Push(100) + st1.Push([]string{"Java", "C++", "Python", "C#", "Ruby"}) + for { + item, err := st1.Pop() + if err != nil { + break + } + fmt.Println(item) + } +} + +/* Output: +[Java C++ Python C# Ruby] +100 +3.14 +Brown +*/ diff --git a/eBook/exercises/chapter_11/main_stack_v2.go b/eBook/exercises/chapter_11/main_stack_v2.go index 447374a..0bc9fd9 100755 --- a/eBook/exercises/chapter_11/main_stack_v2.go +++ b/eBook/exercises/chapter_11/main_stack_v2.go @@ -1,17 +1,17 @@ -// main_stack_v2.go -package main - -import ( - "./stack/collection" - "fmt" -) - -func main() { - var s collection.Stack - s.Push("world") - s.Push("hello, ") - for s.Size() > 0 { - fmt.Print(s.Pop()) - } - fmt.Println() -} \ No newline at end of file +// main_stack_v2.go +package main + +import ( + "./stack/collection" + "fmt" +) + +func main() { + var s collection.Stack + s.Push("world") + s.Push("hello, ") + for s.Size() > 0 { + fmt.Print(s.Pop()) + } + fmt.Println() +} diff --git a/eBook/exercises/chapter_11/map_function_interface.go b/eBook/exercises/chapter_11/map_function_interface.go index 90edce9..022b8f3 100755 --- a/eBook/exercises/chapter_11/map_function_interface.go +++ b/eBook/exercises/chapter_11/map_function_interface.go @@ -1,62 +1,63 @@ -package main - -import "fmt" - -type obj interface{} - -func main() { - // define a generic lambda function mf: - mf := func(i obj) obj { - switch i.(type) { - case int: - return i.(int) * 2 - case string: - return i.(string) + i.(string) - } - return i - } - - isl := []obj{0, 1, 2, 3, 4, 5} - res1 := mapFunc(mf, isl) - for _, v := range res1 { - fmt.Println(v) - } - println() - - ssl := []obj{"0", "1", "2", "3", "4", "5"} - res2 := mapFunc(mf, ssl) - for _, v := range res2 { - fmt.Println(v) - } -} - -func mapFunc(mf func(obj) obj, list []obj) ([]obj) { - result := make([]obj, len(list)) - - for ix, v := range list { - result[ix] = mf(v) - } - - // Equivalent: - /* - for ix := 0; ix 0 {os.Stdout.WriteString(" ")} - switch a := arg.(type) { // type switch - case Stringer: os.Stdout.WriteString(a.String()) - case int: os.Stdout.WriteString(strconv.Itoa(a)) - case string: os.Stdout.WriteString(a) - // more types - default: os.Stdout.WriteString("???") - } - } -} - -func main() { - print(Day(1), "was", Celsius(18.36)) // Tuesday was 18.4 °C -} -// Tuesday was 18.4 °C \ No newline at end of file +// print.go +package main + +import ( + "os" + "strconv" +) + +type Stringer interface { + String() string +} + +type Celsius float64 + +func (c Celsius) String() string { + return strconv.FormatFloat(float64(c), 'f', 1, 64) + " °C" +} + +type Day int + +var dayName = []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"} + +func (day Day) String() string { + return dayName[day] +} + +func print(args ...interface{}) { + for i, arg := range args { + if i > 0 { + os.Stdout.WriteString(" ") + } + switch a := arg.(type) { // type switch + case Stringer: + os.Stdout.WriteString(a.String()) + case int: + os.Stdout.WriteString(strconv.Itoa(a)) + case string: + os.Stdout.WriteString(a) + // more types + default: + os.Stdout.WriteString("???") + } + } +} + +func main() { + print(Day(1), "was", Celsius(18.36)) // Tuesday was 18.4 °C +} + +// Tuesday was 18.4 °C diff --git a/eBook/exercises/chapter_11/simple_interface.go b/eBook/exercises/chapter_11/simple_interface.go index f4a6fd9..fb831ff 100755 --- a/eBook/exercises/chapter_11/simple_interface.go +++ b/eBook/exercises/chapter_11/simple_interface.go @@ -1,34 +1,35 @@ -// simple_interface.go -package main - -import ( - "fmt" -) - -type Simpler interface { - Get() int - Put(int) -} - -type Simple struct { - i int -} - -func (p *Simple) Get() int { - return p.i -} - -func (p *Simple) Put(u int) { - p.i = u -} - -func fI(it Simpler) int { - it.Put(5) - return it.Get() -} - -func main() { - var s Simple - fmt.Println(fI(&s)) // &s is required because Get() is defined with a receiver type pointer -} -// Output: 5 \ No newline at end of file +// simple_interface.go +package main + +import ( + "fmt" +) + +type Simpler interface { + Get() int + Put(int) +} + +type Simple struct { + i int +} + +func (p *Simple) Get() int { + return p.i +} + +func (p *Simple) Put(u int) { + p.i = u +} + +func fI(it Simpler) int { + it.Put(5) + return it.Get() +} + +func main() { + var s Simple + fmt.Println(fI(&s)) // &s is required because Get() is defined with a receiver type pointer +} + +// Output: 5 diff --git a/eBook/exercises/chapter_11/simple_interface2.go b/eBook/exercises/chapter_11/simple_interface2.go index 5fb495b..835389d 100755 --- a/eBook/exercises/chapter_11/simple_interface2.go +++ b/eBook/exercises/chapter_11/simple_interface2.go @@ -1,61 +1,62 @@ -// simple_interface2.go -package main - -import ( - "fmt" -) - -type Simpler interface { - Get() int - Set(int) -} - -type Simple struct { - i int -} - -func (p *Simple) Get() int { - return p.i -} - -func (p *Simple) Set(u int) { - p.i = u -} - -type RSimple struct { - i int - j int -} - -func (p *RSimple) Get() int { - return p.j -} - -func (p *RSimple) Set(u int) { - p.j = u -} - -func fI(it Simpler) int { - switch it.(type) { - case *Simple: - it.Set(5) - return it.Get() - case *RSimple: - it.Set(50) - return it.Get() - default: - return 99 - } - return 0 -} - -func main() { - var s Simple - fmt.Println(fI(&s)) // &s is required because Get() is defined with a receiver type pointer - var r RSimple - fmt.Println(fI(&r)) -} -/* Output: -5 -50 -*/ \ No newline at end of file +// simple_interface2.go +package main + +import ( + "fmt" +) + +type Simpler interface { + Get() int + Set(int) +} + +type Simple struct { + i int +} + +func (p *Simple) Get() int { + return p.i +} + +func (p *Simple) Set(u int) { + p.i = u +} + +type RSimple struct { + i int + j int +} + +func (p *RSimple) Get() int { + return p.j +} + +func (p *RSimple) Set(u int) { + p.j = u +} + +func fI(it Simpler) int { + switch it.(type) { + case *Simple: + it.Set(5) + return it.Get() + case *RSimple: + it.Set(50) + return it.Get() + default: + return 99 + } + return 0 +} + +func main() { + var s Simple + fmt.Println(fI(&s)) // &s is required because Get() is defined with a receiver type pointer + var r RSimple + fmt.Println(fI(&r)) +} + +/* Output: +5 +50 +*/ diff --git a/eBook/exercises/chapter_11/simple_interface3.go b/eBook/exercises/chapter_11/simple_interface3.go index f747f4b..19866e8 100755 --- a/eBook/exercises/chapter_11/simple_interface3.go +++ b/eBook/exercises/chapter_11/simple_interface3.go @@ -1,74 +1,75 @@ -// simple_interface2.go -package main - -import ( - "fmt" -) - -type Simpler interface { - Get() int - Set(int) -} - -type Simple struct { - i int -} - -func (p *Simple) Get() int { - return p.i -} - -func (p *Simple) Set(u int) { - p.i = u -} - -type RSimple struct { - i int - j int -} - -func (p *RSimple) Get() int { - return p.j -} - -func (p *RSimple) Set(u int) { - p.j = u -} - -func fI(it Simpler) int { - switch it.(type) { - case *Simple: - it.Set(5) - return it.Get() - case *RSimple: - it.Set(50) - return it.Get() - default: - return 99 - } - return 0 -} - - -func gI(any interface{}) int { - // return any.(Simpler).Get() // unsafe, runtime panic possible - if v, ok := any.(Simpler); ok { - return v.Get() - } - return 0 // default value -} -/* Output: -6 -60 -*/ - -func main() { - var s Simple = Simple{6} - fmt.Println(gI(&s)) // &s is required because Get() is defined with a receiver type pointer - var r RSimple = RSimple{60,60} - fmt.Println(gI(&r)) -} -/* Output: -6 -60 -*/ \ No newline at end of file +// simple_interface2.go +package main + +import ( + "fmt" +) + +type Simpler interface { + Get() int + Set(int) +} + +type Simple struct { + i int +} + +func (p *Simple) Get() int { + return p.i +} + +func (p *Simple) Set(u int) { + p.i = u +} + +type RSimple struct { + i int + j int +} + +func (p *RSimple) Get() int { + return p.j +} + +func (p *RSimple) Set(u int) { + p.j = u +} + +func fI(it Simpler) int { + switch it.(type) { + case *Simple: + it.Set(5) + return it.Get() + case *RSimple: + it.Set(50) + return it.Get() + default: + return 99 + } + return 0 +} + +func gI(any interface{}) int { + // return any.(Simpler).Get() // unsafe, runtime panic possible + if v, ok := any.(Simpler); ok { + return v.Get() + } + return 0 // default value +} + +/* Output: +6 +60 +*/ + +func main() { + var s Simple = Simple{6} + fmt.Println(gI(&s)) // &s is required because Get() is defined with a receiver type pointer + var r RSimple = RSimple{60, 60} + fmt.Println(gI(&r)) +} + +/* Output: +6 +60 +*/ diff --git a/eBook/exercises/chapter_11/sort/sort.go b/eBook/exercises/chapter_11/sort/sort.go index 9135d40..ccb995b 100755 --- a/eBook/exercises/chapter_11/sort/sort.go +++ b/eBook/exercises/chapter_11/sort/sort.go @@ -1,60 +1,60 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. -package sort - -type Sorter interface { - Len() int - Less(i, j int) bool - Swap(i, j int) -} - -/* -func Sort(Sorter Interface) { - for i := 1; i < data.Len(); i++ { - for j := i; j > 0 && data.Less(j, j-1); j-- { - data.Swap(j, j-1) - } - } -} -*/ - -func Sort(data Sorter) { - for pass:=1; pass < data.Len(); pass++ { - for i:=0; i < data.Len() - pass; i++ { - if data.Less(i+1, i) { - data.Swap(i, i+1) - } - } - } -} - -func IsSorted(data Sorter) bool { - n := data.Len() - for i := n - 1; i > 0; i-- { - if data.Less(i, i-1) { - return false - } - } - return true -} - -// Convenience types for common cases -type IntArray []int - -func (p IntArray) Len() int { return len(p) } -func (p IntArray) Less(i, j int) bool { return p[i] < p[j] } -func (p IntArray) Swap(i, j int) { p[i], p[j] = p[j], p[i] } - -type StringArray []string - -func (p StringArray) Len() int { return len(p) } -func (p StringArray) Less(i, j int) bool { return p[i] < p[j] } -func (p StringArray) Swap(i, j int) { p[i], p[j] = p[j], p[i] } - -// Convenience wrappers for common cases -func SortInts(a []int) { Sort(IntArray(a)) } -func SortStrings(a []string) { Sort(StringArray(a)) } - -func IntsAreSorted(a []int) bool { return IsSorted(IntArray(a)) } -func StringsAreSorted(a []string) bool { return IsSorted(StringArray(a)) } +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +package sort + +type Sorter interface { + Len() int + Less(i, j int) bool + Swap(i, j int) +} + +/* +func Sort(Sorter Interface) { + for i := 1; i < data.Len(); i++ { + for j := i; j > 0 && data.Less(j, j-1); j-- { + data.Swap(j, j-1) + } + } +} +*/ + +func Sort(data Sorter) { + for pass := 1; pass < data.Len(); pass++ { + for i := 0; i < data.Len()-pass; i++ { + if data.Less(i+1, i) { + data.Swap(i, i+1) + } + } + } +} + +func IsSorted(data Sorter) bool { + n := data.Len() + for i := n - 1; i > 0; i-- { + if data.Less(i, i-1) { + return false + } + } + return true +} + +// Convenience types for common cases +type IntArray []int + +func (p IntArray) Len() int { return len(p) } +func (p IntArray) Less(i, j int) bool { return p[i] < p[j] } +func (p IntArray) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +type StringArray []string + +func (p StringArray) Len() int { return len(p) } +func (p StringArray) Less(i, j int) bool { return p[i] < p[j] } +func (p StringArray) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +// Convenience wrappers for common cases +func SortInts(a []int) { Sort(IntArray(a)) } +func SortStrings(a []string) { Sort(StringArray(a)) } + +func IntsAreSorted(a []int) bool { return IsSorted(IntArray(a)) } +func StringsAreSorted(a []string) bool { return IsSorted(StringArray(a)) } diff --git a/eBook/exercises/chapter_11/sort_persons.go b/eBook/exercises/chapter_11/sort_persons.go index 31b4a6d..0a6812f 100755 --- a/eBook/exercises/chapter_11/sort_persons.go +++ b/eBook/exercises/chapter_11/sort_persons.go @@ -1,36 +1,36 @@ -// sort_persons.go -package main - -import ( - "fmt" - "./sort" -) - -type Person struct { - firstName string - lastName string -} - -type Persons []Person - -func (p Persons) Len() int { return len(p) } - -func (p Persons) Less(i, j int) bool { - in := p[i].lastName + " " + p[i].firstName - jn := p[j].lastName + " " + p[j].firstName - return in < jn -} - -func (p Persons) Swap(i, j int) { - p[i], p[j] = p[j], p[i] -} - -func main() { - p1 := Person{"Xavier","Papadopoulos"} - p2 := Person{"Chris","Naegels"} - p3 := Person{"John","Doe"} - arrP := Persons{p1,p2,p3} - fmt.Printf("Before sorting: %v\n", arrP) - sort.Sort(arrP) - fmt.Printf("After sorting: %v\n", arrP) -} +// sort_persons.go +package main + +import ( + "./sort" + "fmt" +) + +type Person struct { + firstName string + lastName string +} + +type Persons []Person + +func (p Persons) Len() int { return len(p) } + +func (p Persons) Less(i, j int) bool { + in := p[i].lastName + " " + p[i].firstName + jn := p[j].lastName + " " + p[j].firstName + return in < jn +} + +func (p Persons) Swap(i, j int) { + p[i], p[j] = p[j], p[i] +} + +func main() { + p1 := Person{"Xavier", "Papadopoulos"} + p2 := Person{"Chris", "Naegels"} + p3 := Person{"John", "Doe"} + arrP := Persons{p1, p2, p3} + fmt.Printf("Before sorting: %v\n", arrP) + sort.Sort(arrP) + fmt.Printf("After sorting: %v\n", arrP) +} diff --git a/eBook/exercises/chapter_11/stack/stack_general.go b/eBook/exercises/chapter_11/stack/stack_general.go index da78464..c610e98 100755 --- a/eBook/exercises/chapter_11/stack/stack_general.go +++ b/eBook/exercises/chapter_11/stack/stack_general.go @@ -1,39 +1,39 @@ -// stack.go -package stack - -import "errors" - -type Stack []interface{} - -func (stack Stack) Len() int { - return len(stack) -} - -func (stack Stack) Cap() int { - return cap(stack) -} - -func (stack Stack) IsEmpty() bool { - return len(stack) == 0 -} - -func (stack *Stack) Push(e interface{}) { - *stack = append(*stack, e) -} - -func (stack Stack) Top() (interface{}, error) { - if len(stack) == 0 { - return nil, errors.New("stack is empty") - } - return stack[len(stack)-1], nil -} - -func (stack *Stack) Pop() (interface{}, error) { - stk := *stack // dereference to a local variable stk - if len(stk) == 0 { - return nil, errors.New("stack is empty") - } - top := stk[len(stk)-1] - *stack = stk[:len(stk)-1] // shrink the stack - return top, nil -} +// stack.go +package stack + +import "errors" + +type Stack []interface{} + +func (stack Stack) Len() int { + return len(stack) +} + +func (stack Stack) Cap() int { + return cap(stack) +} + +func (stack Stack) IsEmpty() bool { + return len(stack) == 0 +} + +func (stack *Stack) Push(e interface{}) { + *stack = append(*stack, e) +} + +func (stack Stack) Top() (interface{}, error) { + if len(stack) == 0 { + return nil, errors.New("stack is empty") + } + return stack[len(stack)-1], nil +} + +func (stack *Stack) Pop() (interface{}, error) { + stk := *stack // dereference to a local variable stk + if len(stk) == 0 { + return nil, errors.New("stack is empty") + } + top := stk[len(stk)-1] + *stack = stk[:len(stk)-1] // shrink the stack + return top, nil +} diff --git a/eBook/exercises/chapter_11/stack/stack_general_v2.go b/eBook/exercises/chapter_11/stack/stack_general_v2.go index d1a6770..6c681cb 100755 --- a/eBook/exercises/chapter_11/stack/stack_general_v2.go +++ b/eBook/exercises/chapter_11/stack/stack_general_v2.go @@ -1,28 +1,28 @@ -// stack_general_v2.go -// Package collection implements a generic stack. -package collection - -// The zero value for Stack is an empty stack ready to use. -type Stack struct { - data []interface{} -} - -// Push adds x to the top of the stack. -func (s *Stack) Push(x interface{}) { - s.data = append(s.data, x) -} - -// Pop removes and returns the top element of the stack. -// It's a run-time error to call Pop on an empty stack. -func (s *Stack) Pop() interface{} { - i := len(s.data) - 1 - res := s.data[i] - s.data[i] = nil // to avoid memory leak - s.data = s.data[:i] - return res -} - -// Size returns the number of elements in the stack. -func (s *Stack) Size() int { - return len(s.data) -} \ No newline at end of file +// stack_general_v2.go +// Package collection implements a generic stack. +package collection + +// The zero value for Stack is an empty stack ready to use. +type Stack struct { + data []interface{} +} + +// Push adds x to the top of the stack. +func (s *Stack) Push(x interface{}) { + s.data = append(s.data, x) +} + +// Pop removes and returns the top element of the stack. +// It's a run-time error to call Pop on an empty stack. +func (s *Stack) Pop() interface{} { + i := len(s.data) - 1 + res := s.data[i] + s.data[i] = nil // to avoid memory leak + s.data = s.data[:i] + return res +} + +// Size returns the number of elements in the stack. +func (s *Stack) Size() int { + return len(s.data) +} diff --git a/eBook/exercises/chapter_12/calculator.go b/eBook/exercises/chapter_12/calculator.go index 9f2b8fe..559be5a 100755 --- a/eBook/exercises/chapter_12/calculator.go +++ b/eBook/exercises/chapter_12/calculator.go @@ -1,55 +1,55 @@ -// calculator.go -// example: calculate 3 + 4 = 7 as input: 3 ENTER 4 ENTER + ENTER --> result = 7, - -package main - -import ( - "fmt" - "strconv" - "bufio" - "os" - "./stack/stack" -) - -func main() { - buf := bufio.NewReader(os.Stdin) - calc1 := new(stack.Stack) - fmt.Println("Give a number, an operator (+, -, *, /), or q to stop:") - for { - token, err := buf.ReadString('\n') - if err != nil { - fmt.Println("Input error !") - os.Exit(1) - } - token = token[0:len(token)-2] // remove "\r\n" - // fmt.Printf("--%s--\n",token) // debug statement - switch { - case token == "q": // stop als invoer = "q" - fmt.Println("Calculator stopped") - return - case token >= "0" && token <= "999999": - i, _ := strconv.Atoi(token) - calc1.Push(i) - case token == "+": - q, _ := calc1.Pop() - p, _ := calc1.Pop() - fmt.Printf("The result of %d %s %d = %d\n", p, token, q, p.(int) + q.(int)) - case token == "-": - q, _ := calc1.Pop() - p, _ := calc1.Pop() - fmt.Printf("The result of %d %s %d = %d\n", p, token, q, p.(int) - q.(int)) - - case token == "*": - q, _ := calc1.Pop() - p, _ := calc1.Pop() - fmt.Printf("The result of %d %s %d = %d\n", p, token, q, p.(int) * q.(int)) - - case token == "/": - q, _ := calc1.Pop() - p, _ := calc1.Pop() - fmt.Printf("The result of %d %s %d = %d\n", p, token, q, p.(int) / q.(int)) - default: - fmt.Println("No valid input") - } - } -} +// calculator.go +// example: calculate 3 + 4 = 7 as input: 3 ENTER 4 ENTER + ENTER --> result = 7, + +package main + +import ( + "./stack/stack" + "bufio" + "fmt" + "os" + "strconv" +) + +func main() { + buf := bufio.NewReader(os.Stdin) + calc1 := new(stack.Stack) + fmt.Println("Give a number, an operator (+, -, *, /), or q to stop:") + for { + token, err := buf.ReadString('\n') + if err != nil { + fmt.Println("Input error !") + os.Exit(1) + } + token = token[0 : len(token)-2] // remove "\r\n" + // fmt.Printf("--%s--\n",token) // debug statement + switch { + case token == "q": // stop als invoer = "q" + fmt.Println("Calculator stopped") + return + case token >= "0" && token <= "999999": + i, _ := strconv.Atoi(token) + calc1.Push(i) + case token == "+": + q, _ := calc1.Pop() + p, _ := calc1.Pop() + fmt.Printf("The result of %d %s %d = %d\n", p, token, q, p.(int)+q.(int)) + case token == "-": + q, _ := calc1.Pop() + p, _ := calc1.Pop() + fmt.Printf("The result of %d %s %d = %d\n", p, token, q, p.(int)-q.(int)) + + case token == "*": + q, _ := calc1.Pop() + p, _ := calc1.Pop() + fmt.Printf("The result of %d %s %d = %d\n", p, token, q, p.(int)*q.(int)) + + case token == "/": + q, _ := calc1.Pop() + p, _ := calc1.Pop() + fmt.Printf("The result of %d %s %d = %d\n", p, token, q, p.(int)/q.(int)) + default: + fmt.Println("No valid input") + } + } +} diff --git a/eBook/exercises/chapter_12/cat_numbered.go b/eBook/exercises/chapter_12/cat_numbered.go index 774c58d..fba287d 100755 --- a/eBook/exercises/chapter_12/cat_numbered.go +++ b/eBook/exercises/chapter_12/cat_numbered.go @@ -1,43 +1,43 @@ -package main - -import ( - "os" - "io" - "fmt" - "bufio" - "flag" -) - -var numberFlag = flag.Bool("n", false, "number each line") - -func cat(r *bufio.Reader) { - i := 1 - for { - buf, err := r.ReadBytes('\n') - if err == io.EOF { - break - } - if *numberFlag { - fmt.Fprintf(os.Stdout, "%5d %s", i, buf) - i++ - } else { - fmt.Fprintf(os.Stdout, "%s", buf) - } - } - return -} - -func main() { - flag.Parse() - if flag.NArg() == 0 { - cat(bufio.NewReader(os.Stdin)) - } - for i := 0; i < flag.NArg(); i++ { - f, err := os.Open(flag.Arg(i)) - if err != nil { - fmt.Fprintf(os.Stderr, "%s:error reading from %s: %s\n", os.Args[0], flag.Arg(i), err.Error()) - continue - } - cat(bufio.NewReader(f)) - } -} +package main + +import ( + "bufio" + "flag" + "fmt" + "io" + "os" +) + +var numberFlag = flag.Bool("n", false, "number each line") + +func cat(r *bufio.Reader) { + i := 1 + for { + buf, err := r.ReadBytes('\n') + if err == io.EOF { + break + } + if *numberFlag { + fmt.Fprintf(os.Stdout, "%5d %s", i, buf) + i++ + } else { + fmt.Fprintf(os.Stdout, "%s", buf) + } + } + return +} + +func main() { + flag.Parse() + if flag.NArg() == 0 { + cat(bufio.NewReader(os.Stdin)) + } + for i := 0; i < flag.NArg(); i++ { + f, err := os.Open(flag.Arg(i)) + if err != nil { + fmt.Fprintf(os.Stderr, "%s:error reading from %s: %s\n", os.Args[0], flag.Arg(i), err.Error()) + continue + } + cat(bufio.NewReader(f)) + } +} diff --git a/eBook/exercises/chapter_12/degob.go b/eBook/exercises/chapter_12/degob.go index 31df21f..58a32f8 100755 --- a/eBook/exercises/chapter_12/degob.go +++ b/eBook/exercises/chapter_12/degob.go @@ -1,41 +1,42 @@ -// degob.go -package main - -import ( - "bufio" - "fmt" - "encoding/gob" - "log" - "os" -) - -type Address struct { - Type string - City string - Country string -} - -type VCard struct { - FirstName string - LastName string - Addresses []*Address - Remark string -} - -var content string -var vc VCard - -func main() { - // using a decoder: - file, _ := os.Open("vcard.gob") - defer file.Close() - inReader := bufio.NewReader(file) - dec := gob.NewDecoder(inReader) - err := dec.Decode(&vc) - if err != nil { - log.Println("Error in decoding gob") - } - fmt.Println(vc) -} -// Output: -// {Jan Kersschot [0x12642e60 0x12642e80] none} \ No newline at end of file +// degob.go +package main + +import ( + "bufio" + "encoding/gob" + "fmt" + "log" + "os" +) + +type Address struct { + Type string + City string + Country string +} + +type VCard struct { + FirstName string + LastName string + Addresses []*Address + Remark string +} + +var content string +var vc VCard + +func main() { + // using a decoder: + file, _ := os.Open("vcard.gob") + defer file.Close() + inReader := bufio.NewReader(file) + dec := gob.NewDecoder(inReader) + err := dec.Decode(&vc) + if err != nil { + log.Println("Error in decoding gob") + } + fmt.Println(vc) +} + +// Output: +// {Jan Kersschot [0x12642e60 0x12642e80] none} diff --git a/eBook/exercises/chapter_12/hash_md5.go b/eBook/exercises/chapter_12/hash_md5.go index 02e987e..7fb4ec6 100755 --- a/eBook/exercises/chapter_12/hash_md5.go +++ b/eBook/exercises/chapter_12/hash_md5.go @@ -1,20 +1,21 @@ -// hash_md5.go -package main - -import ( - "fmt"; - "crypto/md5" - "io" -) - -func main() { - hasher := md5.New() - b := []byte{} - io.WriteString(hasher, "test") - fmt.Printf("Result: %x\n", hasher.Sum(b)) - fmt.Printf("Result: %d\n", hasher.Sum(b)) -} -/* Output: -Result: 098f6bcd4621d373cade4e832627b4f6 -Result: [9 143 107 205 70 33 211 115 202 222 78 131 38 39 180 246] -*/ +// hash_md5.go +package main + +import ( + "crypto/md5" + "fmt" + "io" +) + +func main() { + hasher := md5.New() + b := []byte{} + io.WriteString(hasher, "test") + fmt.Printf("Result: %x\n", hasher.Sum(b)) + fmt.Printf("Result: %d\n", hasher.Sum(b)) +} + +/* Output: +Result: 098f6bcd4621d373cade4e832627b4f6 +Result: [9 143 107 205 70 33 211 115 202 222 78 131 38 39 180 246] +*/ diff --git a/eBook/exercises/chapter_12/hello_who.go b/eBook/exercises/chapter_12/hello_who.go index ed11a37..2175689 100755 --- a/eBook/exercises/chapter_12/hello_who.go +++ b/eBook/exercises/chapter_12/hello_who.go @@ -1,16 +1,16 @@ -// hello_who.go -package main - -import ( - "fmt" - "os" - "strings" -) - -func main() { - who := "World" - if len(os.Args) > 1 { // os.Args[0] == hello_who - who = strings.Join(os.Args[1:], " ") - } - fmt.Println("Hello", who, "!") -} +// hello_who.go +package main + +import ( + "fmt" + "os" + "strings" +) + +func main() { + who := "World" + if len(os.Args) > 1 { // os.Args[0] == hello_who + who = strings.Join(os.Args[1:], " ") + } + fmt.Println("Hello", who, "!") +} diff --git a/eBook/exercises/chapter_12/read_csv.go b/eBook/exercises/chapter_12/read_csv.go index 213a654..266e276 100755 --- a/eBook/exercises/chapter_12/read_csv.go +++ b/eBook/exercises/chapter_12/read_csv.go @@ -1,67 +1,68 @@ -// read_csv.go -package main - -import ( - "bufio" - "fmt" - "log" - "io" - "os" - "strconv" - "strings" -) - -type Book struct { - title string - price float64 - quantity int -} - -func main() { - bks := make([]Book, 1) - file, err := os.Open("products.txt") - if err != nil { - log.Fatalf("Error %s opening file products.txt: ", err) - } - defer file.Close() - - reader := bufio.NewReader(file) - for { - // read one line from the file: - line, err := reader.ReadString('\n') - if err == io.EOF { - break - } - // remove \r and \n so 2(in Windows, in Linux only \n, so 1): - line = string(line[:len(line)-2]) - //fmt.Printf("The input was: -%s-", line) - - strSl := strings.Split(line, ";") - book := new(Book) - book.title = strSl[0] - book.price, err = strconv.ParseFloat(strSl[1], 32) - if err!=nil { - fmt.Printf("Error in file: %v", err) - } - //fmt.Printf("The quan was:-%s-", strSl[2]) - book.quantity, err = strconv.Atoi(strSl[2]) - if err!=nil { - fmt.Printf("Error in file: %v", err) - } - if bks[0].title == "" { - bks[0] = *book - } else { - bks = append(bks, *book) - } - } - fmt.Println("We have read the following books from the file: ") - for _, bk := range bks { - fmt.Println(bk) - } -} -/* Output: -We have read the following books from the file: -{"The ABC of Go" 25.5 1500} -{"Functional Programming with Go" 56 280} -{"Go for It" 45.900001525878906 356} -*/ +// read_csv.go +package main + +import ( + "bufio" + "fmt" + "io" + "log" + "os" + "strconv" + "strings" +) + +type Book struct { + title string + price float64 + quantity int +} + +func main() { + bks := make([]Book, 1) + file, err := os.Open("products.txt") + if err != nil { + log.Fatalf("Error %s opening file products.txt: ", err) + } + defer file.Close() + + reader := bufio.NewReader(file) + for { + // read one line from the file: + line, err := reader.ReadString('\n') + if err == io.EOF { + break + } + // remove \r and \n so 2(in Windows, in Linux only \n, so 1): + line = string(line[:len(line)-2]) + //fmt.Printf("The input was: -%s-", line) + + strSl := strings.Split(line, ";") + book := new(Book) + book.title = strSl[0] + book.price, err = strconv.ParseFloat(strSl[1], 32) + if err != nil { + fmt.Printf("Error in file: %v", err) + } + //fmt.Printf("The quan was:-%s-", strSl[2]) + book.quantity, err = strconv.Atoi(strSl[2]) + if err != nil { + fmt.Printf("Error in file: %v", err) + } + if bks[0].title == "" { + bks[0] = *book + } else { + bks = append(bks, *book) + } + } + fmt.Println("We have read the following books from the file: ") + for _, bk := range bks { + fmt.Println(bk) + } +} + +/* Output: +We have read the following books from the file: +{"The ABC of Go" 25.5 1500} +{"Functional Programming with Go" 56 280} +{"Go for It" 45.900001525878906 356} +*/ diff --git a/eBook/exercises/chapter_12/remove_3till5char.go b/eBook/exercises/chapter_12/remove_3till5char.go index 18f9055..729d224 100755 --- a/eBook/exercises/chapter_12/remove_3till5char.go +++ b/eBook/exercises/chapter_12/remove_3till5char.go @@ -1,37 +1,37 @@ -// remove_first6char.go -package main - -import ( - "fmt" - "io" - "bufio" - "os" -) - -func main() { - inputFile, _ := os.Open("goprogram") - outputFile, _ := os.OpenFile("goprogramT", os.O_WRONLY|os.O_CREATE, 0666) - defer inputFile.Close() - defer outputFile.Close() - inputReader := bufio.NewReader(inputFile) - outputWriter := bufio.NewWriter(outputFile) - for { - // inputString, readerError := inputReader.ReadString('\n') - inputString, _, readerError := inputReader.ReadLine() - if readerError == io.EOF { - fmt.Println("EOF") - break - } - //fmt.Printf("The input was: --%s--", inputString) - outputString := string([]byte(inputString)[2:5]) + "\r\n" - //fmt.Printf("The output was: --%s--", outputString) - _, err := outputWriter.WriteString(outputString) - //fmt.Printf("Number of bytes written %d\n", n) - if (err != nil) { - fmt.Println(err) - return - } - } - outputWriter.Flush() - fmt.Println("Conversion done") -} +// remove_first6char.go +package main + +import ( + "bufio" + "fmt" + "io" + "os" +) + +func main() { + inputFile, _ := os.Open("goprogram") + outputFile, _ := os.OpenFile("goprogramT", os.O_WRONLY|os.O_CREATE, 0666) + defer inputFile.Close() + defer outputFile.Close() + inputReader := bufio.NewReader(inputFile) + outputWriter := bufio.NewWriter(outputFile) + for { + // inputString, readerError := inputReader.ReadString('\n') + inputString, _, readerError := inputReader.ReadLine() + if readerError == io.EOF { + fmt.Println("EOF") + break + } + //fmt.Printf("The input was: --%s--", inputString) + outputString := string([]byte(inputString)[2:5]) + "\r\n" + //fmt.Printf("The output was: --%s--", outputString) + _, err := outputWriter.WriteString(outputString) + //fmt.Printf("Number of bytes written %d\n", n) + if err != nil { + fmt.Println(err) + return + } + } + outputWriter.Flush() + fmt.Println("Conversion done") +} diff --git a/eBook/exercises/chapter_12/stack/stack_struct.go b/eBook/exercises/chapter_12/stack/stack_struct.go index 08a58e4..643683f 100755 --- a/eBook/exercises/chapter_12/stack/stack_struct.go +++ b/eBook/exercises/chapter_12/stack/stack_struct.go @@ -1,32 +1,32 @@ -// stack_struct.go -package stack - -import "strconv" -const LIMIT = 10 - -type Stack struct { - ix int // first free position, so data[ix] == 0 - data [LIMIT]int -} - -func (st *Stack) Push(n int) { - if (st.ix + 1 > LIMIT) { - return // stack is full! - } - st.data[st.ix] = n - st.ix++ -} - -func (st *Stack) Pop() int { - st.ix-- - return st.data[st.ix] -} - -func (st Stack) String() string { - str := "" - for ix:=0; ix LIMIT { + return // stack is full! + } + st.data[st.ix] = n + st.ix++ +} + +func (st *Stack) Pop() int { + st.ix-- + return st.data[st.ix] +} + +func (st Stack) String() string { + str := "" + for ix := 0; ix < st.ix; ix++ { + str += "[" + strconv.Itoa(ix) + ":" + strconv.Itoa(st.data[ix]) + "] " + } + return str +} diff --git a/eBook/exercises/chapter_12/wiki_part1.go b/eBook/exercises/chapter_12/wiki_part1.go index a47d978..844fe0d 100644 --- a/eBook/exercises/chapter_12/wiki_part1.go +++ b/eBook/exercises/chapter_12/wiki_part1.go @@ -33,6 +33,7 @@ func main() { new_page.load("Page.md") fmt.Println(string(new_page.Body)) } + /* Output: * # Page * ## Section1 diff --git a/eBook/exercises/chapter_12/word_letter_count.go b/eBook/exercises/chapter_12/word_letter_count.go index 4e4b216..98fc49f 100755 --- a/eBook/exercises/chapter_12/word_letter_count.go +++ b/eBook/exercises/chapter_12/word_letter_count.go @@ -1,36 +1,37 @@ -// Q28_word_letter_count.go -package main - -import ( - "fmt" - "bufio" - "os" - "strings" -) -var nrchars, nrwords, nrlines int - -func main() { - nrchars, nrwords, nrlines = 0, 0, 0 - inputReader := bufio.NewReader(os.Stdin) - fmt.Println("Please enter some input, type S to stop: ") - for { - input, err := inputReader.ReadString('\n') - if err != nil { - fmt.Printf("An error occurred: %s\n", err) - } - if input == "S\r\n" { // Windows, on Linux it is "S\n" - fmt.Println("Here are the counts:") - fmt.Printf("Number of characters: %d\n", nrchars) - fmt.Printf("Number of words: %d\n", nrwords) - fmt.Printf("Number of lines: %d\n", nrlines) - os.Exit(0) - } - Counters(input) - } -} - -func Counters(input string) { - nrchars += len(input) - 2 // -2 for \r\n - nrwords += len(strings.Fields(input)) - nrlines++ -} +// Q28_word_letter_count.go +package main + +import ( + "bufio" + "fmt" + "os" + "strings" +) + +var nrchars, nrwords, nrlines int + +func main() { + nrchars, nrwords, nrlines = 0, 0, 0 + inputReader := bufio.NewReader(os.Stdin) + fmt.Println("Please enter some input, type S to stop: ") + for { + input, err := inputReader.ReadString('\n') + if err != nil { + fmt.Printf("An error occurred: %s\n", err) + } + if input == "S\r\n" { // Windows, on Linux it is "S\n" + fmt.Println("Here are the counts:") + fmt.Printf("Number of characters: %d\n", nrchars) + fmt.Printf("Number of words: %d\n", nrwords) + fmt.Printf("Number of lines: %d\n", nrlines) + os.Exit(0) + } + Counters(input) + } +} + +func Counters(input string) { + nrchars += len(input) - 2 // -2 for \r\n + nrwords += len(strings.Fields(input)) + nrlines++ +} diff --git a/eBook/exercises/chapter_13/panic_defer.go b/eBook/exercises/chapter_13/panic_defer.go index bca1761..a808473 100755 --- a/eBook/exercises/chapter_13/panic_defer.go +++ b/eBook/exercises/chapter_13/panic_defer.go @@ -1,44 +1,45 @@ -// panic_defer.go -package main - -import "fmt" - -func main() { - f() - fmt.Println("Returned normally from f.") -} - -func f() { - defer func() { - if r := recover(); r != nil { - fmt.Println("Recovered in f", r) - } - }() - fmt.Println("Calling g.") - g(0) - fmt.Println("Returned normally from g.") -} - -func g(i int) { - if i > 3 { - fmt.Println("Panicking!") - panic(fmt.Sprintf("%v", i)) - } - defer fmt.Println("Defer in g", i) - fmt.Println("Printing in g", i) - g(i + 1) -} -/* Output: -Calling g. -Printing in g 0 -Printing in g 1 -Printing in g 2 -Printing in g 3 -Panicking! -Defer in g 3 -Defer in g 2 -Defer in g 1 -Defer in g 0 -Recovered in f 4 -Returned normally from f. -*/ +// panic_defer.go +package main + +import "fmt" + +func main() { + f() + fmt.Println("Returned normally from f.") +} + +func f() { + defer func() { + if r := recover(); r != nil { + fmt.Println("Recovered in f", r) + } + }() + fmt.Println("Calling g.") + g(0) + fmt.Println("Returned normally from g.") +} + +func g(i int) { + if i > 3 { + fmt.Println("Panicking!") + panic(fmt.Sprintf("%v", i)) + } + defer fmt.Println("Defer in g", i) + fmt.Println("Printing in g", i) + g(i + 1) +} + +/* Output: +Calling g. +Printing in g 0 +Printing in g 1 +Printing in g 2 +Printing in g 3 +Panicking! +Defer in g 3 +Defer in g 2 +Defer in g 1 +Defer in g 0 +Recovered in f 4 +Returned normally from f. +*/ diff --git a/eBook/exercises/chapter_13/panic_defer_convint.go b/eBook/exercises/chapter_13/panic_defer_convint.go index db4012f..9a7825b 100755 --- a/eBook/exercises/chapter_13/panic_defer_convint.go +++ b/eBook/exercises/chapter_13/panic_defer_convint.go @@ -1,44 +1,45 @@ -// panic_defer_convint.go -package main - -import ( - "fmt" - "math" -) - -func main() { - l := int64(15000) - if i, err := IntFromInt64(l); err!= nil { - fmt.Printf("The conversion of %d to an int32 resulted in an error: %s", l, err.Error()) - } else { - fmt.Printf("%d converted to an int32 is %d", l, i) - } - fmt.Println() - l = int64(math.MaxInt32 + 15000) - if i, err := IntFromInt64(l); err!= nil { - fmt.Printf("The conversion of %d to an int32 resulted in an error: %s", l, err.Error()) - } else { - fmt.Printf("%d converted to an int32 is %d", l, i) - } -} - -func ConvertInt64ToInt(l int64) int { - if math.MinInt32 <= l && l <= math.MaxInt32 { - return int(l) - } - panic(fmt.Sprintf("%d is out of the int32 range", l)) -} - -func IntFromInt64(l int64) (i int, err error) { - defer func() { - if e := recover(); e != nil { - err = fmt.Errorf("%v", e) - } - }() - i = ConvertInt64ToInt(l) - return i, nil -} -/* Output: -15000 converted to an int32 is 15000 -The conversion of 2147498647 to an int32 resulted in an error: 2147498647 is out of the int32 range -*/ \ No newline at end of file +// panic_defer_convint.go +package main + +import ( + "fmt" + "math" +) + +func main() { + l := int64(15000) + if i, err := IntFromInt64(l); err != nil { + fmt.Printf("The conversion of %d to an int32 resulted in an error: %s", l, err.Error()) + } else { + fmt.Printf("%d converted to an int32 is %d", l, i) + } + fmt.Println() + l = int64(math.MaxInt32 + 15000) + if i, err := IntFromInt64(l); err != nil { + fmt.Printf("The conversion of %d to an int32 resulted in an error: %s", l, err.Error()) + } else { + fmt.Printf("%d converted to an int32 is %d", l, i) + } +} + +func ConvertInt64ToInt(l int64) int { + if math.MinInt32 <= l && l <= math.MaxInt32 { + return int(l) + } + panic(fmt.Sprintf("%d is out of the int32 range", l)) +} + +func IntFromInt64(l int64) (i int, err error) { + defer func() { + if e := recover(); e != nil { + err = fmt.Errorf("%v", e) + } + }() + i = ConvertInt64ToInt(l) + return i, nil +} + +/* Output: +15000 converted to an int32 is 15000 +The conversion of 2147498647 to an int32 resulted in an error: 2147498647 is out of the int32 range +*/ diff --git a/eBook/exercises/chapter_13/recover_divbyzero.go b/eBook/exercises/chapter_13/recover_divbyzero.go index 6a90d66..091db1a 100755 --- a/eBook/exercises/chapter_13/recover_divbyzero.go +++ b/eBook/exercises/chapter_13/recover_divbyzero.go @@ -1,34 +1,35 @@ -// recover_divbyzero.go -package main - -import ( - "fmt" -) - -func badCall() { - a, b := 10, 0 - n := a / b - fmt.Println(n) -} - -func test() { - defer func() { - if e := recover(); e != nil { - fmt.Printf("Panicing %s\r\n", e); - } - - }() - badCall() - fmt.Printf("After bad call\r\n"); -} - -func main() { - fmt.Printf("Calling test\r\n"); - test() - fmt.Printf("Test completed\r\n"); -} -/* Output: -Calling test -Panicing runtime error: integer divide by zero -Test completed -*/ +// recover_divbyzero.go +package main + +import ( + "fmt" +) + +func badCall() { + a, b := 10, 0 + n := a / b + fmt.Println(n) +} + +func test() { + defer func() { + if e := recover(); e != nil { + fmt.Printf("Panicing %s\r\n", e) + } + + }() + badCall() + fmt.Printf("After bad call\r\n") +} + +func main() { + fmt.Printf("Calling test\r\n") + test() + fmt.Printf("Test completed\r\n") +} + +/* Output: +Calling test +Panicing runtime error: integer divide by zero +Test completed +*/ diff --git a/eBook/exercises/chapter_13/string_reverse.go b/eBook/exercises/chapter_13/string_reverse.go index 2069480..1fea12a 100755 --- a/eBook/exercises/chapter_13/string_reverse.go +++ b/eBook/exercises/chapter_13/string_reverse.go @@ -1,18 +1,18 @@ -// string_reverse.go -package strev - -func Reverse(s string) string { - runes := []rune(s) - n, h := len(runes), len(runes)/2 - for i := 0; i < h; i++ { - runes[i], runes[n-1-i] = runes[n-1-i], runes[i] - } - return string(runes) -} - -/* -func main() { - s := "My Test String!" - fmt.Println(s, " --> ", Reverse(s)) -} -*/ \ No newline at end of file +// string_reverse.go +package strev + +func Reverse(s string) string { + runes := []rune(s) + n, h := len(runes), len(runes)/2 + for i := 0; i < h; i++ { + runes[i], runes[n-1-i] = runes[n-1-i], runes[i] + } + return string(runes) +} + +/* +func main() { + s := "My Test String!" + fmt.Println(s, " --> ", Reverse(s)) +} +*/ diff --git a/eBook/exercises/chapter_13/string_reverse_test.go b/eBook/exercises/chapter_13/string_reverse_test.go index d767773..0723716 100755 --- a/eBook/exercises/chapter_13/string_reverse_test.go +++ b/eBook/exercises/chapter_13/string_reverse_test.go @@ -1,40 +1,40 @@ -// string_reverse_test.go -package strev - -import "testing" -import "./strev" - -type ReverseTest struct { - in, out string -} - -var ReverseTests = []ReverseTest { - ReverseTest{"ABCD", "DCBA"}, - ReverseTest{"CVO-AZ", "ZA-OVC"}, - ReverseTest{"Hello 世界", "界世 olleH"}, -} - -func TestReverse(t *testing.T) { -/* - in := "CVO-AZ" - out := Reverse(in) - exp := "ZA-OVC" - if out != exp { - t.Errorf("Reverse of %s expects %s, but got %s", in, exp, out) - } -*/ -// testing with a battery of testdata: - for _, r := range ReverseTests { - exp := strev.Reverse(r.in) - if r.out != exp { - t.Errorf("Reverse of %s expects %s, but got %s", r.in, exp, r.out) - } - } -} - -func BenchmarkReverse(b *testing.B) { - s := "ABCD" - for i:=0; i < b.N; i++ { - strev.Reverse(s) - } -} +// string_reverse_test.go +package strev + +import "testing" +import "./strev" + +type ReverseTest struct { + in, out string +} + +var ReverseTests = []ReverseTest{ + {"ABCD", "DCBA"}, + {"CVO-AZ", "ZA-OVC"}, + {"Hello 世界", "界世 olleH"}, +} + +func TestReverse(t *testing.T) { + /* + in := "CVO-AZ" + out := Reverse(in) + exp := "ZA-OVC" + if out != exp { + t.Errorf("Reverse of %s expects %s, but got %s", in, exp, out) + } + */ + // testing with a battery of testdata: + for _, r := range ReverseTests { + exp := strev.Reverse(r.in) + if r.out != exp { + t.Errorf("Reverse of %s expects %s, but got %s", r.in, exp, r.out) + } + } +} + +func BenchmarkReverse(b *testing.B) { + s := "ABCD" + for i := 0; i < b.N; i++ { + strev.Reverse(s) + } +} diff --git a/eBook/exercises/chapter_14/blocking.go b/eBook/exercises/chapter_14/blocking.go index 3224ba1..d7ed06b 100755 --- a/eBook/exercises/chapter_14/blocking.go +++ b/eBook/exercises/chapter_14/blocking.go @@ -1,19 +1,19 @@ -// blocking.go -// throw: all goroutines are asleep - deadlock! -package main - -import ( - "fmt" -) - -func f1(in chan int) { - fmt.Println(<-in) -} - -func main() { - out := make(chan int) - //out := make(chan int, 1) // solution 2 - // go f1(out) // solution 1 - out <- 2 - go f1(out) -} +// blocking.go +// throw: all goroutines are asleep - deadlock! +package main + +import ( + "fmt" +) + +func f1(in chan int) { + fmt.Println(<-in) +} + +func main() { + out := make(chan int) + //out := make(chan int, 1) // solution 2 + // go f1(out) // solution 1 + out <- 2 + go f1(out) +} diff --git a/eBook/exercises/chapter_14/channel_block3.go b/eBook/exercises/chapter_14/channel_block3.go index 00cfba7..193a7ec 100755 --- a/eBook/exercises/chapter_14/channel_block3.go +++ b/eBook/exercises/chapter_14/channel_block3.go @@ -1,22 +1,23 @@ -package main - -import "fmt" -import "time" - -func main() { - c := make(chan int) - go func() { - time.Sleep(15 * 1e9) - x := <-c - fmt.Println("received", x) - }() - fmt.Println("sending", 10) - c <- 10 - fmt.Println("sent", 10) -} -/* Output: -sending 10 -(15 s later): -received 10 -sent 10 -*/ \ No newline at end of file +package main + +import "fmt" +import "time" + +func main() { + c := make(chan int) + go func() { + time.Sleep(15 * 1e9) + x := <-c + fmt.Println("received", x) + }() + fmt.Println("sending", 10) + c <- 10 + fmt.Println("sent", 10) +} + +/* Output: +sending 10 +(15 s later): +received 10 +sent 10 +*/ diff --git a/eBook/exercises/chapter_14/channel_buffer.go b/eBook/exercises/chapter_14/channel_buffer.go index 07e907b..5d0ead3 100755 --- a/eBook/exercises/chapter_14/channel_buffer.go +++ b/eBook/exercises/chapter_14/channel_buffer.go @@ -1,21 +1,22 @@ -package main - -import "fmt" -import "time" - -func main() { - c := make(chan int, 50) - go func() { - time.Sleep(15 * 1e9) - x := <-c - fmt.Println("received", x) - }() - fmt.Println("sending", 10) - c <- 10 - fmt.Println("sent", 10) -} -/* Output: -sending 10 -sent 10 // prints immediately -no further output, because main() then stops -*/ \ No newline at end of file +package main + +import "fmt" +import "time" + +func main() { + c := make(chan int, 50) + go func() { + time.Sleep(15 * 1e9) + x := <-c + fmt.Println("received", x) + }() + fmt.Println("sending", 10) + c <- 10 + fmt.Println("sent", 10) +} + +/* Output: +sending 10 +sent 10 // prints immediately +no further output, because main() then stops +*/ diff --git a/eBook/exercises/chapter_14/concurrent_pi.go b/eBook/exercises/chapter_14/concurrent_pi.go index 7ea2d59..d238f3d 100755 --- a/eBook/exercises/chapter_14/concurrent_pi.go +++ b/eBook/exercises/chapter_14/concurrent_pi.go @@ -1,45 +1,46 @@ -// Concurrent computation of pi. -// See http://goo.gl/ZuTZM. - Comparison with Scala! -// -// This demonstrates Go's ability to handle -// large numbers of concurrent processes. -// It is an unreasonable way to calculate pi. -package main - -import ( - "fmt" - "math" - "time" -) - -func main() { - start := time.Now() - fmt.Println(CalculatePi(5000)) - end := time.Now() - delta := end.Sub(start) - fmt.Printf("longCalculation took this amount of time: %s\n", delta) -} - -// CalculatePi launches n goroutines to compute an -// series-approximation of pi. -func CalculatePi(n int) float64 { - ch := make(chan float64) - for k := 0; k <= n; k++ { - // calculate k-th term in the series - go term(ch, float64(k)) - } - f := 0.0 - //wait for all goroutines to complete, get and sum up their results: - for k := 0; k <= n; k++ { - f += <-ch - } - return f -} - -func term(ch chan float64, k float64) { - ch <- 4 * math.Pow(-1, k) / (2*k + 1) -} -/* Output: -3.14179261359579 -The calculation took this amount of time: 0.028002 -*/ \ No newline at end of file +// Concurrent computation of pi. +// See http://goo.gl/ZuTZM. - Comparison with Scala! +// +// This demonstrates Go's ability to handle +// large numbers of concurrent processes. +// It is an unreasonable way to calculate pi. +package main + +import ( + "fmt" + "math" + "time" +) + +func main() { + start := time.Now() + fmt.Println(CalculatePi(5000)) + end := time.Now() + delta := end.Sub(start) + fmt.Printf("longCalculation took this amount of time: %s\n", delta) +} + +// CalculatePi launches n goroutines to compute an +// series-approximation of pi. +func CalculatePi(n int) float64 { + ch := make(chan float64) + for k := 0; k <= n; k++ { + // calculate k-th term in the series + go term(ch, float64(k)) + } + f := 0.0 + //wait for all goroutines to complete, get and sum up their results: + for k := 0; k <= n; k++ { + f += <-ch + } + return f +} + +func term(ch chan float64, k float64) { + ch <- 4 * math.Pow(-1, k) / (2*k + 1) +} + +/* Output: +3.14179261359579 +The calculation took this amount of time: 0.028002 +*/ diff --git a/eBook/exercises/chapter_14/concurrent_pi2.go b/eBook/exercises/chapter_14/concurrent_pi2.go index 621f148..38e5e8e 100755 --- a/eBook/exercises/chapter_14/concurrent_pi2.go +++ b/eBook/exercises/chapter_14/concurrent_pi2.go @@ -1,45 +1,46 @@ -// concurrent_pi2.go -package main - -import ( - "fmt" - "math" - "runtime" - "time" -) - -const NCPU = 2 - -func main() { - start := time.Now() - runtime.GOMAXPROCS(2) - fmt.Println(CalculatePi(5000)) - end := time.Now() - delta := end.Sub(start) - fmt.Printf("longCalculation took this amount of time: %s\n", delta) -} - -func CalculatePi(end int) float64 { - ch := make(chan float64) - for i := 0; i < NCPU; i++ { - go term(ch, i*end/NCPU, (i+1)*end/NCPU) - } - result := 0.0 - for i := 0; i < NCPU; i++ { - result += <-ch - } - return result -} - -func term(ch chan float64, start, end int) { - result := 0.0 - for i := start; i < end; i++ { - x := float64(i) - result += 4 * (math.Pow(-1, x) / (2.0*x + 1.0)) - } - ch <- result -} -/* Output: -3.1413926535917938 -The calculation took this amount of time: 0.002000 -*/ +// concurrent_pi2.go +package main + +import ( + "fmt" + "math" + "runtime" + "time" +) + +const NCPU = 2 + +func main() { + start := time.Now() + runtime.GOMAXPROCS(2) + fmt.Println(CalculatePi(5000)) + end := time.Now() + delta := end.Sub(start) + fmt.Printf("longCalculation took this amount of time: %s\n", delta) +} + +func CalculatePi(end int) float64 { + ch := make(chan float64) + for i := 0; i < NCPU; i++ { + go term(ch, i*end/NCPU, (i+1)*end/NCPU) + } + result := 0.0 + for i := 0; i < NCPU; i++ { + result += <-ch + } + return result +} + +func term(ch chan float64, start, end int) { + result := 0.0 + for i := start; i < end; i++ { + x := float64(i) + result += 4 * (math.Pow(-1, x) / (2.0*x + 1.0)) + } + ch <- result +} + +/* Output: +3.1413926535917938 +The calculation took this amount of time: 0.002000 +*/ diff --git a/eBook/exercises/chapter_14/general_lazy_evalution2.go b/eBook/exercises/chapter_14/general_lazy_evalution2.go index e51ff6c..4db94ee 100755 --- a/eBook/exercises/chapter_14/general_lazy_evalution2.go +++ b/eBook/exercises/chapter_14/general_lazy_evalution2.go @@ -1,59 +1,60 @@ -package main - -import ( - "fmt" -) - -type Any interface{} -type EvalFunc func(Any) (Any, Any) - -func main() { - fibFunc := func(state Any) (Any, Any) { - os := state.([]uint64) - v1 := os[0] - v2 := os[1] - ns := []uint64{v2, v1 + v2} - return v1, ns - } - fib := BuildLazyUInt64Evaluator(fibFunc, []uint64{0, 1}) - - for i := 0; i < 10; i++ { - fmt.Printf("Fib nr %v: %v\n", i, fib()) - } -} - -func BuildLazyEvaluator(evalFunc EvalFunc, initState Any) func() Any { - retValChan := make(chan Any) - loopFunc := func() { - var actState Any = initState - var retVal Any - for { - retVal, actState = evalFunc(actState) - retValChan <- retVal - } - } - retFunc := func() Any { - return <-retValChan - } - go loopFunc() - return retFunc -} - -func BuildLazyUInt64Evaluator(evalFunc EvalFunc, initState Any) func() uint64 { - ef := BuildLazyEvaluator(evalFunc, initState) - return func() uint64 { - return ef().(uint64) - } -} -/* Output: -Fib nr 0: 0 -Fib nr 1: 1 -Fib nr 2: 1 -Fib nr 3: 2 -Fib nr 4: 3 -Fib nr 5: 5 -Fib nr 6: 8 -Fib nr 7: 13 -Fib nr 8: 21 -Fib nr 9: 34 -*/ +package main + +import ( + "fmt" +) + +type Any interface{} +type EvalFunc func(Any) (Any, Any) + +func main() { + fibFunc := func(state Any) (Any, Any) { + os := state.([]uint64) + v1 := os[0] + v2 := os[1] + ns := []uint64{v2, v1 + v2} + return v1, ns + } + fib := BuildLazyUInt64Evaluator(fibFunc, []uint64{0, 1}) + + for i := 0; i < 10; i++ { + fmt.Printf("Fib nr %v: %v\n", i, fib()) + } +} + +func BuildLazyEvaluator(evalFunc EvalFunc, initState Any) func() Any { + retValChan := make(chan Any) + loopFunc := func() { + var actState Any = initState + var retVal Any + for { + retVal, actState = evalFunc(actState) + retValChan <- retVal + } + } + retFunc := func() Any { + return <-retValChan + } + go loopFunc() + return retFunc +} + +func BuildLazyUInt64Evaluator(evalFunc EvalFunc, initState Any) func() uint64 { + ef := BuildLazyEvaluator(evalFunc, initState) + return func() uint64 { + return ef().(uint64) + } +} + +/* Output: +Fib nr 0: 0 +Fib nr 1: 1 +Fib nr 2: 1 +Fib nr 3: 2 +Fib nr 4: 3 +Fib nr 5: 5 +Fib nr 6: 8 +Fib nr 7: 13 +Fib nr 8: 21 +Fib nr 9: 34 +*/ diff --git a/eBook/exercises/chapter_14/gofibonacci.go b/eBook/exercises/chapter_14/gofibonacci.go index 8dc6e0a..147984e 100755 --- a/eBook/exercises/chapter_14/gofibonacci.go +++ b/eBook/exercises/chapter_14/gofibonacci.go @@ -1,44 +1,44 @@ -// Q26_fibonacci_go.go -package main - -import ( - "fmt" - "time" - "os" -) - -func main() { - term := 25 - i := 0 - c := make(chan int) - start := time.Now() - - go fibnterms(term, c) - for { - if result, ok := <-c; ok { - fmt.Printf("fibonacci(%d) is: %d\n", i, result) - i++ - } else { - end := time.Now() - delta := end.Sub(start) - fmt.Printf("longCalculation took this amount of time: %s\n", delta) - os.Exit(0) - } - } -} - -func fibnterms(term int, c chan int) { - for i := 0; i <= term; i++ { - c <- fibonacci(i) - } - close(c) -} - -func fibonacci(n int) (res int) { - if n <= 1 { - res = 1 - } else { - res = fibonacci(n-1) + fibonacci(n-2) - } - return -} +// Q26_fibonacci_go.go +package main + +import ( + "fmt" + "os" + "time" +) + +func main() { + term := 25 + i := 0 + c := make(chan int) + start := time.Now() + + go fibnterms(term, c) + for { + if result, ok := <-c; ok { + fmt.Printf("fibonacci(%d) is: %d\n", i, result) + i++ + } else { + end := time.Now() + delta := end.Sub(start) + fmt.Printf("longCalculation took this amount of time: %s\n", delta) + os.Exit(0) + } + } +} + +func fibnterms(term int, c chan int) { + for i := 0; i <= term; i++ { + c <- fibonacci(i) + } + close(c) +} + +func fibonacci(n int) (res int) { + if n <= 1 { + res = 1 + } else { + res = fibonacci(n-1) + fibonacci(n-2) + } + return +} diff --git a/eBook/exercises/chapter_14/gofibonacci2.go b/eBook/exercises/chapter_14/gofibonacci2.go index 46e7a59..c731775 100755 --- a/eBook/exercises/chapter_14/gofibonacci2.go +++ b/eBook/exercises/chapter_14/gofibonacci2.go @@ -1,35 +1,36 @@ -// gofibonacci2.go -package main - -import ( - "fmt" -) - -func fibonacci(n int, c chan int) { - x, y := 1, 1 - for i := 0; i < n; i++ { - c <- x - x, y = y, x+y - } - close(c) -} - -func main() { - c := make(chan int, 10) - go fibonacci(cap(c), c) - for i := range c { - fmt.Println(i) - } -} -/* Output: -1 -1 -2 -3 -5 -8 -13 -21 -34 -55 -*/ +// gofibonacci2.go +package main + +import ( + "fmt" +) + +func fibonacci(n int, c chan int) { + x, y := 1, 1 + for i := 0; i < n; i++ { + c <- x + x, y = y, x+y + } + close(c) +} + +func main() { + c := make(chan int, 10) + go fibonacci(cap(c), c) + for i := range c { + fmt.Println(i) + } +} + +/* Output: +1 +1 +2 +3 +5 +8 +13 +21 +34 +55 +*/ diff --git a/eBook/exercises/chapter_14/gofibonacci3.go b/eBook/exercises/chapter_14/gofibonacci3.go index 8560a3f..2764595 100755 --- a/eBook/exercises/chapter_14/gofibonacci3.go +++ b/eBook/exercises/chapter_14/gofibonacci3.go @@ -1,45 +1,45 @@ -// courtesy of: http://sdh33b.blogspot.com/2009/12/fibonacci-in-go.html -package main - -import ( - "fmt" - "time" -) - -func dup3(in <-chan int) (<-chan int, <-chan int, <-chan int) { - a, b, c := make(chan int, 2), make(chan int, 2), make(chan int, 2) - go func() { - for { - x := <-in - a <- x - b <- x - c <- x - } - }() - return a, b, c -} - -func fib() <-chan int { - x := make(chan int, 2) - a, b, out := dup3(x) - go func() { - x <- 0 - x <- 1 - <-a - for { - x <- <-a + <-b - } - }() - return out -} - -func main() { - start := time.Now() - x := fib() - for i := 0; i < 10; i++ { - fmt.Println(<-x) - } - end := time.Now() - delta := end.Sub(start) - fmt.Printf("longCalculation took this amount of time: %s\n", delta) -} +// courtesy of: http://sdh33b.blogspot.com/2009/12/fibonacci-in-go.html +package main + +import ( + "fmt" + "time" +) + +func dup3(in <-chan int) (<-chan int, <-chan int, <-chan int) { + a, b, c := make(chan int, 2), make(chan int, 2), make(chan int, 2) + go func() { + for { + x := <-in + a <- x + b <- x + c <- x + } + }() + return a, b, c +} + +func fib() <-chan int { + x := make(chan int, 2) + a, b, out := dup3(x) + go func() { + x <- 0 + x <- 1 + <-a + for { + x <- <-a + <-b + } + }() + return out +} + +func main() { + start := time.Now() + x := fib() + for i := 0; i < 10; i++ { + fmt.Println(<-x) + } + end := time.Now() + delta := end.Sub(start) + fmt.Printf("longCalculation took this amount of time: %s\n", delta) +} diff --git a/eBook/exercises/chapter_14/gofibonacci_select.go b/eBook/exercises/chapter_14/gofibonacci_select.go index 1811d14..fe75b84 100755 --- a/eBook/exercises/chapter_14/gofibonacci_select.go +++ b/eBook/exercises/chapter_14/gofibonacci_select.go @@ -1,42 +1,43 @@ -// gofibonacci_select.go -package main - -import "fmt" - -func fibonacci(c, quit chan int) { - x, y := 1, 1 - for { - select { - case c <- x: - x, y = y, x+y - case <-quit: - fmt.Println("quit") - return - } - } -} - -func main() { - c := make(chan int) - quit := make(chan int) - go func() { - for i := 0; i < 10; i++ { - fmt.Println(<-c) - } - quit <- 0 - }() - fibonacci(c, quit) -} -/* Output: -1 -1 -2 -3 -5 -8 -13 -21 -34 -55 -quit -*/ +// gofibonacci_select.go +package main + +import "fmt" + +func fibonacci(c, quit chan int) { + x, y := 1, 1 + for { + select { + case c <- x: + x, y = y, x+y + case <-quit: + fmt.Println("quit") + return + } + } +} + +func main() { + c := make(chan int) + quit := make(chan int) + go func() { + for i := 0; i < 10; i++ { + fmt.Println(<-c) + } + quit <- 0 + }() + fibonacci(c, quit) +} + +/* Output: +1 +1 +2 +3 +5 +8 +13 +21 +34 +55 +quit +*/ diff --git a/eBook/exercises/chapter_14/goroutine_close.go b/eBook/exercises/chapter_14/goroutine_close.go index 56ea4e1..8720008 100755 --- a/eBook/exercises/chapter_14/goroutine_close.go +++ b/eBook/exercises/chapter_14/goroutine_close.go @@ -1,26 +1,26 @@ -// Q20_goroutine.go -package main - -import ( - "fmt" -) - -func tel(ch chan int) { - for i:=0; i < 15; i++ { - ch <- i - } - close(ch) // if this is ommitted: panic: all goroutines are asleep - deadlock! -} - -func main() { - var ok = true - var i int - ch := make(chan int) - - go tel(ch) - for ok { - if i, ok= <-ch; ok { - fmt.Printf("ok is %t and the counter is at %d\n", ok, i) - } - } -} +// Q20_goroutine.go +package main + +import ( + "fmt" +) + +func tel(ch chan int) { + for i := 0; i < 15; i++ { + ch <- i + } + close(ch) // if this is ommitted: panic: all goroutines are asleep - deadlock! +} + +func main() { + var ok = true + var i int + ch := make(chan int) + + go tel(ch) + for ok { + if i, ok = <-ch; ok { + fmt.Printf("ok is %t and the counter is at %d\n", ok, i) + } + } +} diff --git a/eBook/exercises/chapter_14/goroutine_panic.go b/eBook/exercises/chapter_14/goroutine_panic.go index a9783dd..2930a34 100755 --- a/eBook/exercises/chapter_14/goroutine_panic.go +++ b/eBook/exercises/chapter_14/goroutine_panic.go @@ -1,22 +1,22 @@ -package main - -import ( - "fmt" -) - -func tel(ch chan int) { - for i := 0; i < 15; i++ { - ch <- i - } -} - -func main() { - var ok = true - ch := make(chan int) - - go tel(ch) - for ok { - i := <-ch - fmt.Printf("ok is %t and the counter is at %d\n", ok, i) - } -} +package main + +import ( + "fmt" +) + +func tel(ch chan int) { + for i := 0; i < 15; i++ { + ch <- i + } +} + +func main() { + var ok = true + ch := make(chan int) + + go tel(ch) + for ok { + i := <-ch + fmt.Printf("ok is %t and the counter is at %d\n", ok, i) + } +} diff --git a/eBook/exercises/chapter_14/goroutine_select.go b/eBook/exercises/chapter_14/goroutine_select.go index 5e2c7da..4f75510 100755 --- a/eBook/exercises/chapter_14/goroutine_select.go +++ b/eBook/exercises/chapter_14/goroutine_select.go @@ -1,31 +1,30 @@ -// Q20b_goroutine.go -package main - -import ( - "fmt" - "os" -) - -func tel(ch chan int, quit chan bool) { - for i:=0; i < 15; i++ { - ch <- i - } - quit <- true -} - -func main() { - var ok = true - ch := make(chan int) - quit := make(chan bool) - - go tel(ch, quit) - for ok { - select { - case i:= <-ch: - fmt.Printf("The counter is at %d\n", i) - case <-quit: - os.Exit(0) - } - } -} - +// Q20b_goroutine.go +package main + +import ( + "fmt" + "os" +) + +func tel(ch chan int, quit chan bool) { + for i := 0; i < 15; i++ { + ch <- i + } + quit <- true +} + +func main() { + var ok = true + ch := make(chan int) + quit := make(chan bool) + + go tel(ch, quit) + for ok { + select { + case i := <-ch: + fmt.Printf("The counter is at %d\n", i) + case <-quit: + os.Exit(0) + } + } +} diff --git a/eBook/exercises/chapter_14/gosum.go b/eBook/exercises/chapter_14/gosum.go index 53271f8..4e876db 100755 --- a/eBook/exercises/chapter_14/gosum.go +++ b/eBook/exercises/chapter_14/gosum.go @@ -1,16 +1,16 @@ -// gosum.go -package main - -import ( - "fmt" -) - -func sum(x, y int, c chan int) { - c <- x + y -} - -func main() { - c := make(chan int) - go sum(12, 13, c) - fmt.Println(<-c) // 25 -} +// gosum.go +package main + +import ( + "fmt" +) + +func sum(x, y int, c chan int) { + c <- x + y +} + +func main() { + c := make(chan int) + go sum(12, 13, c) + fmt.Println(<-c) // 25 +} diff --git a/eBook/exercises/chapter_14/multiplex_server3.go b/eBook/exercises/chapter_14/multiplex_server3.go index 6d1c2e5..1baafd9 100755 --- a/eBook/exercises/chapter_14/multiplex_server3.go +++ b/eBook/exercises/chapter_14/multiplex_server3.go @@ -1,58 +1,59 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. -package main - -import "fmt" - -type Request struct { - a, b int - replyc chan int // reply channel inside the Request -} - -type binOp func(a, b int) int - -func run(op binOp, req *Request) { - req.replyc <- op(req.a, req.b) -} - -func (r *Request) String() string { - return fmt.Sprintf("%d+%d=%d", r.a, r.b, <-r.replyc) -} - -func server(op binOp, service chan *Request, quit chan bool) { - for { - select { - case req := <-service: - go run(op, req) - case <-quit: - return // stop infinite loop - } - } -} - -func startServer(op binOp) (service chan *Request, quit chan bool) { - service = make(chan *Request) - quit = make(chan bool) - go server(op, service, quit) - return service, quit -} - -func main() { - adder, quit := startServer(func(a, b int) int { return a + b }) - // make requests: - req1 := &Request{3, 4, make(chan int)} - req2 := &Request{150, 250, make(chan int)} - // send requests on the service channel - adder <- req1 - adder <- req2 - // ask for the results: ( method String() is called ) - fmt.Println(req1, req2) - // shutdown server: - quit <- true - fmt.Print("done") -} -/* output: -3+4=7 150+250=400 -done -*/ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +package main + +import "fmt" + +type Request struct { + a, b int + replyc chan int // reply channel inside the Request +} + +type binOp func(a, b int) int + +func run(op binOp, req *Request) { + req.replyc <- op(req.a, req.b) +} + +func (r *Request) String() string { + return fmt.Sprintf("%d+%d=%d", r.a, r.b, <-r.replyc) +} + +func server(op binOp, service chan *Request, quit chan bool) { + for { + select { + case req := <-service: + go run(op, req) + case <-quit: + return // stop infinite loop + } + } +} + +func startServer(op binOp) (service chan *Request, quit chan bool) { + service = make(chan *Request) + quit = make(chan bool) + go server(op, service, quit) + return service, quit +} + +func main() { + adder, quit := startServer(func(a, b int) int { return a + b }) + // make requests: + req1 := &Request{3, 4, make(chan int)} + req2 := &Request{150, 250, make(chan int)} + // send requests on the service channel + adder <- req1 + adder <- req2 + // ask for the results: ( method String() is called ) + fmt.Println(req1, req2) + // shutdown server: + quit <- true + fmt.Print("done") +} + +/* output: +3+4=7 150+250=400 +done +*/ diff --git a/eBook/exercises/chapter_14/polar_to_cartesian.go b/eBook/exercises/chapter_14/polar_to_cartesian.go index 01be44f..6a373ca 100755 --- a/eBook/exercises/chapter_14/polar_to_cartesian.go +++ b/eBook/exercises/chapter_14/polar_to_cartesian.go @@ -1,101 +1,102 @@ -// polartocartesian.go -package main - -import ( - "bufio" - "fmt" - "math" - "os" - "runtime" - "strconv" - "strings" -) - -type polar struct { - radius float64 - Θ float64 -} - -type cartesian struct { - x float64 - y float64 -} - -const result = "Polar: radius=%.02f angle=%.02f degrees -- Cartesian: x=%.02f y=%.02f\n" - -var prompt = "Enter a radius and an angle (in degrees), e.g., 12.5 90, " + "or %s to quit." - -func init() { - if runtime.GOOS == "windows" { - prompt = fmt.Sprintf(prompt, "Ctrl+Z, Enter") - } else { // Unix-like - prompt = fmt.Sprintf(prompt, "Ctrl+D") - } -} - -func main() { - questions := make(chan polar) - defer close(questions) - answers := createSolver(questions) - defer close(answers) - interact(questions, answers) -} - -func createSolver(questions chan polar) chan cartesian { - answers := make(chan cartesian) - go func() { - for { - polarCoord := <-questions - Θ := polarCoord.Θ * math.Pi / 180.0 // degrees to radians - x := polarCoord.radius * math.Cos(Θ) - y := polarCoord.radius * math.Sin(Θ) - answers <- cartesian{x, y} - } - }() - return answers -} - -func interact(questions chan polar, answers chan cartesian) { - reader := bufio.NewReader(os.Stdin) - fmt.Println(prompt) - for { - fmt.Printf("Radius and angle: ") - line, err := reader.ReadString('\n') - if err != nil { - break - } - line = line[:len(line)-1] // chop of newline character - if numbers := strings.Fields(line); len(numbers) == 2 { - polars, err := floatsForStrings(numbers) - if err != nil { - fmt.Fprintln(os.Stderr, "invalid number") - continue - } - questions <- polar{polars[0], polars[1]} - coord := <-answers - fmt.Printf(result, polars[0], polars[1], coord.x, coord.y) - } else { - fmt.Fprintln(os.Stderr, "invalid input") - } - } - fmt.Println() -} - -func floatsForStrings(numbers []string) ([]float64, error) { - var floats []float64 - for _, number := range numbers { - if x, err := strconv.ParseFloat(number, 64); err != nil { - return nil, err - } else { - floats = append(floats, x) - } - } - return floats, nil -} -/* Output: -Enter a radius and an angle (in degrees), e.g., 12.5 90, or Ctrl+Z, Enter to qui -t. -Radius and angle: 12.5 90 -Polar: radius=12.50 angle=90.00 degrees -- Cartesian: x=0.00 y=12.50 -Radius and angle: ^Z -*/ +// polartocartesian.go +package main + +import ( + "bufio" + "fmt" + "math" + "os" + "runtime" + "strconv" + "strings" +) + +type polar struct { + radius float64 + Θ float64 +} + +type cartesian struct { + x float64 + y float64 +} + +const result = "Polar: radius=%.02f angle=%.02f degrees -- Cartesian: x=%.02f y=%.02f\n" + +var prompt = "Enter a radius and an angle (in degrees), e.g., 12.5 90, " + "or %s to quit." + +func init() { + if runtime.GOOS == "windows" { + prompt = fmt.Sprintf(prompt, "Ctrl+Z, Enter") + } else { // Unix-like + prompt = fmt.Sprintf(prompt, "Ctrl+D") + } +} + +func main() { + questions := make(chan polar) + defer close(questions) + answers := createSolver(questions) + defer close(answers) + interact(questions, answers) +} + +func createSolver(questions chan polar) chan cartesian { + answers := make(chan cartesian) + go func() { + for { + polarCoord := <-questions + Θ := polarCoord.Θ * math.Pi / 180.0 // degrees to radians + x := polarCoord.radius * math.Cos(Θ) + y := polarCoord.radius * math.Sin(Θ) + answers <- cartesian{x, y} + } + }() + return answers +} + +func interact(questions chan polar, answers chan cartesian) { + reader := bufio.NewReader(os.Stdin) + fmt.Println(prompt) + for { + fmt.Printf("Radius and angle: ") + line, err := reader.ReadString('\n') + if err != nil { + break + } + line = line[:len(line)-1] // chop of newline character + if numbers := strings.Fields(line); len(numbers) == 2 { + polars, err := floatsForStrings(numbers) + if err != nil { + fmt.Fprintln(os.Stderr, "invalid number") + continue + } + questions <- polar{polars[0], polars[1]} + coord := <-answers + fmt.Printf(result, polars[0], polars[1], coord.x, coord.y) + } else { + fmt.Fprintln(os.Stderr, "invalid input") + } + } + fmt.Println() +} + +func floatsForStrings(numbers []string) ([]float64, error) { + var floats []float64 + for _, number := range numbers { + if x, err := strconv.ParseFloat(number, 64); err != nil { + return nil, err + } else { + floats = append(floats, x) + } + } + return floats, nil +} + +/* Output: +Enter a radius and an angle (in degrees), e.g., 12.5 90, or Ctrl+Z, Enter to qui +t. +Radius and angle: 12.5 90 +Polar: radius=12.50 angle=90.00 degrees -- Cartesian: x=0.00 y=12.50 +Radius and angle: ^Z +*/ diff --git a/eBook/exercises/chapter_14/producer_consumer.go b/eBook/exercises/chapter_14/producer_consumer.go index 465dae2..77774b6 100755 --- a/eBook/exercises/chapter_14/producer_consumer.go +++ b/eBook/exercises/chapter_14/producer_consumer.go @@ -1,42 +1,43 @@ -// goroutines2.go -package main - -import "fmt" - -// integer producer: -func numGen(start, count int, out chan<- int) { - for i := 0; i < count; i++ { - out <- start - start = start + count - } - close(out) -} - -// integer consumer: -func numEchoRange(in <-chan int, done chan<- bool) { - for num := range in { - fmt.Printf("%d\n", num) - } - done <- true -} - -func main() { - numChan := make(chan int) - done := make(chan bool) - go numGen(0, 10, numChan) - go numEchoRange(numChan, done) - - <-done -} -/* Output: -0 -10 -20 -30 -40 -50 -60 -70 -80 -90 -*/ \ No newline at end of file +// goroutines2.go +package main + +import "fmt" + +// integer producer: +func numGen(start, count int, out chan<- int) { + for i := 0; i < count; i++ { + out <- start + start = start + count + } + close(out) +} + +// integer consumer: +func numEchoRange(in <-chan int, done chan<- bool) { + for num := range in { + fmt.Printf("%d\n", num) + } + done <- true +} + +func main() { + numChan := make(chan int) + done := make(chan bool) + go numGen(0, 10, numChan) + go numEchoRange(numChan, done) + + <-done +} + +/* Output: +0 +10 +20 +30 +40 +50 +60 +70 +80 +90 +*/ diff --git a/eBook/exercises/chapter_14/producer_consumer2.go b/eBook/exercises/chapter_14/producer_consumer2.go index 353daa3..d85f17c 100755 --- a/eBook/exercises/chapter_14/producer_consumer2.go +++ b/eBook/exercises/chapter_14/producer_consumer2.go @@ -1,29 +1,30 @@ -// prod_cons.go -/* producer-consumer problem in Go */ -package main - -import "fmt" - -var done = make(chan bool) -var msgs = make(chan int) - -func produce() { - for i := 0; i < 10; i++ { - msgs <- i - } - done <- true -} - -func consume() { - for { - msg := <-msgs - fmt.Print(msg, " ") - } -} - -func main() { - go produce() - go consume() - <-done -} -// Output: 0 1 2 3 4 5 6 7 8 9 \ No newline at end of file +// prod_cons.go +/* producer-consumer problem in Go */ +package main + +import "fmt" + +var done = make(chan bool) +var msgs = make(chan int) + +func produce() { + for i := 0; i < 10; i++ { + msgs <- i + } + done <- true +} + +func consume() { + for { + msg := <-msgs + fmt.Print(msg, " ") + } +} + +func main() { + go produce() + go consume() + <-done +} + +// Output: 0 1 2 3 4 5 6 7 8 9 diff --git a/eBook/exercises/chapter_14/random_bitgen.go b/eBook/exercises/chapter_14/random_bitgen.go index 5a31efe..e83d83a 100755 --- a/eBook/exercises/chapter_14/random_bitgen.go +++ b/eBook/exercises/chapter_14/random_bitgen.go @@ -1,23 +1,23 @@ -package main - -import ( - "fmt" -) - -func main() { - c := make(chan int) - // consumer: - go func() { - for { - fmt.Print(<-c, " ") - } - }() - // producer: - for { - select { - case c <- 0: - case c <- 1: - } - } - -} +package main + +import ( + "fmt" +) + +func main() { + c := make(chan int) + // consumer: + go func() { + for { + fmt.Print(<-c, " ") + } + }() + // producer: + for { + select { + case c <- 0: + case c <- 1: + } + } + +} diff --git a/eBook/exercises/chapter_15/client1.go b/eBook/exercises/chapter_15/client1.go index 179aee4..7aad489 100755 --- a/eBook/exercises/chapter_15/client1.go +++ b/eBook/exercises/chapter_15/client1.go @@ -1,46 +1,46 @@ -package main - -import ( - "fmt" - "os" - "net" - "bufio" - "strings" -) - -func main() { - var conn net.Conn - var error error - var inputReader *bufio.Reader - var input string - var clientName string - - // maak connectie met de server: - conn, error = net.Dial("tcp", "localhost:50000") - checkError(error) - - inputReader = bufio.NewReader(os.Stdin) - fmt.Println("First, what is your name?") - clientName, _ = inputReader.ReadString('\n') - // fmt.Printf("CLIENTNAME %s",clientName) - trimmedClient := strings.Trim(clientName, "\r\n") // "\r\n" voor Windows, "\n" voor Linux - - for { - fmt.Println("What to send to the server? Type Q to quit. Type SH to shutdown server.") - input, _ = inputReader.ReadString('\n') - trimmedInput := strings.Trim(input, "\r\n") - // fmt.Printf("input:--%s--",input) - // fmt.Printf("trimmedInput:--%s--",trimmedInput) - if trimmedInput == "Q" { - return - } - _, error = conn.Write([]byte(trimmedClient + " says: " + trimmedInput)) - checkError(error) - } -} - -func checkError(error error) { - if error != nil { - panic("Error: " + error.Error()) // terminate program - } -} \ No newline at end of file +package main + +import ( + "bufio" + "fmt" + "net" + "os" + "strings" +) + +func main() { + var conn net.Conn + var error error + var inputReader *bufio.Reader + var input string + var clientName string + + // maak connectie met de server: + conn, error = net.Dial("tcp", "localhost:50000") + checkError(error) + + inputReader = bufio.NewReader(os.Stdin) + fmt.Println("First, what is your name?") + clientName, _ = inputReader.ReadString('\n') + // fmt.Printf("CLIENTNAME %s",clientName) + trimmedClient := strings.Trim(clientName, "\r\n") // "\r\n" voor Windows, "\n" voor Linux + + for { + fmt.Println("What to send to the server? Type Q to quit. Type SH to shutdown server.") + input, _ = inputReader.ReadString('\n') + trimmedInput := strings.Trim(input, "\r\n") + // fmt.Printf("input:--%s--",input) + // fmt.Printf("trimmedInput:--%s--",trimmedInput) + if trimmedInput == "Q" { + return + } + _, error = conn.Write([]byte(trimmedClient + " says: " + trimmedInput)) + checkError(error) + } +} + +func checkError(error error) { + if error != nil { + panic("Error: " + error.Error()) // terminate program + } +} diff --git a/eBook/exercises/chapter_15/hello_server.go b/eBook/exercises/chapter_15/hello_server.go index fbeb8a3..97a2479 100755 --- a/eBook/exercises/chapter_15/hello_server.go +++ b/eBook/exercises/chapter_15/hello_server.go @@ -1,19 +1,20 @@ -// hello_server.go -package main - -import ( - "fmt" - "net/http" -) - -type Hello struct{} - -func (h Hello) ServeHTTP(w http.ResponseWriter, r *http.Request) { - fmt.Fprint(w, "Hello!") -} - -func main() { - var h Hello - http.ListenAndServe("localhost:4000",h) -} -// Output in browser-window with url http://localhost:4000: Hello! +// hello_server.go +package main + +import ( + "fmt" + "net/http" +) + +type Hello struct{} + +func (h Hello) ServeHTTP(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, "Hello!") +} + +func main() { + var h Hello + http.ListenAndServe("localhost:4000", h) +} + +// Output in browser-window with url http://localhost:4000: Hello! diff --git a/eBook/exercises/chapter_15/http_fetch2.go b/eBook/exercises/chapter_15/http_fetch2.go index 8ef2c0b..7495ec0 100755 --- a/eBook/exercises/chapter_15/http_fetch2.go +++ b/eBook/exercises/chapter_15/http_fetch2.go @@ -1,31 +1,31 @@ -// httpfetch.go -package main - -import ( - "bufio" - "fmt" - "net/http" - "io/ioutil" - "log" - "os" - "strings" -) - -func main() { - fmt.Print("Give the url from which to read: ") - iread := bufio.NewReader(os.Stdin) - url, _ := iread.ReadString('\n') - url = strings.Trim(url," \n\r") // trimming space,etc. - // fmt.Println("***", url,"***") // debugging - res, err := http.Get(url) - CheckError(err) - data, err := ioutil.ReadAll(res.Body) - CheckError(err) - fmt.Printf("Got: %q", string(data)) -} - -func CheckError(err error) { - if err != nil { - log.Fatalf("Get: %v", err) - } -} +// httpfetch.go +package main + +import ( + "bufio" + "fmt" + "io/ioutil" + "log" + "net/http" + "os" + "strings" +) + +func main() { + fmt.Print("Give the url from which to read: ") + iread := bufio.NewReader(os.Stdin) + url, _ := iread.ReadString('\n') + url = strings.Trim(url, " \n\r") // trimming space,etc. + // fmt.Println("***", url,"***") // debugging + res, err := http.Get(url) + CheckError(err) + data, err := ioutil.ReadAll(res.Body) + CheckError(err) + fmt.Printf("Got: %q", string(data)) +} + +func CheckError(err error) { + if err != nil { + log.Fatalf("Get: %v", err) + } +} diff --git a/eBook/exercises/chapter_15/server1.go b/eBook/exercises/chapter_15/server1.go index 5ffa2bf..041755e 100755 --- a/eBook/exercises/chapter_15/server1.go +++ b/eBook/exercises/chapter_15/server1.go @@ -1,75 +1,75 @@ -package main - -import ( - "fmt" - "os" - "net" - "strings" -) - -// Map of the clients: contains: clientname - 1 (active) / 0 - (inactive) -var mapUsers map[string]int - -func main() { - var listener net.Listener - var error error - var conn net.Conn - mapUsers = make(map[string]int) - - fmt.Println("Starting the server ...") - - // create listener: - listener, error = net.Listen("tcp", "localhost:50000") - checkError(error) - // listen and accept connections from clients: - for { - conn, error = listener.Accept() - checkError(error) - go doServerStuff(conn) - } -} - -func doServerStuff(conn net.Conn) { - var buf []byte - var error error - - for { - buf = make([]byte, 512) - _, error = conn.Read(buf) - checkError(error) - input := string(buf) - if strings.Contains(input, ": SH") { - fmt.Println("Server shutting down.") - os.Exit(0) - } - // op commando WHO: write out mapUsers - if strings.Contains(input, ": WHO") { - DisplayList() - } - // extract clientname: - ix := strings.Index(input, "says") - clName := input[0:ix-1] - //fmt.Printf("The clientname is ---%s---\n", string(clName)) - // set clientname active in mapUsers: - mapUsers[string(clName)] = 1 - fmt.Printf("Received data: --%v--", string(buf)) - } -} - -// advantage: code is cleaner, -// disadvantage: the server process has to stop at any error: -// a simple return continues in the function where we came from! -func checkError(error error) { - if error != nil { - panic("Error: " + error.Error()) // terminate program - } -} - -func DisplayList() { - fmt.Println("--------------------------------------------") - fmt.Println("This is the client list: 1=active, 0=inactive") - for key, value := range mapUsers { - fmt.Printf("User %s is %d\n", key, value) - } - fmt.Println("--------------------------------------------") -} +package main + +import ( + "fmt" + "net" + "os" + "strings" +) + +// Map of the clients: contains: clientname - 1 (active) / 0 - (inactive) +var mapUsers map[string]int + +func main() { + var listener net.Listener + var error error + var conn net.Conn + mapUsers = make(map[string]int) + + fmt.Println("Starting the server ...") + + // create listener: + listener, error = net.Listen("tcp", "localhost:50000") + checkError(error) + // listen and accept connections from clients: + for { + conn, error = listener.Accept() + checkError(error) + go doServerStuff(conn) + } +} + +func doServerStuff(conn net.Conn) { + var buf []byte + var error error + + for { + buf = make([]byte, 512) + _, error = conn.Read(buf) + checkError(error) + input := string(buf) + if strings.Contains(input, ": SH") { + fmt.Println("Server shutting down.") + os.Exit(0) + } + // op commando WHO: write out mapUsers + if strings.Contains(input, ": WHO") { + DisplayList() + } + // extract clientname: + ix := strings.Index(input, "says") + clName := input[0 : ix-1] + //fmt.Printf("The clientname is ---%s---\n", string(clName)) + // set clientname active in mapUsers: + mapUsers[string(clName)] = 1 + fmt.Printf("Received data: --%v--", string(buf)) + } +} + +// advantage: code is cleaner, +// disadvantage: the server process has to stop at any error: +// a simple return continues in the function where we came from! +func checkError(error error) { + if error != nil { + panic("Error: " + error.Error()) // terminate program + } +} + +func DisplayList() { + fmt.Println("--------------------------------------------") + fmt.Println("This is the client list: 1=active, 0=inactive") + for key, value := range mapUsers { + fmt.Printf("User %s is %d\n", key, value) + } + fmt.Println("--------------------------------------------") +} diff --git a/eBook/exercises/chapter_15/statistics.go b/eBook/exercises/chapter_15/statistics.go index e49189e..fa22ff1 100755 --- a/eBook/exercises/chapter_15/statistics.go +++ b/eBook/exercises/chapter_15/statistics.go @@ -1,110 +1,110 @@ -// statistics.go -package main - -import ( - "fmt" - "net/http" - "sort" - "strings" - "strconv" - "log" -) - -type statistics struct { - numbers []float64 - mean float64 - median float64 -} - -const form = `
-
-
- -
` - -const error = `

%s

` - -var pageTop = "" -var pageBottom = "" - -func main() { - http.HandleFunc("/", homePage) - if err := http.ListenAndServe(":9001", nil); err != nil { - log.Fatal("failed to start server", err) - } -} - -func homePage(writer http.ResponseWriter, request *http.Request) { - writer.Header().Set("Content-Type", "text/html") - err := request.ParseForm() // Must be called before writing response - fmt.Fprint(writer, pageTop, form) - if err != nil { - fmt.Fprintf(writer, error, err) - } else { - if numbers, message, ok := processRequest(request); ok { - stats := getStats(numbers) - fmt.Fprint(writer, formatStats(stats)) - } else if message != "" { - fmt.Fprintf(writer, error, message) - } - } - fmt.Fprint(writer, pageBottom) -} - -func processRequest(request *http.Request) ([]float64, string, bool) { - var numbers []float64 - var text string - if slice, found := request.Form["numbers"]; found && len(slice) > 0 { - //处理如果网页中输入的是中文逗号 - if strings.Contains(slice[0], ",") { - text = strings.Replace(slice[0], ",", " ", -1) - } else { - text = strings.Replace(slice[0], ",", " ", -1) - } - for _, field := range strings.Fields(text) { - if x, err := strconv.ParseFloat(field, 64); err != nil { - return numbers, "'" + field + "' is invalid", false - } else { - numbers = append(numbers, x) - } - } - } - if len(numbers) == 0 { - return numbers, "", false // no data first time form is shown - } - return numbers, "", true -} - -func getStats(numbers []float64) (stats statistics) { - stats.numbers = numbers - sort.Float64s(stats.numbers) - stats.mean = sum(numbers) / float64(len(numbers)) - stats.median = median(numbers) - return -} - -func sum(numbers []float64) (total float64) { - for _, x := range numbers { - total += x - } - return -} - -func median(numbers []float64) float64 { - middle := len(numbers)/2 - result := numbers[middle] - if len(numbers)%2 == 0 { - result = (result + numbers[middle-1]) / 2 - } - return result -} - -func formatStats(stats statistics) string { - return fmt.Sprintf(` - - - - - -
Results
Numbers%v
Count%d
Mean%f
Median%f
`, stats.numbers, len(stats.numbers), stats.mean, stats.median) -} +// statistics.go +package main + +import ( + "fmt" + "log" + "net/http" + "sort" + "strconv" + "strings" +) + +type statistics struct { + numbers []float64 + mean float64 + median float64 +} + +const form = `
+
+
+ +
` + +const error = `

%s

` + +var pageTop = "" +var pageBottom = "" + +func main() { + http.HandleFunc("/", homePage) + if err := http.ListenAndServe(":9001", nil); err != nil { + log.Fatal("failed to start server", err) + } +} + +func homePage(writer http.ResponseWriter, request *http.Request) { + writer.Header().Set("Content-Type", "text/html") + err := request.ParseForm() // Must be called before writing response + fmt.Fprint(writer, pageTop, form) + if err != nil { + fmt.Fprintf(writer, error, err) + } else { + if numbers, message, ok := processRequest(request); ok { + stats := getStats(numbers) + fmt.Fprint(writer, formatStats(stats)) + } else if message != "" { + fmt.Fprintf(writer, error, message) + } + } + fmt.Fprint(writer, pageBottom) +} + +func processRequest(request *http.Request) ([]float64, string, bool) { + var numbers []float64 + var text string + if slice, found := request.Form["numbers"]; found && len(slice) > 0 { + //处理如果网页中输入的是中文逗号 + if strings.Contains(slice[0], ",") { + text = strings.Replace(slice[0], ",", " ", -1) + } else { + text = strings.Replace(slice[0], ",", " ", -1) + } + for _, field := range strings.Fields(text) { + if x, err := strconv.ParseFloat(field, 64); err != nil { + return numbers, "'" + field + "' is invalid", false + } else { + numbers = append(numbers, x) + } + } + } + if len(numbers) == 0 { + return numbers, "", false // no data first time form is shown + } + return numbers, "", true +} + +func getStats(numbers []float64) (stats statistics) { + stats.numbers = numbers + sort.Float64s(stats.numbers) + stats.mean = sum(numbers) / float64(len(numbers)) + stats.median = median(numbers) + return +} + +func sum(numbers []float64) (total float64) { + for _, x := range numbers { + total += x + } + return +} + +func median(numbers []float64) float64 { + middle := len(numbers) / 2 + result := numbers[middle] + if len(numbers)%2 == 0 { + result = (result + numbers[middle-1]) / 2 + } + return result +} + +func formatStats(stats statistics) string { + return fmt.Sprintf(` + + + + + +
Results
Numbers%v
Count%d
Mean%f
Median%f
`, stats.numbers, len(stats.numbers), stats.mean, stats.median) +} diff --git a/eBook/exercises/chapter_15/template_validation_recover.go b/eBook/exercises/chapter_15/template_validation_recover.go index 2159188..55b1c78 100755 --- a/eBook/exercises/chapter_15/template_validation_recover.go +++ b/eBook/exercises/chapter_15/template_validation_recover.go @@ -1,29 +1,30 @@ -// template_validation_recover.go -package main - -import ( - "text/template" - "fmt" - "log" -) - -func main() { - tOk := template.New("ok") - tErr := template.New("error_template") - defer func() { - if err := recover(); err != nil { - log.Printf("run time panic: %v", err) - } - }() - - //a valid template, so no panic with Must: - template.Must(tOk.Parse("/* and a comment */ some static text: {{ .Name }}")) - fmt.Println("The first one parsed OK.") - fmt.Println("The next one ought to fail.") - template.Must(tErr.Parse(" some static text {{ .Name }")) -} -/* Output: -The first one parsed OK. -The next one ought to fail. -2011/10/27 10:56:27 run time panic: template: error_template:1: unexpected "}" in command -*/ \ No newline at end of file +// template_validation_recover.go +package main + +import ( + "fmt" + "log" + "text/template" +) + +func main() { + tOk := template.New("ok") + tErr := template.New("error_template") + defer func() { + if err := recover(); err != nil { + log.Printf("run time panic: %v", err) + } + }() + + //a valid template, so no panic with Must: + template.Must(tOk.Parse("/* and a comment */ some static text: {{ .Name }}")) + fmt.Println("The first one parsed OK.") + fmt.Println("The next one ought to fail.") + template.Must(tErr.Parse(" some static text {{ .Name }")) +} + +/* Output: +The first one parsed OK. +The next one ought to fail. +2011/10/27 10:56:27 run time panic: template: error_template:1: unexpected "}" in command +*/ diff --git a/eBook/exercises/chapter_15/twitter_status_json.go b/eBook/exercises/chapter_15/twitter_status_json.go index 2dc1319..e285670 100755 --- a/eBook/exercises/chapter_15/twitter_status_json.go +++ b/eBook/exercises/chapter_15/twitter_status_json.go @@ -1,33 +1,34 @@ -// twitter_status_json.go -package main - -import ( - "net/http" - "fmt" - "encoding/json" - "io/ioutil" -) - -type Status struct { - Text string -} - -type User struct { - Status Status -} - -func main() { - /* perform an HTTP request for the twitter status of user: Googland */ - res, _:= http.Get("http://twitter.com/users/Googland.json") - /* initialize the structure of the JSON response */ - user := User{Status{""}} - /* unmarshal the JSON into our structures */ - temp, _ := ioutil.ReadAll(res.Body) - body := []byte(temp) - json.Unmarshal(body, &user) - fmt.Printf("status: %s", user.Status.Text) -} -/* Output: -status: Robot cars invade California, on orders from Google: -Google has been testing self-driving cars ... http://bit.ly/cbtpUN http://retwt.me/97p -*/ \ No newline at end of file +// twitter_status_json.go +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" +) + +type Status struct { + Text string +} + +type User struct { + Status Status +} + +func main() { + /* perform an HTTP request for the twitter status of user: Googland */ + res, _ := http.Get("http://twitter.com/users/Googland.json") + /* initialize the structure of the JSON response */ + user := User{Status{""}} + /* unmarshal the JSON into our structures */ + temp, _ := ioutil.ReadAll(res.Body) + body := []byte(temp) + json.Unmarshal(body, &user) + fmt.Printf("status: %s", user.Status.Text) +} + +/* Output: +status: Robot cars invade California, on orders from Google: +Google has been testing self-driving cars ... http://bit.ly/cbtpUN http://retwt.me/97p +*/ diff --git a/eBook/exercises/chapter_15/webhello2.go b/eBook/exercises/chapter_15/webhello2.go index b026a59..a4c3935 100755 --- a/eBook/exercises/chapter_15/webhello2.go +++ b/eBook/exercises/chapter_15/webhello2.go @@ -1,24 +1,24 @@ -// webhello2.go -package main - -import ( - "net/http" - "fmt" - "strings" -) - -func helloHandler(w http.ResponseWriter, r *http.Request) { - remPartOfURL := r.URL.Path[len("/hello/"):] //get everything after the /hello/ part of the URL - fmt.Fprintf(w, "Hello %s!", remPartOfURL) -} - -func shouthelloHandler(w http.ResponseWriter, r *http.Request) { - remPartOfURL := r.URL.Path[len("/shouthello/"):] //get everything after the /shouthello/ part of the URL - fmt.Fprintf(w, "Hello %s!", strings.ToUpper(remPartOfURL)) -} - -func main() { - http.HandleFunc("/hello/", helloHandler) - http.HandleFunc("/shouthello/", shouthelloHandler) - http.ListenAndServe("localhost:9999", nil) -} +// webhello2.go +package main + +import ( + "fmt" + "net/http" + "strings" +) + +func helloHandler(w http.ResponseWriter, r *http.Request) { + remPartOfURL := r.URL.Path[len("/hello/"):] //get everything after the /hello/ part of the URL + fmt.Fprintf(w, "Hello %s!", remPartOfURL) +} + +func shouthelloHandler(w http.ResponseWriter, r *http.Request) { + remPartOfURL := r.URL.Path[len("/shouthello/"):] //get everything after the /shouthello/ part of the URL + fmt.Fprintf(w, "Hello %s!", strings.ToUpper(remPartOfURL)) +} + +func main() { + http.HandleFunc("/hello/", helloHandler) + http.HandleFunc("/shouthello/", shouthelloHandler) + http.ListenAndServe("localhost:9999", nil) +}