remove: unfinished sections + move them to WIP branch

This commit is contained in:
Inanc Gumus
2018-11-12 17:22:47 +03:00
parent 4f6d58c538
commit 5d997f9501
77 changed files with 3 additions and 3193 deletions

View File

@ -1,28 +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"
func main() {
jake := "jake"
joe := "joe"
lee := "lee"
lina := "lina"
fmt.Println(jake)
fmt.Println(joe)
fmt.Println(lee)
fmt.Println(lina)
// for each name
// you need to declare a variable
// and then you need to print it
//
// but by using an array, you don't need to do that
}

View File

@ -1,27 +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"
func main() {
// instead of storing the names in variables,
// you can use an array to store all of the names
// in a single variable
// names := [3]string{"jake", "joe", "lee"}
names := [4]string{"jake", "joe", "lee", "lina"}
// doing so allows you to loop over the names
// and print each one of them
//
// you can't do this without arrays
for _, name := range names {
fmt.Println(name)
}
}

View File

@ -1,18 +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"
func main() {
ages := [3]int{15, 30, 25}
for _, age := range ages {
fmt.Println(age)
}
}

View File

@ -1,18 +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
func main() {
// uncomment the code below to observe the error
// ages := [3]int{15, 30, 25, 44}
// for _, age := range ages {
// fmt.Println(age)
// }
}

View File

@ -1,39 +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"
func main() {
// you cannot use variables
// when setting the length of an array
// length := 3
// but, you can use constants and constant expressions
const length = 3 * 2
ages := [3 * 2]int{15, 30, 25}
for _, age := range ages {
fmt.Println(age)
}
}
// EXERCISE:
// Try to put the `length` constant
// in place of `3 * 2` above.
// EXERCISE:
// Try to put the `length` variable
// in place of `3 * 2` above.
//
// And observe the error.
//
// To do that, you need comment-out
// the length constant first.

View File

@ -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
func main() {
// -----
// you cannot use incompatible values
// than the array's element type
//
// uncomment the code parts below one by one
// then observe the errors
// -----
// for example you can't use a string
// ages := [3]int{15, 30, "hi"}
// -----
// or a float64, etc...
// ages := [3]int{15, 30, 5.5}
// -----
// of course this is valid, since it's untyped
// 5. becomes 5 (int)
// ages := [3]int{15, 30, 5.}
// -----
// for _, age := range ages {
// fmt.Println(age)
// }
}
// EXERCISE:
// Try to put the `length` constant
// in place of `3 * 2` above.
// EXERCISE:
// Try to put the `length` variable
// in place of `3 * 2` above.
//
// And observe the error.
//
// To do that, you need comment-out
// the length constant first.

View File

@ -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
import "fmt"
func main() {
ages := [...]int{15, 30, 25}
// equals to:
// ages := [3]int{15, 30, 25}
for _, age := range ages {
fmt.Println(age)
}
}

View File

@ -1,22 +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"
func main() {
ages := [3]int{15, 30, 25}
fmt.Printf("%T\n", ages) // [3]int
fmt.Printf("%T\n", [...]int{15, 30, 25}) // [3]int
fmt.Printf("%T\n", [2]int{15, 30}) // [2]int
fmt.Printf("%T\n", [1]string{"hi"}) // [1]string
fmt.Printf("%T\n", [...]float64{3.14, 6.28}) // [2]float64
}

View File

@ -1,16 +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"
func main() {
var ages [3]int
fmt.Println(ages)
}

View File

@ -1,16 +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"
func main() {
ages := [3]int{1}
fmt.Println(ages)
}

View File

@ -1,18 +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"
func main() {
names := [...]string{
"lina", "bob", "jane",
}
fmt.Printf("%#v\n", names)
}

View File

@ -1,18 +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"
func main() {
names := [5]string{
"lina", "bob", "jane",
}
fmt.Printf("%#v\n", names)
}

View File

@ -1,21 +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"
func main() {
names := [5]string{
"lina", "bob", "jane",
}
fmt.Printf("%#v\n", names)
temperatures := [10]float64{1.5, 2.5}
fmt.Printf("%#v\n", temperatures)
}

View File

@ -1,35 +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"
func main() {
ages := [2]int{15, 20}
// i can directly use `len`
fmt.Println(len(ages)) // 2
// i can also assign its result to a variable
l := len(ages)
fmt.Println(l) // 2
// let's print the length of a few arrays
l = len([1]bool{true}) // 1
fmt.Println(l)
l = len([3]string{"lina", "james", "joe"}) // 3
fmt.Println(l)
// this array doesn't initialize any elements
// but its length is still 5
// whether the elements are initialized or not
l = len([5]int{})
fmt.Println(l) // 5
fmt.Println([5]int{})
}

View File

@ -1,32 +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"
func main() {
ages := [2]int{15, 20}
// WRONG (try it):
// fmt.Println(ages[-1])
fmt.Println("1st item:", ages[0])
fmt.Println("2nd item:", ages[1])
// fmt.Println("2nd item:", ages[2])
// fmt.Println(ages[len(ages)])
// here, `len(ages) - 1` equals to 1
fmt.Println("last item:", ages[len(ages)-1])
// let's display the indexes and the items
// of the array
for i, v := range ages {
fmt.Printf("index: %d, value: %d\n", i, v)
}
}

View File

@ -1,49 +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"
func main() {
ages := [2]int{15, 20}
ages[0] = 6
ages[1] *= 3
fmt.Println(ages)
// increase the last element by 1
ages[1]++
ages[len(ages)-1]++
fmt.Println(ages)
// v is a copy
for _, v := range ages {
// it's like:
// v = ages[0]
// v++
// and:
// v = ages[1]
// v++
v++
}
fmt.Println(ages)
// you don't need to use blank-identifier for the value
// for i, _ := range ages {
for i := range ages {
ages[i]++
}
fmt.Println(ages)
}

View File

@ -1,30 +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"
func main() {
a := [3]int{6, 9, 3}
b := [3]int{6, 9, 3}
if a == b {
fmt.Println("they're equal!")
// they're comparable
// since their types are identical
fmt.Printf("1st array's type is %T\n", a)
fmt.Printf("2nd array's type is %T\n", b)
// go compares arrays like this
// it compares the elements one by one
fmt.Println(a[0] == b[0])
fmt.Println(a[1] == b[1])
fmt.Println(a[2] == b[2])
}
}

View File

@ -1,39 +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"
func main() {
a := [3]int{6, 9, 3}
b := [3]int{3, 9, 6}
if a == b {
fmt.Println("they're equal!")
} else {
fmt.Println("they're not equal! a==b?", a == b)
// but, they're comparable
// since their types are identical
fmt.Printf("1st array's type is %T\n", a)
fmt.Printf("2nd array's type is %T\n", b)
// go compares arrays like this
// it compares the elements one by one
fmt.Println(a[0] == b[0]) // false
fmt.Println(a[1] == b[1]) // true
fmt.Println(a[2] == b[2]) // false
// actually Go will quit comparing these arrays
// once it sees unequal items
//
// so, it will stop the comparison (short-circuit)
// when it sees the first item is false
// and it will return false
}
}

View File

@ -1,24 +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
func main() {
// these two arrays not comparable
// their types are different
// uncomment all the code below and observe the error
// a := [3]int{6, 9, 3}
// b := [2]int{6, 9}
// you can't ask this question
// if a == b {
// fmt.Println("they're equal!")
// }
}

View File

@ -1,26 +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"
func main() {
a := [2]string{"jane", "lina"}
b := [2]string{"jane", "lina"}
c := [2]string{"mike", "joe"}
fmt.Println("a==b?", a == b) // equal
fmt.Println("a==c?", a == c) // not equal
// cannot compare
d := [3]string{"jane", "lina"}
// fmt.Println("c==d?", c == d)
fmt.Printf("type of c is %T\n", c)
fmt.Printf("type of d is %T\n", d)
}

View File

