add: slices - first part

This commit is contained in:
Inanc Gumus
2018-12-18 15:20:37 +03:00
parent 3ac61333fd
commit d2be3d6692
92 changed files with 2284 additions and 683 deletions

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() {
{
// its length is part of its type
var nums [5]int
fmt.Printf("nums array: %#v\n", nums)
}
{
// its length is not part of its type
var nums []int
fmt.Printf("nums slice: %#v\n", nums)
fmt.Printf("len(nums) : %d\n", len(nums))
// won't work: the slice is nil.
// fmt.Printf("nums[0]: %d\n", nums[0])
// fmt.Printf("nums[1]: %d\n", nums[1])
}
}

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 "fmt"
func main() {
var array [2]int
// zero value of an array is zero-valued elements
fmt.Printf("array : %#v\n", array)
// nope: arrays are fixed length
// array[2] = 0
var slice []int
// zero value of a slice is nil
fmt.Println("slice == nil?", slice == nil)
// nope: they don't exist:
// _ = slice[0]
// _ = slice[1]
// len function still works though
fmt.Println("len(slice) :", len(slice))
// array's length is part of its type
fmt.Printf("array's type: %T\n", array)
// whereas, slice's length isn't part of its type
fmt.Printf("slice's type: %T\n", slice)
}

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"
// STORY:
// You want to list the books and games you have
func main() {
var books [5]string
books[0] = "dracula"
books[1] = "1984"
books[2] = "island"
newBooks := [5]string{"ulysses", "fire"}
if books == newBooks {
}
books = newBooks
games := []string{"kokemon", "sims"}
newGames := []string{"pacman", "doom", "pong"}
newGames = games
games = nil
games = []string{}
var ok string
for i, game := range games {
if game != newGames[i] {
ok = "not "
break
}
}
if len(games) != len(newGames) {
ok = "not "
}
fmt.Printf("games and newGames are %sequal\n\n", ok)
fmt.Printf("books : %#v\n", books)
fmt.Printf("new books : %#v\n", newBooks)
fmt.Printf("games : %T\n", games)
fmt.Printf("new games : %#v\n", newGames)
fmt.Printf("games's length: %d\n", len(games))
fmt.Printf("games's nil : %t\n", games == nil)
}

View File

