add: exercises and quiz for appending and slicing

This commit is contained in:
Inanc Gumus
2019-01-30 16:47:30 +03:00
parent 1068a0b9cd
commit 8ec394bc10
23 changed files with 928 additions and 63 deletions

View File

@ -0,0 +1,38 @@
package main
// ---------------------------------------------------------
// EXERCISE: Append and Sort Numbers
//
// We'll have a []string that should contain numbers.
//
// Your task is to convert the []string to an int slice.
//
// 1. Get the numbers from the command-line
//
// 2. Append them to an []int
//
// 3. Sort the numbers
//
// 4. Print them
//
// 5. Handle the error cases
//
//
// EXPECTED OUTPUT
//
// go run main.go
// provide a few numbers
//
// go run main.go 4 6 1 3 0 9 2
// [0 1 2 3 4 6 9]
//
// go run main.go a b c
// []
//
// go run main.go 4 a 1 c d 9
// [1 4 9]
//
// ---------------------------------------------------------
func main() {
}

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"
"os"
"sort"
"strconv"
)
func main() {
args := os.Args[1:]
if len(args) == 0 {
fmt.Println("provide a few numbers")
return
}
var nums []int
for _, s := range args {
n, err := strconv.Atoi(s)
if err != nil {
continue
}
nums = append(nums, n)
}
sort.Ints(nums)
fmt.Println(nums)
}

View File

@ -0,0 +1,71 @@
package main
// ---------------------------------------------------------
// EXERCISE: Housing Prices
//
// We have received housing prices. Your task is to load the data into
// appropriately typed slices then print them.
//
// 1. Check out the expected output
//
//
// 2. Check out the code below
//
// 1. header : stores the column headers
// 2. data : stores the real data related to each column
// 3. separator: you will use it to separate the data
//
//
// 3. Parse the data
//
// 1. Separate it into rows by using the newline character ("\n")
//
// 2. For each row, separate it by using the separator (",")
//
//
// 4. Load the data into distinct slices
//
// 1. Load the locations into a []string
// 2. Load the sizes into []int
// 3. Load the beds into []int
// 4. Load the baths into []int
// 5. Load the prices into []int
//
//
// 5. Print the header
//
// 1. Separate it by using the separator
//
// 2. Print each column 15 character wide ("%-15s")
//
//
// 6. Print the rows from the slices that you've created, line by line
//
//
// EXPECTED OUTPUT
//
// Location Size Beds Baths Price
// ===========================================================================
// New York 100 2 1 100000
// New York 150 3 2 200000
// Paris 200 4 3 400000
// Istanbul 500 10 5 1000000
//
//
// HINTS
//
// + strings.Split function can separate a string into a []string
//
// ---------------------------------------------------------
func main() {
const (
header = "Location,Size,Beds,Baths,Price"
data = `New York,100,2,1,100000
New York,150,3,2,200000
Paris,200,4,3,400000
Istanbul,500,10,5,1000000`
separator = ","
)
}

View File

@ -0,0 +1,65 @@
// 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() {
const (
header = "Location,Size,Beds,Baths,Price"
data = `New York,100,2,1,100000
New York,150,3,2,200000
Paris,200,4,3,400000
Istanbul,500,10,5,1000000`
separator = ","
)
var (
locs []string
sizes, beds, baths, prices []int
)
rows := strings.Split(data, "\n")
for _, row := range rows {
cols := strings.Split(row, separator)
locs = append(locs, cols[0])
n, _ := strconv.Atoi(cols[1])
sizes = append(sizes, n)
n, _ = strconv.Atoi(cols[2])
beds = append(beds, n)
n, _ = strconv.Atoi(cols[3])
baths = append(baths, n)
n, _ = strconv.Atoi(cols[4])
prices = append(prices, n)
}
for _, h := range strings.Split(header, separator) {
fmt.Printf("%-15s", h)
}
fmt.Printf("\n%s\n", strings.Repeat("=", 75))
for i := range rows {
fmt.Printf("%-15s", locs[i])
fmt.Printf("%-15d", sizes[i])
fmt.Printf("%-15d", beds[i])
fmt.Printf("%-15d", baths[i])
fmt.Printf("%-15d", prices[i])
fmt.Println()
}
}

