diff --git a/25-functions/exercises/README.md b/25-functions/exercises/README.md new file mode 100644 index 0000000..e91a884 --- /dev/null +++ b/25-functions/exercises/README.md @@ -0,0 +1,9 @@ +# Function Exercises + +1. **[Refactor the Game Store to Funcs - Step #1](https://github.com/inancgumus/learngo/tree/master/25-functions/exercises/refactor-to-funcs-1)** + + Remember the game store program from the structs exercises? Now, it's time to refactor it to funcs. + +2. **[Refactor the Game Store to Funcs - Step #2](https://github.com/inancgumus/learngo/tree/master/25-functions/exercises/refactor-to-funcs-2)** + + Let's continue the refactoring from the previous exercise. This time, you're going to refactor the command handling logic. \ No newline at end of file diff --git a/25-functions/exercises/refactor-to-funcs-1/main.go b/25-functions/exercises/refactor-to-funcs-1/main.go new file mode 100644 index 0000000..5e3ca3c --- /dev/null +++ b/25-functions/exercises/refactor-to-funcs-1/main.go @@ -0,0 +1,150 @@ +// 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/ +// + +// --------------------------------------------------------- +// EXERCISE: Refactor the game store to funcs - step #1 +// +// Remember the game store program from the structs exercises? +// Now, it's time to refactor it to funcs. +// +// Create games.go file +// +// 1- Move the structs there +// +// 2- Add a func that creates and returns a game. +// +// Name : newGame +// Inputs: id, price, name and genre +// Output: game +// +// 3- Add a func that adds a `game` to `[]game` and returns `[]game`: +// +// Name : addGame +// Inputs: []game, game +// Output: []game +// +// 4- Add a func that uses newGame and addGame funcs to load up the game +// store: +// +// Name : load +// Inputs: none +// Output: []game +// +// 5- Add a func that indexes games by ID: +// +// Name : indexByID +// Inputs: []game +// Output: map[int]game +// +// 6- Add a func that prints the given game: +// +// Name : printGame +// Inputs: game +// +// +// Go back to main.go and change the existing code with +// the new funcs that you've created. There are hints +// inside the code. +// +// --------------------------------------------------------- + +package main + +import ( + "bufio" + "fmt" + "os" + "strconv" + "strings" +) + +func main() { + type item struct { + id int + name string + price int + } + + type game struct { + item + genre string + } + + // load() + games := []game{ + { + item: item{id: 1, name: "god of war", price: 50}, + genre: "action adventure", + }, + {item: item{id: 2, name: "x-com 2", price: 40}, genre: "strategy"}, + {item: item{id: 3, name: "minecraft", price: 20}, genre: "sandbox"}, + } + + // indexByID() + byID := make(map[int]game) + for _, g := range games { + byID[g.id] = g + } + + fmt.Printf("Inanc's game store has %d games.\n", len(games)) + + in := bufio.NewScanner(os.Stdin) + for { + fmt.Printf(` + > list : lists all the games + > id N : queries a game by id + > quit : quits + +`) + + if !in.Scan() { + break + } + + fmt.Println() + + cmd := strings.Fields(in.Text()) + if len(cmd) == 0 { + continue + } + + switch cmd[0] { + case "quit": + fmt.Println("bye!") + return + + case "list": + for _, g := range games { + // printGame() + fmt.Printf("#%d: %-15q %-20s $%d\n", + g.id, g.name, "("+g.genre+")", g.price) + } + + case "id": + if len(cmd) != 2 { + fmt.Println("wrong id") + continue + } + + id, err := strconv.Atoi(cmd[1]) + if err != nil { + fmt.Println("wrong id") + continue + } + + g, ok := byID[id] + if !ok { + fmt.Println("sorry. i don't have the game") + continue + } + + // printGame() + fmt.Printf("#%d: %-15q %-20s $%d\n", + g.id, g.name, "("+g.genre+")", g.price) + } + } +} diff --git a/25-functions/exercises/refactor-to-funcs-1/solution/games.go b/25-functions/exercises/refactor-to-funcs-1/solution/games.go new file mode 100644 index 0000000..a62520c --- /dev/null +++ b/25-functions/exercises/refactor-to-funcs-1/solution/games.go @@ -0,0 +1,52 @@ +// 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 item struct { + id int + name string + price int +} + +type game struct { + item + genre string +} + +func load() (games []game) { + games = addGame(games, newGame(1, 50, "god of war", "action adventure")) + games = addGame(games, newGame(2, 40, "x-com 2", "strategy")) + games = addGame(games, newGame(3, 20, "minecraft", "sandbox")) + return +} + +func addGame(games []game, g game) []game { + return append(games, g) +} + +func newGame(id, price int, name, genre string) game { + return game{ + item: item{id: id, name: name, price: price}, + genre: genre, + } +} + +func indexByID(games []game) (byID map[int]game) { + byID = make(map[int]game) + for _, g := range games { + byID[g.id] = g + } + return +} + +func printGame(g game) { + fmt.Printf("#%d: %-15q %-20s $%d\n", + g.id, g.name, "("+g.genre+")", g.price) +} diff --git a/25-functions/exercises/refactor-to-funcs-1/solution/main.go b/25-functions/exercises/refactor-to-funcs-1/solution/main.go new file mode 100644 index 0000000..f184b57 --- /dev/null +++ b/25-functions/exercises/refactor-to-funcs-1/solution/main.go @@ -0,0 +1,75 @@ +// 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 ( + "bufio" + "fmt" + "os" + "strconv" + "strings" +) + +func main() { + games := load() + byID := indexByID(games) + + fmt.Printf("Inanc's game store has %d games.\n", len(games)) + + in := bufio.NewScanner(os.Stdin) + for { + fmt.Printf(` + > list : lists all the games + > id N : queries a game by id + > quit : quits + +`) + + if !in.Scan() { + break + } + + fmt.Println() + + cmd := strings.Fields(in.Text()) + if len(cmd) == 0 { + continue + } + + switch cmd[0] { + case "quit": + fmt.Println("bye!") + return + + case "list": + for _, g := range games { + printGame(g) + } + + case "id": + if len(cmd) != 2 { + fmt.Println("wrong id") + continue + } + + id, err := strconv.Atoi(cmd[1]) + if err != nil { + fmt.Println("wrong id") + continue + } + + g, ok := byID[id] + if !ok { + fmt.Println("sorry. i don't have the game") + continue + } + + printGame(g) + } + } +} diff --git a/25-functions/exercises/refactor-to-funcs-2/games.go b/25-functions/exercises/refactor-to-funcs-2/games.go new file mode 100644 index 0000000..a62520c --- /dev/null +++ b/25-functions/exercises/refactor-to-funcs-2/games.go @@ -0,0 +1,52 @@ +// 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 item struct { + id int + name string + price int +} + +type game struct { + item + genre string +} + +func load() (games []game) { + games = addGame(games, newGame(1, 50, "god of war", "action adventure")) + games = addGame(games, newGame(2, 40, "x-com 2", "strategy")) + games = addGame(games, newGame(3, 20, "minecraft", "sandbox")) + return +} + +func addGame(games []game, g game) []game { + return append(games, g) +} + +func newGame(id, price int, name, genre string) game { + return game{ + item: item{id: id, name: name, price: price}, + genre: genre, + } +} + +func indexByID(games []game) (byID map[int]game) { + byID = make(map[int]game) + for _, g := range games { + byID[g.id] = g + } + return +} + +func printGame(g game) { + fmt.Printf("#%d: %-15q %-20s $%d\n", + g.id, g.name, "("+g.genre+")", g.price) +} diff --git a/25-functions/exercises/refactor-to-funcs-2/main.go b/25-functions/exercises/refactor-to-funcs-2/main.go new file mode 100644 index 0000000..599ed5d --- /dev/null +++ b/25-functions/exercises/refactor-to-funcs-2/main.go @@ -0,0 +1,129 @@ +// 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/ +// + +// --------------------------------------------------------- +// EXERCISE: Refactor the game store to funcs - step #2 +// +// Let's continue the refactoring from the previous +// exercise. This time, you're going to refactor the +// command handling logic. +// +// +// Create commands.go file +// +// 1- Add a func that runs the given command from the user: +// +// Name : runCmd +// Inputs: input string, []game, map[int]game +// Output: bool +// +// This func returns true if it wants the program to +// continue. When it returns false, the program will +// terminate. So, all the commands that it calls need +// to return true or false as well depending on whether +// they want to cause the program to terminate or not. +// +// 2- Add a func that handles the quit command: +// +// Name : cmdQuit +// Input : none +// Output: bool +// +// 3- Add a func that handles the list command: +// +// Name : cmdList +// Inputs: []game +// Output: bool +// +// 4- Add a func that handles the id command: +// +// Name : cmdByID +// Inputs: cmd []string, []game, map[int]game +// Output: bool +// +// 5- Refactor the runCmd() with the cmdXXX funcs. +// +// Go back to main.go and change the existing code with +// the new funcs that you've created. There are hints +// inside the code. +// +// --------------------------------------------------------- + +package main + +import ( + "bufio" + "fmt" + "os" + "strconv" + "strings" +) + +func main() { + games := load() + byID := indexByID(games) + + fmt.Printf("Inanc's game store has %d games.\n", len(games)) + + in := bufio.NewScanner(os.Stdin) + for { + // menu() + fmt.Printf(` + > list : lists all the games + > id N : queries a game by id + > quit : quits + +`) + + if !in.Scan() { + break + } + + // --- runCmd start --- + fmt.Println() + + cmd := strings.Fields(in.Text()) + if len(cmd) == 0 { + continue + } + + switch cmd[0] { + case "quit": + // cmdQuit() + fmt.Println("bye!") + return + + case "list": + // cmdList() + for _, g := range games { + printGame(g) + } + + case "id": + // cmdByID + if len(cmd) != 2 { + fmt.Println("wrong id") + continue + } + + id, err := strconv.Atoi(cmd[1]) + if err != nil { + fmt.Println("wrong id") + continue + } + + g, ok := byID[id] + if !ok { + fmt.Println("sorry. i don't have the game") + continue + } + + printGame(g) + } + // --- runCmd end --- + } +} diff --git a/25-functions/exercises/refactor-to-funcs-2/solution/commands.go b/25-functions/exercises/refactor-to-funcs-2/solution/commands.go new file mode 100644 index 0000000..3e167f6 --- /dev/null +++ b/25-functions/exercises/refactor-to-funcs-2/solution/commands.go @@ -0,0 +1,70 @@ +// 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" + "strconv" + "strings" +) + +func runCmd(input string, games []game, byID map[int]game) bool { + fmt.Println() + + cmd := strings.Fields(input) + if len(cmd) == 0 { + return true + } + + switch cmd[0] { + case "quit": + return cmdQuit() + + case "list": + return cmdList(games) + + case "id": + return cmdByID(cmd, games, byID) + } + return true +} + +func cmdQuit() bool { + fmt.Println("bye!") + return false +} + +func cmdList(games []game) bool { + for _, g := range games { + printGame(g) + } + return true +} + +func cmdByID(cmd []string, games []game, byID map[int]game) bool { + if len(cmd) != 2 { + fmt.Println("wrong id") + return true + } + + id, err := strconv.Atoi(cmd[1]) + if err != nil { + fmt.Println("wrong id") + return true + } + + g, ok := byID[id] + if !ok { + fmt.Println("sorry. i don't have the game") + return true + } + + printGame(g) + + return true +} diff --git a/25-functions/exercises/refactor-to-funcs-2/solution/games.go b/25-functions/exercises/refactor-to-funcs-2/solution/games.go new file mode 100644 index 0000000..a62520c --- /dev/null +++ b/25-functions/exercises/refactor-to-funcs-2/solution/games.go @@ -0,0 +1,52 @@ +// 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 item struct { + id int + name string + price int +} + +type game struct { + item + genre string +} + +func load() (games []game) { + games = addGame(games, newGame(1, 50, "god of war", "action adventure")) + games = addGame(games, newGame(2, 40, "x-com 2", "strategy")) + games = addGame(games, newGame(3, 20, "minecraft", "sandbox")) + return +} + +func addGame(games []game, g game) []game { + return append(games, g) +} + +func newGame(id, price int, name, genre string) game { + return game{ + item: item{id: id, name: name, price: price}, + genre: genre, + } +} + +func indexByID(games []game) (byID map[int]game) { + byID = make(map[int]game) + for _, g := range games { + byID[g.id] = g + } + return +} + +func printGame(g game) { + fmt.Printf("#%d: %-15q %-20s $%d\n", + g.id, g.name, "("+g.genre+")", g.price) +} diff --git a/25-functions/exercises/refactor-to-funcs-2/solution/main.go b/25-functions/exercises/refactor-to-funcs-2/solution/main.go new file mode 100644 index 0000000..a2152ed --- /dev/null +++ b/25-functions/exercises/refactor-to-funcs-2/solution/main.go @@ -0,0 +1,35 @@ +// 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 ( + "bufio" + "fmt" + "os" +) + +func main() { + games := load() + byID := indexByID(games) + + fmt.Printf("Inanc's game store has %d games.\n", len(games)) + + in := bufio.NewScanner(os.Stdin) + for { + fmt.Printf(` + > list : lists all the games + > id N : queries a game by id + > quit : quits + +`) + + if !in.Scan() || !runCmd(in.Text(), games, byID) { + break + } + } +} diff --git a/25-functions/questions/README.md b/25-functions/questions/README.md new file mode 100644 index 0000000..fec8f2b --- /dev/null +++ b/25-functions/questions/README.md @@ -0,0 +1,7 @@ +## ? +1. text *CORRECT* +2. text + +> **1:** +> +