@ -8,23 +8,25 @@
package main
import (
"fmt"
"math/rand"
"time"
s "github.com/inancgumus/prettyslice"
)
func main() {
rand.Seed(time.Now().UnixNano())
const max = 10
// max, _ := strconv.Atoi(os.Args[1])
const max = 5
var uniques [max]int
// It's harder to make a program dynamic using arrays
// max, _ := strconv.Atoi(os.Args[1])
// var uniques [10]int
loop:
for found := 0; found < max; {
n := rand.Intn(max + 1)
n := rand.Intn(max) + 1
fmt.Print(n, " ")
for _, u := range uniques {
if u == n {
@ -36,5 +38,5 @@ loop:
found++
}
s.Show("Uniques", uniques)
fmt.Println("\n\nuniques:", uniques)
}

View File

@ -8,12 +8,12 @@
package main
import (
"fmt"
"math/rand"
"os"
"sort"
"strconv"
"time"
s "github.com/inancgumus/prettyslice"
)
func main() {
@ -27,7 +27,8 @@ func main() {
loop:
// you can still use the len function on a nil slice
for len(uniques) < max {
n := rand.Intn(max + 1)
n := rand.Intn(max) + 1
fmt.Print(n, " ")
for _, u := range uniques {
if u == n {
@ -35,9 +36,21 @@ loop:
}
}
// let's grow the slice by appending
// append can add new elements the slice
uniques = append(uniques, n)
// a slice doesn't contain any elements from the beginning
// uniques[found] = n
// found++
}
s.Show("Uniques", uniques)
fmt.Println("\n\nuniques:", uniques)
fmt.Println("\nlength of uniques:", len(uniques))
sort.Ints(uniques)
fmt.Println("\nsorted:", uniques)
nums := [5]int{5, 4, 3, 2, 1}
sort.Ints(nums[:])
fmt.Println("\nnums:", nums)
}

View File

@ -4,5 +4,5 @@ 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`
2. Type: `go get -u github.com/inancgumus/prettyslice`
3. That's all.

View File

@ -0,0 +1,122 @@
# Slices vs Arrays Quiz
## Why you want to use a slice instead of an array?
1. I like arrays more
2. I want to create a dynamic collection, so I need an array
3. A slice's length is dynamic, so I can create dynamic collections *CORRECT*
## When does the length of a slice is determined?
1. At compile-time
2. In runtime *CORRECT*
3. When a program terminates
> **2:** A slice's length is not a part of its type. So its length can change at runtime.
## Which function call below is correct?
```go
// Let's say there's a function like this.
func sort(nums []int) {
// ...
}
```
1. sort([...]int{3, 1, 6})
2. sort([]int32{3, 1, 6})
3. sort([]int{3, 1, 6}) *CORRECT*
> **1:** You can't call the sort function using an array. It expects an int slice.
>
> **2:** You can't call the sort function using an int32 slice. It expects an int slice.
>
> **3:** That's right! You can pass an int slice to the sort function.
## What is the zero value of this slice?
```go
var tasks []string
```
1. 0
2. 1
3. nil *CORRECT*
4. unknown
> **3:** This is a nil slice. Unlike an array, a slice's zero value is nil.
## What does this code print?
```go
var tasks []string
fmt.Println(len(tasks))
```
1. 0 *CORRECT*
2. 1
3. nil
4. It doesn't work.
> **1:** Yes, you can use the len function on a nil slice. It returns 0 because the slice doesn't contain any elements yet.
## What does this code print?
```go
var tasks []string
fmt.Println(tasks[0])
```
1. 0
2. 1
3. nil
4. It doesn't work. *CORRECT*
> **4:** You can't get an element that does not exist. A nil slice does not contain any elements.
## Which declaration below is a correct slice declaration?
1. [...]int{}
2. [2]string{"hello", "world"}
3. []string{"hello", "world"} *CORRECT*
4. string[2]{"hello", world"}
## This code doesn't work, why?
```go
colors := []string{"red", "blue", "green"}
tones := []string{"dark", "light"}
if colors == tones {
// ...
}
```
1. The slices have different lengths
2. If statement doesn't contain any statements
3. Slices cannot be compared *CORRECT*
> **3:** That's right! A slice value can only be compared to a nil value.
## What is the length of this slice?
```go
[]uint64{}
```
1. 64
2. 1
3. 0 *CORRECT*
4. Error
> **3:** That's right. This is an empty slice, it doesn't contain any elements.
## What is the length of this slice?
```go
[]string{"i'm", "going", "to", "stay", "\"here\""}
```
1. 0
2. 1
3. 2
4. 3
5. 4
6. 5 *CORRECT*

View File

@ -0,0 +1,3 @@
# Slice Quizzes
* [Slices vs Arrays](1-slices-vs-arrays.md)

View File

@ -1,3 +1,5 @@
// For more Go tutorials: learngoprogramming.com
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"
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,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,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 +1 @@
I'm going to add more sections after I complete the previous ones. Exciting!
This folder contains directories and files that belong to unreleased lectures and sections. So, it's your responsibility to do something with those; they can work or cannot, they are not stable. I change these files all the time. This is my scratch-pad.

View File

@ -0,0 +1,71 @@
// 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
// Before running this program:
//
// RUN: `go run nums/main.go`
// It will create a 12 MB long nums.txt file.
import (
"fmt"
"io/ioutil"
"runtime"
s "github.com/inancgumus/prettyslice"
)
const (
loops = 1000
file = "nums.txt"
)
var buf []byte
func main() {
{
b, _ := ioutil.ReadFile(file)
buf = b[:1]
s.Show("sliced buf", buf)
}
report()
{
var nilBuf []byte
b, _ := ioutil.ReadFile(file)
buf = append(nilBuf, b[:1]...)
s.Show("copied buf", buf)
}
report()
}
func report() {
const KB = 1024
var m runtime.MemStats
r := func() {
runtime.ReadMemStats(&m)
fmt.Printf("%v KB\n", m.Alloc/KB)
}
fmt.Print(" > Before Garbage Collection: ")
r()
runtime.GC()
fmt.Print(" > After Garbage Colletion : ")
r()
}
func init() {
s.Width = 50
s.PrintBacking = true
s.MaxElements = 10
}

View File

@ -0,0 +1,32 @@
// 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 (
"bufio"
"fmt"
"os"
)
func main() {
const path = "nums.txt"
_ = os.Remove(path)
f, _ := os.OpenFile(path,
os.O_CREATE|os.O_WRONLY,
0644)
defer f.Close()
const size = 1000000
w := bufio.NewWriterSize(f, 1<<16)
for i := 1; i <= size; i++ {
fmt.Fprintf(w, "num: %d\n", i)
}
w.Flush()
}

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

@ -10,14 +10,12 @@ package main
import s "github.com/inancgumus/prettyslice"
func main() {
ships := []string{
"Normandy", "Verrikan", "Nexus",
}
ages := []int{35, 15, 25}
first, last := ages[0:1], ages[1:3]
// frigates := ships[:2]
frigates := ships[:2:2]
frigates = append(frigates, "Warsaw")
s.Show("ages", ages)
s.Show("first", first)
s.Show("last", last)
s.Show("Ships", ships)
s.Show("Frigates", frigates)
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

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

@ -8,19 +8,21 @@
package main
import (
"fmt"
s "github.com/inancgumus/prettyslice"
)
func main() {
var basket []string
evens := []int{2, 4}
odds := []int{3, 5, 7}
basket = append(basket, "banana")
basket = append(basket, "milk", "apple")
s.Show("evens [before]", evens)
s.Show("odds [before]", odds)
todo := []string{"tea", "coffee", "salt"}
basket = append(basket, todo...)
N := copy(evens, odds)
fmt.Printf("%d element(s) are copied.\n", N)
_ = append(basket, "pepper")
s.Show("my basket", basket)
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 @@
learngoprogramming.com

View File

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

View File

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

View File

@ -0,0 +1,67 @@
// 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
}
var data []byte
// optimize:
// var total int
// for _, file := range files {
// if file.Size() == 0 {
// // +1 for the newline character
// total += len(file.Name()) + 1
// }
// }
// data := make([]byte, 0, total)
for _, file := range files {
if file.Size() == 0 {
name := file.Name()
// fmt.Println(name)
data = append(data, name...)
data = append(data, '\n')
}
}
ioutil.WriteFile("out.txt", data, 0644)
fmt.Printf("%s", data)
}
// See: https://www.tutorialspoint.com/unix/unix-file-permission.htm
// See: http://permissions-calculator.org/

View File

@ -10,6 +10,8 @@ package main
import (
"fmt"
"time"
"github.com/inancgumus/screen"
)
const (
@ -30,10 +32,9 @@ func main() {
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)
screen.Clear()
for i := 0; i < maxFrames; i++ {
// -------------------------------------------------
// PUT THE BALL
// -------------------------------------------------
@ -58,7 +59,10 @@ func main() {
buf = append(buf, '\n')
}
// clear the screen and draw the board
fmt.Print("\033[2J", string(buf))
screen.MoveTopLeft()
fmt.Print(string(buf))
// draw after a while: slows down the animation
time.Sleep(time.Second / 20)
}
}

View File

@ -10,6 +10,8 @@ package main
import (
"fmt"
"time"
"github.com/inancgumus/screen"
)
const (
@ -33,10 +35,9 @@ func main() {
xVel, yVel = 1, 1 // velocities
)
for i := 0; i < maxFrames; i++ {
// draw after a while: slows down the animation
time.Sleep(time.Second / 20)
screen.Clear()
for i := 0; i < maxFrames; i++ {
// -------------------------------------------------
// CALCULATE THE NEXT BALL POSITION
// -------------------------------------------------
@ -82,6 +83,12 @@ func main() {
}
// clear the screen and draw the board
fmt.Print("\x0c", string(buf))
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)`

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
// ---------------------------------------------------------
// EXERCISE: ?
//
// 1. Declare the following slices:
//
// 1. The names of your friends (names slice)
//
// 2. The distances to locations (distances slice)
//
// 3. A data buffer (data slice)
//
// 4. Currency exchange ratios (ratios slice)
//
// 5. Up/Down status of web servers (alives slice)
//
//
// 2. Print their type, length and whether they're equal to nil value or not.
//
//
// EXPECTED OUTPUT
// names : []string 0 true
// distances: []int 0 true
// data : []uint8 0 true
// ratios : []float64 0 true
// alives : []bool 0 true
// ---------------------------------------------------------
func main() {
}

View File

@ -0,0 +1,26 @@
// 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 (
names []string // The names of your friends
distances []int // The distances
data []byte // A data buffer
ratios []float64 // Currency exchange ratios
alives []bool // Up/Down status of web servers
)
fmt.Printf("names : %T %d %t\n", names, len(names), names == nil)
fmt.Printf("distances: %T %d %t\n", distances, len(distances), distances == nil)
fmt.Printf("data : %T %d %t\n", data, len(data), data == nil)
fmt.Printf("ratios : %T %d %t\n", ratios, len(ratios), ratios == nil)
fmt.Printf("alives : %T %d %t\n", alives, len(alives), alives == nil)
}

View File

@ -0,0 +1,41 @@
// 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"
// ---------------------------------------------------------
// EXERCISE: ?
//
// Assign empty slices to all the slices that you've declared in the previous
// exercise, and print them here.
//
//
// EXPECTED OUTPUT
// names : []string 0 false
// distances: []int 0 false
// data : []uint8 0 false
// ratios : []float64 0 false
// alives : []bool 0 false
// ---------------------------------------------------------
func main() {
var (
names []string // The names of your friends
distances []int // The distances
data []byte // A data buffer
ratios []float64 // Currency exchange ratios
alives []bool // Up/Down status of web servers
)
fmt.Printf("names : %T %d %t\n", names, len(names), names == nil)
fmt.Printf("distances: %T %d %t\n", distances, len(distances), distances == nil)
fmt.Printf("data : %T %d %t\n", data, len(data), data == nil)
fmt.Printf("ratios : %T %d %t\n", ratios, len(ratios), ratios == nil)
fmt.Printf("alives : %T %d %t\n", alives, len(alives), alives == nil)
}

View File

@ -0,0 +1,32 @@
// 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 (
names []string // The names of your friends
distances []int // The distances
data []byte // A data buffer
ratios []float64 // Currency exchange ratios
alives []bool // Up/Down status of web servers
)
names = []string{}
distances = []int{}
data = []byte{}
ratios = []float64{}
alives = []bool{}
fmt.Printf("names : %T %d %t\n", names, len(names), names == nil)
fmt.Printf("distances: %T %d %t\n", distances, len(distances), distances == nil)
fmt.Printf("data : %T %d %t\n", data, len(data), data == nil)
fmt.Printf("ratios : %T %d %t\n", ratios, len(ratios), ratios == nil)
fmt.Printf("alives : %T %d %t\n", alives, len(alives), alives == nil)
}

