add: quiz and exercises to pointers

This commit is contained in:
Inanc Gumus
2019-06-30 17:04:27 +03:00
parent 1fb9f43a67
commit ac856db508
16 changed files with 618 additions and 0 deletions

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/
//
// ---------------------------------------------------------
// EXERCISE: Basics
//
// Let's warm up with the pointer basics. Please follow the
// instructions inside the code. Run the solution to see
// its output if you need to.
// ---------------------------------------------------------
package main
type computer struct {
brand string
}
func main() {
// create a nil pointer with the type of pointer to a computer
// compare the pointer variable to a nil value, and say it's nil
// create an apple computer by putting its address to a pointer variable
// put the apple into a new pointer variable
// compare the apples: if they are equal say so and print their addresses
// create a sony computer by putting its address to a new pointer variable
// compare apple to sony, if they are not equal say so and print their
// addresses
// put apple's value into a new ordinary variable
// print apple pointer variable's address, and the address it points to
// and, print the new variable's addresses as well
// compare the value that is pointed by the apple and the new variable
// if they are equal say so
// print the values:
// the value that is pointed by the apple and the new variable
// create a new function: change
// the func can change the given computer's brand to another brand
// change sony's brand to hp using the func — print sony's brand
// write a func that returns the value that is pointed by the given *computer
// print the returned value
// write a new constructor func that returns a pointer to a computer
// and call the func 3 times and print the returned values' addresses
}

View File

@ -0,0 +1,96 @@
// 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"
type computer struct {
brand string
}
func main() {
// create a nil pointer with the type of pointer to a computer
var null *computer
// compare the pointer variable to a nil value
if null == nil {
// , and say it's nil
fmt.Println("null computer is nil")
}
// create an apple computer by putting its address to a pointer variable
apple := &computer{brand: "apple"}
// put the apple into a new pointer variable
newApple := apple
// compare the apples: if they are equal
if apple == newApple {
// say so and print their addresses
fmt.Printf("apples are equal : apple: %p newApple: %p\n",
apple, newApple)
}
// create a sony computer by putting its address to a new pointer variable
sony := &computer{brand: "sony"}
// compare apple to sony, if they are not equal
if apple != sony {
// say so and print their addresses
fmt.Printf("apple and sony are inequal: apple: %p sony: %p\n",
apple, sony)
}
// put apple's value into a new ordinary variable
appleVal := *apple
// print apple pointer variable's address, and the address it points to
// and, print the new variable's addresses as well
fmt.Printf("apple : %p %p\n", &apple, apple)
fmt.Printf("appleVal : %p\n", &appleVal)
// compare the value that is pointed by the apple and the new variable
if *apple == appleVal {
// if they are equal say so
fmt.Println("apple and appleVal are equal")
// print the values:
// the value that is pointed by the apple and the new variable
fmt.Printf("apple : %+v — appleVal: %+v\n",
*apple, appleVal)
}
// change sony's brand to hp using the func
change(sony, "hp")
// print sony's brand
fmt.Printf("sony : %s\n", sony.brand)
// print the returned value
fmt.Printf("appleVal : %+v\n", valueOf(apple))
// and call the func 3 times and print the returned values' addresses
fmt.Printf("dell's address : %p\n", newComputer("dell"))
fmt.Printf("lenovo's address : %p\n", newComputer("lenovo"))
fmt.Printf("acer's address : %p\n", newComputer("acer"))
}
// create a new function: change
// the func can change the given computer's brand to another brand
func change(c *computer, brand string) {
c.brand = brand
}
// write a func that returns the value that is pointed by the given *computer
func valueOf(c *computer) computer {
return *c
}
// write a new constructor func that returns a pointer to a computer
func newComputer(brand string) *computer {
return &computer{brand: brand}
}

View File

@ -0,0 +1,45 @@
// 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/
//
// ---------------------------------------------------------
// EXERCISE: Swap
//
// Using funcs, swap values through pointers, and swap
// the addresses of the pointers.
//
//
// 1- Swap the values through a func
//
// a- Declare two float variables
//
// b- Declare a func that can swap the variables' values
// through their memory addresses
//
// c- Pass the variables' addresses to the func
//
// d- Print the variables
//
//
// 2- Swap the addresses of the float pointers through a func
//
// a- Declare two float pointer variables and,
// assign them the addresses of float variables
//
// b- Declare a func that can swap the addresses
// of two float pointers
//
// c- Pass the pointer variables to the func
//
// d- Print the addresses, and values that are
// pointed by the pointer variables
//
// ---------------------------------------------------------
package main
func main() {
}