@ -1,38 +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"
func main() {
type (
A [3]int
B [3]int
)
x := A{1, 2, 3}
y := B{1, 2, 3}
z := [3]int{1, 2, 3}
fmt.Printf("x's type: %T\n", x) // named type : main.A
fmt.Printf("y's type: %T\n", y) // named type : main.B
fmt.Printf("z's type: %T\n", z) // unnamed type: [3]int
// cannot compare different named types
// fmt.Println("x==y?", x == y)
// can convert between identical types
fmt.Println("x==y?", x == A(y))
fmt.Println("x==y?", B(x) == y)
fmt.Printf("x's type : %T\n", x)
fmt.Printf("A(y)'s type: %T\n", A(y))
// can compare to unnamed types
fmt.Println("x==z?", x == z)
}

View File

@ -1,24 +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"
func main() {
a := [3]int{5, 4, 7}
// this assignment will create a new array value
// and then it will be stored in the b variable
b := a
fmt.Println("a =>", a)
fmt.Println("b =>", b)
// they're equal, they're clones
fmt.Println("a==b?", a == b)
}

View File

@ -1,27 +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"
func main() {
a := [3]int{5, 4, 7}
b := a
// this will only change the 'a' array
a[0] = 10
fmt.Println("a =>", a)
fmt.Println("b =>", b)
// this will only change the 'b' array
b[1] = 20
fmt.Println("a =>", a)
fmt.Println("b =>", b)
}

View File

@ -1,23 +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"
func main() {
a := [3]int{5, 4, 7}
b := [3]int{6, 9, 3}
b = a
fmt.Println("b =>", b)
b[0] = 100
fmt.Println("a =>", a)
fmt.Println("b =>", b)
}

View File

@ -1,23 +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
func main() {
// you can't assign the array 'a' to the array 'b'
// a's type is [2]int whereas b's type is [3]int
// when two values are not comparable,
// then they're not assignable either
// uncomment and observe the error
// a := [2]int{5, 4}
// b := [3]int{6, 9, 3}
// b = a
}

View File

@ -1,31 +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"
func main() {
a := [3]int{10, 4, 7}
// like the assignment passing an array to a function
// creates a copy of the array
fmt.Println("a (before) =>", a)
incr(a)
fmt.Println("a (after) =>", a)
}
// inside the function
// the passed array 'a' is a new copy (a clone)
// it's not the original one
func incr(a [3]int) {
// this only changes the copy of the passed array
a[1]++
// this prints the copied array not the original one
fmt.Println("a (inside) =>", a)
}

View File

@ -1,49 +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"
func main() {
// [LENGTH]TYPE {
// ELEMENTS
// }
// LENGTH=2 and TYPE=[2]int
// nums := [2][2]int{
// [2]int{2, 4},
// [2]int{1, 3},
// }
// code below is the same as the code above
nums := [2][2]int{
{2, 4},
{1, 3},
}
fmt.Println("nums =", nums)
fmt.Println("nums[0] =", nums[0])
fmt.Println("nums[1] =", nums[1])
fmt.Println("nums[0][0] =", nums[0][0])
fmt.Println("nums[0][1] =", nums[0][1])
fmt.Println("nums[1][0] =", nums[1][0])
fmt.Println("nums[1][1] =", nums[1][1])
fmt.Println("len(nums) =", len(nums))
fmt.Println("len(nums[0]) =", len(nums[0]))
fmt.Println("len(nums[1]) =", len(nums[1]))
for i, array := range nums {
for j, n := range array {
// nums[i][j] = number
fmt.Printf("nums[%d][%d] = %d\n", i, j, n)
}
}
}

View File

@ -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
import "fmt"
func main() {
rates := [3]float64{
0.5,
2.5,
1.5,
}
fmt.Println(rates)
}

View File

@ -1,28 +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"
func main() {
rates := [3]float64{
0: 0.5, // index: 0
1: 2.5, // index: 1
2: 1.5, // index: 2
}
fmt.Println(rates)
// above array literal equals to this:
//
// rates := [3]float64{
// 0.5,
// 2.5,
// 1.5,
// }
}

View File

@ -1,28 +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"
func main() {
rates := [3]float64{
1: 2.5, // index: 1
0: 0.5, // index: 0
2: 1.5, // index: 2
}
fmt.Println(rates)
// above array literal equals to this:
//
// rates := [3]float64{
// 0.5,
// 2.5,
// 1.5,
// }
}

View File

@ -1,28 +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"
func main() {
rates := [3]float64{
// index 0 empty
// index 1 empty
2: 1.5, // index: 2
}
fmt.Println(rates)
// above array literal equals to this:
//
// rates := [3]float64{
// 0.,
// 0.,
// 1.5,
// }
}

View File

@ -1,36 +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"
func main() {
// ellipsis (...) below calculates the length of the
// array automatically
rates := [...]float64{
// index 0 empty
// index 1 empty
// index 2 empty
// index 3 empty
// index 4 empty
5: 1.5, // index: 5
}
fmt.Println(rates)
// above array literal equals to this:
//
// rates := [6]float64{
// 0.,
// 0.,
// 0.,
// 0.,
// 0.,
// 1.5,
// }
}

View File

@ -1,34 +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"
func main() {
rates := [...]float64{
// index 1 to 4 empty
5: 1.5, // index: 5
2.5, // index: 6
0: 0.5, // index: 0
}
fmt.Println(rates)
// above array literal equals to this:
//
// rates := [7]float64{
// 0.5,
// 0.,
// 0.,
// 0.,
// 0.,
// 1.5,
// 2.5,
// }
}

View File

@ -1,21 +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"
func main() {
rates := [...]float64{
25.5, // ethereum
120.5, // wanchain
}
// uses magic values - not good
fmt.Printf("1 BTC is %g ETH\n", rates[0])
fmt.Printf("1 BTC is %g WAN\n", rates[1])
}

View File

@ -1,30 +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"
// REFACTORED VERSION
// It uses well-defined names instead of magic numbers.
// Thanks to keyed elements and constants.
func main() {
const (
ETH = iota
WAN
)
rates := [...]float64{
ETH: 25.5,
WAN: 120.5,
}
// uses well-defined names (ETH, WAN, ...) - good
fmt.Printf("1 BTC is %g ETH\n", rates[ETH])
fmt.Printf("1 BTC is %g WAN\n", rates[WAN])
}

View File

@ -1,38 +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"
"math/rand"
"os"
"time"
)
func main() {
args := os.Args[1:]
if len(args) != 1 {
fmt.Println("[your name]")
return
}
name := args[0]
moods := [...]string{
"happy 😀", "good 👍", "awesome 😎",
"sad 😞", "bad 👎", "terrible 😩",
}
rand.Seed(time.Now().UnixNano())
n := rand.Intn(len(moods))
fmt.Printf("%s feels %s\n", name, moods[n])
}
// inspired from:
// https://github.com/moby/moby/blob/1fd7e4c28d3a4a21c3540f03a045f96a4190b527/pkg/namesgenerator/names-generator.go

View File

@ -1,39 +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"
"math/rand"
"os"
"time"
)
func main() {
args := os.Args[1:]
if len(args) != 2 {
fmt.Println("[your name] [positive|negative]")
return
}
name, mood := args[0], args[1]
moods := [...][3]string{
{"happy 😀", "good 👍", "awesome 😎"},
{"sad 😞", "bad 👎", "terrible 😩"},
}
rand.Seed(time.Now().UnixNano())
n := rand.Intn(len(moods[0]))
var mi int
if mood != "positive" {
mi = 1
}
fmt.Printf("%s feels %s\n", name, moods[mi][n])
}

View File

