Merge pull request #11 from tiburon-777/hw10_program_optimization
Hw10 program optimizationpull/12/head
commit
34aba1ad22
|
@ -30,6 +30,13 @@ GetDomainStat(r, "edu") // {"quinu": 1}
|
|||
- удалять имеющийся лишний код (кроме функции `GetDomainStat`);
|
||||
- добавлять юнит-тесты.
|
||||
|
||||
**Обратите внимание на запуск TestGetDomainStat_Time_And_Memory**
|
||||
```bash
|
||||
go test -v -count=1 -timeout=30s -tags bench .
|
||||
```
|
||||
|
||||
Здесь используется билд-тэг bench, чтобы отделить обычные тесты от тестов производительности.
|
||||
|
||||
### Критерии оценки
|
||||
- Пайплайн зелёный и нет попытки «обмануть» систему - 4 балла
|
||||
- Добавлены юнит-тесты - до 3 баллов
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
module github.com/fixme_my_friend/hw10_program_optimization
|
||||
module github.com/tiburon-777/HW_OTUS/hw10_program_optimization
|
||||
|
||||
go 1.14
|
||||
|
||||
require github.com/stretchr/testify v1.5.1
|
||||
require (
|
||||
github.com/json-iterator/go v1.1.10
|
||||
github.com/stretchr/testify v1.5.1
|
||||
)
|
||||
|
|
|
@ -1,8 +1,18 @@
|
|||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
package hw10_program_optimization //nolint:golint,stylecheck
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"bufio"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
|
@ -21,47 +20,25 @@ type User struct {
|
|||
|
||||
type DomainStat map[string]int
|
||||
|
||||
var json = jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
|
||||
func GetDomainStat(r io.Reader, domain string) (DomainStat, error) {
|
||||
u, err := getUsers(r)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get users error: %s", err)
|
||||
}
|
||||
return countDomains(u, domain)
|
||||
}
|
||||
|
||||
type users [100_000]User
|
||||
|
||||
func getUsers(r io.Reader) (result users, err error) {
|
||||
content, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
lines := strings.Split(string(content), "\n")
|
||||
for i, line := range lines {
|
||||
var user User
|
||||
if err = json.Unmarshal([]byte(line), &user); err != nil {
|
||||
return
|
||||
}
|
||||
result[i] = user
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func countDomains(u users, domain string) (DomainStat, error) {
|
||||
result := make(DomainStat)
|
||||
|
||||
for _, user := range u {
|
||||
matched, err := regexp.Match("\\."+domain, []byte(user.Email))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
var err error
|
||||
var user User
|
||||
e := bufio.NewReader(r)
|
||||
for {
|
||||
line, _, err := e.ReadLine()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err = json.Unmarshal(line, &user); err != nil {
|
||||
return DomainStat{}, err
|
||||
}
|
||||
|
||||
if matched {
|
||||
num := result[strings.ToLower(strings.SplitN(user.Email, "@", 2)[1])]
|
||||
num++
|
||||
result[strings.ToLower(strings.SplitN(user.Email, "@", 2)[1])] = num
|
||||
if strings.HasSuffix(user.Email, "."+domain) {
|
||||
result[strings.ToLower(strings.SplitN(user.Email, "@", 2)[1])]++
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
return result, err
|
||||
}
|
||||
|
|
|
@ -16,6 +16,13 @@ func TestGetDomainStat(t *testing.T) {
|
|||
{"Id":4,"Name":"Gregory Reid","Username":"tButler","Email":"5Moore@Teklist.net","Phone":"520-04-16","Password":"r639qLNu","Address":"Sunfield Park 20"}
|
||||
{"Id":5,"Name":"Janice Rose","Username":"KeithHart","Email":"nulla@Linktype.com","Phone":"146-91-01","Password":"acSBF5","Address":"Russell Trail 61"}`
|
||||
|
||||
dataNeg := `{"Id":1,"Name":"Howard Mendoza","Username":"0Oliver","Email":"aliquid_qui_ea@Brow@sedrive.gov","Phone":"6-866-899-36-79","Password":"InAQJvsq","Address":"Blackbird Place 25"
|
||||
{"Id":2,"Name":"Jesse Vasquez","Username":"qRichardson","Email":"mLynchbroWsecat.com","Phone":"9-373-949-64-00","Password":"SiZLeNSGn","Address":"Fulton Hill 80"}`
|
||||
|
||||
dataCase1 := `{"Id":1,"Name":"Howard Mendoza","Username":"0Oliver","Email":"aliquid_qui_ea@Browsedrive.run","Phone":"6-866-899-36-79","Password":"InAQJvsq","Address":"Blackbird Place 25"}
|
||||
{"Id":2,"Name":"Jesse Vasquez","Username":"qRichardson","Email":"mLynch@broWsecat.run","Phone":"9-373-949-64-00","Password":"SiZLeNSGn","Address":"Fulton Hill 80"}
|
||||
{"Id":4,"Name":"Gregory Reid","Username":"tButler","Email":"5Moore@Teklist.ru","Phone":"520-04-16","Password":"r639qLNu","Address":"Sunfield Park 20"}`
|
||||
|
||||
t.Run("find 'com'", func(t *testing.T) {
|
||||
result, err := GetDomainStat(bytes.NewBufferString(data), "com")
|
||||
require.NoError(t, err)
|
||||
|
@ -36,4 +43,16 @@ func TestGetDomainStat(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
require.Equal(t, DomainStat{}, result)
|
||||
})
|
||||
|
||||
t.Run("Error test", func(t *testing.T) {
|
||||
result, err := GetDomainStat(bytes.NewBufferString(dataNeg), "unknown")
|
||||
require.Error(t, err)
|
||||
require.Equal(t, DomainStat{}, result)
|
||||
})
|
||||
|
||||
t.Run("Case1 test", func(t *testing.T) {
|
||||
result, err := GetDomainStat(bytes.NewBufferString(dataCase1), "ru")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, DomainStat{"teklist.ru": 1}, result)
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue