reorganize: starting with funcs

This commit is contained in:
Inanc Gumus
2019-04-27 20:18:24 +03:00
parent d71e42c6e4
commit cc790d9c06
60 changed files with 0 additions and 0 deletions

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 showN() {
if N == 0 {
fmt.Println("showN : N is zero, increment it.")
return
}
fmt.Printf("showN : N = %d\n", N)
}
func incrN() {
N++
}
// you cannot declare a function within the same package with the same name
// func incrN() {
// }

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/
//
//
// You need run this program like so:
// go run .
//
// This will magically pass all the go files in the current directory to the
// Go compiler.
//
//
// BUT NOT like so:
// go run main.go
//
// Because, the compiler needs to see global.go too
// It can't magically find global.go — what you give is what you get.
//
package main
// N is a shared counter which is BAD
var N int
func main() {
showN()
incrN()
incrN()
showN()
}

View File

@ -0,0 +1,117 @@
// 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/
//
//
// You need run this program like so:
// go run .
//
// This will magically pass all the go files in the current directory to the
// Go compiler.
//
//
// BUT NOT like so:
// go run main.go
//
// Because, the compiler needs to see global.go too
// It can't magically find global.go — what you give is what you get.
//
package main
import (
"fmt"
"strconv"
)
func main() {
local := 10
show(local)
incrWrong(local)
fmt.Printf("local → %d\n", local)
// incr(local)
local = incr(local)
show(local)
local = incrBy(local, 5)
show(local)
_, err := incrByStr(local, "TWO")
if err != nil {
fmt.Printf("err → %s\n", err)
}
local, _ = incrByStr(local, "2")
show(local)
// CHAINING
// can't save the number back into main's local
show(incrBy(local, 2))
show(local)
// can't pass the results of the multiple-value returning func
// show(incrByStr(local, "3"))
// can call showErr directly because it accepts the same types
// of parameters as with incrByStr's result values.
// local = sanitize(incrByStr(local, "NOPE"))
// show(local)
local = sanitize(incrByStr(local, "2"))
show(local)
local = limit(incrBy(local, 5), 2000)
show(local)
}
func show(n int) {
// can't access main's local
// fmt.Printf("show : n = %d\n", local)
fmt.Printf("show → n = %d\n", n)
}
// wrong: incr can't access to main's `local`
func incrWrong(n int) {
// n := local
n++
// can't return (there are no result values)
// return n
}
func incr(n int) int {
n++
return n
}
func incrBy(n, factor int) int {
return n * factor
}
func incrByStr(n int, factor string) (int, error) {
m, err := strconv.Atoi(factor)
n = incrBy(n, m)
return n, err
}
func sanitize(n int, err error) int {
if err != nil {
return 0
}
return n
}
func limit(n, lim int) (m int) {
// var m int
m = n
if m >= lim {
m = lim
}
// return m
return
}

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,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 (
"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
}
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,
}
}
// 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,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 (
"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
}

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
}