@ -1,72 +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"
"math/rand"
"os"
"strconv"
"time"
)
const (
maxTurns = 5 // less is more difficult
usage = `Welcome to the Lucky Number Game!
The program will pick %d random numbers.
Your mission is to guess one of those numbers.
The greater your number is, harder it gets.
Wanna play?
`
)
func main() {
rand.Seed(time.Now().UnixNano())
args := os.Args[1:]
if len(args) != 1 {
fmt.Printf(usage, maxTurns)
return
}
guess, err := strconv.Atoi(args[0])
if err != nil {
fmt.Println("Not a number.")
return
}
if guess < 0 {
fmt.Println("Please pick a positive number.")
return
}
// This array will store the generated random numbers
var pickeds [maxTurns]int
for turn := 0; turn < maxTurns; turn++ {
n := rand.Intn(guess + 1)
pickeds[turn] = n
if n == guess {
fmt.Println("🎉 YOU WIN!")
goto pickeds
}
}
fmt.Println("☠️ YOU LOST... Try again?")
pickeds:
fmt.Println("Computer has picked these:", pickeds)
// after this line the program automatically exits
}

1
14-arrays/README.md Normal file
View File

@ -0,0 +1 @@
This section is in progress. I'm working hard to update the course all the time. Hold on!

View File

@ -1,22 +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
// ---------------------------------------------------------
// EXERCISE
// ?
//
// NOTE
// ?
//
// EXPECTED OUTPUT
// ?
// ---------------------------------------------------------
func main() {
}

View File

@ -1,11 +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
func main() {
}

View File

@ -1,82 +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"
"math/rand"
"os"
"strconv"
"time"
)
const (
maxTurns = 5 // less is more difficult
usage = `Welcome to the Lucky Number Game!
The program will pick %d random numbers.
Your mission is to guess one of those numbers.
The greater your number is, harder it gets.
Wanna play?
`
)
func main() {
rand.Seed(time.Now().UnixNano())
args := os.Args[1:]
if len(args) != 1 {
fmt.Printf(usage, maxTurns)
return
}
guess, err := strconv.Atoi(args[0])
if err != nil {
fmt.Println("Not a number.")
return
}
if guess < 0 {
fmt.Println("Please pick a positive number.")
return
}
// This array will store the generated random numbers
var pickeds [maxTurns]int
for turn := 0; turn < maxTurns; turn++ {
var n int
pick:
for {
n = rand.Intn(guess + 1)
for _, v := range pickeds {
if n == v {
continue pick
}
}
break
}
pickeds[turn] = n
if n == guess {
fmt.Println("🎉 YOU WIN!")
goto pickeds
}
}
fmt.Println("☠️ YOU LOST... Try again?")
pickeds:
fmt.Println("Computer has picked these:", pickeds)
// after this line the program automatically exits
}

View File

@ -1,3 +0,0 @@
## ?
* text *CORRECT*
* text

View File

@ -1,82 +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"
func main() {
// -----------------------------------------------------
// COMPLEX LITERALS:
// -----------------------------------------------------
// array literal : [4]int{1, 2, 3}
// slice literal : []int{1, 2, 3}
//
// You didn't learn about these yet:
//
// map literal : map[int]int{1: 2}
// struct literal: struct{ x, y int }{ 1, 2 }
// -----------------------------------------------------
// SLICE LITERAL:
// -----------------------------------------------------
r := []rune{'h', 'e', 'y'} // 3 items
i := []int{'h', 'e', 'y'} // 3 items
b := []byte{'h', 'e', 'y'} // 3 items
s := []string{"hey"} // 1 item
fmt.Printf("[]rune type: %T\n", r)
fmt.Printf("[]int type: %T\n", i)
fmt.Printf("[]byte type: %T\n", b)
fmt.Printf("[]string type: %T\n", s)
// -----------------------------------------------------
// multi-dimensional slice
// -----------------------------------------------------
multi := [][]rune{
{1, 2, 3},
// each item can have a different length
{4, 5, 6, 7, 8},
}
fmt.Printf("multi's type : %T\n", multi)
fmt.Printf("multi's length : %d\n", len(multi))
fmt.Printf("multi[0]'s length: %d\n", len(multi[0]))
fmt.Printf("multi[1]'s length: %d\n", len(multi[1]))
// -----------------------------------------------------
// getting and setting elements
// -----------------------------------------------------
hello := []rune{'h', 'e', 'y'}
fmt.Println(hello[0], hello[1], hello[2])
hello[0] = 'y'
hello[1] = 'o'
hello[2] = '!'
fmt.Println(hello[0], hello[1], hello[2])
// -----------------------------------------------------
// empty slice
// -----------------------------------------------------
e := []rune{}
fmt.Printf("empty slice's length: %d\n", len(e))
// -----------------------------------------------------
// nil slice
// slice's zero value is nil
// -----------------------------------------------------
var n []rune
fmt.Println("Really nil?", n == nil)
// you can't get/set elements of a nil slice
// if you run the code below, it will error at runtime
//
// fmt.Println(n[0])
// fmt.Println(n[1])
// but you can get its length
fmt.Printf("nil slice's length: %d\n", len(n))
}

View File

@ -1,61 +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"
s "github.com/inancgumus/prettyslice"
)
func main() {
basket := []string{"banana", "apple", "coffee"}
s.Show("basket (before)", basket)
// #1 example: type
fmt.Printf("[]string type: %T\n", basket)
// #2 example: getting and setting elements
fmt.Println(basket[0], basket[1], basket[2])
basket[0] = "pepper"
basket[1] = "water"
basket[2] = "tea"
s.Show("basket (after)", basket)
// #3 example: empty slice
emptyBasket := []rune{}
s.Show(`emptyBasket := []rune{}`, emptyBasket)
// #4 example: nil slice
// a slice's zero value is nil
var nilButHappy []rune
s.Show(`var nilButHappy []rune`, nilButHappy)
// #5 example: comparing to nil
fmt.Println("nilButHappy == nil", nilButHappy == nil)
fmt.Println("emptyBasket == nil", emptyBasket == nil)
// you can't compare slices other than nil
// nilButHappy == emptyBasket
// #6 example: comparing slices
newBasket := []string{"pepper", "water", "tea"}
equal := true
for i := range basket {
if basket[i] != newBasket[i] {
equal = false
break
}
}
s.Show("equal?", basket, newBasket)
fmt.Println(equal)
}

View File

@ -1,46 +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 (
s "github.com/inancgumus/prettyslice"
)
func main() {
nums := []int{1, 2, 3}
s.Show("nums := []int{1, 2, 3}", nums)
// -----------------------------------------------------
nums = append(nums, 4)
s.Show("append(nums, 4)", nums)
// -----------------------------------------------------
nums = append(nums, 9)
s.Show("append(nums, 9)", nums)
// -----------------------------------------------------
// let's reset nums
// and let's add multiple elements
nums = []int{1, 2, 3}
s.Show("nums = []int{1, 2, 3}", nums)
nums = append(nums, 4, 9)
s.Show("append(nums, 4, 9)", nums)
// -----------------------------------------------------
// let's reset nums again
// let's add multiple elements using the ellipsis
nums = []int{1, 2, 3}
tens := []int{12, 13}
s.Show("nums = []int{1, 2, 3}", nums)
s.Show("tens := []int{12, 13}", tens)
nums = append(nums, tens...)
s.Show("append(nums, tens...)", nums)
}

View File

@ -1,26 +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 (
s "github.com/inancgumus/prettyslice"
)
func main() {
var basket []string
basket = append(basket, "banana")
basket = append(basket, "milk", "apple")
todo := []string{"tea", "coffee", "salt"}
basket = append(basket, todo...)
_ = append(basket, "pepper")
s.Show("my basket", basket)
}

View File

@ -1,40 +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 (
"math/rand"
"time"
s "github.com/inancgumus/prettyslice"
)
func main() {
rand.Seed(time.Now().UnixNano())
const max = 10
// max, _ := strconv.Atoi(os.Args[1])
var uniques [max]int
loop:
for found := 0; found < max; {
n := rand.Intn(max + 1)
for _, u := range uniques {
if u == n {
continue loop
}
}
uniques[found] = n
found++
}
s.Show("Uniques", uniques)
}

View File

