diff --git a/interfaces/09-little-refactor/list.go b/interfaces/09-little-refactor/list.go new file mode 100644 index 0000000..80825d9 --- /dev/null +++ b/interfaces/09-little-refactor/list.go @@ -0,0 +1,29 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import "fmt" + +type list []*product + +func (l list) print() { + if len(l) == 0 { + fmt.Println("Sorry. We're waiting for delivery 🚚.") + return + } + + for _, p := range l { + p.print() + } +} + +func (l list) discount(ratio float64) { + for _, p := range l { + p.discount(ratio) + } +} diff --git a/interfaces/09-little-refactor/main.go b/interfaces/09-little-refactor/main.go new file mode 100644 index 0000000..5561cf3 --- /dev/null +++ b/interfaces/09-little-refactor/main.go @@ -0,0 +1,19 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +func main() { + l := list{ + {title: "moby dick", price: 10, released: toTimestamp(118281600)}, + {title: "odyssey", price: 15, released: toTimestamp("733622400")}, + {title: "hobbit", price: 25}, + } + + l.discount(.5) + l.print() +} diff --git a/interfaces/composition/game.go b/interfaces/09-little-refactor/money.go similarity index 67% rename from interfaces/composition/game.go rename to interfaces/09-little-refactor/money.go index 3604b15..86f7d63 100644 --- a/interfaces/composition/game.go +++ b/interfaces/09-little-refactor/money.go @@ -7,6 +7,10 @@ package main -type game struct { - product +import "fmt" + +type money float64 + +func (m money) string() string { + return fmt.Sprintf("$%.2f", m) } diff --git a/interfaces/09-little-refactor/product.go b/interfaces/09-little-refactor/product.go new file mode 100644 index 0000000..cdd6549 --- /dev/null +++ b/interfaces/09-little-refactor/product.go @@ -0,0 +1,26 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import ( + "fmt" +) + +type product struct { + title string + price money + released timestamp +} + +func (p *product) print() { + fmt.Printf("%s: %s (%s)\n", p.title, p.price.string(), p.released.string()) +} + +func (p *product) discount(ratio float64) { + p.price *= money(1 - ratio) +} diff --git a/interfaces/09-little-refactor/timestamp.go b/interfaces/09-little-refactor/timestamp.go new file mode 100644 index 0000000..b27e515 --- /dev/null +++ b/interfaces/09-little-refactor/timestamp.go @@ -0,0 +1,45 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import ( + "strconv" + "time" +) + +// timestamp stores, formats and automatically prints a timestamp. +type timestamp struct { + // timestamp anonymously embeds a time. + // no need to convert a time value to a timestamp value to use the methods of the time type. + time.Time +} + +func (ts timestamp) string() string { + if ts.IsZero() { // same as: ts.Time.IsZero() + return "unknown" + } + + // Mon Jan 2 15:04:05 -0700 MST 2006 + const layout = "2006/01" + return ts.Format(layout) // same as: ts.Time.Format(layout) +} + +// toTimestamp returns a timestamp value depending on the type of `v`. +func toTimestamp(v interface{}) (ts timestamp) { + var t int + + switch v := v.(type) { + case int: + t = v + case string: + t, _ = strconv.Atoi(v) + } + + ts.Time = time.Unix(int64(t), 0) + return ts +} diff --git a/interfaces/09-stringer/_handlemethods.go b/interfaces/10-stringer/_handlemethods.go similarity index 100% rename from interfaces/09-stringer/_handlemethods.go rename to interfaces/10-stringer/_handlemethods.go diff --git a/interfaces/10-stringer/list.go b/interfaces/10-stringer/list.go new file mode 100644 index 0000000..84952d6 --- /dev/null +++ b/interfaces/10-stringer/list.go @@ -0,0 +1,33 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import ( + "fmt" + "strings" +) + +type list []*product + +func (l list) String() string { + if len(l) == 0 { + return "Sorry. We're waiting for delivery 🚚.\n" + } + + var str strings.Builder + for _, p := range l { + fmt.Fprintf(&str, "* %s\n", p) + } + return str.String() +} + +func (l list) discount(ratio float64) { + for _, p := range l { + p.discount(ratio) + } +} diff --git a/interfaces/10-stringer/main.go b/interfaces/10-stringer/main.go new file mode 100644 index 0000000..f15eff2 --- /dev/null +++ b/interfaces/10-stringer/main.go @@ -0,0 +1,32 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import "fmt" + +func main() { + // The money type is a stringer. + // You don't need to call the String method when printing a value of it. + // var pocket money = 10 + // fmt.Println(pocket) + + l := list{ + {title: "moby dick", price: 10, released: toTimestamp(118281600)}, + {title: "odyssey", price: 15, released: toTimestamp("733622400")}, + {title: "hobbit", price: 25}, + } + + // The list is a stringer. + // The `fmt.Print` function can print the `l` + // by calling `l`'s `String()` method. + // + // Underneath, `fmt.Print` uses a type switch to + // detect whether a type is a Stringer: + // https://golang.org/src/fmt/print.go#L627 + fmt.Print(l) +} diff --git a/interfaces/10-marshaler/money.go b/interfaces/10-stringer/money.go similarity index 100% rename from interfaces/10-marshaler/money.go rename to interfaces/10-stringer/money.go diff --git a/interfaces/composition/product.go b/interfaces/10-stringer/product.go similarity index 65% rename from interfaces/composition/product.go rename to interfaces/10-stringer/product.go index 84e2ce6..18fa646 100644 --- a/interfaces/composition/product.go +++ b/interfaces/10-stringer/product.go @@ -7,21 +7,20 @@ package main -import "fmt" +import ( + "fmt" +) type product struct { - Title string - Price money -} - -func (p *product) discount(ratio float64) { - p.Price *= money(1 - ratio) -} - -func (p *product) sum() money { - return p.Price + title string + price money + released timestamp } func (p *product) String() string { - return fmt.Sprintf("%-15s: %s", p.Title, p.Price) + return fmt.Sprintf("%s: %s (%s)", p.title, p.price, p.released) +} + +func (p *product) discount(ratio float64) { + p.price *= money(1 - ratio) } diff --git a/interfaces/10-stringer/timestamp.go b/interfaces/10-stringer/timestamp.go new file mode 100644 index 0000000..6e43c4d --- /dev/null +++ b/interfaces/10-stringer/timestamp.go @@ -0,0 +1,43 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import ( + "strconv" + "time" +) + +// timestamp stores, formats and automatically prints a timestamp: it's a stringer. +type timestamp struct { + time.Time +} + +// String method makes the timestamp an fmt.stringer. +func (ts timestamp) String() string { + if ts.IsZero() { + return "unknown" + } + + // Mon Jan 2 15:04:05 -0700 MST 2006 + const layout = "2006/01" + return ts.Format(layout) +} + +func toTimestamp(v interface{}) (ts timestamp) { + var t int + + switch v := v.(type) { + case int: + t = v + case string: + t, _ = strconv.Atoi(v) + } + + ts.Time = time.Unix(int64(t), 0) + return ts +} diff --git a/interfaces/11-sort/list.go b/interfaces/11-sort/list.go new file mode 100644 index 0000000..49d3e4f --- /dev/null +++ b/interfaces/11-sort/list.go @@ -0,0 +1,54 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import ( + "fmt" + "sort" + "strings" +) + +// product is now *product because sorting will unnecessarily copy the product values + +type list []*product + +func (l list) String() string { + if len(l) == 0 { + return "Sorry. We're waiting for delivery 🚚.\n" + } + + sort.Sort(l) + var str strings.Builder + for _, p := range l { + fmt.Fprintf(&str, "* %s\n", p) + } + return str.String() +} + +func (l list) discount(ratio float64) { + for _, p := range l { + p.discount(ratio) + } +} + +// by default `list` sorts by `title`. +func (l list) Len() int { return len(l) } +func (l list) Swap(i, j int) { l[i], l[j] = l[j], l[i] } +func (l list) Less(i, j int) bool { return l[i].title < l[j].title } + +// byRelease sorts by product release dates. +type byRelease struct { + // byRelease embeds `list` and reuses list's Len and Swap methods. + list +} + +func (bp byRelease) Less(i, j int) bool { + // Before() accepts a time.Time but `released` is not time.Time. + // `released.Time` is necessary. + return bp.list[i].released.Before(bp.list[j].released.Time) +} diff --git a/interfaces/11-sort/main.go b/interfaces/11-sort/main.go new file mode 100644 index 0000000..3691fed --- /dev/null +++ b/interfaces/11-sort/main.go @@ -0,0 +1,28 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import ( + "fmt" + "sort" +) + +func main() { + l := list{ + {title: "moby dick", price: 10, released: toTimestamp(118281600)}, + {title: "odyssey", price: 15, released: toTimestamp("733622400")}, + {title: "hobbit", price: 25}, + } + + // sort.Sort(l) + // sort.Sort(sort.Reverse(l)) + // sort.Sort(byRelease{l}) + sort.Sort(sort.Reverse(byRelease{l})) + + fmt.Print(l) +} diff --git a/interfaces/11-decode-toiface/money.go b/interfaces/11-sort/money.go similarity index 100% rename from interfaces/11-decode-toiface/money.go rename to interfaces/11-sort/money.go diff --git a/interfaces/11-sort/product.go b/interfaces/11-sort/product.go new file mode 100644 index 0000000..18fa646 --- /dev/null +++ b/interfaces/11-sort/product.go @@ -0,0 +1,26 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import ( + "fmt" +) + +type product struct { + title string + price money + released timestamp +} + +func (p *product) String() string { + return fmt.Sprintf("%s: %s (%s)", p.title, p.price, p.released) +} + +func (p *product) discount(ratio float64) { + p.price *= money(1 - ratio) +} diff --git a/interfaces/11-sort/timestamp.go b/interfaces/11-sort/timestamp.go new file mode 100644 index 0000000..fea05b2 --- /dev/null +++ b/interfaces/11-sort/timestamp.go @@ -0,0 +1,41 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import ( + "strconv" + "time" +) + +type timestamp struct { + time.Time +} + +func (ts timestamp) String() string { + if ts.IsZero() { + return "unknown" + } + + // Mon Jan 2 15:04:05 -0700 MST 2006 + const layout = "2006/01" + return ts.Format(layout) +} + +func toTimestamp(v interface{}) (ts timestamp) { + var t int + + switch v := v.(type) { + case int: + t = v + case string: + t, _ = strconv.Atoi(v) + } + + ts.Time = time.Unix(int64(t), 0) + return ts +} diff --git a/interfaces/12-marshaler/database.json b/interfaces/12-marshaler/database.json new file mode 100644 index 0000000..8a3df19 --- /dev/null +++ b/interfaces/12-marshaler/database.json @@ -0,0 +1,17 @@ +[ + { + "title": "moby dick", + "price": 10, + "released": 118281600 + }, + { + "title": "odyssey", + "price": 15, + "released": 733622400 + }, + { + "title": "hobbit", + "price": 25, + "released": -62135596800 + } +] \ No newline at end of file diff --git a/interfaces/12-marshaler/json.go b/interfaces/12-marshaler/json.go new file mode 100644 index 0000000..b4018db --- /dev/null +++ b/interfaces/12-marshaler/json.go @@ -0,0 +1,29 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import ( + "encoding/json" +) + +func encode() ([]byte, error) { + l := list{ + {Title: "moby dick", Price: 10, Released: toTimestamp(118281600)}, + {Title: "odyssey", Price: 15, Released: toTimestamp("733622400")}, + {Title: "hobbit", Price: 25}, + } + + return json.MarshalIndent(l, "", "\t") +} + +func decode(data []byte) (l list, err error) { + if err := json.Unmarshal(data, &l); err != nil { + return nil, err + } + return l, nil +} diff --git a/interfaces/12-marshaler/list.go b/interfaces/12-marshaler/list.go new file mode 100644 index 0000000..c0787f4 --- /dev/null +++ b/interfaces/12-marshaler/list.go @@ -0,0 +1,49 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import ( + "fmt" + "sort" + "strings" +) + +type list []*product + +func (l list) String() string { + if len(l) == 0 { + return "Sorry. We're waiting for delivery 🚚.\n" + } + + sort.Sort(l) + var str strings.Builder + for _, p := range l { + fmt.Fprintf(&str, "* %s\n", p) + } + return str.String() +} + +func (l list) discount(ratio float64) { + for _, p := range l { + p.discount(ratio) + } +} + +// by default `list` sorts by `Title`. +func (l list) Len() int { return len(l) } +func (l list) Swap(i, j int) { l[i], l[j] = l[j], l[i] } +func (l list) Less(i, j int) bool { return l[i].Title < l[j].Title } + +// byRelease sorts by product release dates. +type byRelease struct { + list +} + +func (bp byRelease) Less(i, j int) bool { + return bp.list[i].Released.Before(bp.list[j].Released.Time) +} diff --git a/interfaces/12-marshaler/main.go b/interfaces/12-marshaler/main.go new file mode 100644 index 0000000..985fc12 --- /dev/null +++ b/interfaces/12-marshaler/main.go @@ -0,0 +1,21 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import ( + "fmt" +) + +func main() { + // removed error handling for brevity (normally you shouldn't do this). + out, _ := encode() + fmt.Println(string(out)) + + l, _ := decode(out) + fmt.Print(l) +} diff --git a/interfaces/12-reflection/money.go b/interfaces/12-marshaler/money.go similarity index 100% rename from interfaces/12-reflection/money.go rename to interfaces/12-marshaler/money.go diff --git a/interfaces/12-marshaler/product.go b/interfaces/12-marshaler/product.go new file mode 100644 index 0000000..356b0d7 --- /dev/null +++ b/interfaces/12-marshaler/product.go @@ -0,0 +1,26 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import ( + "fmt" +) + +type product struct { + Title string `json:"title"` + Price money `json:"price"` + Released timestamp `json:"released,omitempty"` +} + +func (p *product) String() string { + return fmt.Sprintf("%s: %s (%s)", p.Title, p.Price, p.Released) +} + +func (p *product) discount(ratio float64) { + p.Price *= money(1 - ratio) +} diff --git a/interfaces/12-marshaler/timestamp.go b/interfaces/12-marshaler/timestamp.go new file mode 100644 index 0000000..ebc9c0a --- /dev/null +++ b/interfaces/12-marshaler/timestamp.go @@ -0,0 +1,57 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import ( + "strconv" + "time" +) + +type timestamp struct { + time.Time +} + +func (ts timestamp) String() string { + if ts.IsZero() { + return "unknown" + } + + // Mon Jan 2 15:04:05 -0700 MST 2006 + const layout = "2006/01" + return ts.Format(layout) +} + +// timestamp knows how to decode itself from json. +// UnmarshalJSON is an implementation of the json.Unmarshaler interface. +// json.Unmarshal and json.Decode call this method. +func (ts *timestamp) UnmarshalJSON(data []byte) error { + *ts = toTimestamp(string(data)) + return nil +} + +// timestamp knows how to encode itself to json. +// MarshalJSON is an implementation of the json.Marshaler interface. +// json.Marshal and json.Encode call this method. +func (ts timestamp) MarshalJSON() (out []byte, err error) { + // return ts.Time.MarshalJSON() + return strconv.AppendInt(out, ts.Unix(), 10), nil +} + +func toTimestamp(v interface{}) (ts timestamp) { + var t int + + switch v := v.(type) { + case int: + t = v + case string: + t, _ = strconv.Atoi(v) + } + + ts.Time = time.Unix(int64(t), 0) + return ts +} diff --git a/interfaces/13-io/database.json b/interfaces/13-io/database.json new file mode 100644 index 0000000..8a3df19 --- /dev/null +++ b/interfaces/13-io/database.json @@ -0,0 +1,17 @@ +[ + { + "title": "moby dick", + "price": 10, + "released": 118281600 + }, + { + "title": "odyssey", + "price": 15, + "released": 733622400 + }, + { + "title": "hobbit", + "price": 25, + "released": -62135596800 + } +] \ No newline at end of file diff --git a/interfaces/13-io/json.go b/interfaces/13-io/json.go new file mode 100644 index 0000000..7507c96 --- /dev/null +++ b/interfaces/13-io/json.go @@ -0,0 +1,59 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import ( + "encoding/json" + "io" + "io/ioutil" + "os" +) + +func encode() ([]byte, error) { + l := list{ + {Title: "moby dick", Price: 10, Released: toTimestamp(118281600)}, + {Title: "odyssey", Price: 15, Released: toTimestamp("733622400")}, + {Title: "hobbit", Price: 25}, + } + + return json.MarshalIndent(l, "", "\t") +} + +func decode(data []byte) (l list, err error) { + if err := json.Unmarshal(data, &l); err != nil { + return nil, err + } + return l, nil +} + +func decodeFile(path string) (list, error) { + // ReadAll reads entire bytes from a file to memory. + data, err := ioutil.ReadFile(path) + if err != nil { + return nil, err + } + return decode(data) +} + +func decodeFileObject(f *os.File) (list, error) { + data, err := ioutil.ReadAll(f) + if err != nil { + return nil, err + } + return decode(data) +} + +func decodeReader(r io.Reader) (l list, err error) { + // data, err := ioutil.ReadAll(r) + // if err != nil { + // return nil, err + // } + // return decode(data) + + return l, json.NewDecoder(r).Decode(&l) +} diff --git a/interfaces/13-io/list.go b/interfaces/13-io/list.go new file mode 100644 index 0000000..c0787f4 --- /dev/null +++ b/interfaces/13-io/list.go @@ -0,0 +1,49 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import ( + "fmt" + "sort" + "strings" +) + +type list []*product + +func (l list) String() string { + if len(l) == 0 { + return "Sorry. We're waiting for delivery 🚚.\n" + } + + sort.Sort(l) + var str strings.Builder + for _, p := range l { + fmt.Fprintf(&str, "* %s\n", p) + } + return str.String() +} + +func (l list) discount(ratio float64) { + for _, p := range l { + p.discount(ratio) + } +} + +// by default `list` sorts by `Title`. +func (l list) Len() int { return len(l) } +func (l list) Swap(i, j int) { l[i], l[j] = l[j], l[i] } +func (l list) Less(i, j int) bool { return l[i].Title < l[j].Title } + +// byRelease sorts by product release dates. +type byRelease struct { + list +} + +func (bp byRelease) Less(i, j int) bool { + return bp.list[i].Released.Before(bp.list[j].Released.Time) +} diff --git a/interfaces/13-io/main.go b/interfaces/13-io/main.go new file mode 100644 index 0000000..10157c6 --- /dev/null +++ b/interfaces/13-io/main.go @@ -0,0 +1,47 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +func main() { + // removed error handling for brevity (normally you shouldn't do this). + + // encode to memory (to a byte slice) + // out, _ := encode() + // fmt.Println(string(out)) + + // read from memory (from a byte slice): + // l, _ := decode(out) + + // read from a file by name: + // l, _ := decodeFile("database.json") + + // read from a file #1 (not good): + // f, _ := os.Open("database.json") + // l, _ := decodeFileObject(f) + // f.Close() + + // read from a file #2 (better): + // f, _ := os.Open("database.json") + // l, _ := decodeReader(f) + // f.Close() + + // read from memory (from a string): + // const data = `[ + // { "title": "moby dick", "price": 10, "released": 118281600 }, + // { "title": "odyssey", "price": 15, "released": 733622400 }, + // { "title": "hobbit", "price": 25, "released": -62135596800 } + // ]` + // l, _ := decodeReader(strings.NewReader(data)) + + // read from inanc's web server: + // res, _ := http.Get("https://inancgumus.github.io/x/database.json") + // l, _ := decodeReader(res.Body) + // res.Body.Close() + + // fmt.Print(l) +} diff --git a/interfaces/13-reflection-2/money.go b/interfaces/13-io/money.go similarity index 100% rename from interfaces/13-reflection-2/money.go rename to interfaces/13-io/money.go diff --git a/interfaces/13-io/product.go b/interfaces/13-io/product.go new file mode 100644 index 0000000..356b0d7 --- /dev/null +++ b/interfaces/13-io/product.go @@ -0,0 +1,26 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import ( + "fmt" +) + +type product struct { + Title string `json:"title"` + Price money `json:"price"` + Released timestamp `json:"released,omitempty"` +} + +func (p *product) String() string { + return fmt.Sprintf("%s: %s (%s)", p.Title, p.Price, p.Released) +} + +func (p *product) discount(ratio float64) { + p.Price *= money(1 - ratio) +} diff --git a/interfaces/13-io/timestamp.go b/interfaces/13-io/timestamp.go new file mode 100644 index 0000000..940fc11 --- /dev/null +++ b/interfaces/13-io/timestamp.go @@ -0,0 +1,50 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import ( + "strconv" + "time" +) + +type timestamp struct { + time.Time +} + +func (ts timestamp) String() string { + if ts.IsZero() { + return "unknown" + } + + // Mon Jan 2 15:04:05 -0700 MST 2006 + const layout = "2006/01" + return ts.Format(layout) +} + +func (ts *timestamp) UnmarshalJSON(data []byte) error { + *ts = toTimestamp(string(data)) + return nil +} + +func (ts timestamp) MarshalJSON() (out []byte, err error) { + return strconv.AppendInt(out, ts.Unix(), 10), nil +} + +func toTimestamp(v interface{}) (ts timestamp) { + var t int + + switch v := v.(type) { + case int: + t = v + case string: + t, _ = strconv.Atoi(v) + } + + ts.Time = time.Unix(int64(t), 0) + return ts +} diff --git a/interfaces/14-composition/database.json b/interfaces/14-composition/database.json new file mode 100644 index 0000000..8a3df19 --- /dev/null +++ b/interfaces/14-composition/database.json @@ -0,0 +1,17 @@ +[ + { + "title": "moby dick", + "price": 10, + "released": 118281600 + }, + { + "title": "odyssey", + "price": 15, + "released": 733622400 + }, + { + "title": "hobbit", + "price": 25, + "released": -62135596800 + } +] \ No newline at end of file diff --git a/interfaces/14-composition/database.json.gz b/interfaces/14-composition/database.json.gz new file mode 100644 index 0000000..90b2e42 Binary files /dev/null and b/interfaces/14-composition/database.json.gz differ diff --git a/interfaces/14-composition/json.go b/interfaces/14-composition/json.go new file mode 100644 index 0000000..7507c96 --- /dev/null +++ b/interfaces/14-composition/json.go @@ -0,0 +1,59 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import ( + "encoding/json" + "io" + "io/ioutil" + "os" +) + +func encode() ([]byte, error) { + l := list{ + {Title: "moby dick", Price: 10, Released: toTimestamp(118281600)}, + {Title: "odyssey", Price: 15, Released: toTimestamp("733622400")}, + {Title: "hobbit", Price: 25}, + } + + return json.MarshalIndent(l, "", "\t") +} + +func decode(data []byte) (l list, err error) { + if err := json.Unmarshal(data, &l); err != nil { + return nil, err + } + return l, nil +} + +func decodeFile(path string) (list, error) { + // ReadAll reads entire bytes from a file to memory. + data, err := ioutil.ReadFile(path) + if err != nil { + return nil, err + } + return decode(data) +} + +func decodeFileObject(f *os.File) (list, error) { + data, err := ioutil.ReadAll(f) + if err != nil { + return nil, err + } + return decode(data) +} + +func decodeReader(r io.Reader) (l list, err error) { + // data, err := ioutil.ReadAll(r) + // if err != nil { + // return nil, err + // } + // return decode(data) + + return l, json.NewDecoder(r).Decode(&l) +} diff --git a/interfaces/14-composition/list.go b/interfaces/14-composition/list.go new file mode 100644 index 0000000..c0787f4 --- /dev/null +++ b/interfaces/14-composition/list.go @@ -0,0 +1,49 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import ( + "fmt" + "sort" + "strings" +) + +type list []*product + +func (l list) String() string { + if len(l) == 0 { + return "Sorry. We're waiting for delivery 🚚.\n" + } + + sort.Sort(l) + var str strings.Builder + for _, p := range l { + fmt.Fprintf(&str, "* %s\n", p) + } + return str.String() +} + +func (l list) discount(ratio float64) { + for _, p := range l { + p.discount(ratio) + } +} + +// by default `list` sorts by `Title`. +func (l list) Len() int { return len(l) } +func (l list) Swap(i, j int) { l[i], l[j] = l[j], l[i] } +func (l list) Less(i, j int) bool { return l[i].Title < l[j].Title } + +// byRelease sorts by product release dates. +type byRelease struct { + list +} + +func (bp byRelease) Less(i, j int) bool { + return bp.list[i].Released.Before(bp.list[j].Released.Time) +} diff --git a/interfaces/14-composition/main.go b/interfaces/14-composition/main.go new file mode 100644 index 0000000..441dbf2 --- /dev/null +++ b/interfaces/14-composition/main.go @@ -0,0 +1,82 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +// compress in bash: +// gzip -k database.json + +func main() { + // removed error handling and x.Close() calls for brevity (normally you shouldn't do this). + // normally: fr.Close(), gr.Close() should also be called to release the resources. + + // data, _ := ioutil.ReadFile("database.json") + // l, _ := decode(data) + + // fmt.Print(string(data)) + // fmt.Print(l) + + // --- + + // fr, _ := os.Open("database.json") + // tr := TeeReader(fr, os.Stdout) + // l, _ := decodeReader(tr) + // fmt.Print(l) + + // --- + + // fr, _ := os.Open("database.json.gz") + // gr, _ := gzip.NewReader(fr) + // tr := TeeReader(gr, os.Stdout) + // l, _ := decodeReader(tr) + // fmt.Print(l) + + // --- + + // TODO: FIX + // l, err := decodeGzip("database.json.gz", os.Stdout) + // l, err := decodeGzip("database.json.gz", ioutil.Discard) + // if err != nil { + // log.Fatalln(err) + // } + // fmt.Print("Products:\n", l) +} + +// func decodeGzipFile(path string) (list, error) { +// fr, err := os.Open("database.json.gz") +// if err != nil { +// return nil, err +// } +// defer fr.Close() + +// return decodeGzip(fr) +// } + +// func decodeGzip(r io.Reader, w io.Writer) (list, error) { +// fr, err := os.Open("database.json.gz") +// if err != nil { +// return nil, err +// } + +// gr, err := gzip.NewReader(fr) +// if err != nil { +// fr.Close() +// return nil, err +// } + +// tr := TeeReader(gr, w) +// l, err := decodeReader(tr) +// if err != nil { +// fr.Close() +// gr.Close() +// return nil, err +// } + +// fr.Close() +// gr.Close() +// return l, nil +// } diff --git a/interfaces/14-io-reader/money.go b/interfaces/14-composition/money.go similarity index 100% rename from interfaces/14-io-reader/money.go rename to interfaces/14-composition/money.go diff --git a/interfaces/14-composition/product.go b/interfaces/14-composition/product.go new file mode 100644 index 0000000..356b0d7 --- /dev/null +++ b/interfaces/14-composition/product.go @@ -0,0 +1,26 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import ( + "fmt" +) + +type product struct { + Title string `json:"title"` + Price money `json:"price"` + Released timestamp `json:"released,omitempty"` +} + +func (p *product) String() string { + return fmt.Sprintf("%s: %s (%s)", p.Title, p.Price, p.Released) +} + +func (p *product) discount(ratio float64) { + p.Price *= money(1 - ratio) +} diff --git a/interfaces/14-composition/tee.go b/interfaces/14-composition/tee.go new file mode 100644 index 0000000..f01bbcd --- /dev/null +++ b/interfaces/14-composition/tee.go @@ -0,0 +1,34 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import "io" + +// TeeReader returns a Reader that writes to w what it reads from r. +// All reads from r performed through it are matched with +// corresponding writes to w. There is no internal buffering - +// the write must complete before the read completes. +// Any error encountered while writing is reported as a read error. +func TeeReader(r io.Reader, w io.Writer) io.Reader { + return &teeReader{r, w} +} + +type teeReader struct { + r io.Reader + w io.Writer +} + +func (t *teeReader) Read(p []byte) (n int, err error) { + n, err = t.r.Read(p) + if n > 0 { + if n, err := t.w.Write(p[:n]); err != nil { + return n, err + } + } + return +} diff --git a/interfaces/14-composition/timestamp.go b/interfaces/14-composition/timestamp.go new file mode 100644 index 0000000..940fc11 --- /dev/null +++ b/interfaces/14-composition/timestamp.go @@ -0,0 +1,50 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import ( + "strconv" + "time" +) + +type timestamp struct { + time.Time +} + +func (ts timestamp) String() string { + if ts.IsZero() { + return "unknown" + } + + // Mon Jan 2 15:04:05 -0700 MST 2006 + const layout = "2006/01" + return ts.Format(layout) +} + +func (ts *timestamp) UnmarshalJSON(data []byte) error { + *ts = toTimestamp(string(data)) + return nil +} + +func (ts timestamp) MarshalJSON() (out []byte, err error) { + return strconv.AppendInt(out, ts.Unix(), 10), nil +} + +func toTimestamp(v interface{}) (ts timestamp) { + var t int + + switch v := v.(type) { + case int: + t = v + case string: + t, _ = strconv.Atoi(v) + } + + ts.Time = time.Unix(int64(t), 0) + return ts +} diff --git a/interfaces/_old/09-stringer/_handlemethods.go b/interfaces/_old/09-stringer/_handlemethods.go new file mode 100644 index 0000000..e6f362b --- /dev/null +++ b/interfaces/_old/09-stringer/_handlemethods.go @@ -0,0 +1,46 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +// In the depths of the Go standard library's fmt package... +// Printing functions use the handleMethods method. + +// Example: +// var pocket money = 10 +// fmt.Println(pocket) + +// the argument can be any type of value +// stores the pocket variable in the argument variable +// ^ +// | +func (p *pp) handleMethods(argument interface{}) (handled bool) { + // ... + + // Checks whether a given argument is an error or an fmt.Stringer + switch v := argument.(type) { + // ... + // If the argument is a Stringer, calls its String() method + case Stringer: + // ... + // pocket.String() + // ^ + // | + p.fmtString(v.String(), verb) + return + } + + // ... +} + +/* +The original `handleMethods` code is more involved: + +https://github.com/golang/go/blob/6f51082da77a1d4cafd5b7af0db69293943f4066/src/fmt/print.go#L574 + + -> 574#handleMethods(..) + -> 627#Stringer type check: If `v` is a Stringer, run: + -> 630#v.String() +*/ \ No newline at end of file diff --git a/interfaces/09-stringer/book.go b/interfaces/_old/09-stringer/book.go similarity index 100% rename from interfaces/09-stringer/book.go rename to interfaces/_old/09-stringer/book.go diff --git a/interfaces/09-stringer/game.go b/interfaces/_old/09-stringer/game.go similarity index 100% rename from interfaces/09-stringer/game.go rename to interfaces/_old/09-stringer/game.go diff --git a/interfaces/09-stringer/list.go b/interfaces/_old/09-stringer/list.go similarity index 100% rename from interfaces/09-stringer/list.go rename to interfaces/_old/09-stringer/list.go diff --git a/interfaces/09-stringer/main.go b/interfaces/_old/09-stringer/main.go similarity index 100% rename from interfaces/09-stringer/main.go rename to interfaces/_old/09-stringer/main.go diff --git a/interfaces/09-stringer/money.go b/interfaces/_old/09-stringer/money.go similarity index 100% rename from interfaces/09-stringer/money.go rename to interfaces/_old/09-stringer/money.go diff --git a/interfaces/09-stringer/product.go b/interfaces/_old/09-stringer/product.go similarity index 100% rename from interfaces/09-stringer/product.go rename to interfaces/_old/09-stringer/product.go diff --git a/interfaces/09-stringer/puzzle.go b/interfaces/_old/09-stringer/puzzle.go similarity index 100% rename from interfaces/09-stringer/puzzle.go rename to interfaces/_old/09-stringer/puzzle.go diff --git a/interfaces/09-stringer/timestamp.go b/interfaces/_old/09-stringer/timestamp.go similarity index 100% rename from interfaces/09-stringer/timestamp.go rename to interfaces/_old/09-stringer/timestamp.go diff --git a/interfaces/09-stringer/toy.go b/interfaces/_old/09-stringer/toy.go similarity index 100% rename from interfaces/09-stringer/toy.go rename to interfaces/_old/09-stringer/toy.go diff --git a/interfaces/10-marshaler/book.go b/interfaces/_old/10-marshaler/book.go similarity index 100% rename from interfaces/10-marshaler/book.go rename to interfaces/_old/10-marshaler/book.go diff --git a/interfaces/10-marshaler/game.go b/interfaces/_old/10-marshaler/game.go similarity index 100% rename from interfaces/10-marshaler/game.go rename to interfaces/_old/10-marshaler/game.go diff --git a/interfaces/10-marshaler/list.go b/interfaces/_old/10-marshaler/list.go similarity index 100% rename from interfaces/10-marshaler/list.go rename to interfaces/_old/10-marshaler/list.go diff --git a/interfaces/10-marshaler/main.go b/interfaces/_old/10-marshaler/main.go similarity index 100% rename from interfaces/10-marshaler/main.go rename to interfaces/_old/10-marshaler/main.go diff --git a/interfaces/15-io-reader-composition/money.go b/interfaces/_old/10-marshaler/money.go similarity index 100% rename from interfaces/15-io-reader-composition/money.go rename to interfaces/_old/10-marshaler/money.go diff --git a/interfaces/10-marshaler/product.go b/interfaces/_old/10-marshaler/product.go similarity index 100% rename from interfaces/10-marshaler/product.go rename to interfaces/_old/10-marshaler/product.go diff --git a/interfaces/10-marshaler/puzzle.go b/interfaces/_old/10-marshaler/puzzle.go similarity index 100% rename from interfaces/10-marshaler/puzzle.go rename to interfaces/_old/10-marshaler/puzzle.go diff --git a/interfaces/10-marshaler/timestamp.go b/interfaces/_old/10-marshaler/timestamp.go similarity index 100% rename from interfaces/10-marshaler/timestamp.go rename to interfaces/_old/10-marshaler/timestamp.go diff --git a/interfaces/10-marshaler/toy.go b/interfaces/_old/10-marshaler/toy.go similarity index 100% rename from interfaces/10-marshaler/toy.go rename to interfaces/_old/10-marshaler/toy.go diff --git a/interfaces/11-decode-toiface/book.go b/interfaces/_old/11-decode-toiface/book.go similarity index 100% rename from interfaces/11-decode-toiface/book.go rename to interfaces/_old/11-decode-toiface/book.go diff --git a/interfaces/11-decode-toiface/database.go b/interfaces/_old/11-decode-toiface/database.go similarity index 100% rename from interfaces/11-decode-toiface/database.go rename to interfaces/_old/11-decode-toiface/database.go diff --git a/interfaces/11-decode-toiface/database.json b/interfaces/_old/11-decode-toiface/database.json similarity index 100% rename from interfaces/11-decode-toiface/database.json rename to interfaces/_old/11-decode-toiface/database.json diff --git a/interfaces/11-decode-toiface/game.go b/interfaces/_old/11-decode-toiface/game.go similarity index 100% rename from interfaces/11-decode-toiface/game.go rename to interfaces/_old/11-decode-toiface/game.go diff --git a/interfaces/11-decode-toiface/list.go b/interfaces/_old/11-decode-toiface/list.go similarity index 100% rename from interfaces/11-decode-toiface/list.go rename to interfaces/_old/11-decode-toiface/list.go diff --git a/interfaces/11-decode-toiface/main.go b/interfaces/_old/11-decode-toiface/main.go similarity index 100% rename from interfaces/11-decode-toiface/main.go rename to interfaces/_old/11-decode-toiface/main.go diff --git a/interfaces/composition/money.go b/interfaces/_old/11-decode-toiface/money.go similarity index 100% rename from interfaces/composition/money.go rename to interfaces/_old/11-decode-toiface/money.go diff --git a/interfaces/11-decode-toiface/product.go b/interfaces/_old/11-decode-toiface/product.go similarity index 100% rename from interfaces/11-decode-toiface/product.go rename to interfaces/_old/11-decode-toiface/product.go diff --git a/interfaces/11-decode-toiface/puzzle.go b/interfaces/_old/11-decode-toiface/puzzle.go similarity index 100% rename from interfaces/11-decode-toiface/puzzle.go rename to interfaces/_old/11-decode-toiface/puzzle.go diff --git a/interfaces/11-decode-toiface/timestamp.go b/interfaces/_old/11-decode-toiface/timestamp.go similarity index 100% rename from interfaces/11-decode-toiface/timestamp.go rename to interfaces/_old/11-decode-toiface/timestamp.go diff --git a/interfaces/11-decode-toiface/toy.go b/interfaces/_old/11-decode-toiface/toy.go similarity index 100% rename from interfaces/11-decode-toiface/toy.go rename to interfaces/_old/11-decode-toiface/toy.go diff --git a/interfaces/12-reflection/book.go b/interfaces/_old/12-reflection/book.go similarity index 100% rename from interfaces/12-reflection/book.go rename to interfaces/_old/12-reflection/book.go diff --git a/interfaces/12-reflection/database.go b/interfaces/_old/12-reflection/database.go similarity index 100% rename from interfaces/12-reflection/database.go rename to interfaces/_old/12-reflection/database.go diff --git a/interfaces/12-reflection/database.json b/interfaces/_old/12-reflection/database.json similarity index 100% rename from interfaces/12-reflection/database.json rename to interfaces/_old/12-reflection/database.json diff --git a/interfaces/12-reflection/game.go b/interfaces/_old/12-reflection/game.go similarity index 100% rename from interfaces/12-reflection/game.go rename to interfaces/_old/12-reflection/game.go diff --git a/interfaces/12-reflection/list.go b/interfaces/_old/12-reflection/list.go similarity index 100% rename from interfaces/12-reflection/list.go rename to interfaces/_old/12-reflection/list.go diff --git a/interfaces/12-reflection/main.go b/interfaces/_old/12-reflection/main.go similarity index 100% rename from interfaces/12-reflection/main.go rename to interfaces/_old/12-reflection/main.go diff --git a/interfaces/composition/puzzle.go b/interfaces/_old/12-reflection/money.go similarity index 67% rename from interfaces/composition/puzzle.go rename to interfaces/_old/12-reflection/money.go index acbaa47..095a039 100644 --- a/interfaces/composition/puzzle.go +++ b/interfaces/_old/12-reflection/money.go @@ -7,6 +7,10 @@ package main -type puzzle struct { - product +import "fmt" + +type money float64 + +func (m money) String() string { + return fmt.Sprintf("$%.2f", m) } diff --git a/interfaces/12-reflection/product.go b/interfaces/_old/12-reflection/product.go similarity index 100% rename from interfaces/12-reflection/product.go rename to interfaces/_old/12-reflection/product.go diff --git a/interfaces/12-reflection/puzzle.go b/interfaces/_old/12-reflection/puzzle.go similarity index 100% rename from interfaces/12-reflection/puzzle.go rename to interfaces/_old/12-reflection/puzzle.go diff --git a/interfaces/12-reflection/timestamp.go b/interfaces/_old/12-reflection/timestamp.go similarity index 100% rename from interfaces/12-reflection/timestamp.go rename to interfaces/_old/12-reflection/timestamp.go diff --git a/interfaces/12-reflection/toy.go b/interfaces/_old/12-reflection/toy.go similarity index 100% rename from interfaces/12-reflection/toy.go rename to interfaces/_old/12-reflection/toy.go diff --git a/interfaces/13-reflection-2/book.go b/interfaces/_old/13-reflection-2/book.go similarity index 100% rename from interfaces/13-reflection-2/book.go rename to interfaces/_old/13-reflection-2/book.go diff --git a/interfaces/13-reflection-2/database.go b/interfaces/_old/13-reflection-2/database.go similarity index 100% rename from interfaces/13-reflection-2/database.go rename to interfaces/_old/13-reflection-2/database.go diff --git a/interfaces/13-reflection-2/database.json b/interfaces/_old/13-reflection-2/database.json similarity index 100% rename from interfaces/13-reflection-2/database.json rename to interfaces/_old/13-reflection-2/database.json diff --git a/interfaces/13-reflection-2/game.go b/interfaces/_old/13-reflection-2/game.go similarity index 100% rename from interfaces/13-reflection-2/game.go rename to interfaces/_old/13-reflection-2/game.go diff --git a/interfaces/13-reflection-2/list.go b/interfaces/_old/13-reflection-2/list.go similarity index 100% rename from interfaces/13-reflection-2/list.go rename to interfaces/_old/13-reflection-2/list.go diff --git a/interfaces/13-reflection-2/main.go b/interfaces/_old/13-reflection-2/main.go similarity index 100% rename from interfaces/13-reflection-2/main.go rename to interfaces/_old/13-reflection-2/main.go diff --git a/interfaces/composition/toy.go b/interfaces/_old/13-reflection-2/money.go similarity index 67% rename from interfaces/composition/toy.go rename to interfaces/_old/13-reflection-2/money.go index ab5613d..095a039 100644 --- a/interfaces/composition/toy.go +++ b/interfaces/_old/13-reflection-2/money.go @@ -7,6 +7,10 @@ package main -type toy struct { - product +import "fmt" + +type money float64 + +func (m money) String() string { + return fmt.Sprintf("$%.2f", m) } diff --git a/interfaces/13-reflection-2/product.go b/interfaces/_old/13-reflection-2/product.go similarity index 100% rename from interfaces/13-reflection-2/product.go rename to interfaces/_old/13-reflection-2/product.go diff --git a/interfaces/13-reflection-2/puzzle.go b/interfaces/_old/13-reflection-2/puzzle.go similarity index 100% rename from interfaces/13-reflection-2/puzzle.go rename to interfaces/_old/13-reflection-2/puzzle.go diff --git a/interfaces/13-reflection-2/timestamp.go b/interfaces/_old/13-reflection-2/timestamp.go similarity index 100% rename from interfaces/13-reflection-2/timestamp.go rename to interfaces/_old/13-reflection-2/timestamp.go diff --git a/interfaces/13-reflection-2/toy.go b/interfaces/_old/13-reflection-2/toy.go similarity index 100% rename from interfaces/13-reflection-2/toy.go rename to interfaces/_old/13-reflection-2/toy.go diff --git a/interfaces/14-io-reader/book.go b/interfaces/_old/14-io-reader/book.go similarity index 100% rename from interfaces/14-io-reader/book.go rename to interfaces/_old/14-io-reader/book.go diff --git a/interfaces/14-io-reader/database.go b/interfaces/_old/14-io-reader/database.go similarity index 100% rename from interfaces/14-io-reader/database.go rename to interfaces/_old/14-io-reader/database.go diff --git a/interfaces/14-io-reader/database.json b/interfaces/_old/14-io-reader/database.json similarity index 100% rename from interfaces/14-io-reader/database.json rename to interfaces/_old/14-io-reader/database.json diff --git a/interfaces/14-io-reader/game.go b/interfaces/_old/14-io-reader/game.go similarity index 100% rename from interfaces/14-io-reader/game.go rename to interfaces/_old/14-io-reader/game.go diff --git a/interfaces/14-io-reader/list.go b/interfaces/_old/14-io-reader/list.go similarity index 100% rename from interfaces/14-io-reader/list.go rename to interfaces/_old/14-io-reader/list.go diff --git a/interfaces/14-io-reader/main.go b/interfaces/_old/14-io-reader/main.go similarity index 100% rename from interfaces/14-io-reader/main.go rename to interfaces/_old/14-io-reader/main.go diff --git a/interfaces/_old/14-io-reader/money.go b/interfaces/_old/14-io-reader/money.go new file mode 100644 index 0000000..095a039 --- /dev/null +++ b/interfaces/_old/14-io-reader/money.go @@ -0,0 +1,16 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import "fmt" + +type money float64 + +func (m money) String() string { + return fmt.Sprintf("$%.2f", m) +} diff --git a/interfaces/14-io-reader/product.go b/interfaces/_old/14-io-reader/product.go similarity index 100% rename from interfaces/14-io-reader/product.go rename to interfaces/_old/14-io-reader/product.go diff --git a/interfaces/14-io-reader/puzzle.go b/interfaces/_old/14-io-reader/puzzle.go similarity index 100% rename from interfaces/14-io-reader/puzzle.go rename to interfaces/_old/14-io-reader/puzzle.go diff --git a/interfaces/14-io-reader/timestamp.go b/interfaces/_old/14-io-reader/timestamp.go similarity index 100% rename from interfaces/14-io-reader/timestamp.go rename to interfaces/_old/14-io-reader/timestamp.go diff --git a/interfaces/14-io-reader/toy.go b/interfaces/_old/14-io-reader/toy.go similarity index 100% rename from interfaces/14-io-reader/toy.go rename to interfaces/_old/14-io-reader/toy.go diff --git a/interfaces/15-io-reader-composition/book.go b/interfaces/_old/15-io-reader-composition/book.go similarity index 100% rename from interfaces/15-io-reader-composition/book.go rename to interfaces/_old/15-io-reader-composition/book.go diff --git a/interfaces/15-io-reader-composition/counter.go b/interfaces/_old/15-io-reader-composition/counter.go similarity index 100% rename from interfaces/15-io-reader-composition/counter.go rename to interfaces/_old/15-io-reader-composition/counter.go diff --git a/interfaces/15-io-reader-composition/database.go b/interfaces/_old/15-io-reader-composition/database.go similarity index 100% rename from interfaces/15-io-reader-composition/database.go rename to interfaces/_old/15-io-reader-composition/database.go diff --git a/interfaces/15-io-reader-composition/database.json b/interfaces/_old/15-io-reader-composition/database.json similarity index 100% rename from interfaces/15-io-reader-composition/database.json rename to interfaces/_old/15-io-reader-composition/database.json diff --git a/interfaces/15-io-reader-composition/database.json.gz b/interfaces/_old/15-io-reader-composition/database.json.gz similarity index 100% rename from interfaces/15-io-reader-composition/database.json.gz rename to interfaces/_old/15-io-reader-composition/database.json.gz diff --git a/interfaces/15-io-reader-composition/game.go b/interfaces/_old/15-io-reader-composition/game.go similarity index 100% rename from interfaces/15-io-reader-composition/game.go rename to interfaces/_old/15-io-reader-composition/game.go diff --git a/interfaces/15-io-reader-composition/list.go b/interfaces/_old/15-io-reader-composition/list.go similarity index 100% rename from interfaces/15-io-reader-composition/list.go rename to interfaces/_old/15-io-reader-composition/list.go diff --git a/interfaces/15-io-reader-composition/main.go b/interfaces/_old/15-io-reader-composition/main.go similarity index 100% rename from interfaces/15-io-reader-composition/main.go rename to interfaces/_old/15-io-reader-composition/main.go diff --git a/interfaces/_old/15-io-reader-composition/money.go b/interfaces/_old/15-io-reader-composition/money.go new file mode 100644 index 0000000..095a039 --- /dev/null +++ b/interfaces/_old/15-io-reader-composition/money.go @@ -0,0 +1,16 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import "fmt" + +type money float64 + +func (m money) String() string { + return fmt.Sprintf("$%.2f", m) +} diff --git a/interfaces/15-io-reader-composition/product.go b/interfaces/_old/15-io-reader-composition/product.go similarity index 100% rename from interfaces/15-io-reader-composition/product.go rename to interfaces/_old/15-io-reader-composition/product.go diff --git a/interfaces/15-io-reader-composition/puzzle.go b/interfaces/_old/15-io-reader-composition/puzzle.go similarity index 100% rename from interfaces/15-io-reader-composition/puzzle.go rename to interfaces/_old/15-io-reader-composition/puzzle.go diff --git a/interfaces/15-io-reader-composition/timestamp.go b/interfaces/_old/15-io-reader-composition/timestamp.go similarity index 100% rename from interfaces/15-io-reader-composition/timestamp.go rename to interfaces/_old/15-io-reader-composition/timestamp.go diff --git a/interfaces/15-io-reader-composition/toy.go b/interfaces/_old/15-io-reader-composition/toy.go similarity index 100% rename from interfaces/15-io-reader-composition/toy.go rename to interfaces/_old/15-io-reader-composition/toy.go diff --git a/interfaces/composition/book.go b/interfaces/composition/book.go deleted file mode 100644 index 75fd437..0000000 --- a/interfaces/composition/book.go +++ /dev/null @@ -1,51 +0,0 @@ -// For more tutorials: https://blog.learngoprogramming.com -// -// Copyright © 2018 Inanc Gumus -// Learn Go Programming Course -// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ -// - -package main - -import ( - "encoding/json" - "fmt" - "strconv" - "time" -) - -type book struct { - product - Published interface{} -} - -func (b *book) String() string { - p := format(b.Published) - return fmt.Sprintf("%s - (%v)", &b.product, p) -} - -func (b *book) MarshalJSON() ([]byte, error) { - type jbook book - - jb := (*jbook)(b) - jb.Published = format(b.Published) - - return json.Marshal(jb) -} - -func format(v interface{}) string { - var t int - - switch v := v.(type) { - case int: - t = v - case string: - t, _ = strconv.Atoi(v) - default: - return "unknown" - } - - const layout = "2006/01" - u := time.Unix(int64(t), 0) - return u.Format(layout) -} diff --git a/interfaces/composition/list.go b/interfaces/composition/list.go deleted file mode 100644 index 39ab0c7..0000000 --- a/interfaces/composition/list.go +++ /dev/null @@ -1,48 +0,0 @@ -// For more tutorials: https://blog.learngoprogramming.com -// -// Copyright © 2018 Inanc Gumus -// Learn Go Programming Course -// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ -// - -package main - -import ( - "fmt" - "strings" -) - -type item interface { - sum() money - discount(ratio float64) - fmt.Stringer // same as: `String() string` -} - -type list []item - -func (l list) String() string { - if len(l) == 0 { - return "Sorry. We're waiting for delivery 🚚." - } - - var str strings.Builder - for _, it := range l { - fmt.Fprintf(&str, "%s\n", it) - } - fmt.Fprintf(&str, "\tTOTAL : $%.2f\n", l.sum()) - - return str.String() -} - -func (l list) sum() (total money) { - for _, it := range l { - total += it.sum() - } - return -} - -func (l list) discount(ratio float64) { - for _, it := range l { - it.discount(ratio) - } -} diff --git a/interfaces/composition/main.go b/interfaces/composition/main.go deleted file mode 100644 index 49b6996..0000000 --- a/interfaces/composition/main.go +++ /dev/null @@ -1,57 +0,0 @@ -// For more tutorials: https://blog.learngoprogramming.com -// -// Copyright © 2018 Inanc Gumus -// Learn Go Programming Course -// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ -// - -package main - -import ( - "encoding/json" - "fmt" -) - -func main() { - store := list{ - &book{product{"moby dick", 10}, 118281600}, - &book{product{"odyssey", 15}, "733622400"}, - &book{product{"hobbit", 25}, nil}, - &puzzle{product{"rubik's cube", 5}}, - &game{product{"minecraft", 20}}, - &game{product{"tetris", 5}}, - &toy{product{"yoda", 150}}, - } - - out, _ := json.MarshalIndent(store, "", "\t") - fmt.Println(string(out)) - - // store.discount(.5) - // fmt.Print(store) - - // var ( - // nilItem item - // nilBook *book - // ) - - // fmt.Println("nilBook ?", nilBook == nil) - // fmt.Println("nilItem?", nilItem == nil) - - // nilItem = nilBook - // fmt.Println("nilItem?", nilItem == nil) - - // books := store[:3] - - // books.discount(.5) - // fmt.Printf("%s\n", store) - - // others := store[3:] - // sort.Sort(byPrice(others)) - // fmt.Printf("\n%s\n", store) - - // store = list{books, others} - // fmt.Printf("\n%s\n", store) - - // // sort.Sort(sort.Reverse(byPrice(store))) - // sort.Sort(byName(store)) -} diff --git a/interfaces/composition/sort.go b/interfaces/composition/sort.go deleted file mode 100644 index 58d358c..0000000 --- a/interfaces/composition/sort.go +++ /dev/null @@ -1,20 +0,0 @@ -// For more tutorials: https://blog.learngoprogramming.com -// -// Copyright © 2018 Inanc Gumus -// Learn Go Programming Course -// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ -// - -package main - -type byPrice list - -func (l byPrice) Less(i, j int) bool { return l[i].sum() < l[j].sum() } -func (l byPrice) Len() int { return len(l) } -func (l byPrice) Swap(i, j int) { l[i], l[j] = l[j], l[i] } - -type byName list - -func (l byName) Less(i, j int) bool { return l[i].String() < l[j].String() } -func (l byName) Len() int { return len(l) } -func (l byName) Swap(i, j int) { l[i], l[j] = l[j], l[i] }