View File

@ -0,0 +1,63 @@
// 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"
// ---------------------------------------------------------
// EXERCISE: ?
//
// 1. Assign the following data using slice literals to the slices that
// you've declared in the first exercise.
//
// 1. The names of your best three friends (to the names slice)
//
// 2. The distances to five different locations (to the distances slice)
//
// 3. Five bytes of data (to the data slice)
//
// 4. Two currency exchange ratios (to the ratios slice)
//
// 5. Up/Down status of four different web servers (to the alives slice)
//
// 2. Print their type, length and whether they're equal to nil value or not
//
// 3. Compare the length of the distances and the data slices; print a message
// if they are equal (use an if statement).
//
//
// EXPECTED OUTPUT
// names : []string 3 false
// distances: []int 5 false
// data : []uint8 5 false
// ratios : []float64 2 false
// alives : []bool 4 false
// The length of the distances and the data slices are the same.
// ---------------------------------------------------------
func main() {
var (
names []string // The names of your friends
distances []int // The distances
data []byte // A data buffer
ratios []float64 // Currency exchange ratios
alives []bool // Up/Down status of web servers
)
names = []string{}
distances = []int{}
data = []byte{}
ratios = []float64{}
alives = []bool{}
fmt.Printf("names : %T %d %t\n", names, len(names), names == nil)
fmt.Printf("distances: %T %d %t\n", distances, len(distances), distances == nil)
fmt.Printf("data : %T %d %t\n", data, len(data), data == nil)
fmt.Printf("ratios : %T %d %t\n", ratios, len(ratios), ratios == nil)
fmt.Printf("alives : %T %d %t\n", alives, len(alives), alives == nil)
}