@ -1,43 +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 (
"math/rand"
"os"
"strconv"
"time"
s "github.com/inancgumus/prettyslice"
)
func main() {
rand.Seed(time.Now().UnixNano())
max, _ := strconv.Atoi(os.Args[1])
// declare an uninitialized nil slice
var uniques []int
loop:
// you can still use the len function on a nil slice
for len(uniques) < max {
n := rand.Intn(max + 1)
for _, u := range uniques {
if u == n {
continue loop
}
}
// let's grow the slice by appending
uniques = append(uniques, n)
}
s.Show("Uniques", uniques)
}

View File

@ -1,28 +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"
s "github.com/inancgumus/prettyslice"
)
func main() {
me := []byte{'m', 'e'}
yo := []byte{'y', 'o', '!'}
s.Show("me [before]", me)
s.Show("yo [before]", yo)
N := copy(me, yo)
fmt.Printf("%d element(s) copied.\n", N)
s.Show("me [after]", me)
s.Show("yo [after]", yo)
}

View File

@ -1,44 +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"
s "github.com/inancgumus/prettyslice"
)
func main() {
// we've received the raining probabilities
data := []float64{10, 25, 30, 50}
s.Show("Probabilities", data)
fmt.Printf("Is it gonna rain? %.f%% chance.\n",
(data[0]+data[1]+data[2]+data[3])/
float64(len(data)))
// -----------------------------------------------------
// but it turns out that the first two items of the data
// has been corrupted by a hacker.
//
// this time, we've received clean data.
// let's overwrite the invalid data by copying
copy(data, []float64{80, 90})
// why copy? why not just assign and overwrite?
// because: it overwrites the whole slice
// data = []float64{80, 90}
s.Show("Probabilities", data)
fmt.Printf("Is it gonna rain? %.f%% chance.\n",
(data[0]+data[1]+data[2]+data[3])/
float64(len(data)))
}

View File

@ -1,78 +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"
s "github.com/inancgumus/prettyslice"
)
/*
If you find this code hard to understand, please comment
some parts of it and run it again.
*/
func main() {
// example #1
slice := []int{5, 6, 7, 8, 9}
s.Show("slice", slice)
// fmt.Println("slice[0]:", slice[0])
// fmt.Println("slice[1]:", slice[1])
// fmt.Println("slice[2]:", slice[2])
// fmt.Println("slice[3]:", slice[3])
// fmt.Println("slice[4]:", slice[4])
// example #2
sliced := slice[1:4]
s.Show("slice[1:4]", sliced)
// fmt.Println("sliced[0]:", sliced[0])
// fmt.Println("sliced[1]:", sliced[1])
// fmt.Println("sliced[2]:", sliced[2])
// fmt.Println("sliced[3]:", sliced[3]) // -> you can't
// example #3
// the new slice will also be effected from this change
sliced = append(sliced, 15)
slice[1] = 200
s.Show("append(sliced, 15)", sliced)
// example #3b
// the new slice won't be effected anymore
// because, go has created a new array for the `s`
sliced = append(sliced, 3)
slice[1] = 0
s.Show("slice[1] = 0", slice)
s.Show("sliced", sliced)
// example #4
// its pointer will stay the same until 8 elements
sliced = append(sliced, 10, 11, 12)
s.Show("append(sliced, 10, 11, 12)", sliced)
// now it will change: 13 the wicked number!
sliced = append(sliced, 13)
s.Show("append(sliced, 13)", sliced)
// example #5
var (
// just declaring it will make it nil
nilButHappy []int
// without any elements will make empty
empty = []int{}
)
s.Show("Empty Slice", empty)
s.Show("Nil Slice", nilButHappy)
fmt.Println("empty == nil?", empty == nil)
fmt.Println("nilButHappy == nil?", nilButHappy == nil)
}

View File

@ -1,36 +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 (
s "github.com/inancgumus/prettyslice"
)
// Please uncomment the examples below to see the results
func main() {
colors := []string{"black", "white"}
// 1st example
vivid := colors
vivid[0] = "orange"
// 2nd example
// vivid = nil
// 3th example
vivid = append(colors, "yellow")
vivid[0] = "gray"
// 4th example
colors = append(colors, "yellow")
colors[0] = "gray"
s.Show("colors slice header", colors)
s.Show("vivid slice header", vivid)
}

View File

@ -1,18 +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 s "github.com/inancgumus/prettyslice"
func main() {
slicable := []byte{'c', 'o', 'l', 'o', 'r'}
s.Show("slicable[0:5]", slicable[0:5])
s.Show("slicable[0:2]", slicable[0:2])
s.Show("slicable[3:5]", slicable[3:5])
s.Show("slicable[1:4]", slicable[1:4])
}

View File

@ -1,56 +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"
s "github.com/inancgumus/prettyslice"
)
func main() {
// 1. slicing creates a new slice
nums := []int{1, 3, 5, 2, 4, 8}
odds := nums[:3]
evens := nums[3:]
// 2. backing array is shared
nums[1], nums[3] = 9, 6
s.Show("nums", nums)
s.Show("odds : nums[:3]", odds)
s.Show("evens: nums[3:]", evens)
// 3. you can create a new slice from an array
heyArr := [3]byte{'h', 'e', 'y'}
hey, he := heyArr[:], heyArr[:2]
// 4. sliced array will be shared among the slices
heyArr[0] = 'm'
s.Show("hey := heyArr[:]", hey)
s.Show("he := heyArr[:2]", he)
// 5. index expression returns a value
// while a slice expression returns a slice
s.Show("nums[0]", nums[0])
s.Show("nums[0:1]", nums[0:1])
fmt.Printf("nums[0] : %T\n", nums[0]) // just int
fmt.Printf("nums[0:1]: %T\n", nums[0:1]) // []int slice
// 6. extending a slice up to its capacity
first := nums[0:1]
s.Show("first := nums[0:1]", first)
s.Show("first[0:2]", first[0:2])
s.Show("first[0:3]", first[0:3])
s.Show("first[0:4]", first[0:4])
s.Show("first[0:5]", first[0:5])
s.Show("first[0:6]", first[0:6])
// s.Show("first[0:7]", first[0:7]) // <- you can't
first = append(first[0:6], 9)
s.Show("first: with a new backing array", first)
}

View File

@ -1,23 +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 s "github.com/inancgumus/prettyslice"
func main() {
ships := []string{
"Normandy", "Verrikan", "Nexus",
}
// frigates := ships[:2]
frigates := ships[:2:2]
frigates = append(frigates, "Warsaw")
s.Show("Ships", ships)
s.Show("Frigates", frigates)
}

View File

@ -1,31 +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 s "github.com/inancgumus/prettyslice"
func main() {
// #1: make preallocates an array
nums := make([]int, 0, 10)
nums = append(nums, 1, 2, 3)
nums = append(nums, 4, 5)
s.Show("nums", nums)
nums = append(nums, 6)
s.Show("nums: doesn't allocate", nums)
// #2: prevent overwriting with make
doubles := make([]int, len(nums) /*, 12 */)
for i := range nums {
doubles[i] = nums[i] * 2
}
s.Show("nums: after doubling", nums)
s.Show("doubles", doubles)
}

View File

