add: append lecture examples
This commit is contained in:
39
15-slices/05-append/1-theory/main.go
Normal file
39
15-slices/05-append/1-theory/main.go
Normal file
@ -0,0 +1,39 @@
|
||||
// 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", nums)
|
||||
|
||||
_ = append(nums, 4)
|
||||
s.Show("nums", nums)
|
||||
|
||||
nums = append(nums, 4)
|
||||
s.Show("nums", nums)
|
||||
|
||||
nums = append(nums, 9)
|
||||
s.Show("nums", nums)
|
||||
|
||||
nums = append(nums, 4)
|
||||
s.Show("nums", nums)
|
||||
|
||||
// or:
|
||||
// nums = append(nums, 4, 9)
|
||||
// s.Show("nums", nums)
|
||||
|
||||
nums = []int{1, 2, 3}
|
||||
tens := []int{12, 13}
|
||||
|
||||
nums = append(nums, tens...)
|
||||
s.Show("nums", nums)
|
||||
}
|
33
15-slices/05-append/2-example/main.go
Normal file
33
15-slices/05-append/2-example/main.go
Normal file
@ -0,0 +1,33 @@
|
||||
// For more tutorials: https://blog.learngoprogramming.com
|
||||
//
|
||||
// Copyright © 2018 Inanc Gumus
|
||||
// Learn Go Programming Course
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
//
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
s "github.com/inancgumus/prettyslice"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var todo []string
|
||||
|
||||
todo = append(todo, "sing")
|
||||
|
||||
// you can only append elements with the same element type of the slice
|
||||
// todo = append(todo, 42)
|
||||
|
||||
todo = append(todo, "run")
|
||||
|
||||
// append is a variadic function, so you can append multiple elements
|
||||
todo = append(todo, "code", "play")
|
||||
|
||||
// you can also append a slice to another slice using ellipsis: ...
|
||||
tomorrow := []string{"see mom", "learn go"}
|
||||
todo = append(todo, tomorrow...)
|
||||
// todo = append(todo, "see mom", "learn go")
|
||||
|
||||
s.Show("todo", todo)
|
||||
}
|
@ -0,0 +1 @@
|
||||
learngoprogramming.com
|
@ -0,0 +1 @@
|
||||
learngoprogramming.com
|
@ -0,0 +1 @@
|
||||
learngoprogramming.com
|
@ -0,0 +1,35 @@
|
||||
// For more tutorials: https://blog.learngoprogramming.com
|
||||
//
|
||||
// Copyright © 2018 Inanc Gumus
|
||||
// Learn Go Programming Course
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
//
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
args := os.Args[1:]
|
||||
if len(args) == 0 {
|
||||
fmt.Println("Provide a directory")
|
||||
return
|
||||
}
|
||||
|
||||
files, err := ioutil.ReadDir(args[0])
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
if file.Size() == 0 {
|
||||
name := file.Name()
|
||||
fmt.Println(name)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
learngoprogramming.com
|
@ -0,0 +1 @@
|
||||
learngoprogramming.com
|
@ -0,0 +1 @@
|
||||
learngoprogramming.com
|
@ -0,0 +1,50 @@
|
||||
// For more tutorials: https://blog.learngoprogramming.com
|
||||
//
|
||||
// Copyright © 2018 Inanc Gumus
|
||||
// Learn Go Programming Course
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
//
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
args := os.Args[1:]
|
||||
if len(args) == 0 {
|
||||
fmt.Println("Provide a directory")
|
||||
return
|
||||
}
|
||||
|
||||
files, err := ioutil.ReadDir(args[0])
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
var names []byte
|
||||
|
||||
for _, file := range files {
|
||||
if file.Size() == 0 {
|
||||
name := file.Name()
|
||||
|
||||
names = append(names, name...)
|
||||
names = append(names, '\n')
|
||||
}
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile("out.txt", names, 0644)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("%s", names)
|
||||
}
|
||||
|
||||
// See: https://www.tutorialspoint.com/unix/unix-file-permission.htm
|
||||
// See: http://permissions-calculator.org/
|
38
x-tba/slices/07-slice-expressions/1-theory/main.go
Normal file
38
x-tba/slices/07-slice-expressions/1-theory/main.go
Normal file
@ -0,0 +1,38 @@
|
||||
// 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() {
|
||||
msg := []byte{'h', 'e', 'l', 'l', 'o'}
|
||||
s.Show("msg", msg)
|
||||
|
||||
s.Show("msg[0:1]", msg[0:1])
|
||||
s.Show("msg[0:2]", msg[0:2])
|
||||
s.Show("msg[0:3]", msg[0:3])
|
||||
s.Show("msg[0:4]", msg[0:4])
|
||||
s.Show("msg[0:5]", msg[0:5])
|
||||
|
||||
// default indexes
|
||||
s.Show("msg[0:]", msg[0:])
|
||||
s.Show("msg[:5]", msg[:5])
|
||||
s.Show("msg[:]", msg[:])
|
||||
|
||||
// error: beyond
|
||||
// s.Show("msg", msg)[:6]
|
||||
|
||||
s.Show("msg[1:4]", msg[1:4])
|
||||
|
||||
s.Show("msg[1:5]", msg[1:5])
|
||||
s.Show("msg[1:]", msg[1:])
|
||||
|
||||
s.Show("append(msg)", append(msg[:4], '!'))
|
||||
}
|
59
x-tba/slices/07-slice-expressions/2-example/main.go
Normal file
59
x-tba/slices/07-slice-expressions/2-example/main.go
Normal file
@ -0,0 +1,59 @@
|
||||
// For more tutorials: https://blog.learngoprogramming.com
|
||||
//
|
||||
// Copyright © 2018 Inanc Gumus
|
||||
// Learn Go Programming Course
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
//
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
s "github.com/inancgumus/prettyslice"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// think of this as search results of a search engine.
|
||||
// it could have been fetched from a database
|
||||
items := []string{
|
||||
"pacman",
|
||||
"mario",
|
||||
"tetris",
|
||||
"doom",
|
||||
"galaga",
|
||||
"frogger",
|
||||
"asteroids",
|
||||
"simcity",
|
||||
"metroid",
|
||||
"defender",
|
||||
"rayman",
|
||||
"tempest",
|
||||
"ultima",
|
||||
}
|
||||
|
||||
s.MaxPerLine = 4
|
||||
s.Show("All items", items)
|
||||
|
||||
top3 := items[:3]
|
||||
s.Show("Top 3 items", top3)
|
||||
|
||||
l := len(items)
|
||||
|
||||
// you can use variables in a slice expression
|
||||
last4 := items[l-4:]
|
||||
s.Show("Last 4 items", last4)
|
||||
|
||||
// reslicing: slicing another sliced slice
|
||||
mid := last4[1:3]
|
||||
s.Show("Last4[1:3]", mid)
|
||||
|
||||
// the same elements can be in different indexes
|
||||
// fmt.Println(items[9], last4[0])
|
||||
|
||||
// slicing returns a slice with the same type of the sliced slice
|
||||
fmt.Printf("slicing : %T %[1]q\n", items[2:3])
|
||||
|
||||
// indexing returns a single element with the type of the indexed slice's element type
|
||||
fmt.Printf("indexing: %T %[1]q\n", items[2])
|
||||
}
|
58
x-tba/slices/08-slice-expressions-pagination/main.go
Normal file
58
x-tba/slices/08-slice-expressions-pagination/main.go
Normal file
@ -0,0 +1,58 @@
|
||||
// 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() {
|
||||
// think of this as search results of a search engine.
|
||||
// it could have been fetched from a database
|
||||
items := []string{
|
||||
"pacman",
|
||||
"mario",
|
||||
"tetris",
|
||||
"doom",
|
||||
"galaga",
|
||||
"frogger",
|
||||
"asteroids",
|
||||
"simcity",
|
||||
"metroid",
|
||||
"defender",
|
||||
"rayman",
|
||||
"tempest",
|
||||
"ultima",
|
||||
}
|
||||
|
||||
// s.Show("0:4", items[0:4])
|
||||
// s.Show("4:8", items[4:8])
|
||||
// s.Show("8:12", items[8:12])
|
||||
// s.Show("12:13", items[12:13])
|
||||
// s.Show("12:14", items[12:14]) // error
|
||||
|
||||
l := len(items)
|
||||
|
||||
const pageSize = 4
|
||||
|
||||
for from := 0; from < l; from += pageSize {
|
||||
to := from + pageSize
|
||||
if to > l {
|
||||
to = l
|
||||
}
|
||||
|
||||
// fmt.Printf("%d:%d\n", from, to)
|
||||
|
||||
currentPage := items[from:to]
|
||||
|
||||
head := fmt.Sprintf("Page #%d", (from/pageSize)+1)
|
||||
s.Show(head, currentPage)
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
// 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() {
|
||||
// ages, first and last2 have the same backing arrays
|
||||
ages := []int{35, 15, 25}
|
||||
first := ages[0:1]
|
||||
last2 := ages[1:3]
|
||||
|
||||
ages[0] = 55
|
||||
ages[1] = 10
|
||||
ages[2] = 20
|
||||
|
||||
// grades and ages have separate backing arrays
|
||||
grades := []int{70, 99}
|
||||
grades[0] = 50
|
||||
|
||||
s.Show("ages", ages)
|
||||
s.Show("ages[0:1]", first)
|
||||
s.Show("ages[1:3]", last2)
|
||||
s.Show("grades", grades)
|
||||
|
||||
// let's create a new scope
|
||||
// 'cause i'm going to use variables with the same name
|
||||
{
|
||||
// ages and agesArray have the same backing arrays
|
||||
agesArray := [3]int{35, 15, 25}
|
||||
ages := agesArray[0:3]
|
||||
|
||||
ages[0] = 100
|
||||
ages[2] = 50
|
||||
|
||||
s.Show("agesArray", agesArray[:])
|
||||
s.Show("agesArray's ages", ages)
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
// For more tutorials: https://blog.learngoprogramming.com
|
||||
//
|
||||
// Copyright © 2018 Inanc Gumus
|
||||
// Learn Go Programming Course
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
//
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
s "github.com/inancgumus/prettyslice"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// #1: arrays and non-empty slice literals create an array.
|
||||
// For the arrays, it's explicit, but for the slices,
|
||||
// it's done implicitly, behind the scenes.
|
||||
|
||||
grades := [...]float64{40, 10, 20, 50, 60, 70} // #1
|
||||
// grades := []float64{40, 10, 20, 50, 60, 70} // #4
|
||||
|
||||
// #5: let's break the connection
|
||||
// #6: comment-out
|
||||
// var newGrades []float64
|
||||
// newGrades = append(newGrades, grades...)
|
||||
|
||||
// #6: shortcut: []float64(nil) is a nil float64 slice
|
||||
// newGrades := append([]float64(nil), grades...)
|
||||
|
||||
// #2: cheap: slicing doesn't allocate new memory (array).
|
||||
// front := grades[:3]
|
||||
|
||||
// front := newGrades[:3] // #5
|
||||
|
||||
// #3: sort its first segment
|
||||
// sort.Float64s(front)
|
||||
|
||||
// #7: new slices look at the same backing array
|
||||
// front, front2, front3, newGrades, they all have the same backing array
|
||||
// front2 := front[:3]
|
||||
// front3 := front
|
||||
|
||||
s.PrintBacking = true // #1
|
||||
s.MaxPerLine = 7 // #1
|
||||
s.Show("grades", grades[:]) // #1
|
||||
// s.Show("newGrades", newGrades) // #5
|
||||
// s.Show("front", front) // #2
|
||||
// s.Show("front2", front2) // #7
|
||||
// s.Show("front3", front3) // #7
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
// For more tutorials: https://blog.learngoprogramming.com
|
||||
//
|
||||
// Copyright © 2018 Inanc Gumus
|
||||
// Learn Go Programming Course
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
//
|
||||
|
||||
package main
|
||||
|
||||
import s "github.com/inancgumus/prettyslice"
|
||||
|
||||
func main() {
|
||||
ages := []int{35, 15, 25}
|
||||
first, last := ages[0:1], ages[1:3]
|
||||
|
||||
s.Show("ages", ages)
|
||||
s.Show("first", first)
|
||||
s.Show("last", last)
|
||||
|
||||
s.Show("nil slice", []int(nil))
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
// 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"
|
||||
|
||||
s "github.com/inancgumus/prettyslice"
|
||||
)
|
||||
|
||||
// type collection [4]string // #1
|
||||
type collection []string // #2
|
||||
|
||||
// go is pass by copy
|
||||
// only the slice header is copied: 3 integer fields (24 bytes)
|
||||
// think of passing an array with millions of elements.
|
||||
|
||||
func main() {
|
||||
// SliceHeader lives here:
|
||||
// https://golang.org/src/runtime/slice.go
|
||||
|
||||
s.PrintElementAddr = true
|
||||
|
||||
// #1
|
||||
data := collection{"slices", "are", "awesome", "period", "!!" /* #5 */}
|
||||
|
||||
// data := collection{"slices", "are", "awesome", "period", "!!"}
|
||||
|
||||
change(data) // #1
|
||||
|
||||
s.Show("main's data", data) // #1
|
||||
fmt.Printf("main's data slice's header: %p\n", &data) // #3
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// #4
|
||||
array := [...]string{"slices", "are", "awesome", "period", "!!" /* #5 */}
|
||||
|
||||
// array's size depends on its elements
|
||||
fmt.Printf("array's size: %d bytes.\n", unsafe.Sizeof(array))
|
||||
|
||||
// slice's size is always fixed: 24 bytes (on a 64-bit system) — slice value = slice header
|
||||
fmt.Printf("slice's size: %d bytes.\n", unsafe.Sizeof(data))
|
||||
}
|
||||
|
||||
// #1
|
||||
// passed value will be copied in the function
|
||||
func change(data collection) {
|
||||
// data is a new variable inside the function:
|
||||
// var data collection
|
||||
|
||||
data[2] = "brilliant!"
|
||||
|
||||
s.Show("change's data", data)
|
||||
fmt.Printf("change's data slice's header: %p\n", &data) // #3
|
||||
}
|
31
x-tba/slices/11-slice-internals-3-len-cap/1-theory/main.go
Normal file
31
x-tba/slices/11-slice-internals-3-len-cap/1-theory/main.go
Normal file
@ -0,0 +1,31 @@
|
||||
// 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() {
|
||||
s.MaxPerLine = 6
|
||||
s.PrintBacking = true
|
||||
|
||||
ages := []int{35, 15, 25}
|
||||
s.Show("ages", ages)
|
||||
|
||||
s.Show("ages[0:0]", ages[0:0])
|
||||
|
||||
for i := 1; i < 4; i++ {
|
||||
txt := fmt.Sprintf("ages[%d:%d]", 0, i)
|
||||
s.Show(txt, ages[0:i])
|
||||
}
|
||||
|
||||
s.Show("append", append(ages, 50))
|
||||
}
|
56
x-tba/slices/11-slice-internals-3-len-cap/2-example/main.go
Normal file
56
x-tba/slices/11-slice-internals-3-len-cap/2-example/main.go
Normal file
@ -0,0 +1,56 @@
|
||||
// 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() {
|
||||
s.PrintBacking = true
|
||||
|
||||
// ----------------------------------------------------
|
||||
// #1 nil slice
|
||||
var games []string // nil slice
|
||||
s.Show("games", games)
|
||||
|
||||
// ----------------------------------------------------
|
||||
// #2 empty slice
|
||||
games = []string{} // empty slice
|
||||
s.Show("games", games)
|
||||
// s.Show("another empty", []int{})
|
||||
|
||||
// ----------------------------------------------------
|
||||
// #3 non-empty slice
|
||||
games = []string{"pacman", "mario", "tetris", "doom"}
|
||||
s.Show("games", games)
|
||||
|
||||
// ----------------------------------------------------
|
||||
// #4 reset the part using the games slice
|
||||
// part is empty but its cap is still 4
|
||||
part := games
|
||||
s.Show("part", part)
|
||||
|
||||
part = games[:0]
|
||||
s.Show("part[:0]", part)
|
||||
s.Show("part[:cap]", part[:cap(part)])
|
||||
|
||||
for cap(part) != 0 {
|
||||
part = part[1:cap(part)]
|
||||
s.Show("part", part)
|
||||
}
|
||||
|
||||
// #6 backing array's elements become inaccessible
|
||||
// games = games[len(games):]
|
||||
|
||||
// ----------------------------------------------------
|
||||
// #5 part doesn't have any more capacity
|
||||
// games slice is still intact
|
||||
s.Show("part", part)
|
||||
s.Show("games", games)
|
||||
}
|
22
x-tba/slices/12-slice-internals-4-append/1-theory/main.go
Normal file
22
x-tba/slices/12-slice-internals-4-append/1-theory/main.go
Normal file
@ -0,0 +1,22 @@
|
||||
// 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() {
|
||||
s.PrintBacking = true
|
||||
|
||||
ages := []int{35, 15}
|
||||
s.Show("ages", ages)
|
||||
|
||||
ages = append(ages, 5)
|
||||
s.Show("append(ages, 5)", ages)
|
||||
}
|
54
x-tba/slices/12-slice-internals-4-append/2-example/main.go
Normal file
54
x-tba/slices/12-slice-internals-4-append/2-example/main.go
Normal file
@ -0,0 +1,54 @@
|
||||
// For more tutorials: https://blog.learngoprogramming.com
|
||||
//
|
||||
// Copyright © 2018 Inanc Gumus
|
||||
// Learn Go Programming Course
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
//
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
s "github.com/inancgumus/prettyslice"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s.PrintBacking = true
|
||||
|
||||
// #1: a nil slice has no backing array
|
||||
var nums []int
|
||||
s.Show("no backing array", nums)
|
||||
|
||||
// #2: creates a new backing array
|
||||
nums = append(nums, 1, 3)
|
||||
s.Show("allocates", nums)
|
||||
|
||||
// #3: creates a new backing array
|
||||
nums = append(nums, 2)
|
||||
s.Show("free capacity", nums)
|
||||
|
||||
// #4: uses the same backing array
|
||||
nums = append(nums, 4)
|
||||
s.Show("no allocation", nums)
|
||||
|
||||
// GOAL: append new odd numbers in the middle
|
||||
// [1 3 2 4] -> [1 3 7 9 2 4]
|
||||
|
||||
// #6: [1 3 2 4] -> [1 3 2 4 2 4]
|
||||
nums = append(nums, nums[2:]...)
|
||||
s.Show("nums <- nums[2:]", nums)
|
||||
|
||||
// #5: overwrites: [1 3 2 4 2 4] -> [1 3 7 9]
|
||||
nums = append(nums[:2], 7, 9)
|
||||
s.Show("nums[:2] <- 7, 9", nums)
|
||||
|
||||
// #7: [1 3 7 9] -> [1 3 7 9 2 4]
|
||||
nums = nums[:6]
|
||||
s.Show("nums: extend", nums)
|
||||
}
|
||||
|
||||
// don't mind about these options
|
||||
// they're just for printing the slices nicely
|
||||
func init() {
|
||||
s.MaxPerLine = 10
|
||||
s.Width = 45
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
// For more tutorials: https://blog.learngoprogramming.com
|
||||
//
|
||||
// Copyright © 2018 Inanc Gumus
|
||||
// Learn Go Programming Course
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
//
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
s "github.com/inancgumus/prettyslice"
|
||||
"github.com/inancgumus/screen"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s.PrintBacking = true
|
||||
s.MaxPerLine = 30
|
||||
s.Width = 150
|
||||
|
||||
var nums []int
|
||||
|
||||
screen.Clear()
|
||||
for cap(nums) <= 128 {
|
||||
screen.MoveTopLeft()
|
||||
|
||||
s.Show("nums", nums)
|
||||
nums = append(nums, rand.Intn(9)+1)
|
||||
|
||||
time.Sleep(time.Second / 4)
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
// 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, oldCap := []int{1}, 1.
|
||||
|
||||
for len(ages) < 5e5 {
|
||||
ages = append(ages, 1)
|
||||
|
||||
c := float64(cap(ages))
|
||||
if c != oldCap {
|
||||
fmt.Printf("len:%-10d cap:%-10g growth:%.2f\n",
|
||||
len(ages), c, c/oldCap)
|
||||
}
|
||||
oldCap = c
|
||||
}
|
||||
}
|
17
x-tba/slices/13-png-parser/1-png-anatomy-format.md
Normal file
17
x-tba/slices/13-png-parser/1-png-anatomy-format.md
Normal file
@ -0,0 +1,17 @@
|
||||
# The Brief Anatomy of a PNG image
|
||||
|
||||
```
|
||||
The first 24 bytes:
|
||||
|
||||
+=================================+
|
||||
| PNG Header | 8 bytes | -> 137 80 78 71 13 10 26 10
|
||||
+---------------------+-----------+
|
||||
| IHDR Chunk Header | |
|
||||
| Chunk Length | 4 bytes | -> The length of the IHDR Chunk Data
|
||||
| Chunk Type | 4 bytes | -> 73 72 68 82
|
||||
+---------------------+-----------+
|
||||
| IHDR Chunk Data | |
|
||||
| Width | 4 bytes | -> Unsigned 32-bit integer
|
||||
| Height | 4 bytes | -> Unsigned 32-bit integer
|
||||
+=================================+
|
||||
```
|
26
x-tba/slices/13-png-parser/2-png-anatomy-example.md
Normal file
26
x-tba/slices/13-png-parser/2-png-anatomy-example.md
Normal file
@ -0,0 +1,26 @@
|
||||
# The Brief Anatomy of a PNG image
|
||||
|
||||
```
|
||||
The first 24 bytes:
|
||||
|
||||
PNG HEADER:
|
||||
╔═════╗╔════╗╔════╗╔════╗╔════╗╔════╗╔════╗╔════╗
|
||||
║ 137 ║║ 80 ║║ 78 ║║ 71 ║║ 13 ║║ 10 ║║ 26 ║║ 10 ║
|
||||
╚═════╝╚════╝╚════╝╚════╝╚════╝╚════╝╚════╝╚════╝
|
||||
0 1 2 3 4 5 6 7
|
||||
|
||||
CHUNK LENGTH CHUNK TYPE (IHDR)
|
||||
╔═══╗╔═══╗╔═══╗╔════╗╔════╗╔════╗╔════╗╔════╗
|
||||
║ 0 ║║ 0 ║║ 0 ║║ 13 ║║ 73 ║║ 72 ║║ 68 ║║ 82 ║
|
||||
╚═══╝╚═══╝╚═══╝╚════╝╚════╝╚════╝╚════╝╚════╝
|
||||
8 9 10 11 12 13 14 15
|
||||
|
||||
( Unsigned 32-bit integers )
|
||||
WIDTH HEIGHT
|
||||
╔═══╗╔═══╗╔═══╗╔════╗╔═══╗╔═══╗╔═══╗╔════╗
|
||||
║ 0 ║║ 0 ║║ 2 ║║ 76 ║║ 0 ║║ 0 ║║ 3 ║║ 32 ║
|
||||
╚═══╝╚═══╝╚═══╝╚════╝╚═══╝╚═══╝╚═══╝╚════╝
|
||||
16 17 18 19 20 21 22 23
|
||||
|
||||
... Other bytes in the png image ...
|
||||
```
|
@ -0,0 +1,5 @@
|
||||
<EFBFBD>PNG
|
||||
|
||||
/<2F>}P<><50><EFBFBD><EFBFBD>̒<>><3E><>0jȂ&<26>✉\<5C>@<40><06><><EFBFBD><EFBFBD>T<03>LU
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>x<><78>/<2F>
|
||||
Z`<60><14>w<EFBFBD><77>;<3B>9<05><>c<EFBFBD><03>
|
After Width: | Height: | Size: 80 B |
BIN
x-tba/slices/13-png-parser/images/broken-missing-png-header.png
Normal file
BIN
x-tba/slices/13-png-parser/images/broken-missing-png-header.png
Normal file
Binary file not shown.
BIN
x-tba/slices/13-png-parser/images/gopher.png
Normal file
BIN
x-tba/slices/13-png-parser/images/gopher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 66 KiB |
86
x-tba/slices/13-png-parser/main.go
Normal file
86
x-tba/slices/13-png-parser/main.go
Normal file
@ -0,0 +1,86 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
ps "github.com/inancgumus/prettyslice"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var (
|
||||
pngHeader = [...]byte{137, 80, 78, 71, 13, 10, 26, 10}
|
||||
ihdrChunkType = [...]byte{73, 72, 68, 82}
|
||||
)
|
||||
|
||||
args := os.Args[1:]
|
||||
if len(args) == 0 {
|
||||
fmt.Println("run with a PNG file")
|
||||
return
|
||||
}
|
||||
|
||||
// this is not the best way
|
||||
// it's better only to read the first 24 bytes
|
||||
// this reads the whole file into memory
|
||||
img, err := ioutil.ReadFile(args[0])
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
// limit the capacity to prevent the errors downward
|
||||
// 'cause we only need the first 24 bytes
|
||||
img = img[:24:24]
|
||||
// ps.Show("first 24 bytes", img)
|
||||
|
||||
// ------------------------------------------
|
||||
// Read the PNG header
|
||||
// https://www.w3.org/TR/2003/REC-PNG-20031110/#5PNG-file-signature
|
||||
// ------------------------------------------
|
||||
lpng := len(pngHeader)
|
||||
if !bytes.Equal(img[:lpng], pngHeader[:]) {
|
||||
fmt.Println("missing PNG header")
|
||||
return
|
||||
}
|
||||
|
||||
// skip the png header
|
||||
img = img[lpng:]
|
||||
|
||||
// ------------------------------------------
|
||||
// Read the IHDR chunk header
|
||||
// The IHDR chunk shall be the first chunk in the PNG datastream.
|
||||
// https://www.w3.org/TR/2003/REC-PNG-20031110/#11IHDR
|
||||
// ------------------------------------------
|
||||
header := img[:8] // get the length and chunk type
|
||||
|
||||
// ensure that the chunk type is IHDR
|
||||
if !bytes.Equal(header[4:8], ihdrChunkType[:]) {
|
||||
fmt.Println("missing IHDR chunk")
|
||||
return
|
||||
}
|
||||
|
||||
// ------------------------------------------
|
||||
// Read the IHDR Chunk Data
|
||||
// ------------------------------------------
|
||||
img = img[len(header):] // skip the IHDR chunk header data
|
||||
ihdr := img[:8] // read the width&height from the ihdr chunk
|
||||
|
||||
// All integers that require more than one byte shall be in:
|
||||
// network byte order = Big Endian
|
||||
// https://www.w3.org/TR/2003/REC-PNG-20031110/#7Integers-and-byte-order
|
||||
fmt.Printf("dimensions: %dx%d\n",
|
||||
// read the first 4 bytes (width)
|
||||
binary.BigEndian.Uint32(ihdr[:4]),
|
||||
// read the next 4 bytes (height)
|
||||
binary.BigEndian.Uint32(ihdr[4:8]))
|
||||
}
|
||||
|
||||
func init() {
|
||||
ps.PrintBacking = true
|
||||
ps.PrettyByteRune = false
|
||||
ps.MaxPerLine = 8
|
||||
ps.MaxElements = 32
|
||||
}
|
28
x-tba/slices/14-full-slice-expressions/1-theory/main.go
Normal file
28
x-tba/slices/14-full-slice-expressions/1-theory/main.go
Normal file
@ -0,0 +1,28 @@
|
||||
// For more tutorials: https://blog.learngoprogramming.com
|
||||
//
|
||||
// Copyright © 2018 Inanc Gumus
|
||||
// Learn Go Programming Course
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
//
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
s "github.com/inancgumus/prettyslice"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s.PrintBacking = true
|
||||
|
||||
sliceable := []byte{'f', 'u', 'l', 'l'}
|
||||
|
||||
s.Show("sliceable", sliceable)
|
||||
s.Show("sliceable[0:3]", sliceable[0:3])
|
||||
s.Show("sliceable[0:3:3]", sliceable[0:3:3])
|
||||
s.Show("sliceable[0:2:2]", sliceable[0:2:2])
|
||||
s.Show("sliceable[0:1:1]", sliceable[0:1:1])
|
||||
s.Show("sliceable[1:3:3]", sliceable[1:3:3])
|
||||
s.Show("sliceable[2:3:3]", sliceable[2:3:3])
|
||||
s.Show("sliceable[2:3:4]", sliceable[2:3:4])
|
||||
s.Show("sliceable[4:4:4]", sliceable[4:4:4])
|
||||
}
|
35
x-tba/slices/14-full-slice-expressions/2-example/main.go
Normal file
35
x-tba/slices/14-full-slice-expressions/2-example/main.go
Normal file
@ -0,0 +1,35 @@
|
||||
// For more tutorials: https://blog.learngoprogramming.com
|
||||
//
|
||||
// Copyright © 2018 Inanc Gumus
|
||||
// Learn Go Programming Course
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
//
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
s "github.com/inancgumus/prettyslice"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s.PrintBacking = true
|
||||
|
||||
nums := []int{1, 3, 2, 4} // #1
|
||||
// odds := nums[:2] // #2
|
||||
// odds := nums[:2:2] // #4
|
||||
// odds = append(odds, 5, 7) // #3
|
||||
|
||||
// odds := append(nums[:2:2], 5, 7) // #5
|
||||
// evens := append(nums[2:4], 6, 8) // #6
|
||||
|
||||
s.Show("nums", nums) // #1
|
||||
// s.Show("odds", odds) // #2
|
||||
// s.Show("evens", evens) // #6
|
||||
}
|
||||
|
||||
// don't mind about these options
|
||||
// they're just for printing the slices nicely
|
||||
func init() {
|
||||
s.MaxPerLine = 10
|
||||
s.Width = 55
|
||||
}
|
25
x-tba/slices/15-make/1-theory/main.go
Normal file
25
x-tba/slices/15-make/1-theory/main.go
Normal file
@ -0,0 +1,25 @@
|
||||
// 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 (
|
||||
prettyslice "github.com/inancgumus/prettyslice"
|
||||
)
|
||||
|
||||
func main() {
|
||||
prettyslice.PrintBacking = true
|
||||
|
||||
prettyslice.Show("make([]int, 3)", make([]int, 3))
|
||||
prettyslice.Show("make([]int, 3, 5)", make([]int, 3, 5))
|
||||
|
||||
s := make([]int, 0, 5)
|
||||
prettyslice.Show("make([]int, 0, 5)", s)
|
||||
|
||||
s = append(s, 42)
|
||||
prettyslice.Show("s = append(s, 42)", s)
|
||||
}
|
83
x-tba/slices/15-make/2-example/main.go
Normal file
83
x-tba/slices/15-make/2-example/main.go
Normal file
@ -0,0 +1,83 @@
|
||||
// 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 (
|
||||
"strings"
|
||||
|
||||
s "github.com/inancgumus/prettyslice"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s.PrintBacking = true
|
||||
s.MaxPerLine = 10
|
||||
|
||||
// #1: assume that tasks can be a long list
|
||||
// ---------------------------------------------
|
||||
tasks := []string{"jump", "run", "read"}
|
||||
|
||||
// #2: INEFFICIENT WAY
|
||||
// ---------------------------------------------
|
||||
// var upTasks []string
|
||||
// s.Show("upTasks", upTasks)
|
||||
|
||||
// for _, task := range tasks {
|
||||
// upTasks = append(upTasks, strings.ToUpper(task))
|
||||
// s.Show("upTasks", upTasks)
|
||||
// }
|
||||
|
||||
// #3: SO SO WAY:
|
||||
// ---------------------------------------------
|
||||
// upTasks := make([]string, len(tasks))
|
||||
// s.Show("upTasks", upTasks)
|
||||
|
||||
// for _, task := range tasks {
|
||||
// upTasks = append(upTasks, strings.ToUpper(task))
|
||||
// s.Show("upTasks", upTasks)
|
||||
// }
|
||||
|
||||
// #4: SO SO WAY 2:
|
||||
// ---------------------------------------------
|
||||
// upTasks := make([]string, len(tasks))
|
||||
// s.Show("upTasks", upTasks)
|
||||
|
||||
// for i, task := range tasks {
|
||||
// upTasks[i] = strings.ToUpper(task)
|
||||
// s.Show("upTasks", upTasks)
|
||||
// }
|
||||
|
||||
// #5: allocates a new array
|
||||
// upTasks = append(upTasks, "PLAY")
|
||||
// s.Show("upTasks", upTasks)
|
||||
|
||||
// #6: SO SO WAY 3
|
||||
// ---------------------------------------------
|
||||
// upTasks := make([]string, 0, len(tasks))
|
||||
|
||||
// #7
|
||||
// upTasks = upTasks[:cap(upTasks)]
|
||||
|
||||
// #6
|
||||
// s.Show("upTasks", upTasks)
|
||||
|
||||
// for i, task := range tasks {
|
||||
// upTasks[i] = strings.ToUpper(task)
|
||||
// s.Show("upTasks", upTasks)
|
||||
// }
|
||||
|
||||
// #8: THE BEST WAY
|
||||
// ---------------------------------------------
|
||||
upTasks := make([]string, 0, len(tasks))
|
||||
|
||||
s.Show("upTasks", upTasks)
|
||||
|
||||
for _, task := range tasks {
|
||||
upTasks = append(upTasks, strings.ToUpper(task))
|
||||
s.Show("upTasks", upTasks)
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
learngoprogramming.com
|
@ -0,0 +1 @@
|
||||
learngoprogramming.com
|
@ -0,0 +1 @@
|
||||
learngoprogramming.com
|
@ -0,0 +1,70 @@
|
||||
// For more tutorials: https://blog.learngoprogramming.com
|
||||
//
|
||||
// Copyright © 2018 Inanc Gumus
|
||||
// Learn Go Programming Course
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
//
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
)
|
||||
|
||||
// You can easily write to a file using bash.
|
||||
//
|
||||
// However, when what you're creating is a library,
|
||||
// then you won't have that option. So, it's good to learn
|
||||
// how to write to a file using a byte slice.
|
||||
|
||||
// ioutil.ReadDir
|
||||
// os.FileInfo
|
||||
|
||||
func main() {
|
||||
args := os.Args[1:]
|
||||
if len(args) == 0 {
|
||||
fmt.Println("Provide a directory")
|
||||
return
|
||||
}
|
||||
|
||||
files, err := ioutil.ReadDir(args[0])
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
// 1st: find the total size of all the empty files
|
||||
var total int
|
||||
for _, file := range files {
|
||||
if file.Size() == 0 {
|
||||
// +1 for the newline character
|
||||
// when printing the filename
|
||||
total += len(file.Name()) + 1
|
||||
}
|
||||
}
|
||||
|
||||
// 2nd: allocate a large enough byte slice in one go
|
||||
names := make([]byte, 0, total)
|
||||
|
||||
for _, file := range files {
|
||||
if file.Size() == 0 {
|
||||
name := file.Name()
|
||||
|
||||
names = append(names, name...)
|
||||
names = append(names, '\n')
|
||||
}
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile("out.txt", names, 0644)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("%s", names)
|
||||
}
|
||||
|
||||
// See: https://www.tutorialspoint.com/unix/unix-file-permission.htm
|
||||
// See: http://permissions-calculator.org/
|
28
x-tba/slices/17-copy/01-usage/main.go
Normal file
28
x-tba/slices/17-copy/01-usage/main.go
Normal file
@ -0,0 +1,28 @@
|
||||
// For more tutorials: https://blog.learngoprogramming.com
|
||||
//
|
||||
// Copyright © 2018 Inanc Gumus
|
||||
// Learn Go Programming Course
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
//
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
s "github.com/inancgumus/prettyslice"
|
||||
)
|
||||
|
||||
func main() {
|
||||
evens := []int{2, 4}
|
||||
odds := []int{3, 5, 7}
|
||||
|
||||
s.Show("evens [before]", evens)
|
||||
s.Show("odds [before]", odds)
|
||||
|
||||
N := copy(evens, odds)
|
||||
fmt.Printf("%d element(s) are copied.\n", N)
|
||||
|
||||
s.Show("evens [after]", evens)
|
||||
s.Show("odds [after]", odds)
|
||||
}
|
56
x-tba/slices/17-copy/02-hacker-incident/main.go
Normal file
56
x-tba/slices/17-copy/02-hacker-incident/main.go
Normal file
@ -0,0 +1,56 @@
|
||||
// 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: received the raining probabilities
|
||||
data := []float64{10, 25, 30, 50}
|
||||
|
||||
// #2: received new data
|
||||
// newData := []float64{80, 90}
|
||||
// for i := 0; i < len(newData); i++ {
|
||||
// data[i] = newData[i]
|
||||
// }
|
||||
|
||||
// #3: use copy
|
||||
// copy(data, []float64{99, 100})
|
||||
|
||||
// #4: received more data than the original
|
||||
// copy(data, []float64{10, 5, 15, 0, 20})
|
||||
|
||||
// #5: returns the # of copied elements
|
||||
// n := copy(data, []float64{10, 5, 15, 0, 20})
|
||||
// fmt.Printf("%d probabilities copied.\n", n)
|
||||
|
||||
// #6: (sometimes) use append instead of copy
|
||||
// data = append(data[:0], []float64{10, 5, 15, 0, 20}...)
|
||||
|
||||
// #7: clone a slice using copy
|
||||
// saved := make([]float64, len(data))
|
||||
// copy(saved, data)
|
||||
|
||||
// #9: clone a slice using append nil (i prefer this)
|
||||
// saved := append([]float64(nil), data...)
|
||||
|
||||
// data[0] = 0 // #8
|
||||
|
||||
// s.Show("Probabilities (saved)", saved) // #7
|
||||
|
||||
// #1: print the probabilities
|
||||
s.Show("Probabilities (data)", data)
|
||||
|
||||
fmt.Printf("Is it gonna rain? %.f%% chance.\n",
|
||||
(data[0]+data[1]+data[2]+data[3])/
|
||||
float64(len(data)))
|
||||
}
|
33
x-tba/slices/18-multi-dimensional-slices/version-1/main.go
Normal file
33
x-tba/slices/18-multi-dimensional-slices/version-1/main.go
Normal file
@ -0,0 +1,33 @@
|
||||
// For more tutorials: https://blog.learngoprogramming.com
|
||||
//
|
||||
// Copyright © 2018 Inanc Gumus
|
||||
// Learn Go Programming Course
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
//
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// 1st day: $200, $100
|
||||
// 2nd day: $500
|
||||
// 3rd day: $50, $25, and $75
|
||||
|
||||
spendings := [][]int{
|
||||
{200, 100}, // 1st day
|
||||
{500}, // 2nd day
|
||||
{50, 25, 75}, // 3rd day
|
||||
}
|
||||
|
||||
for i, daily := range spendings {
|
||||
var total int
|
||||
for _, spending := range daily {
|
||||
total += spending
|
||||
}
|
||||
|
||||
fmt.Printf("Day %d: %d\n", i+1, total)
|
||||
}
|
||||
}
|
30
x-tba/slices/18-multi-dimensional-slices/version-2/main.go
Normal file
30
x-tba/slices/18-multi-dimensional-slices/version-2/main.go
Normal file
@ -0,0 +1,30 @@
|
||||
// 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() {
|
||||
spendings := make([][]int, 0, 5)
|
||||
|
||||
spendings = append(spendings, []int{200, 100})
|
||||
spendings = append(spendings, []int{25, 10, 45, 60})
|
||||
spendings = append(spendings, []int{5, 15, 35})
|
||||
spendings = append(spendings, []int{95, 10}, []int{50, 25})
|
||||
|
||||
for i, daily := range spendings {
|
||||
var total int
|
||||
for _, spending := range daily {
|
||||
total += spending
|
||||
}
|
||||
|
||||
fmt.Printf("Day %d: %d\n", i+1, total)
|
||||
}
|
||||
}
|
52
x-tba/slices/18-multi-dimensional-slices/version-3/main.go
Normal file
52
x-tba/slices/18-multi-dimensional-slices/version-3/main.go
Normal file
@ -0,0 +1,52 @@
|
||||
// For more tutorials: https://blog.learngoprogramming.com
|
||||
//
|
||||
// Copyright © 2018 Inanc Gumus
|
||||
// Learn Go Programming Course
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
//
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func main() {
|
||||
spendings := fetch()
|
||||
|
||||
for i, daily := range spendings {
|
||||
var total int
|
||||
for _, spending := range daily {
|
||||
total += spending
|
||||
}
|
||||
|
||||
fmt.Printf("Day %d: %d\n", i+1, total)
|
||||
}
|
||||
}
|
||||
|
||||
func fetch() [][]int {
|
||||
content := `200 100
|
||||
25 10 45 60
|
||||
5 15 35
|
||||
95 10
|
||||
50 25`
|
||||
|
||||
lines := strings.Split(content, "\n")
|
||||
|
||||
spendings := make([][]int, len(lines))
|
||||
|
||||
for i, line := range lines {
|
||||
fields := strings.Fields(line)
|
||||
|
||||
spendings[i] = make([]int, len(fields))
|
||||
|
||||
for j, field := range fields {
|
||||
spending, _ := strconv.Atoi(field)
|
||||
spendings[i][j] = spending
|
||||
}
|
||||
}
|
||||
|
||||
return spendings
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
// For more tutorials: https://blog.learngoprogramming.com
|
||||
//
|
||||
// Copyright © 2018 Inanc Gumus
|
||||
// Learn Go Programming Course
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
//
|
||||
|
||||
package main
|
||||
|
||||
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))
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
// 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"
|
||||
|
||||
"github.com/inancgumus/screen"
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
screen.Clear()
|
||||
|
||||
for i := 0; i < maxFrames; i++ {
|
||||
// -------------------------------------------------
|
||||
// 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')
|
||||
}
|
||||
|
||||
screen.MoveTopLeft()
|
||||
fmt.Print(string(buf))
|
||||
|
||||
// draw after a while: slows down the animation
|
||||
time.Sleep(time.Second / 20)
|
||||
}
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
// 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"
|
||||
|
||||
"github.com/inancgumus/screen"
|
||||
)
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
screen.Clear()
|
||||
|
||||
for i := 0; i < maxFrames; i++ {
|
||||
// -------------------------------------------------
|
||||
// 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
|
||||
screen.MoveTopLeft()
|
||||
fmt.Print(string(buf))
|
||||
|
||||
// TODO: in the notes this is at the beginning of the loop
|
||||
|
||||
// draw after a while: slows down the animation
|
||||
time.Sleep(time.Second / 20)
|
||||
}
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
// 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"
|
||||
|
||||
"github.com/inancgumus/screen"
|
||||
)
|
||||
|
||||
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
|
||||
pX, pY int // previous ball positions (for clearing)
|
||||
xVel, yVel = 1, 1 // velocities
|
||||
|
||||
buf [width * height]rune // drawing buffer
|
||||
)
|
||||
|
||||
screen.Clear()
|
||||
|
||||
for i := 0; i < maxFrames; i++ {
|
||||
// -------------------------------------------------
|
||||
// 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
|
||||
}
|
||||
|
||||
// -------------------------------------------------
|
||||
// PUT THE BALL AND CLEAR THE BOARD
|
||||
// -------------------------------------------------
|
||||
board[X][Y] = true
|
||||
board[pX][pY] = false
|
||||
pX, pY = X, Y
|
||||
|
||||
// -------------------------------------------------
|
||||
// DRAW THE BOARD
|
||||
// -------------------------------------------------
|
||||
var ball rune
|
||||
|
||||
// rewind the buffer
|
||||
bufs := buf[:]
|
||||
|
||||
for y := range board[0] {
|
||||
for x := range board {
|
||||
ball = ' '
|
||||
if board[x][y] {
|
||||
ball = '🎾'
|
||||
}
|
||||
bufs = append(bufs, ball, ' ')
|
||||
}
|
||||
bufs = append(bufs, '\n')
|
||||
}
|
||||
|
||||
// clear the screen and draw the board
|
||||
screen.MoveTopLeft()
|
||||
fmt.Print(string(bufs))
|
||||
|
||||
// draw after a while: slows down the animation
|
||||
time.Sleep(time.Second / 20)
|
||||
}
|
||||
}
|
166
x-tba/slices/19-bouncing-ball-challenge/README.md
Normal file
166
x-tba/slices/19-bouncing-ball-challenge/README.md
Normal file
@ -0,0 +1,166 @@
|
||||
# Bouncing Ball Challenge
|
||||
|
||||
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 gain a good experience while doing this.
|
||||
|
||||
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
||||
|
||||
## Declare the constants
|
||||
* The width and the height of the board.
|
||||
|
||||
* It can be anything, just experiment.
|
||||
|
||||
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
||||
|
||||
## Declare the ball positions and velocity:
|
||||
The ball should be in a known position on your board, and it should have a velocity.
|
||||
|
||||
* **Velocity means: Speed and Direction**
|
||||
|
||||
* X velocity = 1 -> _ball moves right_
|
||||
* X velocity = -1 -> _ball moves left_
|
||||
* Y velocity = 1 -> _ball moves down_
|
||||
* Y velocity = -1 -> _ball moves up_
|
||||
|
||||
* Declare variables for the ball's positions: `X` and `Y`
|
||||
|
||||
* Declare variables for the ball's velocity: `xVelocity` and `yVelocity`
|
||||
|
||||
* On each step: Add velocities to ball's position. This will make the ball move.
|
||||
|
||||
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
||||
|
||||
## 🎾 CREATE THE BOARD
|
||||
|
||||
You can use a multi-dimensional bool slice to create the board. Each element in the slice corresponds to whether the ball is in that element (or position) or not.
|
||||
|
||||
* Use the `make` function to initialize your board.
|
||||
|
||||
* Remember: Zero value for a slice is `nil`.
|
||||
* So, you need to initialize each sub-slice of the board slice.
|
||||
|
||||
* You can use `[][]bool` for your board.
|
||||
|
||||
* It's because, when you set one of the elements to true, then you'd 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
|
||||
```
|
||||
|
||||
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
||||
|
||||
## 🎾 CLEAR THE SCREEN
|
||||
|
||||
* Before the loop, clear the screen once by using the screen package.
|
||||
|
||||
* It's [here](https://github.com/inancgumus/screen).
|
||||
* Its documentation is [here](https://godoc.org/github.com/inancgumus/screen).
|
||||
|
||||
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
||||
|
||||
## 🎾 DRAWING LOOP
|
||||
This is the main loop that will draw the board and the ball to the screen continuously.
|
||||
|
||||
* Create the loop
|
||||
|
||||
* On each step of the loop, you're going to:
|
||||
* Clear the board
|
||||
* Calculate the next ball position
|
||||
* Draw the board and the balls
|
||||
|
||||
Explanations for these steps follow...
|
||||
|
||||
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
||||
|
||||
## 🎾 CLEAR THE BOARD
|
||||
At the beginning your board should not contain the ball.
|
||||
|
||||
* So, set all the inner slices of the board slice to `false`.
|
||||
|
||||
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
||||
|
||||
## 🎾 CALCULATE THE NEXT BALL POSITION
|
||||
You need to calculate the ball's next position on the board.
|
||||
|
||||
* Add the velocities to the ball's current position:
|
||||
|
||||
* `X += xVelocity`
|
||||
* `Y += yVelocity`
|
||||
|
||||
* When the ball hits the borders of the board change its direction.
|
||||
|
||||
* **HINT:** You can multiply any velocity by `-1` to change its direction.
|
||||
|
||||
* Set the ball's position on the board.
|
||||
|
||||
* You will use this information when drawing the board.
|
||||
|
||||
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
||||
|
||||
## 🎾 DRAW THE BOARD
|
||||
Instead of drawing the board and the ball to the screen everytime, you will fill a buffer, and when you complete, you will draw the whole board and the ball once by printing the buffer that you filled.
|
||||
|
||||
* Make a large enough rune slice named `buf` using the `make` function.
|
||||
|
||||
* **HINT:** `width * height` will give you a large enough buffer.
|
||||
|
||||
* **TIP:** You could also use `string` concatenation but it would be inefficient.
|
||||
|
||||
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
||||
|
||||
## FILL YOUR BUFFER:
|
||||
|
||||
* Filling your buffer:
|
||||
|
||||
* Loop for the height of the board (_described below_).
|
||||
|
||||
* Then in a nested loop (_described below_), loop for the width of the board.
|
||||
|
||||
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
||||
|
||||
## NESTEP LOOP: WIDTH LOOP
|
||||
* On each step of the nested loop, do this:
|
||||
|
||||
* Check whether the ball is in the x, y positions.
|
||||
* You need to check for it using your board slice.
|
||||
|
||||
* If so, `append` this tennis ball '🎾' to the buffer.
|
||||
* If not, `append` this pool ball '🎱' to the buffer.
|
||||
|
||||
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
||||
|
||||
## NESTEP LOOP: HEIGHT LOOP
|
||||
|
||||
* After the nested loop (but in the height loop):
|
||||
|
||||
* `append` the newline character to the buffer: `'\n'`
|
||||
* This will allow you to print the next row to the next line.
|
||||
|
||||
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
||||
|
||||
## 🎾 MOVE THE CURSOR
|
||||
|
||||
* After the loop, move the cursor to the top-left position by using the screen package.
|
||||
|
||||
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
||||
|
||||
## PRINT THE BOARD (USING THE BUFFER):
|
||||
|
||||
* Do not forget converting it to `string`. Because your buffer is `[]rune`, like so:
|
||||
|
||||
`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 :) Like so:
|
||||
|
||||
`time.Sleep(time.Millisecond * 60)`
|
Reference in New Issue
Block a user