View File

@ -0,0 +1,38 @@
package main
// ---------------------------------------------------------
// EXERCISE: Housing Prices and Averages
//
// Use the previous exercise to solve this exercise (Housing Prices).
//
// Your task is to print the averages of the sizes, beds, baths, and prices.
//
//
// EXPECTED OUTPUT
//
// Location Size Beds Baths Price
// ===========================================================================
// New York 100 2 1 100000
// New York 150 3 2 200000
// Paris 200 4 3 400000
// Istanbul 500 10 5 1000000
//
// ===========================================================================
// 237.50 4.75 2.75 425000.00
//
// ---------------------------------------------------------
func main() {
const (
header = "Location,Size,Beds,Baths,Price"
data = `New York,100,2,1,100000
New York,150,3,2,200000
Paris,200,4,3,400000
Istanbul,500,10,5,1000000`
separator = ","
)
// Solve this exercise by using your previous solution for
// the "Housing Prices" exercise.
}

View File

@ -0,0 +1,104 @@
// 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() {
const (
header = "Location,Size,Beds,Baths,Price"
data = `New York,100,2,1,100000
New York,150,3,2,200000
Paris,200,4,3,400000
Istanbul,500,10,5,1000000`
separator = ","
)
var (
locs []string
sizes, beds, baths, prices []int
)
rows := strings.Split(data, "\n")
for _, row := range rows {
cols := strings.Split(row, separator)
locs = append(locs, cols[0])
n, _ := strconv.Atoi(cols[1])
sizes = append(sizes, n)
n, _ = strconv.Atoi(cols[2])
beds = append(beds, n)
n, _ = strconv.Atoi(cols[3])
baths = append(baths, n)
n, _ = strconv.Atoi(cols[4])
prices = append(prices, n)
}
for _, h := range strings.Split(header, separator) {
fmt.Printf("%-15s", h)
}
fmt.Printf("\n%s\n", strings.Repeat("=", 75))
for i := range rows {
fmt.Printf("%-15s", locs[i])
fmt.Printf("%-15d", sizes[i])
fmt.Printf("%-15d", beds[i])
fmt.Printf("%-15d", baths[i])
fmt.Printf("%-15d", prices[i])
fmt.Println()
}
// -------------------------------------------------------------------------
// print the averages
//
// evil note:
// later on, you will see how easy it would be to solve this
// using the functions instead. there are a lot of repetitive code here.
// -------------------------------------------------------------------------
fmt.Printf("\n%s\n", strings.Repeat("=", 75))
// jump over the location column
fmt.Printf("%-15s", "")
var sum int
for _, n := range sizes {
sum += n
}
fmt.Printf("%-15.2f", float64(sum)/float64(len(sizes)))
sum = 0
for _, n := range beds {
sum += n
}
fmt.Printf("%-15.2f", float64(sum)/float64(len(beds)))
sum = 0
for _, n := range baths {
sum += n
}
fmt.Printf("%-15.2f", float64(sum)/float64(len(baths)))
sum = 0
for _, n := range prices {
sum += n
}
fmt.Printf("%-15.2f", float64(sum)/float64(len(prices)))
fmt.Println()
}

View File

@ -0,0 +1,54 @@
package main
// ---------------------------------------------------------
// EXERCISE: Slice the numbers
//
// We've a string that contains even and odd numbers.
//
// 1. Convert the string to an []int
//
// 2. Print the slice
//
// 3. Slice it for the even numbers and print it (assign it to a new slice variable)
//
// 4. Slice it for the odd numbers and print it (assign it to a new slice variable)
//
// 5. Slice it for the two numbers at the middle
//
// 6. Slice it for the first two numbers
//
// 7. Slice it for the last two numbers (use the len function)
//
// 8. Slice the evens slice for the last one number
//
// 9. Slice the odds slice for the last two numbers
//
//
// EXPECTED OUTPUT
// go run main.go
//
// nums : [2 4 6 1 3 5]
// evens : [2 4 6]
// odds : [1 3 5]
// middle : [6 1]
// first 2 : [2 4]
// last 2 : [3 5]
// evens last 1: [6]
// odds last 2 : [4 6]
//
//
// NOTE
//
// You can also use my prettyslice package for printing the slices.
//
//
// HINT
//
// Find a function in the strings package for splitting the string into []string
//
// ---------------------------------------------------------
func main() {
// uncomment the declaration below
// data := "2 4 6 1 3 5"
}