@ -1,181 +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
//
// Post your solution to twitter with this hashtag:
// #learngoprogramming
//
// Notify me on twitter by adding my account to your tweet:
// @inancgumus
//
//
//
// This document contains what you need to do to create
// the bouncing ball animation.
//
// You're going to learn a great deal of knowledge about
// slices and you'll earn a good experience while doing this.
//
// However, refer to this document only when you get stuck.
// Do not follow it step by step.
// Try to solve the challenge on your own.
//
// This document organized into steps/sections.
// So you can jump to that step/section directly.
//
// Good luck!
//
//
// #1 Declare constants here.
//
// The width and the height of the board.
// You're going to draw your board using these.
func main() {
//
// -> Declare ball positions: X and Y
// Initialize them to 0s.
// -> Declare ball's velocity: xVelocity and yVelocity
//
// Velocity means: Speed and Direction
// X velocity = 1 // balls moves to the right
// X velocity = -1 // balls moves to the left
// Y velocity = 1 // balls moves down
// Y velocity = -1 // balls moves up
//
// -> On each step, add velocities to ball's position.
//
// 🎾 CREATE THE BOARD
//
//
// -> Use the make function to initialize your board.
// Remember: You also need to initialize each sub-slice.
// (in a for loop)
//
// -> You can use [][]bool for your board.
//
// Because, when you set one of the items to true,
// then you know that the ball is in that position.
//
// EXAMPLE:
// false false false false
// false true -+ false false
// false false | false false
// v
// the ball is here
// board[1][1] is true
//
// 🎾 DRAWING LOOP
//
// {
//
// Create a loop.
//
// On each step of the loop, you're going to:
// -> Clear the board
// -> Calculate the next ball position
// -> Draw the board with the balls
//
// 🎾 CLEAR THE BOARD
//
// -> Set all the board elements to false.
// (I mean the sub-slices' elements)
//
// 🎾 CALCULATE THE NEXT BALL POSITION
//
// -> Add the velocities to the ball's current position:
//
// X += xVelocity
// Y += yVelocity
//
// 👉 When ball hits the borders change its direction.
//
// -> Multiply the velocity by -1 to change its X direction.
// -> Do the same for the Y velocity as well.
// 👉 Set the ball's position in the board.
//
// -> You will use this information when drawing the board.
//
// 🎾 DRAW THE BOARD
//
// -> Make a large enough []rune `buffer`.
//
// HINT: width * height will give you a large enough buffer.
// TIP : You could also use string but it would be inefficient.
//
// 👉 FILL YOUR BUFFER:
//
// + It's better to use buffers for these kind of things.
// + It's worst to call the Print functions all the time.
//
// 1. Loop for the height of the board.
// 2. Then in a nested loop, loop for the width of the board.
//
// 👉 NESTEP LOOP (WIDTH LOOP):
//
// In each step of the nested loop, do this:
//
// 1. Check whether the ball is in the x, y positions.
// You need to check for it using your board slice.
//
// 2. If so, append this tennis ball '🎾' to the buf slice.
// 3. If not, append this pool ball '🎱' to the buf slice.
//
// 👉 HEIGHT LOOP:
//
// After the nested loop (but in the height loop):
//
// 1. Append the newline character to the buf: '\n'
// This will allow you to print the next row to the
// next line.
//
// 🎾 PRINT THE BOARD
//
// After the loop print this to clear the screen.
//
// fmt.Print("\033[2J")
//
// Note : This will only work in Linux and Mac.
// For Windows: Just install Ubuntu bash on Windows, it's easy now!
// It isn't a virtual machine.
// https://docs.microsoft.com/en-us/windows/wsl/install-win10
//
// 👉 PRINT YOUR BOARD (USING THE BUFFER):
//
// -> Do not forget converting it to string.
// Because your buffer is []rune.
//
// fmt.Print(string(buf))
//
// You'll learn the details about rune and strings later.
//
// 👉 SLOW DOWN THE SPEED
// And lastly, call the time.Sleep function to slow down
// the speed of the loop, so you can see the ball :)
//
// time.Sleep(time.Millisecond * 60)
// } DRAWING LOOP ENDS HERE 👈
}

View File

@ -1,47 +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"
)
const (
width = 25
height = 8
)
func main() {
// -------------------------------------------------
// CREATE THE BOARD
// -------------------------------------------------
board := make([][]bool, width)
for row := range board {
board[row] = make([]bool, height)
}
// -------------------------------------------------
// DRAW THE BOARD
// -------------------------------------------------
var (
buf = make([]rune, 0, width*height)
ball rune
)
for y := range board[0] {
for x := range board {
ball = '🎱'
if board[x][y] {
ball = '🎾'
}
buf = append(buf, ball, ' ')
}
buf = append(buf, '\n')
}
fmt.Print(string(buf))
}

View File

@ -1,64 +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"
"time"
)
const (
width = 25
height = 8
maxFrames = 1200
)
func main() {
// -------------------------------------------------
// CREATE THE BOARD
// -------------------------------------------------
board := make([][]bool, width)
for row := range board {
board[row] = make([]bool, height)
}
var X, Y int // ball positions
for i := 0; i < maxFrames; i++ {
// draw after a while: slows down the animation
time.Sleep(time.Second / 20)
// -------------------------------------------------
// PUT THE BALL
// -------------------------------------------------
board[X][Y] = true
// -------------------------------------------------
// DRAW THE BOARD
// -------------------------------------------------
var (
buf = make([]rune, 0, width*height)
ball rune
)
for y := range board[0] {
for x := range board {
ball = '🎱'
if board[x][y] {
ball = '🎾'
}
buf = append(buf, ball, ' ')
}
buf = append(buf, '\n')
}
// clear the screen and draw the board
fmt.Print("\033[2J", string(buf))
}
}

View File

@ -1,87 +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"
"time"
)
const (
width = 25
height = 8
maxFrames = 1200
)
func main() {
// -------------------------------------------------
// CREATE THE BOARD
// -------------------------------------------------
board := make([][]bool, width)
for row := range board {
board[row] = make([]bool, height)
}
var (
X, Y int // ball positions
xVel, yVel = 1, 1 // velocities
)
for i := 0; i < maxFrames; i++ {
// draw after a while: slows down the animation
time.Sleep(time.Second / 20)
// -------------------------------------------------
// CALCULATE THE NEXT BALL POSITION
// -------------------------------------------------
X += xVel
Y += yVel
// when the ball hits the borders change its direction
// by changing its velocity
if X <= 0 || X >= width-1 {
xVel *= -1
}
if Y <= 0 || Y >= height-1 {
yVel *= -1
}
// -------------------------------------------------
// CLEAR THE BOARD AND PUT THE BALL
// -------------------------------------------------
for y := range board[0] {
for x := range board {
board[x][y] = false
}
}
board[X][Y] = true
// -------------------------------------------------
// DRAW THE BOARD
// -------------------------------------------------
var (
buf = make([]rune, 0, width*height)
ball rune
)
for y := range board[0] {
for x := range board {
ball = '🎱'
if board[x][y] {
ball = '🎾'
}
buf = append(buf, ball, ' ')
}
buf = append(buf, '\n')
}
// clear the screen and draw the board
fmt.Print("\x0c", string(buf))
}
}

View File

@ -1,8 +0,0 @@
# WARNING
For the code in this section, you should install my prettyslice library.
## STEPS
1. Open your command-line
2. Type: `go get github.com/inancgumus/prettyslice`
3. That's all.

1
15-slices/README.md Normal file
View File

@ -0,0 +1 @@
This section is in progress. I'm working hard to update the course all the time. Hold on!

View File

@ -1,45 +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"
func main() {
var g, o rune
g, o = 'g', 'o'
g, o = 103, 111
g, o = 0x67, 0x6f
g, o = '\U00000067', '\U0000006f'
g, o = '\u0067', '\u006f'
g, o = '\x67', '\x6f'
fmt.Println("codepoints")
fmt.Printf(" dec : %d %d\n", g, o)
fmt.Printf(" hex : %x %x\n", g, o)
fmt.Printf(" unicode : %U %U\n", g, o)
fmt.Printf(" chars : %c %c\n", g, o)
// g++
// o -= 6
g -= 'a' - 'A'
o -= 'a' - 'A'
fmt.Println("codepoints")
fmt.Printf(" dec : %d %d\n", g, o)
fmt.Printf(" hex : %x %x\n", g, o)
fmt.Printf(" unicode : %U %U\n", g, o)
fmt.Printf(" chars : %c %c\n", g, o)
// string representations
// fmt.Print("string() : ", string(g), string(o), "\n")
// fmt.Print("hex 1 byte : \x67\x6f \n")
// fmt.Print("hex 2 bytes : \u0067\u006f \n")
// fmt.Print("hex 4 bytes : \U00000067\U0000006f \n")
}