View File

@ -0,0 +1,36 @@
// 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 (
names []string // The names of your friends
distances []int // The distances
data []byte // A data buffer
ratios []float64 // Currency exchange ratios
alives []bool // Up/Down status of web servers
)
names = []string{"serpil", "ebru", "lina"}
distances = []int{100, 200, 300, 400, 500}
data = []byte{'I', 'N', 'A', 'N', 'C'}
ratios = []float64{3.14, 6.28}
alives = []bool{true, false, false, true}
fmt.Printf("names : %T %d %t\n", names, len(names), names == nil)
fmt.Printf("distances: %T %d %t\n", distances, len(distances), distances == nil)
fmt.Printf("data : %T %d %t\n", data, len(data), data == nil)
fmt.Printf("ratios : %T %d %t\n", ratios, len(ratios), ratios == nil)
fmt.Printf("alives : %T %d %t\n", alives, len(alives), alives == nil)
if len(distances) == len(data) {
fmt.Println("The length of the distances and the data slices are the same.")
}
}

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 "fmt"
// ---------------------------------------------------------
// EXERCISE: Declare the arrays as slices
//
// 1. First run the following program as it is
//
// 2. Then change the array declarations to slice declarations
//
// 3. Observe whether anything changes or not (on the surface :)).
//
// EXPECTED OUTPUT
// names : []string ["Einstein" "Tesla" "Shepard"]
// distances: []int [50 40 75 30 125]
// data : []uint8 [72 69 76 76 79]
// ratios : []float64 %!f(BADINDEX)
// alives : []bool [true false true false]
// zero : []uint8 []
// ---------------------------------------------------------
func main() {
names := [3]string{"Einstein", "Tesla", "Shepard"}
distances := [...]int{50, 40, 75, 30, 125}
data := [5]byte{'H', 'E', 'L', 'L', 'O'}
ratios := [1]float64{3.14145}
alives := [...]bool{true, false, true, false}
zero := [0]byte{}
fmt.Printf("names : %[1]T %[1]q\n", names)
fmt.Printf("distances: %[1]T %[1]d\n", distances)
fmt.Printf("data : %[1]T %[1]d\n", data)
fmt.Printf("ratios : %[1]T %[1].2f\n", ratios)
fmt.Printf("alives : %[1]T %[1]t\n", alives)
fmt.Printf("zero : %[1]T %[1]d\n", zero)
}

