interfaces: refactor

This commit is contained in:
Inanc Gumus
2019-08-19 10:21:11 +03:00
parent b95be49711
commit 158f475a2d
89 changed files with 784 additions and 2 deletions

View File

@@ -0,0 +1,7 @@
### PROBLEM
+ ...
## SOLUTION
+ `parser struct` -> `pipeline struct`
+ `parse()` -> `pipe(pipeline)`

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() {
pipes := pipeline{
// read: textParser(),
// write: textSummary(),
// filterBy: notUsing(domainExtFilter("io", "com")),
// groupBy: domainGrouper,
}
res, err := pipe(pipes)
if err != nil {
fmt.Println("> Err:", err)
return
}
summarize(res)
}

View File

@@ -0,0 +1,48 @@
// 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"
)
// pipeline determines the behavior of log processing
type pipeline struct {
}
// pipe the log lines through funcs and produce a result
func pipe(opts pipeline) ([]result, error) {
var (
l = 1
in = bufio.NewScanner(os.Stdin)
sum = make(map[string]result)
)
// parse the log lines
for in.Scan() {
r, err := parseResult(in.Text())
if err != nil {
return nil, fmt.Errorf("line %d: %v", l, err)
}
l++
// group the log lines by domain
sum[r.domain] = addResult(r, sum[r.domain])
}
// collect the grouped results
res := make([]result, 0, len(sum))
for _, r := range sum {
res = append(res, r)
}
return res, in.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"
)
const fieldsLength = 4
// result stores the parsed result for a domain
type result struct {
domain, page string
visits, uniques int
// add more metrics if needed
}
// parseResult from a log line
func parseResult(line string) (r result, err error) {
fields := strings.Fields(line)
if len(fields) != fieldsLength {
return r, fmt.Errorf("wrong input: %v", fields)
}
r.domain = fields[0]
r.page = fields[1]
r.visits, err = strconv.Atoi(fields[2])
if err != nil || r.visits < 0 {
return r, fmt.Errorf("wrong input: %q", fields[2])
}
r.uniques, err = strconv.Atoi(fields[3])
if err != nil || r.uniques < 0 {
return r, fmt.Errorf("wrong input: %q", fields[3])
}
return r, nil
}
// addResult to another one
func addResult(r, other result) result {
r.visits += other.visits
r.uniques += other.uniques
return r
}

View File

@@ -0,0 +1,48 @@
// 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"
"sort"
"strings"
)
// summarize summarizes and prints the parsing result
// + violation: accesses the parsing internals: p.domains + p.sum + p.total
// + give it the []result only.
// + let it calculate the total.
const (
// DOMAINS PAGES VISITS UNIQUES
// ^ ^ ^ ^
// | | | |
header = "%-25s %-10s %10s %10s\n"
line = "%-25s %-10s %10d %10d\n"
footer = "\n%-36s %10d %10d\n" // -> "" VISITS UNIQUES
dash = "-"
dashLength = 58
)
// summarize summarizes and prints the parsing result
func summarize(res []result) {
sort.Slice(res, func(i, j int) bool {
return res[i].domain <= res[j].domain
})
fmt.Printf(header, "DOMAIN", "PAGES", "VISITS", "UNIQUES")
fmt.Println(strings.Repeat("-", dashLength))
var total result
for _, r := range res {
total = addResult(total, r)
fmt.Printf(line, r.domain, r.page, r.visits, r.uniques)
}
fmt.Printf(footer, "TOTAL", total.visits, total.uniques)
}