View File

@ -1,28 +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"
func main() {
msg := "WONDERFUL!"
bytes := []byte(msg)
fmt.Println("msg :", msg)
fmt.Println("bytes :", bytes)
fmt.Println("string(bytes) :", string(bytes))
fmt.Println("string(87) :", string(87))
fmt.Println()
for i, v := range msg {
fmt.Printf(
"msg[%d] : %d = %[2]q\n",
i, v)
}
}

View File

@ -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 (
"fmt"
)
func main() {
// GOALS:
// 1- String value is immutable
// 2- Indexing vs Slicing
// 3- Using bytes for manipulating strings
mood := "wonder"
// 1- a string value is immutable (read-only)
// mood[1] = 'a'
// 2- Indexing vs Slicing
// "wonder"
// ^ ^^^^
// | ||||
// "wandering"
// "w" + "a" + "nder" + "ing"
// wandering := mood[0] + "a" + mood[2:] + "ing"
// fmt.Printf("mood[0] : %T - %[1]v\n", mood[0]) // byte
// fmt.Printf("mood[0:1] : %T - %[1]v\n", mood[0:1]) // string
// wandering := mood[:1] + "a" + mood[2:] + "ing"
fmt.Println(mood)
// fmt.Println(wandering)
// 3- converting creates a new byte slice (allocation)
b := []byte(mood)
b[1] = 'a'
// b = append(b, 'i', 'n', 'g')
// b = append(b, []byte{'i', 'n', 'g'})
b = append(b, "ing"...)
// starts copying from the first element
copy(b, "listen")
// starts copying from the "7th" element
copy(b[6:], "ed.")
fmt.Println(string(b))
}

View File

@ -1,77 +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/
//
/*
------------------------------------------------------------
RULES
------------------------------------------------------------
* You shouldn't use a standard library function.
* You should only solve the challenge by manipulating the bytes directly.
* Manipulate the bytes of a string using indexing, slicing, appending etc.
* Be efficient: Do not use string concat (+ operator).
* Instead, create a new byte slice as a buffer from the given string argument.
* Then, manipulate it during your program.
* And, for once, print that buffer.
------------------------------------------------------------
STEPS
------------------------------------------------------------
* Mask only links starting with http://
* Don't check for uppercase/lowercase letters
* The goal is to learn manipulating bytes in strings
* It's not about creating a perfect masker
* For example: A spammer can prevent the masker like this (for now this is OK):
"Here's my spammy page: hTTp://youth-elixir.com"
* But, you should catch this:
"Here's my spammy page: http://hehefouls.netHAHAHA see you."
"Here's my spammy page: http://******************* see you."
*/
package main
func main() {
// ---------------------------------------------------------------
// #1
// ---------------------------------------------------------------
// Check whether there's a command line argument or not
// If not, quit from the program with a message
// ---------------------------------------------------------------
// #2
// ---------------------------------------------------------------
// Create a byte buffer as big as the argument
// ---------------------------------------------------------------
// #3
// ---------------------------------------------------------------
// 1- Loop and detect the http:// patterns
// 2- Copy the input character by character to the buffer
// 3- If you detect http:// pattern, copy the http:// first,
// then copy the *s instead of the original link until
// you see a whitespace character.
//
// Here: http://www.mylink.com Click!
// -> Here: http://************** Click!
//
// ---------------------------------------------------------------
// #4
// ---------------------------------------------------------------
// Print the buffer as a string
}

View File

@ -1,7 +0,0 @@
Hi guys,
Here is my new spammy webpage http://www.mysuperpage.com <-- This is my website!
Please click on the link now!!!
When you click, I will be rich, thanks!

View File

@ -1,88 +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/
//
/*
#1- Get and check the input
#2- Create a buffer with a sufficient size
#3- Write input to the buffer as it is and print it
#4- Detect the link
#5- Mask the link
#6- Detect white spaces and disable the masking
#7- Write http:// to the buffer, just before the link
*/
package main
import (
"fmt"
"os"
)
const (
link = "http://"
mask = '*'
)
func main() {
args := os.Args[1:]
if len(args) != 1 {
fmt.Println("gimme somethin' to censor!")
return
}
var (
text = args[0]
size = len(text)
// create a sufficient buffer for the output
//
// and adjust its slice pointer to the first element
// of the backing array! -> make(..., 0, ...)
buf = make([]byte, 0, size)
in bool
)
for i := 0; i < size; i++ {
nlink := len(link)
// slice the input and look for the link pattern
// do not slice it when it goes beyond the input text's capacity
if len(text[i:]) >= nlink && text[i:i+nlink] == link {
// jump to the next character after "http://"
i += nlink
// set the flag: we're in a link! -> "http://....."
in = true
// add the "http://" manually
buf = append(buf, link...)
}
// get the current byte from the input
c := text[i]
// disable the link detection flag
// this will prevent masking the rest of the bytes
switch c {
case ' ', '\t', '\n': // try -> unicode.IsSpace
in = false
}
// if we're in the link detection mode (inside the link bytes)
// then, mask the current character
if in {
c = mask
}
// add the current character to the buffer
buf = append(buf, c)
}
// print out the buffer as text (string)
fmt.Println(string(buf))
}

View File

@ -1,7 +0,0 @@
Hi guys,
Here is my new spammy webpage http://www.mysuperpage.com <-- This is my website!
Please click on the link now!!!
When you click, I will be rich, thanks!

View File

@ -1,144 +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"
"unicode/utf8"
"unsafe"
)
// Please run this code and experiment with it
// Observe the results
// USELESS-NOTE : "Öykü" means "Story" in Turkish!
func main() {
fmt.Println("-----------------------------------")
fmt.Println("ASCII Codepoints")
fmt.Println("-----------------------------------")
var (
a, z byte = 'a', 'z'
A, Z byte = 'A', 'Z'
d0, d9 byte = '0', '9'
)
for _, c := range []byte{a, z, A, Z, d0, d9} {
fmt.Printf("%c - 1 byte - %[1]U - %[1]d\n", c)
}
fmt.Println("\n-----------------------------------")
fmt.Println("Unicode Codepoints")
fmt.Println("-----------------------------------")
var (
Ö = 'Ö'
= '栗'
monkey = '🙉'
)
for _, c := range []rune{rune(A), Ö, , monkey} {
fmt.Printf("%c - %d bytes - %[1]U - %[1]d\n", c, cptb(c))
}
fmt.Println("\n-----------------------------------")
fmt.Println("UTF-8 Encoded")
fmt.Println("-----------------------------------")
// utf8.RuneLen finds the number of bytes necessary for
// encoding a codepoint to utf8
for _, c := range []rune{rune(A), Ö, , monkey} {
fmt.Printf("%c - %d bytes - %[1]U - %[1]d\n", c,
utf8.RuneLen(c))
}
fmt.Println("\n-----------------------------------")
fmt.Println("Example: Unicode Codepoints")
fmt.Println("-----------------------------------")
var (
ö = 'ö'
y = 'y'
k = 'k'
ü = 'ü'
)
var (
oykuRunes = []rune{ö, y, k, ü}
total int
)
for _, c := range oykuRunes {
fmt.Printf("%c - %d bytes - %[1]U - %[1]d\n", c, cptb(c))
// unsafe.Sizeof finds the memory size of simple values
// don't use it in production-level code -> it's unsafe!
total += int(unsafe.Sizeof(c))
}
fmt.Printf("TOTAL: %d bytes.\n", total)
fmt.Println("\n-----------------------------------")
fmt.Println("Example: Indexing")
fmt.Println("-----------------------------------")
fmt.Printf("%c%c%c%c\n",
oykuRunes[0], oykuRunes[1], oykuRunes[2],
oykuRunes[len(oykuRunes)-1])
// string to []rune
oykuRunes = []rune("öykü")
fmt.Printf("%c%c%c%c\n",
oykuRunes[0], oykuRunes[1], oykuRunes[2],
oykuRunes[len(oykuRunes)-1])
fmt.Println("\n-----------------------------------")
fmt.Println("Example: UTF-8 Encoding")
fmt.Println("-----------------------------------")
// this is also ok
// oykuString := string(oykuRunes)
oykuString := "öykü"
fmt.Printf("TOTAL bytes in oykuRunes : %d\n", total)
fmt.Printf("TOTAL bytes in oykuString: %d\n", len(oykuString))
fmt.Printf("TOTAL runes in oykuString: %d\n",
utf8.RuneCountInString(oykuString))
fmt.Printf("Runes of oykuString : %s\n", oykuString)
fmt.Printf("Bytes of oykuString : % x\n", oykuString)
fmt.Println()
for i := 0; i < len(oykuString); i++ {
fmt.Printf("oykuString[%d]: %c\n", i, oykuString[i])
}
// slicing returns a slice with the type of the sliced value
// so, the sliced value is a string, then a string is returned
//
// example:
// oykuString[0:2] is a string
fmt.Println()
fmt.Printf("oykuString[0:2]: %q\n", oykuString[0:2])
fmt.Printf("oykuString[4:6]: %q\n", oykuString[4:6])
}
// -------------------------------------------------------------------
// cptb finds how many bytes are necessary to represent a codepoint
// cptb means codepoint to bytes
func cptb(r rune) int {
switch {
case r <= 0xFF: // 255
return 1
case r <= 0xFFFF: // 65,535
return 2
case r <= 0xFFFFF: // 16,777,215
return 3
}
return 4
}