View File

@ -0,0 +1,40 @@
// 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() {
data := "2 4 6 1 3 5"
splitted := strings.Fields(data)
var nums []int
for _, s := range splitted {
n, _ := strconv.Atoi(s)
nums = append(nums, n)
}
// rest of the code for this exercise
fmt.Println("nums :", nums)
evens, odds := nums[:3], nums[3:]
fmt.Println("evens :", evens)
fmt.Println("odds :", odds)
fmt.Println("middle :", nums[2:4])
fmt.Println("first 2 :", nums[:2])
fmt.Println("last 2 :", nums[len(nums)-2:])
fmt.Println("evens last 1:", evens[len(evens)-1:])
fmt.Println("odds last 2 :", evens[len(evens)-2:])
}

View File

@ -0,0 +1,109 @@
package main
// ---------------------------------------------------------
// EXERCISE: Slicing by arguments
//
// We've a []string, you will get arguments from the command-line,
// then you will print only the elements that are requested.
//
// 1. Print the []string (it's in the code below)
//
// 2. Get the starting and stopping positions from the command-line
//
// 3. Print the []string slice by slicing it using the starting and stopping
// positions
//
// 4. Handle the error cases (see the expected output below)
//
// 5. Add new elements to the []string slice literal.
// Your program should work without changing the rest of the code.
//
// 6. Now, play with your program, get a deeper sense of how the slicing
// works.
//
//
// EXPECTED OUTPUT
//
// go run main.go
// ["Normandy" "Verrikan" "Nexus" "Warsaw"]
//
// Provide only the [starting] and [stopping] positions
//
//
// (error because: we expect only two arguments)
//
// go run main.go 1 2 4
// ["Normandy" "Verrikan" "Nexus" "Warsaw"]
//
// Provide only the [starting] and [stopping] positions
//
//
// (error because: starting index >= 0 && stopping pos <= len(slice) )
//
// go run main.go -1 5
// ["Normandy" "Verrikan" "Nexus" "Warsaw"]
//
// Wrong positions
//
//
// (error because: starting <= stopping)
//
// go run main.go 3 2
// ["Normandy" "Verrikan" "Nexus" "Warsaw"]
//
// Wrong positions
//
//
// go run main.go 0
// ["Normandy" "Verrikan" "Nexus" "Warsaw"]
//
// [Normandy Verrikan Nexus Warsaw]
//
//
// go run main.go 1
// ["Normandy" "Verrikan" "Nexus" "Warsaw"]
//
// [Verrikan Nexus Warsaw]
//
//
// go run main.go 2
// ["Normandy" "Verrikan" "Nexus" "Warsaw"]
//
// [Nexus Warsaw]
//
//
// go run main.go 3
// ["Normandy" "Verrikan" "Nexus" "Warsaw"]
//
// [Warsaw]
//
//
// go run main.go 4
// ["Normandy" "Verrikan" "Nexus" "Warsaw"]
//
// []
//
//
// go run main.go 0 3
// ["Normandy" "Verrikan" "Nexus" "Warsaw"]
//
// [Normandy Verrikan Nexus]
//
//
// go run main.go 1 3
// ["Normandy" "Verrikan" "Nexus" "Warsaw"]
//
// [Verrikan Nexus]
//
//
// go run main.go 1 2
// ["Normandy" "Verrikan" "Nexus" "Warsaw"]
//
// [Verrikan]
//
// ---------------------------------------------------------
func main() {
// uncomment the slice below
// ships := []string{"Normandy", "Verrikan", "Nexus", "Warsaw"}
}

View File