View File

@ -0,0 +1,29 @@
// For more tutorials: https://blog.learngoprogramming.com
//
// Copyright © 2018 Inanc Gumus
// Learn Go Programming Course
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
//
package main
import "fmt"
func main() {
a, b := 3.14, 6.28
swap(&a, &b)
fmt.Printf("a : %g — b : %g\n", a, b)
pa, pb := &a, &b
pa, pb = swapAddr(pa, pb)
fmt.Printf("pa: %p — pb: %p\n", pa, pb)
fmt.Printf("pa: %g — pb: %g\n", *pa, *pb)
}
func swap(a, b *float64) {
*a, *b = *b, *a
}
func swapAddr(a, b *float64) (*float64, *float64) {
return b, a
}

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/
//
// ---------------------------------------------------------
// EXERCISE: Fix the crash
//
// EXPECTED OUTPUT
//
// brand: apple
// ---------------------------------------------------------
package main
import "fmt"
type computer struct {
brand *string
}
func main() {
var c *computer
change(c, "apple")
fmt.Printf("brand: %s\n", c.brand)
}
func change(c *computer, brand string) {
(*c.brand) = brand
}

View File

@ -0,0 +1,24 @@
// 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"
type computer struct {
brand *string
}
func main() {
c := &computer{} // init with a value (before: c was nil)
change(c, "apple")
fmt.Printf("brand: %s\n", *c.brand) // print the pointed value
}
func change(c *computer, brand string) {
c.brand = &brand // set the brand's address
}

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/
//
// ---------------------------------------------------------
// EXERCISE: Simplify the code
// HINT : Remove the unnecessary pointer usages
// ---------------------------------------------------------
package main
import "fmt"
func main() {
var schools []map[int]string
schools = append(schools, make(map[int]string))
load(&schools[0], &([]string{"batman", "superman"}))
schools = append(schools, make(map[int]string))
load(&schools[1], &([]string{"spiderman", "wonder woman"}))
fmt.Println(schools[0])
fmt.Println(schools[1])
}
func load(m *map[int]string, students *[]string) {
for i, name := range *students {
(*m)[i+1] = name
}
}

View File

@ -0,0 +1,29 @@
// 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() {
schools := make([]map[int]string, 2)
for i := range schools {
schools[i] = make(map[int]string)
}
load(schools[0], []string{"batman", "superman"})
load(schools[1], []string{"spiderman", "wonder woman"})
fmt.Println(schools[0])
fmt.Println(schools[1])
}
func load(m map[int]string, students []string) {
for i, name := range students {
m[i+1] = name
}
}

View File

@ -0,0 +1,6 @@
learngoprogramming.com 10
learngoprogramming.com 10
golang.org 4
golang.org 6
blog.golang.org 20
blog.golang.org 10

View File

@ -0,0 +1,6 @@
learngoprogramming.com 10
learngoprogramming.com 10
golang.org
golang.org 6
blog.golang.org 20
blog.golang.org 10

View File

@ -0,0 +1,6 @@
learngoprogramming.com 10
learngoprogramming.com 10
golang.org -100
golang.org 6
blog.golang.org 20
blog.golang.org 10

View File

@ -0,0 +1,6 @@
learngoprogramming.com 10
learngoprogramming.com 10
golang.org FOUR
golang.org 6
blog.golang.org 20
blog.golang.org 10

View File

@ -0,0 +1,53 @@
// 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"
"sort"
"strings"
)
func main() {
p := newParser()
// Scan the standard-in line by line
in := bufio.NewScanner(os.Stdin)
for in.Scan() {
p.lines++
parsed, err := parse(p, in.Text())
if err != nil {
fmt.Println(err)
return
}
p = update(p, parsed)
}
// Print the visits per domain
sort.Strings(p.domains)
fmt.Printf("%-30s %10s\n", "DOMAIN", "VISITS")
fmt.Println(strings.Repeat("-", 45))
for _, domain := range p.domains {
parsed := p.sum[domain]
fmt.Printf("%-30s %10d\n", domain, parsed.visits)
}
// Print the total visits for all domains
fmt.Printf("\n%-30s %10d\n", "TOTAL", p.total)
// Let's handle the error
if err := in.Err(); err != nil {
fmt.Println("> Err:", err)
}
}

View File