View File

@ -1,60 +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"
"unicode/utf8"
"unsafe"
)
func main() {
// try yourself: try other runes!
// you can find more here: https://unicode-table.com
// r := '🙉'
// r := '\u011e'
r := 'Ğ'
// only codepoint (can't be printed)
fmt.Printf("before encoding: %d\n", r)
fmt.Printf(" bits : %016b\n", r)
fmt.Printf(" bytes: % x\n", r)
// utf-8 encoded string
encoded := string(r)
encodedBytes := []byte(encoded)
fmt.Println()
fmt.Printf("after encoding: %q\n", encoded)
fmt.Printf(" bits : %8b\n", encodedBytes)
fmt.Printf(" bytes: % x\n", encodedBytes)
// utf-8 string efficient to store and transmit
// but, it's harder to use.
//
// rune slice is inefficient.
// but, it's easy to use.
fmt.Println()
fmt.Println("string (utf-8) vs []rune (unicode)")
s := "hava çok güzel 😳"
fmt.Printf("%q\n", s)
fmt.Printf(" size : %d bytes\n", len(s))
fmt.Printf(" len : %d chars\n", utf8.RuneCountInString(s))
fmt.Printf(" s[5] : %q\n", s[5])
fmt.Printf(" s[5:7] : %q\n", s[5:7])
runes := []rune(s)
size := int(unsafe.Sizeof(runes[0])) * len(runes)
fmt.Printf("\n%q\n", runes)
fmt.Printf(" size : %d bytes\n", size)
fmt.Printf(" len : %d chars\n", len(runes))
fmt.Printf(" runes[5] : %q\n", runes[5])
}

View File

@ -1,66 +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"
"unicode"
"unicode/utf8"
)
const lineWidth = 40
func main() {
text := `Galaksinin Batı Sarmal Kolu'nun bir ucunda, haritası bile çıkarılmamış ücra bir köşede, gözlerden uzak, küçük ve sarı bir güneş vardır.
Bu güneşin yörüngesinde, kabaca yüz kırksekiz milyon kilometre uzağında, tamamıyla önemsiz ve mavi-yeşil renkli, küçük bir gezegen döner.
Gezegenin maymun soyundan gelen canlıları öyle ilkeldir ki dijital kol saatinin hâlâ çok etkileyici bir buluş olduğunu düşünürler.`
var lw int // line width
for _, r := range text {
fmt.Printf("%c", r)
switch lw++; {
case lw > lineWidth && r != '\n' && unicode.IsSpace(r):
fmt.Println()
fallthrough
case r == '\n':
lw = 0
}
}
fmt.Println()
}
// call it like: runeHandler(text)
func runeHandler(text string) {
for i := 0; i < len(text); {
r := rune(text[i])
size := 1
if r > utf8.RuneSelf {
r, size = utf8.DecodeRuneInString(text[i:])
// check out the other functions as well, play with them!
//
// for example (type these into the command-line):
// go doc utf8
// go doc utf8 EncodeRune
}
i += size
fmt.Printf("%c", r)
}
}
// call it like: byteHandler(text)
func byteHandler(text string) {
for i := 0; i < len(text); i++ {
fmt.Printf("%c", text[i])
}
}

View File

@ -1,45 +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"
"unsafe"
)
func main() {
// empty := ""
// dump(empty)
hello := "hello"
dump(hello)
dump("hello")
dump("hello!")
for i := range hello {
dump(hello[i : i+1])
}
dump(string([]byte(hello)))
dump(string([]byte(hello)))
dump(string([]rune(hello)))
}
// StringHeader is used by a string value
// In practice, you should use: reflect.Header
type StringHeader struct {
// points to a backing array's item
pointer uintptr // where it starts
length int // where it ends
}
// dump prints the string header of a string value
func dump(s string) {
ptr := *(*StringHeader)(unsafe.Pointer(&s))
fmt.Printf("%q: %+v\n", s, ptr)
}

View File

@ -0,0 +1 @@
This section is in progress. I'm working hard to update the course all the time. Hold on!

View File

@ -1,83 +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"
"os"
"strconv"
"strings"
)
const (
asciiStart = '\u0001' // 1
asciiStop = '\u007f' // 127
cols = 1
)
func main() {
// DETERMINE START - STOP POSITIONS
var start, stop int
if args := os.Args[1:]; len(args) == 2 {
start, _ = strconv.Atoi(args[0])
stop, _ = strconv.Atoi(args[1])
}
if start == 0 || stop == 0 {
start, stop = asciiStart, asciiStop
}
// PRINT HEADER
for i := 0; i < cols; i++ {
fmt.Printf("| %-6s %-8s %-8s %-14s", "rune", "dec", "code", "bytes")
}
fmt.Print("\n", strings.Repeat("-", 40*cols), "\n")
// PRINT TABLE
for n, l := start, 0; n <= stop; n++ {
// draw the line
fmt.Printf("| %-6q %-8d %-8U % -14x", n, n, n, string(n))
// go to next line if columns are consumed
if l++; l%cols == 0 {
fmt.Println()
continue
}
}
fmt.Println()
}
/*
EXAMPLE BLOCKS
1 byte
------------------------------------------------------------
asciiStart = '\u0001' -> 32
asciiStop = '\u007f' -> 127
2 bytes
------------------------------------------------------------
latin1Start = '\u0080' -> 128
latin1Stop = '\u00ff' -> 255
3 bytes
------------------------------------------------------------
dingbatStart = '\u2700' -> 9984
dingbatStop = '\u27bf' -> 10175
4 bytes
------------------------------------------------------------
emojiStart = '\U0001f600' -> 128512
emojiStop = '\U0001f64f' -> 128591
transportStart = '\U0001F680' -> 128640
transportStop = '\U0001f6ff' -> 128767
BIG THANK YOU! -> https://unicode-table.com/
*/

View File

