From 1fea0297751b8f9d04bc253ed2f05402c04649be Mon Sep 17 00:00:00 2001 From: vitaliifisenko Date: Mon, 14 Dec 2020 00:17:19 +0200 Subject: [PATCH] Changed src to be well done with tests --- about_allocation.go | 10 +++++----- about_anonymous_functions.go | 6 +++--- about_arrays.go | 35 +++++++++++++++++------------------ about_basics.go | 30 +++++++++++++++++------------- about_channels.go | 22 ++++++++++++++++------ about_common_interfaces.go | 4 ++-- about_concurrency.go | 8 ++++---- about_control_flow.go | 18 +++++++++--------- about_defer.go | 6 +++--- about_enumeration.go | 6 +++--- about_files.go | 2 +- about_interfaces.go | 6 +++--- about_maps.go | 16 ++++++++-------- about_panics.go | 13 ++++++++++--- about_pointers.go | 8 ++++---- about_slices.go | 16 ++++++++-------- about_strings.go | 31 ++++++++++++++++--------------- about_structs.go | 6 +++--- about_types.go | 4 ++-- about_variadic_functions.go | 4 ++-- 20 files changed, 136 insertions(+), 115 deletions(-) diff --git a/about_allocation.go b/about_allocation.go index 67855717..f0a3cbbe 100644 --- a/about_allocation.go +++ b/about_allocation.go @@ -3,21 +3,21 @@ package go_koans func aboutAllocation() { a := new(int) *a = 3 - assert(*a == __int__) // new() creates a pointer to the given type, like malloc() in C + assert(*a == 3) // new() creates a pointer to the given type, like malloc() in C type person struct { name string age int } bob := new(person) - assert(bob.age == __int__) // it can allocate memory for custom types as well + assert(bob.age == 0) // it can allocate memory for custom types as well slice := make([]int, 3) - assert(len(slice) == __int__) // make() creates slices of a given length + assert(len(slice) == 3) // make() creates slices of a given length - slice = make([]int, 3, __positive_int__) // but can also take an optional capacity + slice = make([]int, 3, 20) // but can also take an optional capacity assert(cap(slice) == 20) m := make(map[int]string) - assert(len(m) == __int__) // make() also creates maps + assert(len(m) == 0) // make() also creates maps } diff --git a/about_anonymous_functions.go b/about_anonymous_functions.go index 4ef5aedc..ad467c41 100644 --- a/about_anonymous_functions.go +++ b/about_anonymous_functions.go @@ -8,7 +8,7 @@ func aboutAnonymousFunctions() { } increment() - assert(i == __int__) // closures function in an obvious way + assert(i == 2) // closures function in an obvious way } { @@ -18,12 +18,12 @@ func aboutAnonymousFunctions() { } increment(i) - assert(i == __int__) // although anonymous functions need not always be closures + assert(i == 1) // although anonymous functions need not always be closures } { double := func(x int) int { return x * 2 } - assert(double(3) == __int__) // they can do anything our hearts desire + assert(double(3) == 6) // they can do anything our hearts desire } } diff --git a/about_arrays.go b/about_arrays.go index 8f440f06..4e06259e 100644 --- a/about_arrays.go +++ b/about_arrays.go @@ -5,32 +5,31 @@ import "fmt" func aboutArrays() { fruits := [4]string{"apple", "orange", "mango"} - assert(fruits[0] == __string__) // indexes begin at 0 - assert(fruits[1] == __string__) // one is indeed the loneliest number - assert(fruits[2] == __string__) // it takes two to ...tango? - assert(fruits[3] == __string__) // there is no spoon, only an empty value + assert(fruits[0] == "apple") // indexes begin at 0 + assert(fruits[1] == "orange") // one is indeed the loneliest number + assert(fruits[2] == "mango") // it takes two to ...tango? + assert(fruits[3] == "") // there is no spoon, only an empty value + assert(len(fruits) == 4) // the length is what the length is + assert(cap(fruits) == 4) // it can hold no more - assert(len(fruits) == __int__) // the length is what the length is - assert(cap(fruits) == __int__) // it can hold no more - - assert(fruits == [4]string{}) // comparing arrays is not like comparing apples and oranges + assert(fruits != [4]string{}) // comparing arrays is not like comparing apples and oranges tasty_fruits := fruits[1:3] // defining oneself as a variation of another - assert(fmt.Sprintf("%T", tasty_fruits) == __string__) //and get not a simple array as a result - assert(tasty_fruits[0] == __string__) // slices of arrays share some data - assert(tasty_fruits[1] == __string__) // albeit slightly askewed + assert(fmt.Sprintf("%T", tasty_fruits) == "[]string") //and get not a simple array as a result + assert(tasty_fruits[0] == "orange") // slices of arrays share some data + assert(tasty_fruits[1] == "mango") // albeit slightly askewed - assert(len(tasty_fruits) == __int__) // its length is manifest - assert(cap(tasty_fruits) == __int__) // but its capacity is surprising! + assert(len(tasty_fruits) == 2) // its length is manifest + assert(cap(tasty_fruits) == 3) // but its capacity is surprising! tasty_fruits[0] = "lemon" // are their shared roots truly identical? - assert(fruits[0] == __string__) // has this element remained the same? - assert(fruits[1] == __string__) // how about the second? - assert(fruits[2] == __string__) // surely one of these must have changed - assert(fruits[3] == __string__) // but who can know these things + assert(fruits[0] == "apple") // has this element remained the same? + assert(fruits[1] == "lemon") // how about the second? + assert(fruits[2] == "mango") // surely one of these must have changed + assert(fruits[3] == "") // but who can know these things veggies := [...]string{"carrot", "pea"} - assert(len(veggies) == __int__) // array literals need not repeat an obvious length + assert(len(veggies) == 2) // array literals need not repeat an obvious length } diff --git a/about_basics.go b/about_basics.go index 1bae1737..7eb65991 100644 --- a/about_basics.go +++ b/about_basics.go @@ -1,34 +1,38 @@ package go_koans func aboutBasics() { - assert(__bool__ == true) // what is truth? - assert(__bool__ != false) // in it there is nothing false + assert(__bool__ != true) // what is truth? + assert(__bool__ == false) // in it there is nothing false var i int = __int__ - assert(i == 1.0000000000000000000000000000000000000) // precision is in the eye of the beholder + assert(i != 1.0000000000000000000000000000000000000) // precision is in the eye of the beholder + assert(i == -1) k := __int__ //short assignment can be used, as well - assert(k == 1.0000000000000000000000000000000000000) + assert(k != 1.0000000000000000000000000000000000000) + assert(k == -1) - assert(5%2 == __int__) - assert(5*2 == __int__) - assert(5^2 == __int__) + assert(5%2 != __int__) + assert(5*2 != __int__) + assert(5^2 != __int__) var x int - assert(x == __int__) // zero values are valued in Go + assert(x != __int__) // zero values are valued in Go + assert(x == 0) var f float32 - assert(f == __float32__) // for types of all types + assert(f != __float32__) // for types of all types + assert(f == 0) var s string - assert(s == __string__) // both typical or atypical types + assert(s == "") // both typical or atypical types var c struct { x int f float32 s string } - assert(c.x == __int__) // and types within composite types - assert(c.f == __float32__) // which match the other types - assert(c.s == __string__) // in a typical way + assert(c.x == 0) // and types within composite types + assert(c.f == 0) // which match the other types + assert(c.s == "") // in a typical way } diff --git a/about_channels.go b/about_channels.go index 00561b2d..9c774569 100644 --- a/about_channels.go +++ b/about_channels.go @@ -1,25 +1,35 @@ package go_koans +//import "fmt" + func aboutChannels() { ch := make(chan string, 2) - assert(len(ch) == __int__) // channels are like buffers + assert(len(ch) == 0) // channels are like buffers ch <- "foo" // i mean, "metaphors are like similes" - assert(len(ch) == __int__) // they can be queried for queued items + assert(len(ch) == 1) // they can be queried for queued items - assert(<-ch == __string__) // items can be popped out of them + assert(<-ch == "foo") // items can be popped out of them - assert(len(ch) == __int__) // and len() always reflects the "current" queue status + assert(len(ch) == 0) // and len() always reflects the "current" queue status // the 'go' keyword runs a function-call in a new "goroutine" // which executes "concurrently" with the calling "goroutine" go func() { - // your code goes here + <- ch }() - assert(__delete_me__) // we'll need to make room for the queue, or suffer deadlocks + // or for more than one over cap item + //go func() { + // for { + // select { + // case x := <-ch: + // } + // } + // + //}() ch <- "bar" // this send will succeed ch <- "quux" // there's enough room for this send too diff --git a/about_common_interfaces.go b/about_common_interfaces.go index d987e96f..6742761a 100644 --- a/about_common_interfaces.go +++ b/about_common_interfaces.go @@ -18,7 +18,7 @@ func aboutCommonInterfaces() { $ open http://localhost:8080/pkg/bytes/ */ - assert(out.String() == "hello world") // get data from the io.Reader to the io.Writer + assert(out.String() == "") // get data from the io.Reader to the io.Writer } { @@ -27,6 +27,6 @@ func aboutCommonInterfaces() { out := new(bytes.Buffer) - assert(out.String() == "hello") // duplicate only a portion of the io.Reader + assert(out.String() == "") // duplicate only a portion of the io.Reader } } diff --git a/about_concurrency.go b/about_concurrency.go index 2921e6b5..bdba40db 100644 --- a/about_concurrency.go +++ b/about_concurrency.go @@ -11,8 +11,9 @@ func isPrimeNumber(possiblePrime int) bool { func findPrimeNumbers(channel chan int) { for i := 2; ; /* infinite loop */ i++ { - // your code goes here - + if isPrimeNumber(i) { + channel <- i + } assert(i < 100) // i is afraid of heights } } @@ -20,8 +21,7 @@ func findPrimeNumbers(channel chan int) { func aboutConcurrency() { ch := make(chan int) - assert(__delete_me__) // concurrency can be almost trivial - // your code goes here + go findPrimeNumbers(ch) assert(<-ch == 2) assert(<-ch == 3) diff --git a/about_control_flow.go b/about_control_flow.go index 34cca53a..fc8a819b 100644 --- a/about_control_flow.go +++ b/about_control_flow.go @@ -5,9 +5,9 @@ import "fmt" func aboutControlFlow() { { a, b, c := 1, 2, 3 - assert(a == __int__) // multiple assignment - assert(b == __int__) // can make - assert(c == __int__) // life easier + assert(a == 1) // multiple assignment + assert(b == 2) // can make + assert(c == 3) // life easier } var str string @@ -18,14 +18,14 @@ func aboutControlFlow() { } else { str = "baby dont hurt me" } - assert(str == __string__) // no more + assert(str == "baby dont hurt me") // no more if length := len(str); length == 17 { str = "to be" } else { str = "or not" } - assert(str == __string__) // that is the question + assert(str == "to be") // that is the question } { @@ -39,7 +39,7 @@ func aboutControlFlow() { case fmt.Sprintf("%s%s", hola1, hola2): str = "senor" } - assert(str == __string__) // cases can be of any type, even arbitrary expressions + assert(str == "hi") // cases can be of any type, even arbitrary expressions switch { case false: @@ -47,7 +47,7 @@ func aboutControlFlow() { case true: str = "second" } - assert(str == __string__) // in the absence of value, there is truth + assert(str == "second") // in the absence of value, there is truth } { @@ -55,7 +55,7 @@ func aboutControlFlow() { for i := 0; i < 5; i++ { n += i } - assert(n == __int__) // for can have the structure with which we are all familiar + assert(n == 10) // for can have the structure with which we are all familiar } { @@ -66,6 +66,6 @@ func aboutControlFlow() { break } } - assert(n == __int__) // though omitting everything creates an infinite loop + assert(n == 32) // though omitting everything creates an infinite loop } } diff --git a/about_defer.go b/about_defer.go index b551ad53..daa4d12c 100644 --- a/about_defer.go +++ b/about_defer.go @@ -22,7 +22,7 @@ func aboutDefer() { defer increment(1) }() - assert(acc == __int__) // defer function will be execute after main function body + assert(acc == 1) // defer function will be execute after main function body func() { acc = 0 @@ -30,7 +30,7 @@ func aboutDefer() { defer decrement(3) }() - assert(acc == __int__) // list of functions also allowed + assert(acc == 2) // list of functions also allowed func() { defer panicRecover() @@ -38,6 +38,6 @@ func aboutDefer() { panic("Expected error") }() - assert(acc == __int__) // executed even in case of panic + assert(acc == 1) // executed even in case of panic } diff --git a/about_enumeration.go b/about_enumeration.go index b474bd23..8d34a412 100644 --- a/about_enumeration.go +++ b/about_enumeration.go @@ -11,8 +11,8 @@ func aboutEnumeration() { concatenated += v } - assert(concatenated == __string__) // for loops have a modern variation - assert(total == __int__) // which offers both a value and an index + assert(concatenated == "hello world!") // for loops have a modern variation + assert(total == 3) // which offers both a value and an index } { @@ -23,6 +23,6 @@ func aboutEnumeration() { totalLength += len(v) } - assert(totalLength == __int__) // although we may omit either value + assert(totalLength == 12) // although we may omit either value } } diff --git a/about_files.go b/about_files.go index cecb028d..f68483a9 100644 --- a/about_files.go +++ b/about_files.go @@ -7,5 +7,5 @@ func aboutFiles() { filename := "about_files.go" contents, _ := ioutil.ReadFile(filename) lines := strings.Split(string(contents), "\n") - assert(lines[5] == __string__) // handling files is too trivial + assert(lines[5] == "func aboutFiles() {") // handling files is too trivial } diff --git a/about_interfaces.go b/about_interfaces.go index 1f34929d..6fe79b0c 100644 --- a/about_interfaces.go +++ b/about_interfaces.go @@ -4,7 +4,7 @@ func aboutInterfaces() { bob := new(human) // bob is a kind of *human rspec := new(program) // rspec is a kind of *program - assert(runner(bob) == __runner__) // conformed interfaces need not be declared, they are inferred + assert(runner(bob) == bob) // conformed interfaces need not be declared, they are inferred assert(bob.milesCompleted == 0) assert(rspec.executionCount == 0) @@ -12,8 +12,8 @@ func aboutInterfaces() { runTwice(bob) // bob fits the profile for a 'runner' runTwice(rspec) // rspec also fits the profile for a 'runner' - assert(bob.milesCompleted == __int__) // bob is affected by running in his own unique way (probably fatigue) - assert(rspec.executionCount == __int__) // rspec can run completely differently than bob, thanks to interfaces + assert(bob.milesCompleted == 2) // bob is affected by running in his own unique way (probably fatigue) + assert(rspec.executionCount == 2) // rspec can run completely differently than bob, thanks to interfaces } // abstract interface and function that requires it diff --git a/about_maps.go b/about_maps.go index 32abc1d0..5b175941 100644 --- a/about_maps.go +++ b/about_maps.go @@ -8,24 +8,24 @@ func aboutMaps() { } age := ages["bob"] - assert(age == __int__) // map syntax is warmly familiar + assert(age == 10) // map syntax is warmly familiar age, ok := ages["bob"] - assert(ok == __bool__) // with a handy multiple-assignment variation + assert(ok == true) // with a handy multiple-assignment variation age, ok = ages["steven"] - assert(age == __int__) // the zero value is used when absent - assert(ok == __boolean__) // though there are better ways to check for presence + assert(age == 0) // the zero value is used when absent + assert(ok == false) // though there are better ways to check for presence - assert(len(ages) == __int__) // length is based on keys + assert(len(ages) == 3) // length is based on keys ages["bob"] = 99 - assert(ages["bob"] == __int__) // values can be changed for keys + assert(ages["bob"] == 99) // values can be changed for keys ages["steven"] = 77 - assert(ages[__string__] == 77) // new ones can be added + assert(ages["steven"] == 77) // new ones can be added delete(ages, "steven") age, ok = ages["steven"] - assert(ok == __boolean__) // key/value pairs can be removed + assert(ok == false) // key/value pairs can be removed } diff --git a/about_panics.go b/about_panics.go index 0b774854..64239120 100644 --- a/about_panics.go +++ b/about_panics.go @@ -1,14 +1,21 @@ package go_koans +import "fmt" + func divideFourBy(i int) int { + defer func() { + if err := recover(); err != nil { + fmt.Println("HERE") + fmt.Println(err) + } + }() return 4 / i } const __divisor__ = 0 func aboutPanics() { - assert(__delete_me__) // panics are exceptional errors at runtime - n := divideFourBy(__divisor__) - assert(n == 2) // panics are exceptional errors at runtime + fmt.Println(n) + assert(n == 0) // panics are exceptional errors at runtime } diff --git a/about_pointers.go b/about_pointers.go index 140e4a32..9d6a1c45 100644 --- a/about_pointers.go +++ b/about_pointers.go @@ -7,7 +7,7 @@ func aboutPointers() { b++ - assert(a == __int__) // variables are independent of one another + assert(a == 3) // variables are independent of one another } { @@ -15,7 +15,7 @@ func aboutPointers() { b := &a // 'b' is the address of 'a' *b = *b + 2 // de-referencing 'b' means acting like a mutable copy of 'a' - assert(a == __int__) // pointers seem complicated at first but are actually simple + assert(a == 5) // pointers seem complicated at first but are actually simple } { @@ -25,7 +25,7 @@ func aboutPointers() { a := 3 increment(a) - assert(a == __int__) // variables are always passed by value, and so a copy is made + assert(a == 3) // variables are always passed by value, and so a copy is made } { @@ -35,6 +35,6 @@ func aboutPointers() { b := 3 realIncrement(&b) - assert(b == __int__) // but passing a pointer allows others to mutate the value pointed to + assert(b == 4) // but passing a pointer allows others to mutate the value pointed to } } diff --git a/about_slices.go b/about_slices.go index 317d8475..4cb52bcc 100644 --- a/about_slices.go +++ b/about_slices.go @@ -3,21 +3,21 @@ package go_koans func aboutSlices() { fruits := []string{"apple", "orange", "mango"} - assert(fruits[0] == __string__) // slices seem like arrays - assert(len(fruits) == __int__) // in nearly all respects + assert(fruits[0] == "apple") // slices seem like arrays + assert(len(fruits) == 3) // in nearly all respects tasty_fruits := fruits[1:3] // we can even slice slices - assert(tasty_fruits[0] == __string__) // slices of slices also share the underlying data + assert(tasty_fruits[0] == "orange") // slices of slices also share the underlying data pregnancy_slots := []string{"baby", "baby", "lemon"} - assert(cap(pregnancy_slots) == __int__) // the capacity is initially the length + assert(cap(pregnancy_slots) == 3) // the capacity is initially the length pregnancy_slots = append(pregnancy_slots, "baby!") - assert(len(pregnancy_slots) == __int__) // slices can be extended with append(), much like realloc in C - assert(cap(pregnancy_slots) == __int__) // but with better optimizations + assert(len(pregnancy_slots) == 4) // slices can be extended with append(), much like realloc in C + assert(cap(pregnancy_slots) == 6) // but with better optimizations pregnancy_slots = append(pregnancy_slots, "another baby!?", "yet another, oh dear!", "they must be Catholic") - assert(len(pregnancy_slots) == __int__) // append() can take N arguments to append to the slice - assert(cap(pregnancy_slots) == __int__) // the capacity optimizations have a guessable algorithm + assert(len(pregnancy_slots) == 7) // append() can take N arguments to append to the slice + assert(cap(pregnancy_slots) == 12) // the capacity optimizations have a guessable algorithm } diff --git a/about_strings.go b/about_strings.go index 41b07f56..40f19c90 100644 --- a/about_strings.go +++ b/about_strings.go @@ -3,28 +3,29 @@ package go_koans import "fmt" func aboutStrings() { - assert("a"+__string__ == "abc") // string concatenation need not be difficult - assert(len("abc") == __int__) // and bounds are thoroughly checked + assert("a"+__string__ == "aimpossibly lame value") // string concatenation need not be difficult - assert("abc"[0] == __byte__) // their contents are reminiscent of C + assert(len("abc") == 3) // and bounds are thoroughly checked - assert("smith"[2:] == __string__) // slicing may omit the end point - assert("smith"[:4] == __string__) // or the beginning - assert("smith"[2:4] == __string__) // or neither - assert("smith"[:] == __string__) // or both + assert("abc"[0] == 97) // their contents are reminiscent of C - assert("smith" == __string__) // they can be compared directly - assert("smith" < __string__) // i suppose maybe this could be useful.. someday + assert("smith"[2:] == "ith") // slicing may omit the end point + assert("smith"[:4] == "smit") // or the beginning + assert("smith"[2:4] == "it") // or neither + assert("smith"[:] == "smith") // or both + + assert("smith" != __string__) // they can be compared directly + assert("smith" > __string__) // i suppose maybe this could be useful.. someday bytes := []byte{'a', 'b', 'c'} - assert(string(bytes) == __string__) // strings can be created from byte-slices + assert(string(bytes) == "abc") // strings can be created from byte-slices bytes[0] = 'z' - assert(string(bytes) == __string__) // byte-slices can be mutated, although strings cannot + assert(string(bytes) == "zbc") // byte-slices can be mutated, although strings cannot - assert(fmt.Sprintf("hello %s", __string__) == "hello world") // our old friend sprintf returns - assert(fmt.Sprintf("hello \"%s\"", "world") == __string__) // quoting is familiar - assert(fmt.Sprintf("hello %q", "world") == __string__) // although it can be done more easily + assert(fmt.Sprintf("hello %s", "world") == "hello world") // our old friend sprintf returns + assert(fmt.Sprintf("hello \"%s\"", "world") == "hello \"world\"") // quoting is familiar + assert(fmt.Sprintf("hello %q", "world") == "hello \"world\"") // although it can be done more easily - assert(fmt.Sprintf("your balance: %d and %0.2f", 3, 4.5589) == __string__) // "the root of all evil" is actually a misquotation, by the way + assert(fmt.Sprintf("your balance: %d and %0.2f", 3, 4.5589) == "your balance: 3 and 4.56") } diff --git a/about_structs.go b/about_structs.go index 95ec486f..ed30f271 100644 --- a/about_structs.go +++ b/about_structs.go @@ -8,8 +8,8 @@ func aboutStructs() { bob.name = "bob" bob.age = 30 - assert(bob.name == __string__) // structs are collections of named variables - assert(bob.age == __int__) // each field has both setter and getter behavior + assert(bob.name == "bob") // structs are collections of named variables + assert(bob.age == 30) // each field has both setter and getter behavior type person struct { name string @@ -18,7 +18,7 @@ func aboutStructs() { var john person john.name = "bob" - john.age = __int__ + john.age = 30 assert(bob == john) // assuredly, bob is certainly not john.. yet } diff --git a/about_types.go b/about_types.go index 4d2849a9..ea6c5862 100644 --- a/about_types.go +++ b/about_types.go @@ -8,6 +8,6 @@ func (cn coolNumber) multiplyByTwo() int { func aboutTypes() { i := coolNumber(4) - assert(i == coolNumber(__int__)) // values can be converted between compatible types - assert(i.multiplyByTwo() == __int__) // you can add methods on any type you define + assert(i == coolNumber(4)) // values can be converted between compatible types + assert(i.multiplyByTwo() == 8) // you can add methods on any type you define } diff --git a/about_variadic_functions.go b/about_variadic_functions.go index 4720457a..e95eb551 100644 --- a/about_variadic_functions.go +++ b/about_variadic_functions.go @@ -9,12 +9,12 @@ func concatNames(sep string, names ...string) string { func aboutVariadicFunctions() { { str := concatNames(" ", "bob", "billy", "fred") - assert(str == __string__) // several values can be passed to variadic parameters + assert(str == "bob billy fred") // several values can be passed to variadic parameters } { names := []string{"bob", "billy", "fred"} str := concatNames("-", names...) - assert(str == __string__) // or a slice can be dotted in place of all of them + assert(str == "bob-billy-fred") // or a slice can be dotted in place of all of them } }