add: append lecture examples

This commit is contained in:
Inanc Gumus
2019-01-28 14:23:59 +03:00
parent d4086d5620
commit 0aab0d17e9
56 changed files with 1762 additions and 0 deletions

View 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)
}

View 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)
}

View File

@ -0,0 +1 @@
learngoprogramming.com

View File

@ -0,0 +1 @@
learngoprogramming.com

View File

@ -0,0 +1 @@
learngoprogramming.com

View 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 (
"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)
}
}
}

View File

@ -0,0 +1 @@
learngoprogramming.com

View File

@ -0,0 +1 @@
learngoprogramming.com

View File

@ -0,0 +1 @@
learngoprogramming.com

View File

@ -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/

View 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], '!'))
}

View 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])
}

View 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)
}
}

View File

@ -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)
}
}

View File

@ -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
}

View File

@ -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))
}

View File

@ -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
}

View 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))
}

View 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)
}

View 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)
}

View 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
}

View File

@ -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)
}
}

View File

@ -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
}
}

View 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
+=================================+
```

View 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 ...
```

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View 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
}

View 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])
}

View 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
}

View 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)
}

View 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)
}
}

View File

@ -0,0 +1 @@
learngoprogramming.com

View File

@ -0,0 +1 @@
learngoprogramming.com

View File

@ -0,0 +1 @@
learngoprogramming.com

View File

@ -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/

View 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)
}

View 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)))
}

View 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)
}
}

View 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)
}
}

View 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
}

View File

@ -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))
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View 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)`