@ -0,0 +1,74 @@
// 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"
)
// result stores the parsed result for a domain
type result struct {
domain string
visits int
// add more metrics if needed
}
// parser keep tracks of the parsing
type parser struct {
sum map[string]result // metrics per domain
domains []string // unique domain names
total int // total visits for all domains
lines int // number of parsed lines (for the error messages)
}
// newParser constructs, initializes and returns a new parser
func newParser() parser {
return parser{sum: make(map[string]result)}
}
// parse parses a log line and returns the parsed result with an error
func parse(p parser, line string) (parsed result, err error) {
fields := strings.Fields(line)
if len(fields) != 2 {
err = fmt.Errorf("wrong input: %v (line #%d)", fields, p.lines)
return
}
parsed.domain = fields[0]
parsed.visits, err = strconv.Atoi(fields[1])
if parsed.visits < 0 || err != nil {
err = fmt.Errorf("wrong input: %q (line #%d)", fields[1], p.lines)
return
}
return
}
// update updates the parser for the given parsing result
func update(p parser, parsed result) parser {
domain, visits := parsed.domain, parsed.visits
// Collect the unique domains
if _, ok := p.sum[domain]; !ok {
p.domains = append(p.domains, domain)
}
// Keep track of total and per domain visits
p.total += visits
// create and assign a new copy of `visit`
p.sum[domain] = result{
domain: domain,
visits: visits + p.sum[domain].visits,
}
return p
}

View File

@ -0,0 +1,21 @@
# Pointer Exercises
1. **[Basics](https://github.com/inancgumus/learngo/tree/master/26-pointers/exercises/01-basics)**
Warm-up and solidify your knowledge of pointers with the basic exercises. This exercise contains 10+ mini exercises in itself.
2. **[Swap](https://github.com/inancgumus/learngo/tree/master/26-pointers/exercises/02-swap)**
Using funcs, swap the values through pointers, and swap the addresses of pointers. It may be tricky than it sounds.
3. **[Fix the Crash](https://github.com/inancgumus/learngo/tree/master/26-pointers/exercises/03-fix-the-crash)**
Fix the crashing program. Another tricky exercise.
4. **[Simplify](https://github.com/inancgumus/learngo/tree/master/26-pointers/exercises/04-simplify)**
Simplify the given code using your knowledge of map, slices, and pointers.
5. **[Rewrite the Log Parser program using pointers](https://github.com/inancgumus/learngo/tree/master/26-pointers/exercises/05-log-parser)**
You've watched the lecture. Now, try to rewrite the same log parser program using pointers on your own.

View File

@ -0,0 +1,98 @@
## What is a pointer?
1. A variable that contains an hexadecimal value
2. A variable that contains a memory address
3. A value that can contain a memory address of a value *CORRECT*
4. A value that points to a function
> **2:** Although a pointer can be put into a variable, it's not solely a variable. You're almost there! But this distinction is very important.
>
> **3:** A pointer is just another value that can contain a memory address of a value.
## Which one is a pointer to a computer?
```go
type computer struct {
brand string
}
```
1. `*computer{}`
2. `var c computer`
3. `var *c computer`
4. `var c *computer` *CORRECT*
> **4:** * in front of a type denotes a pointer type.
## Which one gets the pointed composite value by the following pointer?
```go
type computer struct {
brand string
}
c := &computer{"Apple"}
```
1. `*c` *CORRECT*
2. `&c`
3. `c`
4. `*computer`
> **1:** * in front of a pointer value gets the value that is pointed by the pointer.
>
> **2:** & in front of a value gets the memory address of that value
>
> **4:** * in front of a type denotes a pointer type.
## What is the result of the following code?
```go
type computer struct {
brand string
}
var a, b *computer
fmt.Print(a == b)
a = &computer{"Apple"}
b = &computer{"Apple"}
fmt.Print(" ", a == b, " ", *a == *b)
```
1. false false false
2. true true true
3. true false true *CORRECT*
4. false true true
> **3:** a and b are nil at the beginning, so they are equal. However, after that, they get two different memory addresses from the composite literals, so their addresses are not equal but their values (that are pointed by the pointers) are equal.
## How many variables are there in the following code?
```go
type computer struct {
brand string
}
func main() {
a = &computer{"Apple"}
b := a
change(b)
change(b)
}
func change(c *computer) {
c.brand = "Indie"
c = nil
}
```
1. 1
2. 2
3. 3
4. 4 *CORRECT*
> **4:** Every time a func runs, it creates new variables from its input params and named result values (if any). There two pointer variables: a and b. Then there are, two more pointer variables because: change is called two times.
## Why you cannot take the address of a map's elements?
1. It's an addressable value
2. It's an unaddressable value *CORRECT*
3. Doing so can crash your program
> **2:** Map elements are not addressable, so you cannot take their addresses.