diff --git a/02_package/icomefromalaska/name2.go b/02_package/icomefromalaska/name2.go new file mode 100644 index 00000000..2b2da8e7 --- /dev/null +++ b/02_package/icomefromalaska/name2.go @@ -0,0 +1,4 @@ +package winniepooh + +// MyName will be exported because it starts with a capital letter. +var BearName = "Pooh" diff --git a/02_package/main/main.go b/02_package/main/main.go index b006c629..13ece67c 100644 --- a/02_package/main/main.go +++ b/02_package/main/main.go @@ -3,9 +3,12 @@ package main import ( "fmt" "github.com/GoesToEleven/GolangTraining/02_package/stringutil" + "github.com/GoesToEleven/GolangTraining/02_package/icomefromalaska" + //someAlias "github.com/GoesToEleven/GolangTraining/02_package/icomefromalaska" ) func main() { fmt.Println(stringutil.Reverse("!oG ,olleH")) fmt.Println(stringutil.MyName) + fmt.Println(winniepooh.BearName) } diff --git a/03_variables/03_less-emphasis/07_all-together/variables.go b/03_variables/03_less-emphasis/07_all-together/variables.go index 61cdc6bc..f1118263 100644 --- a/03_variables/03_less-emphasis/07_all-together/variables.go +++ b/03_variables/03_less-emphasis/07_all-together/variables.go @@ -2,14 +2,14 @@ package main import "fmt" -var a = "this is stored in the variable a" // package scope -var b, c string = "stored in b", "stored in c" // package scope -var d string // package scope +var a = "this is stored in the variable a" // package scope +var b, c string = "stored in b", "stored in c" // package scope +var d string // package scope func main() { d = "stored in d" // declaration above; assignment here; package scope - var e = 42 // function scope - subsequent variables have func scope: + var e = 42 // function scope - subsequent variables have func scope: f := 43 g := "stored in g" h, i := "stored in h", "stored in i" diff --git a/04_scope/05_same-package/main.go b/04_scope/05_same-package/main.go index 914d4f85..0c6f0ce2 100644 --- a/04_scope/05_same-package/main.go +++ b/04_scope/05_same-package/main.go @@ -2,7 +2,7 @@ package main import "fmt" -func main(){ +func main() { fmt.Println(x) } diff --git a/05_blank-identifier/02_http-get_example/01_with-error-checking/main.go b/05_blank-identifier/02_http-get_example/01_with-error-checking/main.go index 3f2a664b..5e75b203 100644 --- a/05_blank-identifier/02_http-get_example/01_with-error-checking/main.go +++ b/05_blank-identifier/02_http-get_example/01_with-error-checking/main.go @@ -8,7 +8,7 @@ import ( ) func main() { - res, err := http.Get("http://www.mcleods.com/") + res, err := http.Get("http://www.geekwiseacademy.com/") if err != nil { log.Fatal(err) } diff --git a/05_blank-identifier/02_http-get_example/02_no-error-checking/main.go b/05_blank-identifier/02_http-get_example/02_no-error-checking/main.go index 97dcf97a..aa913b41 100644 --- a/05_blank-identifier/02_http-get_example/02_no-error-checking/main.go +++ b/05_blank-identifier/02_http-get_example/02_no-error-checking/main.go @@ -7,8 +7,8 @@ import ( ) func main() { - res, _ := http.Get("http://www.mcleods.com/") + res, _ := http.Get("http://www.geekwiseacademy.com/") page, _ := ioutil.ReadAll(res.Body) res.Body.Close() fmt.Printf("%s", page) -} +} \ No newline at end of file diff --git a/10_for-loop/07_rune-loop_UTF8/01/main.go b/10_for-loop/07_rune-loop_UTF8/01/main.go index 3ba703bb..e832d128 100644 --- a/10_for-loop/07_rune-loop_UTF8/01/main.go +++ b/10_for-loop/07_rune-loop_UTF8/01/main.go @@ -28,4 +28,4 @@ A byte is 8 bits. []byte deals with bytes, that is, only 1 byte (8 bits) at a time. []int32 allows us to store the value of 4 bytes, that is, 4 bytes * 8 bits per byte = 32 bits. -*/ \ No newline at end of file +*/ diff --git a/14_functions/05_return-naming/main.go b/14_functions/05_return-naming/main.go index a2b78d07..6646b4a7 100644 --- a/14_functions/05_return-naming/main.go +++ b/14_functions/05_return-naming/main.go @@ -18,4 +18,4 @@ Avoid using named returns. Occasionally named returns are useful. Read this article for more information: https://www.goinggo.net/2013/10/functions-and-naked-returns-in-go.html -*/ \ No newline at end of file +*/ diff --git a/14_functions/11_closure/05/main.go b/14_functions/11_closure/05/main.go index 58ac4f48..60a20223 100644 --- a/14_functions/11_closure/05/main.go +++ b/14_functions/11_closure/05/main.go @@ -13,11 +13,11 @@ func wrapper() func() int { func main() { incrementA := wrapper() incrementB := wrapper() - fmt.Println("A:",incrementA()) - fmt.Println("A:",incrementA()) - fmt.Println("B:",incrementB()) - fmt.Println("B:",incrementB()) - fmt.Println("B:",incrementB()) + fmt.Println("A:", incrementA()) + fmt.Println("A:", incrementA()) + fmt.Println("B:", incrementB()) + fmt.Println("B:", incrementB()) + fmt.Println("B:", incrementB()) } /* diff --git a/16_exercise-solutions/03_variadic-greatest/main.go b/16_exercise-solutions/03_variadic-greatest/main.go index 65ecf80e..3784b710 100644 --- a/16_exercise-solutions/03_variadic-greatest/main.go +++ b/16_exercise-solutions/03_variadic-greatest/main.go @@ -44,4 +44,4 @@ if you only have negative numbers you need largest to be something less than zero Thanks to Ricardo G for this code improvement! -*/ \ No newline at end of file +*/ diff --git a/19_map/14_hash-table/03_words-in-buckets/01_slice-bucket/main.go b/19_map/14_hash-table/03_words-in-buckets/01_slice-bucket/main.go index e3e25cee..61a48ef1 100644 --- a/19_map/14_hash-table/03_words-in-buckets/01_slice-bucket/main.go +++ b/19_map/14_hash-table/03_words-in-buckets/01_slice-bucket/main.go @@ -22,10 +22,8 @@ func main() { // Create slice of slice of string to hold slices of words buckets := make([][]string, 12) - - // code here has been updated from the recording - // see below for explanation - + // code here has been updated from the recording + // see below for explanation // Loop over the words for scanner.Scan() { @@ -54,7 +52,6 @@ func hashBucket(word string, buckets int) int { // return len(word) % buckets } - /* UPDATED CODE Up above, the code has been updated from the recording diff --git a/20_struct/00_object-oriented/notes.txt b/20_struct/00_object-oriented/notes.txt index e4ff4ffb..e62344cb 100644 --- a/20_struct/00_object-oriented/notes.txt +++ b/20_struct/00_object-oriented/notes.txt @@ -6,7 +6,7 @@ behavior ("methods") exported / un-exported (2) Reusability -inheritence ("embedded types") +inheritance ("embedded types") (3) Polymorphism interfaces @@ -23,9 +23,9 @@ Classes -- classes hold both: ==== state / data / fields ==== behavior / methods --- Public / private +-- public / private -Inheritence +Inheritance ////////////// In Go: diff --git a/21_interfaces/01_interface/02_interface/main.go b/21_interfaces/01_interface/02_interface/main.go index 226dad9d..ba094e88 100644 --- a/21_interfaces/01_interface/02_interface/main.go +++ b/21_interfaces/01_interface/02_interface/main.go @@ -21,5 +21,6 @@ func info(z shape) { func main() { s := square{10} + fmt.Printf("%T\n",s) info(s) } diff --git a/22_go-routines/06_race-condition/main.go b/22_go-routines/06_race-condition/main.go index a59bbc65..d1b58555 100644 --- a/22_go-routines/06_race-condition/main.go +++ b/22_go-routines/06_race-condition/main.go @@ -19,6 +19,7 @@ func main() { } func incrementor(s string) { + rand.Seed(time.Now().UnixNano()) for i := 0; i < 20; i++ { x := counter x++ diff --git a/22_go-routines/08_atomicity/main.go b/22_go-routines/08_atomicity/main.go index c2ae26a5..bf7211c1 100644 --- a/22_go-routines/08_atomicity/main.go +++ b/22_go-routines/08_atomicity/main.go @@ -23,7 +23,7 @@ func incrementor(s string) { for i := 0; i < 20; i++ { time.Sleep(time.Duration(rand.Intn(3)) * time.Millisecond) atomic.AddInt64(&counter, 1) - fmt.Println(s, i, "Counter:", counter) + fmt.Println(s, i, "Counter:", atomic.LoadInt64(&counter)) // access without race } wg.Done() } diff --git a/22_go-routines/09_channels/04_pass-return-channels/main.go b/22_go-routines/09_channels/04_pass-return-channels/main.go index 00c8b823..1991a245 100644 --- a/22_go-routines/09_channels/04_pass-return-channels/main.go +++ b/22_go-routines/09_channels/04_pass-return-channels/main.go @@ -32,4 +32,4 @@ func puller(c chan int) chan int { close(out) }() return out -} \ No newline at end of file +} diff --git a/22_go-routines/09_channels/05_channel-direction/main.go b/22_go-routines/09_channels/05_channel-direction/main.go index c50009f6..c17700e6 100644 --- a/22_go-routines/09_channels/05_channel-direction/main.go +++ b/22_go-routines/09_channels/05_channel-direction/main.go @@ -38,4 +38,4 @@ func puller(c <-chan int) <-chan int { The optional <- operator specifies the channel direction, send or receive. If no direction is given, the channel is bidirectional. https://golang.org/ref/spec#Channel_types -*/ \ No newline at end of file +*/ diff --git a/22_go-routines/09_channels/06_refactor/main.go b/22_go-routines/09_channels/06_refactor/main.go index c586ddf1..4911a690 100644 --- a/22_go-routines/09_channels/06_refactor/main.go +++ b/22_go-routines/09_channels/06_refactor/main.go @@ -31,4 +31,4 @@ func puller(c <-chan int) <-chan int { close(out) }() return out -} \ No newline at end of file +} diff --git a/22_go-routines/09_channels/07_incrementor/main.go b/22_go-routines/09_channels/07_incrementor/main.go index 91b87523..c858f10f 100644 --- a/22_go-routines/09_channels/07_incrementor/main.go +++ b/22_go-routines/09_channels/07_incrementor/main.go @@ -35,4 +35,4 @@ func puller(c chan int) chan int { close(out) }() return out -} \ No newline at end of file +} diff --git a/22_go-routines/12_channels_pipeline/02_sq-output/main.go b/22_go-routines/12_channels_pipeline/02_sq-output/main.go index 56e51b0d..5fb779b6 100644 --- a/22_go-routines/12_channels_pipeline/02_sq-output/main.go +++ b/22_go-routines/12_channels_pipeline/02_sq-output/main.go @@ -9,9 +9,6 @@ func main() { } } - - - func gen(nums ...int) chan int { out := make(chan int) go func() { diff --git a/22_go-routines/12_channels_pipeline/04_challenge-solution/main.go b/22_go-routines/12_channels_pipeline/04_challenge-solution/01_original-solution/main.go similarity index 100% rename from 22_go-routines/12_channels_pipeline/04_challenge-solution/main.go rename to 22_go-routines/12_channels_pipeline/04_challenge-solution/01_original-solution/main.go diff --git a/22_go-routines/12_channels_pipeline/04_challenge-solution/02_another-solution/main.go b/22_go-routines/12_channels_pipeline/04_challenge-solution/02_another-solution/main.go new file mode 100644 index 00000000..c9a7592e --- /dev/null +++ b/22_go-routines/12_channels_pipeline/04_challenge-solution/02_another-solution/main.go @@ -0,0 +1,45 @@ +package main + +import ( + "fmt" + "math/rand" + "sync" +) + +const numFactorials = 100 +const rdLimit = 20 + +func main() { + var w sync.WaitGroup + w.Add(numFactorials) + factorial(&w) + w.Wait() + +} + +func factorial(wmain *sync.WaitGroup) { + var w sync.WaitGroup + rand.Seed(42) + + w.Add(numFactorials + 1) + + for j := 1; j <= numFactorials; j++ { + + go func() { + f := rand.Intn(rdLimit) + w.Wait() + total := 1 + for i := f; i > 0; i-- { + + total *= i + } + fmt.Println(f, total) + (*wmain).Done() + //out <- total + + }() + w.Done() + } + fmt.Println("All done with initialization") + w.Done() +} \ No newline at end of file diff --git a/22_go-routines/12_channels_pipeline/04_challenge-solution/README.md b/22_go-routines/12_channels_pipeline/04_challenge-solution/README.md new file mode 100644 index 00000000..8589eeda --- /dev/null +++ b/22_go-routines/12_channels_pipeline/04_challenge-solution/README.md @@ -0,0 +1,42 @@ +A student sent me the below note so I included the student's excellent solution to this project: + +Todd, I reviewed your solution to 22_go-routines/04_challenge-solution in your Golang Programming class. + +I believe your solution might not run 100 factorial computations concurrently and in parallel as the following statement will calculate the factorials sequentially, since it is receiving them - one by one - from the pipeline: +out <- fact(n) + +I used the sync package to create a solution that I believe will accomplish your goal. Let me know if I am missing something: + +https://github.com/arsanjea/udemyTraining/blob/master/Exercises/exercise38.go + +///// + +# Definitions + +## concurrency +a design pattern +go uses goroutines to create concurrent design patterns + +## parallelism +running code from a program on more than one cpu +parallelism implies you have used concurrent design patterns + +## sequentially +one thing happening after another, in sequence + +# here are my thoughts + +The original solution uses concurrent design patterns. It uses two different goroutines. The [control flow](https://en.wikipedia.org/wiki/Control_flow) of the program is no longer a straight top-to-bottom sequence. Different goroutines have been launched. + +The program may or may not run in parallel. If the program is run on a machine with two or more cpus, the program has the potential to run in parallel. Each of our three goroutines (the two goroutines we launched, and main) could be running on different cpu cores. + +Jean-Marc Arsan is correct: the program IS still running sequentially. Even though calculations are occuring in different goroutines, and potentially on different CPU cores, the sequence in which they occur is still sequential. + +goroutines allow synchronization of code. + +In this original example, the code is synchronized. + +Thank you, Jean-Marc, for your comment on this code! + +I appreciate these discussions and hope the notes and your new code sample are helpful to everyone! + diff --git a/22_go-routines/13_channels_fan-out_fan-in/05_challenge-solution/main.go b/22_go-routines/13_channels_fan-out_fan-in/05_challenge-solution/main.go index aecc5928..b8aee537 100644 --- a/22_go-routines/13_channels_fan-out_fan-in/05_challenge-solution/main.go +++ b/22_go-routines/13_channels_fan-out_fan-in/05_challenge-solution/main.go @@ -3,10 +3,11 @@ package main import ( "fmt" "time" + "sync/atomic" ) -var workerID int -var publisherID int +var workerID int64 +var publisherID int64 func main() { input := make(chan string) @@ -22,8 +23,12 @@ func main() { // publisher pushes data into a channel func publisher(out chan string) { - publisherID++ - thisID := publisherID + atomic.AddInt64(&publisherID, 1) + // atomic was added after recording to fix a race condition + // discover race conditions with the -race flag + // for example: go run -race main.go + // learn about the atomic package: https://godoc.org/sync/atomic#AddInt64 + thisID := atomic.LoadInt64(&publisherID) dataID := 0 for { dataID++ @@ -34,8 +39,12 @@ func publisher(out chan string) { } func workerProcess(in <-chan string) { - workerID++ - thisID := workerID + atomic.AddInt64(&workerID, 1) + // atomic was added after recording to fix a race condition + // discover race conditions with the -race flag + // for example: go run -race main.go + // learn about the atomic package: https://godoc.org/sync/atomic#AddInt64 + thisID := atomic.LoadInt64(&workerID) for { fmt.Printf("%d: waiting for input...\n", thisID) input := <-in diff --git a/22_go-routines/13_channels_fan-out_fan-in/10_van-sickle_fan-out_fan-in/main.go b/22_go-routines/13_channels_fan-out_fan-in/10_van-sickle_fan-out_fan-in/main.go index 98e3aa5c..d734b471 100644 --- a/22_go-routines/13_channels_fan-out_fan-in/10_van-sickle_fan-out_fan-in/main.go +++ b/22_go-routines/13_channels_fan-out_fan-in/10_van-sickle_fan-out_fan-in/main.go @@ -67,4 +67,4 @@ func fact(n int) int { This code was provided by my friend, Mike Van Sickle He is an awesome programmer, an awesome Go programmer, and an awesome teacher Check out his courses on pluralsight to learn more about Go! -*/ \ No newline at end of file +*/ diff --git a/22_go-routines/15_for-fun/01/main.go b/22_go-routines/15_for-fun/01/main.go new file mode 100644 index 00000000..b8542f49 --- /dev/null +++ b/22_go-routines/15_for-fun/01/main.go @@ -0,0 +1,40 @@ +package main + +import ( + "fmt" +) + +func main() { + m := map[int]int{} + m[4] = 7 + m[3] = 87 + m[72] = 19 + + ch := make(chan int) + + // for closing ch + ch2 := make(chan int) + go func() { + var i int + for n := range ch2 { + i += n + if i == len(m) { + close(ch) + } + } + }() + + go func() { + for _, v := range m { + ch <- v + ch2 <- 1 + } + }() + + for v := range ch { + fmt.Println(v) + } + + // good housekeeping + close(ch2) +} \ No newline at end of file diff --git a/22_go-routines/15_for-fun/README.md b/22_go-routines/15_for-fun/README.md new file mode 100644 index 00000000..8e256c9b --- /dev/null +++ b/22_go-routines/15_for-fun/README.md @@ -0,0 +1,5 @@ +# New Code + +These files were added into this repo after the training was recorded. + +There are no lectures associated with these files. However, please peruse them and enjoy them! \ No newline at end of file diff --git a/23_error-handling/02_err-not-nil/01_fmt-println/main.go b/23_error-handling/02_err-not-nil/01_fmt-println/main.go index 57c05eb2..e076b8a5 100644 --- a/23_error-handling/02_err-not-nil/01_fmt-println/main.go +++ b/23_error-handling/02_err-not-nil/01_fmt-println/main.go @@ -1,8 +1,8 @@ package main import ( - "os" "fmt" + "os" ) func main() { @@ -11,10 +11,8 @@ func main() { fmt.Println("err happened", err) // log.Println("err happened", err) // log.Fatalln(err) - // panic(err) + // panic(err) } } // Println formats using the default formats for its operands and writes to standard output. - - diff --git a/23_error-handling/02_err-not-nil/02_log-println/main.go b/23_error-handling/02_err-not-nil/02_log-println/main.go index aee07342..f2be7a43 100644 --- a/23_error-handling/02_err-not-nil/02_log-println/main.go +++ b/23_error-handling/02_err-not-nil/02_log-println/main.go @@ -1,8 +1,8 @@ package main import ( - "os" "log" + "os" ) func main() { @@ -11,7 +11,7 @@ func main() { // fmt.Println("err happened", err) log.Println("err happened", err) // log.Fatalln(err) - // panic(err) + // panic(err) } } diff --git a/23_error-handling/02_err-not-nil/03_log-set-output/main.go b/23_error-handling/02_err-not-nil/03_log-set-output/main.go index cfb9f18e..4a054dec 100644 --- a/23_error-handling/02_err-not-nil/03_log-set-output/main.go +++ b/23_error-handling/02_err-not-nil/03_log-set-output/main.go @@ -1,9 +1,9 @@ package main import ( - "os" - "log" "fmt" + "log" + "os" ) func init() { @@ -20,7 +20,7 @@ func main() { // fmt.Println("err happened", err) log.Println("err happened", err) // log.Fatalln(err) - // panic(err) + // panic(err) } } diff --git a/23_error-handling/02_err-not-nil/04_log-fatalln/main.go b/23_error-handling/02_err-not-nil/04_log-fatalln/main.go index 54993aad..c20d1c19 100644 --- a/23_error-handling/02_err-not-nil/04_log-fatalln/main.go +++ b/23_error-handling/02_err-not-nil/04_log-fatalln/main.go @@ -1,8 +1,8 @@ package main import ( - "os" "log" + "os" ) func main() { @@ -11,7 +11,7 @@ func main() { // fmt.Println("err happened", err) // log.Println("err happened", err) log.Fatalln(err) - // panic(err) + // panic(err) } } diff --git a/23_error-handling/02_err-not-nil/05_panic/main.go b/23_error-handling/02_err-not-nil/05_panic/main.go index e75c5544..6108b57d 100644 --- a/23_error-handling/02_err-not-nil/05_panic/main.go +++ b/23_error-handling/02_err-not-nil/05_panic/main.go @@ -10,8 +10,6 @@ func main() { // fmt.Println("err happened", err) // log.Println("err happened", err) // log.Fatalln(err) - panic(err) + panic(err) } } - - diff --git a/23_error-handling/03_custom-errors/01_errors-new/main.go b/23_error-handling/03_custom-errors/01_errors-new/main.go index babc4e62..d7327c18 100644 --- a/23_error-handling/03_custom-errors/01_errors-new/main.go +++ b/23_error-handling/03_custom-errors/01_errors-new/main.go @@ -18,4 +18,4 @@ func Sqrt(f float64) (float64, error) { } // implementation return 42, nil -} \ No newline at end of file +} diff --git a/23_error-handling/03_custom-errors/02_errors-new_var/main.go b/23_error-handling/03_custom-errors/02_errors-new_var/main.go index 28fe0d47..71deea09 100644 --- a/23_error-handling/03_custom-errors/02_errors-new_var/main.go +++ b/23_error-handling/03_custom-errors/02_errors-new_var/main.go @@ -2,8 +2,8 @@ package main import ( "errors" - "log" "fmt" + "log" ) var ErrNorgateMath = errors.New("norgate math: square root of negative number") @@ -27,12 +27,3 @@ func Sqrt(f float64) (float64, error) { // see use of errors.New in standard library: // http://golang.org/src/pkg/bufio/bufio.go // http://golang.org/src/pkg/io/io.go - - - - - - - - - diff --git a/23_error-handling/03_custom-errors/03_fmt-errorf/main.go b/23_error-handling/03_custom-errors/03_fmt-errorf/main.go index 55e67012..47a3bd13 100644 --- a/23_error-handling/03_custom-errors/03_fmt-errorf/main.go +++ b/23_error-handling/03_custom-errors/03_fmt-errorf/main.go @@ -1,8 +1,8 @@ package main import ( - "log" "fmt" + "log" ) func main() { @@ -18,4 +18,4 @@ func Sqrt(f float64) (float64, error) { } // implementation return 42, nil -} \ No newline at end of file +} diff --git a/23_error-handling/03_custom-errors/04_fmt-errorf_var/main.go b/23_error-handling/03_custom-errors/04_fmt-errorf_var/main.go index 25b50a31..fd12405f 100644 --- a/23_error-handling/03_custom-errors/04_fmt-errorf_var/main.go +++ b/23_error-handling/03_custom-errors/04_fmt-errorf_var/main.go @@ -1,8 +1,8 @@ package main import ( - "log" "fmt" + "log" ) func main() { @@ -19,4 +19,4 @@ func Sqrt(f float64) (float64, error) { } // implementation return 42, nil -} \ No newline at end of file +} diff --git a/23_error-handling/03_custom-errors/05_custom-type/main.go b/23_error-handling/03_custom-errors/05_custom-type/main.go index 7cf4b5b7..fc49d209 100644 --- a/23_error-handling/03_custom-errors/05_custom-type/main.go +++ b/23_error-handling/03_custom-errors/05_custom-type/main.go @@ -1,13 +1,13 @@ package main import ( - "log" "fmt" + "log" ) type NorgateMathError struct { - lat, long string - err error + lat, long string + err error } func (n *NorgateMathError) Error() string { diff --git a/24_testing/00_under-development/01/sample.txt b/24_testing/00_under-development/01/sample.txt deleted file mode 100644 index c1460a1d..00000000 --- a/24_testing/00_under-development/01/sample.txt +++ /dev/null @@ -1,29 +0,0 @@ -main.go - -package main - -import "fmt" - -func sup(name string) string { - return "Sup, " + name -} - -func main() { - fmt.Println(sup("Ewan")) -} -Now our tests in, main_test.go - -package main - -import "testing" - -func TestSup(t *testing.T) { - expected := "Sup, Ewan" - outcome := sup("Ewan") - if outcome != expected { - t.Fatalf("Expected %s, got %s", expected, outcome) - } -} -All I do now is run go test and I get... - -http://ewanvalentine.io/why-go-solves-so-many-problems-for-web-developers/?utm_source=golangweekly&utm_medium=email \ No newline at end of file diff --git a/24_testing/math.go b/24_testing/math.go new file mode 100755 index 00000000..6de51307 --- /dev/null +++ b/24_testing/math.go @@ -0,0 +1,9 @@ +package math + +func Adder(xs ...int) int { + res := 0 + for _, v := range xs { + res += v + } + return res +} diff --git a/24_testing/math_test.go b/24_testing/math_test.go new file mode 100755 index 00000000..76b78e7f --- /dev/null +++ b/24_testing/math_test.go @@ -0,0 +1,43 @@ +package math + +import ( + "fmt" + "testing" + "testing/quick" +) + +func TestAdder(t *testing.T) { + result := Adder(4, 7) + if result != 11 { + t.Fatal("4 + 7 did not equal 11") + } +} + +func BenchmarkAdder(b *testing.B) { + for i := 0; i < b.N; i++ { + Adder(4, 7) + } +} + +func ExampleAdder() { + fmt.Println(Adder(4, 7)) + // Output: + // 11 +} + +func ExampleAdder_multiple() { + fmt.Println(Adder(3, 6, 7, 4, 61)) + // Output: + // 81 +} + +func TestAdderBlackbox(t *testing.T) { + err := quick.Check(a, nil) + if err != nil { + t.Fatal(err) + } +} + +func a(x, y int) bool { + return Adder(x, y) == x+y +} diff --git a/25_code-walk/main.go b/25_code-walk/main.go index 2c2566db..f177d265 100644 --- a/25_code-walk/main.go +++ b/25_code-walk/main.go @@ -103,4 +103,4 @@ func main() { fmt.Printf("Wins, losses staying at k =% 4d: %s\n", k+1, ratioString(wins[k], games-wins[k])) } -} \ No newline at end of file +} diff --git a/25_code-walk/with-comments/main.go b/25_code-walk/with-comments/main.go index 02fb0362..941daaed 100644 --- a/25_code-walk/with-comments/main.go +++ b/25_code-walk/with-comments/main.go @@ -118,4 +118,4 @@ func main() { fmt.Printf("Wins, losses staying at k =% 4d: %s\n", k+1, ratioString(wins[k], games-wins[k])) } -} \ No newline at end of file +} diff --git a/26_QUESTIONS-FROM-STUDENTS/01-package-scope/main.go b/26_QUESTIONS-FROM-STUDENTS/01-package-scope/main.go index c9910279..bd9f9846 100644 --- a/26_QUESTIONS-FROM-STUDENTS/01-package-scope/main.go +++ b/26_QUESTIONS-FROM-STUDENTS/01-package-scope/main.go @@ -2,6 +2,6 @@ package main import "fmt" -func main(){ +func main() { fmt.Println(x) } diff --git a/26_QUESTIONS-FROM-STUDENTS/04_goroutines_closing-chan/01_broken-code/main.go b/26_QUESTIONS-FROM-STUDENTS/04_goroutines_closing-chan/01_broken-code/main.go index 4bf679d0..3e393617 100644 --- a/26_QUESTIONS-FROM-STUDENTS/04_goroutines_closing-chan/01_broken-code/main.go +++ b/26_QUESTIONS-FROM-STUDENTS/04_goroutines_closing-chan/01_broken-code/main.go @@ -45,4 +45,4 @@ func fanIn(input1, input2 <-chan string) <-chan string { close(c) }() return c -} \ No newline at end of file +} diff --git a/26_QUESTIONS-FROM-STUDENTS/04_goroutines_closing-chan/02_fixed-code/main.go b/26_QUESTIONS-FROM-STUDENTS/04_goroutines_closing-chan/02_fixed-code/main.go index 7e0f8d6a..b8072d7e 100644 --- a/26_QUESTIONS-FROM-STUDENTS/04_goroutines_closing-chan/02_fixed-code/main.go +++ b/26_QUESTIONS-FROM-STUDENTS/04_goroutines_closing-chan/02_fixed-code/main.go @@ -83,14 +83,14 @@ func fanIn(input1, input2 <-chan string) <-chan string { go func(x <-chan string) { for n := range x { - c <-n + c <- n } done <- true }(input1) go func(x <-chan string) { for n := range x { - c <-n + c <- n } done <- true }(input2) @@ -111,4 +111,4 @@ func fanIn(input1, input2 <-chan string) <-chan string { // program flow comes to here and this func returns // the channel c return c -} \ No newline at end of file +} diff --git a/26_QUESTIONS-FROM-STUDENTS/06_performance-ramifications/main.go b/26_QUESTIONS-FROM-STUDENTS/06_performance-ramifications/01_called/main.go similarity index 89% rename from 26_QUESTIONS-FROM-STUDENTS/06_performance-ramifications/main.go rename to 26_QUESTIONS-FROM-STUDENTS/06_performance-ramifications/01_called/main.go index 532e93bc..dd8eb6c9 100644 --- a/26_QUESTIONS-FROM-STUDENTS/06_performance-ramifications/main.go +++ b/26_QUESTIONS-FROM-STUDENTS/06_performance-ramifications/01_called/main.go @@ -2,10 +2,11 @@ package main import ( "fmt" + "time" ) func main() { - + start := time.Now() in := gen() f := factorial(in) @@ -13,6 +14,8 @@ func main() { for n := range f { fmt.Println(n) } + + fmt.Println(time.Since(start)) } func gen() <-chan int { diff --git a/26_QUESTIONS-FROM-STUDENTS/06_performance-ramifications/02_not-called/main.go b/26_QUESTIONS-FROM-STUDENTS/06_performance-ramifications/02_not-called/main.go new file mode 100644 index 00000000..878c2a08 --- /dev/null +++ b/26_QUESTIONS-FROM-STUDENTS/06_performance-ramifications/02_not-called/main.go @@ -0,0 +1,47 @@ +package main + +import ( + "fmt" + "time" +) + +func main() { + start := time.Now() + in := gen() + + f := factorial(in) + + for n := range f { + fmt.Println(n) + } + + fmt.Println(time.Since(start)) +} + +func gen() <-chan int { + out := make(chan int) + go func() { + for i := 0; i < 10; i++ { + for j := 3; j < 13; j++ { + out <- j + } + } + close(out) + }() + return out +} + +func factorial(in <-chan int) <-chan int { + out := make(chan int) + go func() { + for n := range in { + total := 1 + for i := n; i > 0; i-- { + total *= i + } + out <- total + } + close(out) + }() + return out +} diff --git a/27_code-in-process/41_TCP/05_redis-clone/i04/main.go b/27_code-in-process/41_TCP/05_redis-clone/i04/main.go index 83b82b1c..6b4c9bbd 100644 --- a/27_code-in-process/41_TCP/05_redis-clone/i04/main.go +++ b/27_code-in-process/41_TCP/05_redis-clone/i04/main.go @@ -20,14 +20,14 @@ func handle(conn net.Conn) { fs := strings.Fields(ln) if len(fs) < 2 { - io.WriteString(conn, "This is an in-memory database \n" + - "Use SET, GET, DEL like this: \n" + - "SET key value \n" + - "GET key \n" + - "DEL key \n\n" + - "For example - try these commands: \n" + - "SET fav chocolate \n" + - "GET fav \n\n\n") + io.WriteString(conn, "This is an in-memory database \n"+ + "Use SET, GET, DEL like this: \n"+ + "SET key value \n"+ + "GET key \n"+ + "DEL key \n\n"+ + "For example - try these commands: \n"+ + "SET fav chocolate \n"+ + "GET fav \n\n\n") continue } diff --git a/27_code-in-process/59_appengine-GCS-storage/02_NewWriter_JSON-auth/storage.go b/27_code-in-process/59_appengine-GCS-storage/02_NewWriter_JSON-auth/storage.go index c4083825..ac45153f 100755 --- a/27_code-in-process/59_appengine-GCS-storage/02_NewWriter_JSON-auth/storage.go +++ b/27_code-in-process/59_appengine-GCS-storage/02_NewWriter_JSON-auth/storage.go @@ -1,10 +1,10 @@ package storage import ( - "io" - "net/http" "google.golang.org/appengine" "google.golang.org/cloud/storage" + "io" + "net/http" ) const gcsBucket = "learning-1130-bucket-01" diff --git a/27_code-in-process/60_movie-website/02_image-upload-GCS/storage.go b/27_code-in-process/60_movie-website/02_image-upload-GCS/storage.go index afc88fb6..c1456626 100755 --- a/27_code-in-process/60_movie-website/02_image-upload-GCS/storage.go +++ b/27_code-in-process/60_movie-website/02_image-upload-GCS/storage.go @@ -1,9 +1,9 @@ package movieinfo import ( - "io" "golang.org/x/net/context" "google.golang.org/cloud/storage" + "io" ) const gcsBucket = "learning-1130-bucket-01" diff --git a/27_code-in-process/63_GCS-filebrowser/storage.go b/27_code-in-process/63_GCS-filebrowser/storage.go index c79f77c4..73a9e942 100755 --- a/27_code-in-process/63_GCS-filebrowser/storage.go +++ b/27_code-in-process/63_GCS-filebrowser/storage.go @@ -1,9 +1,9 @@ package filebrowser import ( - "io" "golang.org/x/net/context" "google.golang.org/cloud/storage" + "io" ) func listBucket(ctx context.Context, bucketName, folder string) ([]string, []string, error) { diff --git a/27_code-in-process/66_authentication_OAUTH/02_manual-auth/04_bcrypt/01/main.go b/27_code-in-process/66_authentication_OAUTH/02_manual-auth/04_bcrypt/01/main.go index 851c814c..bbada1f3 100644 --- a/27_code-in-process/66_authentication_OAUTH/02_manual-auth/04_bcrypt/01/main.go +++ b/27_code-in-process/66_authentication_OAUTH/02_manual-auth/04_bcrypt/01/main.go @@ -10,7 +10,7 @@ func main() { bs, _ := bcrypt.GenerateFromPassword([]byte(p), bcrypt.MinCost) fmt.Println(bs) // fmt.Println(string(bs)) - fmt.Printf("%x \n", bs) + fmt.Printf("%X \n", bs) err := bcrypt.CompareHashAndPassword(bs, []byte(p)) if err != nil { diff --git a/27_code-in-process/66_authentication_OAUTH/05_oauth-google/routes.go b/27_code-in-process/66_authentication_OAUTH/05_oauth-google/routes.go index 96a01bad..aae622b6 100644 --- a/27_code-in-process/66_authentication_OAUTH/05_oauth-google/routes.go +++ b/27_code-in-process/66_authentication_OAUTH/05_oauth-google/routes.go @@ -8,32 +8,32 @@ import ( "google.golang.org/api/gmail/v1" - "golang.org/x/oauth2/google" "golang.org/x/oauth2" + "golang.org/x/oauth2/google" - "net/http" - "io" "github.com/nu7hatch/gouuid" + "io" + "net/http" ) var conf = &oauth2.Config{ - ClientID:"979509136073-10ce3r5s8mka304l6od82t3nltp9cf8s.apps.googleusercontent.com", - ClientSecret:"5zwpEL5WwwekeMsZoz6mcC0s", - RedirectURL:"https://practical-scion-114602.appspot.com/oauth2callback", - Scopes:[]string{"https://www.googleapis.com/auth/gmail.readonly"}, - Endpoint: google.Endpoint, + ClientID: "979509136073-10ce3r5s8mka304l6od82t3nltp9cf8s.apps.googleusercontent.com", + ClientSecret: "5zwpEL5WwwekeMsZoz6mcC0s", + RedirectURL: "https://practical-scion-114602.appspot.com/oauth2callback", + Scopes: []string{"https://www.googleapis.com/auth/gmail.readonly"}, + Endpoint: google.Endpoint, } func init() { r := httprouter.New() - r.GET("/",handleIndex) - r.GET("/login",handleLogin) - r.GET("/oauth2callback",handleAuthorize) - http.Handle("/",r) + r.GET("/", handleIndex) + r.GET("/login", handleLogin) + r.GET("/oauth2callback", handleAuthorize) + http.Handle("/", r) } func handleIndex(res http.ResponseWriter, req *http.Request, _ httprouter.Params) { - io.WriteString(res,` + io.WriteString(res, `
@@ -46,72 +46,72 @@ func handleLogin(res http.ResponseWriter, req *http.Request, _ httprouter.Params ctx := appengine.NewContext(req) //get session for storing state to check on callback - s := getSession(ctx,req) + s := getSession(ctx, req) //generate state for checking later state, err := uuid.NewV4() if err != nil { - http.Error(res, "Server Error",http.StatusInternalServerError) - log.Errorf(ctx,err.Error()) + http.Error(res, "Server Error", http.StatusInternalServerError) + log.Errorf(ctx, err.Error()) return } //put state in session and putting to memcache to check on callback s.State = state.String() - err = putSession(ctx,res,s) + err = putSession(ctx, res, s) if err != nil { - http.Error(res, "Server Error",http.StatusInternalServerError) - log.Errorf(ctx,err.Error()) + http.Error(res, "Server Error", http.StatusInternalServerError) + log.Errorf(ctx, err.Error()) return } //generate the authorization url that goes to the login and consent page for google. //I set the ApprovalForce option so that it asks for consent each time so that we can see it. //Shows application asking to "Have offline access" each time. can remove second arg to remove this. - url := conf.AuthCodeURL(s.State,oauth2.ApprovalForce) - http.Redirect(res,req,url,http.StatusSeeOther) + url := conf.AuthCodeURL(s.State, oauth2.ApprovalForce) + http.Redirect(res, req, url, http.StatusSeeOther) } func handleAuthorize(res http.ResponseWriter, req *http.Request, _ httprouter.Params) { ctx := appengine.NewContext(req) //retrieve code and state from the callback - code, state := req.FormValue("code"),req.FormValue("state") + code, state := req.FormValue("code"), req.FormValue("state") //get session from memcache - s := getSession(ctx,req) + s := getSession(ctx, req) //compare state from callback with state stored in memcache - if state != s.State{ + if state != s.State { http.Error(res, "Detected cross-site attack", http.StatusUnauthorized) log.Criticalf(ctx, "Non-matching states from %s", req.RemoteAddr) return } //exchange the auth code given for an access token - tok, err := conf.Exchange(ctx,code) + tok, err := conf.Exchange(ctx, code) if err != nil { - http.Error(res, "Server Error",http.StatusInternalServerError) - log.Errorf(ctx,err.Error()) + http.Error(res, "Server Error", http.StatusInternalServerError) + log.Errorf(ctx, err.Error()) return } //create a client from the token - client := conf.Client(ctx,tok) + client := conf.Client(ctx, tok) //create a gmail service from the client srv, err := gmail.New(client) if err != nil { - http.Error(res, "Server Error",http.StatusInternalServerError) - log.Errorf(ctx,err.Error()) + http.Error(res, "Server Error", http.StatusInternalServerError) + log.Errorf(ctx, err.Error()) return } //request a list of messages in the user's mailbox list, err := srv.Users.Threads.List("me").Do() if err != nil { - http.Error(res, "Server Error",http.StatusInternalServerError) - log.Errorf(ctx,err.Error()) + http.Error(res, "Server Error", http.StatusInternalServerError) + log.Errorf(ctx, err.Error()) return } @@ -120,15 +120,14 @@ func handleAuthorize(res http.ResponseWriter, req *http.Request, _ httprouter.Pa if len(list.Threads) > 0 { i := 1 for _, val := range list.Threads { - output += "- "+val.Snippet+"...
" + output += "- " + val.Snippet + "...
" if i > 25 { break } i++ } - }else{ + } else { output += "You have no messages!
" } - io.WriteString(res,output) + io.WriteString(res, output) } - diff --git a/27_code-in-process/68_task-queue/01_delay/routes.go b/27_code-in-process/68_task-queue/01_delay/routes.go index 8b910f8a..7eade4a9 100755 --- a/27_code-in-process/68_task-queue/01_delay/routes.go +++ b/27_code-in-process/68_task-queue/01_delay/routes.go @@ -1,9 +1,9 @@ package taskexample import ( + "google.golang.org/appengine" "io" "net/http" - "google.golang.org/appengine" ) func init() { diff --git a/27_code-in-process/97_temp/main.go b/27_code-in-process/97_temp/01/main.go similarity index 90% rename from 27_code-in-process/97_temp/main.go rename to 27_code-in-process/97_temp/01/main.go index 10af530c..a2d48dc3 100644 --- a/27_code-in-process/97_temp/main.go +++ b/27_code-in-process/97_temp/01/main.go @@ -1,20 +1,18 @@ package main -import( +import ( "fmt" "sync" "time" ) - - func main() { var count int64 c := make(chan int64) var wg sync.WaitGroup // bees - for i:=0; i<5000;i++{ + for i := 0; i < 5000; i++ { wg.Add(1) go func(in chan int64) { defer wg.Done() diff --git a/27_code-in-process/97_temp/02/02 b/27_code-in-process/97_temp/02/02 new file mode 100755 index 00000000..462158d0 Binary files /dev/null and b/27_code-in-process/97_temp/02/02 differ diff --git a/27_code-in-process/97_temp/02/main.go b/27_code-in-process/97_temp/02/main.go new file mode 100644 index 00000000..66bf5b72 --- /dev/null +++ b/27_code-in-process/97_temp/02/main.go @@ -0,0 +1,15 @@ +package main + +import ( + "fmt" +) + +func init() { + fmt.Println("Who ran first?", x) +} + +func main() { + fmt.Println("Hello world.") +} + +var x int = 17 diff --git a/LICENSE.txt b/LICENSE.txt index 300374b8..348cf030 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,2 +1,2 @@ All material is licensed under the Apache License Version 2.0, January 2004 -http://www.apache.org/licenses/LICENSE-2.0 \ No newline at end of file +http://www.apache.org/licenses/LICENSE-2.0