add: variadic funcs
This commit is contained in:
@ -0,0 +1,6 @@
|
|||||||
|
learngoprogramming.com 10
|
||||||
|
learngoprogramming.com 10
|
||||||
|
golang.org 4
|
||||||
|
golang.org 6
|
||||||
|
blog.golang.org 20
|
||||||
|
blog.golang.org 10
|
@ -0,0 +1,6 @@
|
|||||||
|
learngoprogramming.com 10
|
||||||
|
learngoprogramming.com 10
|
||||||
|
golang.org
|
||||||
|
golang.org 6
|
||||||
|
blog.golang.org 20
|
||||||
|
blog.golang.org 10
|
@ -0,0 +1,6 @@
|
|||||||
|
learngoprogramming.com 10
|
||||||
|
learngoprogramming.com 10
|
||||||
|
golang.org -100
|
||||||
|
golang.org 6
|
||||||
|
blog.golang.org 20
|
||||||
|
blog.golang.org 10
|
@ -0,0 +1,6 @@
|
|||||||
|
learngoprogramming.com 10
|
||||||
|
learngoprogramming.com 10
|
||||||
|
golang.org FOUR
|
||||||
|
golang.org 6
|
||||||
|
blog.golang.org 20
|
||||||
|
blog.golang.org 10
|
@ -0,0 +1,51 @@
|
|||||||
|
// 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()
|
||||||
|
|
||||||
|
in := bufio.NewScanner(os.Stdin)
|
||||||
|
for in.Scan() {
|
||||||
|
parsed := parse(p, in.Text())
|
||||||
|
update(p, parsed)
|
||||||
|
}
|
||||||
|
|
||||||
|
summarize(p)
|
||||||
|
dumpErrs(in.Err(), err(p))
|
||||||
|
}
|
||||||
|
|
||||||
|
// summarize summarizes and prints the parsing result
|
||||||
|
func summarize(p *parser) {
|
||||||
|
sort.Strings(p.domains)
|
||||||
|
|
||||||
|
fmt.Printf("%-30s %10s\n", "DOMAIN", "VISITS")
|
||||||
|
fmt.Println(strings.Repeat("-", 45))
|
||||||
|
|
||||||
|
for _, domain := range p.domains {
|
||||||
|
fmt.Printf("%-30s %10d\n", domain, p.sum[domain].visits)
|
||||||
|
}
|
||||||
|
fmt.Printf("\n%-30s %10d\n", "TOTAL", p.total)
|
||||||
|
}
|
||||||
|
|
||||||
|
// dumpErrs simplifies handling multiple errors
|
||||||
|
func dumpErrs(errs ...error) {
|
||||||
|
for _, err := range errs {
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("> Err:", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
// 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)
|
||||||
|
lerr error // the last error occurred
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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) (r result) {
|
||||||
|
if p.lerr != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
p.lines++
|
||||||
|
|
||||||
|
fields := strings.Fields(line)
|
||||||
|
if len(fields) != 2 {
|
||||||
|
p.lerr = fmt.Errorf("wrong input: %v (line #%d)", fields, p.lines)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
|
||||||
|
r.domain = fields[0]
|
||||||
|
r.visits, err = strconv.Atoi(fields[1])
|
||||||
|
|
||||||
|
if r.visits < 0 || err != nil {
|
||||||
|
p.lerr = fmt.Errorf("wrong input: %q (line #%d)", fields[1], p.lines)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// update updates the errors for the given parsing result
|
||||||
|
func update(p *parser, r result) {
|
||||||
|
if p.lerr != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect the unique domains
|
||||||
|
if _, ok := p.sum[r.domain]; !ok {
|
||||||
|
p.domains = append(p.domains, r.domain)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep track of total and per domain visits
|
||||||
|
p.total += r.visits
|
||||||
|
|
||||||
|
// create and assign a new copy of `visit`
|
||||||
|
p.sum[r.domain] = result{
|
||||||
|
domain: r.domain,
|
||||||
|
visits: r.visits + p.sum[r.domain].visits,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// err returns the last error encountered
|
||||||
|
func err(p *parser) error {
|
||||||
|
return p.lerr
|
||||||
|
}
|
73
27-functions-advanced/01-variadic-funcs/main.go
Normal file
73
27-functions-advanced/01-variadic-funcs/main.go
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
// 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() {
|
||||||
|
nums := []int{2, 3, 7}
|
||||||
|
fmt.Printf("nums : %d\n", nums)
|
||||||
|
|
||||||
|
n := avgNoVariadic(nums)
|
||||||
|
fmt.Printf("avgNoVariadic : %d\n", n)
|
||||||
|
|
||||||
|
n = avg(2, 3, 7)
|
||||||
|
fmt.Printf("avg(2, 3, 7) : %d\n", n)
|
||||||
|
|
||||||
|
n = avg(2, 3, 7, 8)
|
||||||
|
fmt.Printf("avg(2, 3, 7, 8) : %d\n", n)
|
||||||
|
|
||||||
|
// use ... to pass a slice
|
||||||
|
n = avg(nums...)
|
||||||
|
fmt.Printf("avg(nums...) : %d\n", n)
|
||||||
|
|
||||||
|
// uses the existing slice
|
||||||
|
double(nums...)
|
||||||
|
fmt.Printf("double(nums...) : %d\n", nums)
|
||||||
|
|
||||||
|
// creates a new slice
|
||||||
|
double(4, 6, 14)
|
||||||
|
fmt.Printf("double(4, 6, 14): %d\n", nums)
|
||||||
|
|
||||||
|
// creates a nil slice
|
||||||
|
fmt.Printf("\nmain.nums : %p\n", nums)
|
||||||
|
investigate("passes main.nums", nums...)
|
||||||
|
investigate("passes main.nums", nums...)
|
||||||
|
investigate("passes args", 4, 6, 14)
|
||||||
|
investigate("passes args", 4, 6, 14)
|
||||||
|
investigate("no args")
|
||||||
|
}
|
||||||
|
|
||||||
|
func investigate(msg string, nums ...int) {
|
||||||
|
fmt.Printf("investigate.nums: %12p -> %s\n", nums, msg)
|
||||||
|
|
||||||
|
if len(nums) > 0 {
|
||||||
|
fmt.Printf("\tfirst element: %d\n", nums[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func double(nums ...int) {
|
||||||
|
for i := range nums {
|
||||||
|
nums[i] *= 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func avg(nums ...int) int {
|
||||||
|
return sum(nums) / len(nums)
|
||||||
|
}
|
||||||
|
|
||||||
|
func avgNoVariadic(nums []int) int {
|
||||||
|
return sum(nums) / len(nums)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sum(nums []int) (total int) {
|
||||||
|
for _, n := range nums {
|
||||||
|
total += n
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
Reference in New Issue
Block a user