View File

@ -0,0 +1,26 @@
// 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{"Einstein", "Tesla", "Shepard"}
distances := []int{50, 40, 75, 30, 125}
data := []byte{'H', 'E', 'L', 'L', 'O'}
ratios := []float64{3.14145}
alives := []bool{true, false, true, false}
zero := []byte{}
fmt.Printf("names : %[1]T %[1]q\n", names)
fmt.Printf("distances: %[1]T %[1]d\n", distances)
fmt.Printf("data : %[1]T %[1]d\n", data)
fmt.Printf("ratios : %[1]T %[1].2f\n", ratios)
fmt.Printf("alives : %[1]T %[1]t\n", alives)
fmt.Printf("zero : %[1]T %[1]d\n", zero)
}

View File

@ -0,0 +1,44 @@
# Slice Exercises
// TODO:
// + Fix the problem
// -> Don't compare using nil, use the len(s)
//
// + Compare two slices whether they're equal (using a loop)
// + Compare arrays and slices using for loops
//
// + Try to compare a slice to an array
## Exercises Level I - Basics
1. **[???](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/???)**
---
2. **[Get and Set Array Elements](https://github.com/inancgumus/learngo/tree/master/14-arrays/exercises/02-get-set-arrays)**
3. **[Refactor to Array Literals](https://github.com/inancgumus/learngo/tree/master/14-arrays/exercises/03-array-literal)**
4. **[Refactor to Ellipsis](https://github.com/inancgumus/learngo/tree/master/14-arrays/exercises/04-ellipsis)**
5. **[Fix](https://github.com/inancgumus/learngo/tree/master/14-arrays/exercises/05-fix)**
6. **[Compare the Arrays](https://github.com/inancgumus/learngo/tree/master/14-arrays/exercises/06-compare)**
7. **[Assign the Arrays](https://github.com/inancgumus/learngo/tree/master/14-arrays/exercises/07-assign)**
---
## Exercises Level II
1. **[Wizard Printer](https://github.com/inancgumus/learngo/tree/master/14-arrays/exercises/08-wizard-printer)**
2. **[Currency Converter](https://github.com/inancgumus/learngo/tree/master/14-arrays/exercises/09-currency-converter)**
3. **[Hipster's Bookstore Search Engine](https://github.com/inancgumus/learngo/tree/master/14-arrays/exercises/10-hipsters-love-search)**
4. **[Find the Average](https://github.com/inancgumus/learngo/tree/master/14-arrays/exercises/11-average)**
5. **[Number Sorter](https://github.com/inancgumus/learngo/tree/master/14-arrays/exercises/12-sorter)**
6. **[Word Finder](https://github.com/inancgumus/learngo/tree/master/14-arrays/exercises/13-word-finder)**

View File

@ -0,0 +1,71 @@
# Slice Exercises
## TODO
* append to slices
* append to a nil slice
* append to an empty slice
* check their length — see how they grow
* fix the problem (forgetten overwriting to the same slice)
* get arguments from command line and make them uppercase
* multiply the numbers
* slicing
* slice exercises... n:m.. using len etc..
* create a pagination
* use the same slice variable
* internals
* shared array: implicit/explicit
* appending to a nil array
* sorts package sorting
* exercises about capacity
* exercises about the mechanics of append
* growing
* adding elements at the middle etc
* exercises about full slice expressions
* questions:
* slice header questions
* slice and ask what's the pointer field, len, cap etc
* when a new backing array is allocated: nil, empty, no capacity
* when to use a full slice expression
---
## Exercises Level I - Basics
1. **[???](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/???)**
---
2. **[Get and Set Array Elements](https://github.com/inancgumus/learngo/tree/master/14-arrays/exercises/02-get-set-arrays)**
3. **[Refactor to Array Literals](https://github.com/inancgumus/learngo/tree/master/14-arrays/exercises/03-array-literal)**
4. **[Refactor to Ellipsis](https://github.com/inancgumus/learngo/tree/master/14-arrays/exercises/04-ellipsis)**
5. **[Fix](https://github.com/inancgumus/learngo/tree/master/14-arrays/exercises/05-fix)**
6. **[Compare the Arrays](https://github.com/inancgumus/learngo/tree/master/14-arrays/exercises/06-compare)**
7. **[Assign the Arrays](https://github.com/inancgumus/learngo/tree/master/14-arrays/exercises/07-assign)**
---
## Exercises Level II
1. **[Wizard Printer](https://github.com/inancgumus/learngo/tree/master/14-arrays/exercises/08-wizard-printer)**
2. **[Currency Converter](https://github.com/inancgumus/learngo/tree/master/14-arrays/exercises/09-currency-converter)**
3. **[Hipster's Bookstore Search Engine](https://github.com/inancgumus/learngo/tree/master/14-arrays/exercises/10-hipsters-love-search)**
4. **[Find the Average](https://github.com/inancgumus/learngo/tree/master/14-arrays/exercises/11-average)**
5. **[Number Sorter](https://github.com/inancgumus/learngo/tree/master/14-arrays/exercises/12-sorter)**
6. **[Word Finder](https://github.com/inancgumus/learngo/tree/master/14-arrays/exercises/13-word-finder)**

View File

@ -0,0 +1,123 @@
# Slice Basics Quiz
## How does the append function work?
1. It appends new elements to the given slice and returns a new slice, it doesn't change the given slice *CORRECT*
2. It appends new elements to the given slice and returns the existing slice
3. It appends new elements to the given slice and returns a new slice, it also changes the given slice
> **1:** Yes, the append function doesn't change the given slice unless you overwrite the result of the append function back to the original slice.
>
> **2:** It doesn't return the existing slice, it returns a new slice. That's why you usually save the result of the append back to the original slice.
>
> **3:** It doesn't change the given slice, it creates and returns a new slice.
## When you call the append function, where it does appends the new elements?
1. It appends them at the beginning of the given slice
2. It appends them at the middle of the given slice
3. It appends them after the length of the given slice *CORRECT*
> **3:** Yes! The append function appends the new elements by looking at the length of the given slice and then returns a new slice with the newly appended elements.
## What's the problem with the following code?
```go
nums := []int{9, 7, 5}
append(nums, []int{2, 4, 6}...)
fmt.Println(nums[3])
```
1. It can't append to an int slice
2. It can't append a slice to another slice
3. It gets an element that doesn't exist yet *CORRECT*
> **3:** That's right. The append function returns a new slice with the newly added elements. But here, it doesn't save the result of the append, so the nums slice only has 3 elements. So, `nums[3]` is invalid, it doesn't exist.
## What does this program print?
```go
nums := []int{9, 7, 5}
evens := append(nums, []int{2, 4, 6}...)
fmt.Println(nums, evens)
```
1. [9 7 5] [2 4 6]
2. [9 7 5] [9 7 5 2 4 6] *CORRECT*
3. [9 7 5 2 4 6] [2 4 6]
4. [9 7 5 2 4 6] [9 7 5 2 4 6]
> **2:** It appends the new elements to the nums slice but it saves the returned slice to the evens slice. So, the nums slice doesn't change. That's why, it prints the original elements from the nums slice first, then it prints the evens slice with the newly added elements.
>
> **3, 4:** It doesn't save the result of the append call back into the nums slice, so the nums slice doesn't contain the new elements.
## What does this program print?
```go
nums := []int{9, 7, 5}
nums = append(nums, 2, 4, 6)
fmt.Println(nums)
```
1. [9 7 5 2 4 6] *CORRECT*
2. [9 7 5]
3. [2 4 6]
4. [2 4 6 9 7 5]
> **1:** It overwrites the nums slice with the new slice that is returned from the append function. So the nums slice has the newly appended elements.
## What does this program print?
```go
nums := []int{9, 7, 5}
nums = append(nums, 2, 4, 6)
fmt.Println(nums[2:4])
```
1. [9 7 5 2 4 6]
2. [5 2] *CORRECT*
3. [4 6]
4. [7 2]
> **2:** nums is [9 7 5 2 4 6]. So, nums[2:4] is [5 2]. Remember, in nums[2:4] -> 2 is the starting index, so nums[2] is 5; And 4 is the stopping position, so nums[4-1] is 2 (-1 because the stopping position is the element position not an index). So, nums[2:4] returns a new slice that contains the elements at the middle of the nums slice.
## What does this program print?
```go
names := []string{"einstein", "rosen", "newton"}
fmt.Println(names[:])
```
1. [einstein rosen newton] *CORRECT*
2. [einstein rosen]
3. [einstein]
4. []
> **1:** The start index's default value is 0, and the stop position's default value is the length of the slice. So, `names[:]` equals to `names[0:3]`. It returns a new slice with the same elements.
## How can you get "rosen" element?
```go
names := []string{"einstein", "rosen", "newton"}
names2 := names[1:len(names) - 1]
```
1. names2[0] *CORRECT*
2. names2[1]
3. names2[2]
> **1:** That's right: names2 is ["rosen"] after the slicing.
>
> **2:** That's not right. names is ["einstein" "rosen" "newton"] but names2 is ["rosen"] after the slicing. So, names2[1] is an error, it's because, the length of the names2 is 1.
## What does this program print?
```go
names := []string{"einstein", "rosen", "newton"}
names = names[1:]
names = names[1:]
fmt.Println(names)
```
1. [einstein rosen newton]
2. [rosen newton]
3. [newton] *CORRECT*
4. []
> **3:** Remember, slicing returns a new slice. Here, each slicing statement overwrites the names slice with the newly returned slice from the slicing. At first, the names was [einstein rosen newton. After the first slicing, the names becomes [rosen newton]. After the second slicing, names becomes [newton]. See this for the complete explanation: https://play.golang.org/p/EsEHrSeByFR

View File

@ -0,0 +1,63 @@
# Slice Internals Quiz
## Where does a slice value stores its elements?
1. In the global backing array that is shared by all the slices
2. In a separate backing array that a slice value points to *CORRECT*
3. In the slice value itself (like an array)
> **1:** There isn't something called the global backing array.
>
> **2:** That's right. A slice doesn't store any elements direcly. It points to an array that is stored separately on the computer memory, and a slice points to that array, a slice is just a window to that array.
>
> **3:** A slice values doesn't store any elements by itself. It's just a description of its backing array.
## What's a backing array?
1. An array of trustworthy friends that you can count on always
2. An array that is stored in the slice value
3. A slice value stores its elements in it *CORRECT*
> **1:** Oh, come on!
>
> **2:** Nope, a slice value doesn't store its backing array, the slice value just points to it. The backing array is stored separately from the slice value.
## What does this program print?
```go
nums := []int{10, 15, 10, 2, 3, 4}
digits := nums[len(nums)-3:]
nums[len(nums)-1] = 8
digits[0] += nums[3]
fmt.Println(digits)
```
1. [2 3 4]
2. [4 3 4]
3. [4 3 8] *CORRECT*
4. [10 15 10]
5. [4 15 8]
> **3:** Awesome! At first, digits is [2 3 4]. After `nums[len(nums)-1] = 8`, the digits becomes [2 3 8] (it's because, digits is created by slicing the nums slice, so they share the same backing array). And lastly, after `digits[0] += nums[3]`, the digits becomes [4 3 8].
## Find the correct explanation below
1. A slice variable can store a slice value and the slice value is actually a slice header behind the scenes *CORRECT*
2. A slice variable can only store the same slice value and it cannot be changed afterward
3. A slice header stores the slice value
> **1:** That's right. You can change the slice values that is being stored in a slice variable, and the slice value is actually a slice header behind the scenes.
>
> **3:** Nope, actually a slice header and a slice value is the same thing.
* after slicing, does it copy all the values to the new slice?
* why indexing a slice is fast? (array is contagious on memory)
* separate backing arrays question
* sliced array share the same explicit array
##
backing array
slice header
capacity
append mechanics

View File

@ -0,0 +1,3 @@
full slice exp
make
copy