@ -0,0 +1,42 @@
// For more tutorials: https://blog.learngoprogramming.com
//
// Copyright © 2018 Inanc Gumus
// Learn Go Programming Course
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
//
package main
import (
"fmt"
"os"
"strconv"
)
func main() {
ships := []string{"Normandy", "Verrikan", "Nexus", "Warsaw"}
fmt.Printf("%q\n\n", ships)
from, to := 0, len(ships)
switch poss := os.Args[1:]; len(poss) {
default:
fallthrough
case 0:
fmt.Println("Provide only the [starting] and [stopping] positions")
return
case 2:
to, _ = strconv.Atoi(poss[1])
fallthrough
case 1:
from, _ = strconv.Atoi(poss[0])
}
if l := len(ships); from < 0 || from > l || to > l || from > to {
fmt.Println("Wrong positions")
return
}
fmt.Println(ships[from:to])
}

View File

@ -0,0 +1,113 @@
package main
// ---------------------------------------------------------
// EXERCISE: Slicing the Housing Prices
//
// We have received housing prices. Your task is to print only the requested
// columns of data (see the expected output).
//
// 1. Separate the data by the newline ("\n") -> rows
//
// 2. Separate each row of the data by the separator (",") -> columns
//
// 3. Find the from and to positions inside the columns depending
// on the command-line arguments.
//
// 4. Print only the requested column headers and their data
//
//
// RESTRICTIONS
//
// + You should use slicing when printing the columns.
//
//
// EXPECTED OUTPUT
//
// go run main.go
// Location Size Beds Baths Price
//
// New York 100 2 1 100000
// New York 150 3 2 200000
// Paris 200 4 3 400000
// Istanbul 500 10 5 1000000
//
//
// go run main.go Location
// Location Size Beds Baths Price
//
// New York 100 2 1 100000
// New York 150 3 2 200000
// Paris 200 4 3 400000
// Istanbul 500 10 5 1000000
//
//
// NOTE : Finds the position of the Size column and slices the columns
// appropriately.
//
// go run main.go Size
// Size Beds Baths Price
//
// 100 2 1 100000
// 150 3 2 200000
// 200 4 3 400000
// 500 10 5 1000000
//
//
// NOTE : Finds the positions of the Size and Baths columns and
// slices the columns appropriately.
//
// go run main.go Size Baths
// Size Beds Baths
//
// 100 2 1
// 150 3 2
// 200 4 3
// 500 10 5
//
//
// go run main.go Beds Price
// Beds Baths Price
//
// 2 1 100000
// 3 2 200000
// 4 3 400000
// 10 5 1000000
//
//
// Note : It works even if the given column name does not exist.
//
// go run main.go Beds NotExist
// Beds Baths Price
//
// 2 1 100000
// 3 2 200000
// 4 3 400000
// 10 5 1000000
//
//
// go run main.go NotExist NotExist
// Location Size Beds Baths Price
//
// New York 100 2 1 100000
// New York 150 3 2 200000
// Paris 200 4 3 400000
// Istanbul 500 10 5 1000000
//
//
// HINTS
//
// + strings.Split function can separate a string into a []string
//
// ---------------------------------------------------------
func main() {
const (
data = `Location,Size,Beds,Baths,Price
New York,100,2,1,100000
New York,150,3,2,200000
Paris,200,4,3,400000
Istanbul,500,10,5,1000000`
separator = ","
)
}

View File

@ -0,0 +1,62 @@
// For more tutorials: https://blog.learngoprogramming.com
//
// Copyright © 2018 Inanc Gumus
// Learn Go Programming Course
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
//
package main
import (
"fmt"
"os"
"strings"
)
func main() {
const (
data = `Location,Size,Beds,Baths,Price
New York,100,2,1,100000
New York,150,3,2,200000
Paris,200,4,3,400000
Istanbul,500,10,5,1000000`
separator = ","
)
// parse the data
rows := strings.Split(data, "\n")
cols := strings.Split(rows[0], separator)
// default case: slice for all the columns
from, to := 0, len(cols)
// find the from and to positions depending on the command-line arguments
args := os.Args[1:]
for i, v := range cols {
l := len(args)
if l >= 1 && v == args[0] {
from = i
}
if l == 2 && v == args[1] {
to = i + 1 // +1 because the stopping index is a position
}
}
for i, row := range rows {
cols := strings.Split(row, separator)
// print the only the requested columns
for _, h := range cols[from:to] {
fmt.Printf("%-15s", h)
}
fmt.Println()
// print extra new line for the header
if i == 0 {
fmt.Println()
}
}
}