@ -1,233 +0,0 @@
# Strings Revisited
## Bytes
* ASCII
* Immutable
## Runes
* Unicode
* vs ASCII
* UTF-8
* Made up of bytes
## Slicing
* String: Read-Only Byte Slice
* Slicing -> String
* Index -> Byte
---
## Read-only byte slice
* A string is a read-only slice
* You can't change its data
* Indexable: Returns you a byte
* Slicable: Returns you a string
## Slicing
* Strings can be sliced just like a slice
* After slicing Go returns you a new string slice
* WARNING: Indexing expression returns you a byte
* s := "hey"
* s[0] + s[1] + s[2] != "hey"
* s[0:3] == "hey
## Underlying array
* Underlying array is a string array
* There's no capacity this time: Only length and pointer.
* Sliced string will refer to that array
* String slicing is cheap — They share the same array
## Unicode
* At the beginning there was only ASCII code standard
* It was using 7-bits to represents 128 characters
* Only English characters
* Each code corresponding to a character
* After Internet nothing couldn't stay the same
* There was a need to introduce more languages
* 127 characters aren't enough for the entire world
* So: Unicode is born
* It collects all of the characters in world's languages
* Unicode can represent every character in every imaginable language system.
* Assigns each character to a codepoint or a rune (in Go)
* Unicode assigns each character a unique number, or code point.
* Codepoint is a numeric number which represents a character in general
* U+2700 -> hex
* Unicode defines codepoints for 1m+ characters
* It includes the ASCII codes too
A chinese character: 汉
Its unicode value: U+6C49
convert 6C49 to binary: 01101100 01001001
embed 6C49 as UTF-8: 11100110 10110001 10001001
## Unicode and Runes
* Rune is a 4-bytes type for storing unicode codepoints
* Rune data type and rune codepoints are different things!
* There's UTF-32 standard which assigns 4 bytes to each codepoint
* But, that's inefficient, so, instead Go uses a variable encoding standard called UTF-8. It assigns different number of bytes to codepoints.
* UTF-8 has been invented by Rob Pike and Ken Thompson (two of the creators of Go)
* So, a rune is 1-4 bytes. Uses 1 byte for ASCII (english).
* 2-3 bytes for most of the characters.
* A string can contain runes
* Each rune can span to multiple bytes
* WARNING: Getting one byte of a string may give you corrupt data
* If you're getting one part of a rune inside the string!
* In a string with runes, you can't easily index the characters
* You need to use unicode and utf8 packages
* Or you need to convert the string into a rune slice
* unicode: letters vs nums, to uppercase, ...
* utf8 : working w/bytes and runes
* RuneCountInString(s) == len([]rune(s))
* DecodeRuneInString(s) returns the first rune
## Ranging over strings
* You can range over a string like a slice
* It will jump over the runes inside the string
* The index variable will be the starting position of each rune
* And the value will be the rune itself
## Representing bytes
* Unicode characters can be hard to type in code
* So, we can use \x and \u in a string to represent bytes and runes
* A string literal is always utf-8 but a string value is not
## Convenience
* It's easy to work with runes in code: []rune
* However, it will consume more memory: Each char is 4 bytes
* "inanç"[4] = gibberish
* r := []rune("inanç") -> five elements rune slice
* r[4] = 'ç'
* string(r)
* // inanç: automatically concatenates the runes to form a string
* string(105) // i -> interprets 105 as a rune value; 'i' not 105
* string(351) // ş -> ""
* printf: %q -> 'ç' %c -> ç %d -> 231
## Bytes
* major libs:
* strings, bytes (have corresponding funcs)
* strconv, unicode
* bytes.Buffer
* []byte can be modified whereas string is immutable
* if you do a lot of string manipulations you can use []byte
* []byte <-> string convertable
* but, each conversion copies the data
* compiler optimizes it mostly
* however, do not blindly convert; use bytes pkg
* it's like the string pkg
* s := "inanc"
* b := []byte(s)
* s := string(b)
## Sprintf
* Just like printf but instead of printing it returns a string
## Builders
* bytes.Buffer
* strings.Builder
* Use WriteRune when adding rune
## Terminology:
Summary: Unicode is a large table mapping characters to numbers and the different UTF encodings specify how these numbers are encoded as bits.
* **ASCII** First character set that maps characters to codepoints or character codes. In terms of alphabets, it only supports basic latin alphabet: English. 2^7=127
* The center of the computer industry was in the USA at that time. As a consequence, they didn't need to support accents or other marks such as á, ü, ç, ñ, etc.
* Once upon a time, computer memory and storage was very expensive. And all of the computers in the world (for practical purposes) were in the hands of English-speaking countries.
* Single byte encoding only using the bottom 7 bits. Basic Latin. (Unicode code points 0-127.) No accents etc.
* **Unicode** is a coded character set. A set of characters and a mapping between the characters and integer code points representing them. Unicode is a superset of ASCII.
* You cannot save text to your hard drive as "Unicode". Unicode is an abstract representation of the text. You need to "encode" this abstract representation. That's where an encoding comes into play.
* Unicode first and foremost defines a table of code points for characters. That's a fancy way of saying "65 stands for A, 66 stands for B and 9,731 stands for ☃" (seriously, it does). How these code points are actually encoded into bits is a different topic.
* **UTF-8** is a character encoding - a way of converting from sequences of bytes to sequences of characters and vice versa. It covers the whole of the Unicode character set.
* UTF-8 uses the ASCII set for the first 128 characters. That's handy because it means ASCII text is also valid in UTF-8.
* **Character Set:** A character set is a list of characters with unique numbers (these numbers are sometimes referred to as “code points”). For example, in the Unicode character set, the number for A is 41.
* **Codepoint:** Characters are referred to by their "Unicode code point".
* Written in hexadecimal (to keep the numbers shorter).
* Preceded by a "U+" (that's just what they do, it has no other meaning than "this is a Unicode code point").
* Unicode itself is a mapping, it defines codepoints and a codepoint is a number, associated with usually a character.
* Code: a system of words, letters, figures, or other symbols substituted for other words, letters, etc.
* **Encoding:** Converting data into a coded form. An encoding on the other hand, is an algorithm that translates a list of numbers to binary so it can be stored on disk. For example UTF-8 would translate the number sequence 1, 2, 3, 4 like this: `00000001 00000010 00000011 00000100`. Our data is now translated into binary and can now be saved to disk.
* To encode means to use something to represent something else. An encoding is the set of rules with which to convert something from one representation to another.
* To represent 1,114,112 different values, two bytes aren't enough. Three bytes are, but three bytes are often awkward to work with, so four bytes would be the comfortable minimum. But, unless you're actually using Chinese or some of the other characters with big numbers that take a lot of bits to encode, you're never going to use a huge chunk of those four bytes.
* If the letter "A" was always encoded to 00000000 00000000 00000000 01000001, "B" always to 00000000 00000000 00000000 01000010 and so on, any document would bloat to four times the necessary size.
* To optimize this, there are several ways to encode Unicode code points into bits. UTF-8 is one of them.
character encoding bits
A UTF-8 01000001
A UTF-16 00000000 01000001
A UTF-32 00000000 00000000 00000000 01000001
U+0000 to U+007F are (correctly) encoded with one byte
U+0080 to U+07FF are encoded with 2 bytes
U+0800 to U+FFFF are encoded with 3 bytes
U+010000 to U+10FFFF are encoded with 4 bytes
* There is NO string or text, without an accompanying encoding standard.
## REFS:
https://unicode-table.com/en/
What's the difference between ASCII and Unicode?
https://stackoverflow.com/a/41198513/115363
https://stackoverflow.com/questions/643694/what-is-the-difference-between-utf-8-and-unicode
https://stackoverflow.com/questions/3951722/whats-the-difference-between-unicode-and-utf-8
https://stackoverflow.com/questions/1543613/how-does-utf-8-variable-width-encoding-work
http://kunststube.net/encoding/
(detailed and simple)
http://www.joelonsoftware.com/articles/Unicode.html
Unicode codepoint to UTF-8 encoding answer: https://stackoverflow.com/a/27939161/115363
http://www.polylab.dk/utf8-vs-unicode.html
Characters, Symbols and the Unicode Miracle - Computerphile
https://www.youtube.com/watch?v=MijmeoH9LT4
The history of UTF-8 as told by Rob Pike
http://doc.cat-v.org/bell_labs/utf-8_history