View File

@ -25,3 +25,20 @@ These are warm-up exercises that will reinforce your knowledge of slices.
2. **[Append #2 — Append to a nil slice](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/08-append-2)**
3. **[Append #3 — Fix the problems](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/09-append-3-fix)**
4. **[Append and Sort Numbers](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/10-append-sort-nums)**
5. **[Housing Prices](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/11-housing-prices)**
6. **[Housing Prices and Averages](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/12-housing-prices-averages)**
---
## Exercises Level III - Slicing
1. **[Slice the numbers](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/13-slicing-basics)**
2. **[Slicing by arguments](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/14-slicing-by-args)**
3. **[Slicing the Housing Prices](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/15-slicing-housing-prices)**

View File

@ -0,0 +1,138 @@
# Slicing Quiz
## What does this code 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]
5. [9 7]
> **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). So, nums[2:4] returns a new slice that contains the elements at the middle of the nums slice.
## What does this code print?
```go
nums := []int{9, 7, 5}
nums = append(nums, 2, 4, 6)
fmt.Println(nums[:2])
```
1. [9 7 5 2 4 6]
2. [5 2]
3. [4 6]
4. [7 2]
5. [9 7] *CORRECT*
> **5:** nums is [9 7 5 2 4 6]. So, nums[:2] is nums[0:2] which in turn returns [9 7].
## What does this code print?
```go
nums := []int{9, 7, 5}
nums = append(nums, 2, 4, 6)
fmt.Println(nums[len(nums)-2:])
```
1. [9 7 5 2 4 6]
2. [5 2]
3. [4 6] *CORRECT*
4. [7 2]
5. [9 7]
> **3:** nums is [9 7 5 2 4 6]. So, nums[len(nums)-2:] is nums[4:6] (len(nums) is 6) which in turn returns [4 6].
## What does this code print?
```go
names := []string{"einstein", "rosen", "newton"}
names = names[:]
fmt.Println(names[:1])
```
1. [einstein rosen newton]
2. [einstein rosen]
3. [einstein] *CORRECT*
4. []
> **3:** names[:] is names[0:3] -> [einstein rosen newton]. names[:1] is names[0:1] -> [einstein].
## What is the type of the marked expression below?
```go
names := []string{"einstein", "rosen", "newton"}
names[2:3] // <- marked
```
1. []string *CORRECT*
2. string
3. names
4. []int
> **1:** Yes! A slicing expression returns a slice.
>
> **2:** Remember, a slicing expression returns a slice. Did I give you the answer? Oops.
## What is the type of the marked expression below?
```go
names := []string{"einstein", "rosen", "newton"}
names[2] // <- marked
```
1. []string
2. string *CORRECT*
3. names
4. []int
> **1:** Remember, an index expression returns an element value, not a slice.
>
> **2:** Yep! An index expression returns an element value. The element type of the []string slice is string, so the returned value is a string value.
## Which index expression returns the "rosen" element?
```go
names := []string{"einstein", "rosen", "newton"}
names = names[1:len(names) - 1]
```
1. names[0] *CORRECT*
2. names[1]
3. names[2]
> **1:** That's right: names2 is ["rosen"] after the slicing.
>
> **2:** That's not right. Remember, indexes are relative to a slice. names is ["einstein" "rosen" "newton"] but names[1:len(names)-1] is ["rosen"]. So, names2[1] is an error, it's because, the length of the last slice is 1.
## What does this code 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 `names = names[1:]` 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
## What does this code print?
```go
i := 2
s := fmt.Sprintf("i = %d * %d = %d", i, i, i*i)
fmt.Print(s)
```
1. i = i * i = i*i
2. i = %d * %d = %d
3. i = 2 * 2 = 2
4. i = 2 * 2 = 4 *CORRECT*
> **4:** Awesome! Sprintf works just like Printf. Instead of printing the result to standard out (usually to command-line prompt), it returns a string value.

View File

@ -1,11 +1,6 @@
# Slice Exercises
## TODO
* 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

View File

@ -1,57 +0,0 @@
# Slicing Quiz
## 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