Skip to content

Commit

Permalink
HW10 is completed
Browse files Browse the repository at this point in the history
Signed-off-by: Pavel Pogodaev <[email protected]>
  • Loading branch information
Pavel Pogodaev committed Nov 18, 2024
1 parent 411b524 commit 9488b41
Show file tree
Hide file tree
Showing 7 changed files with 223 additions and 25 deletions.
Empty file removed hw10_program_optimization/.sync
Empty file.
3 changes: 3 additions & 0 deletions hw10_program_optimization/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ go 1.22

require github.com/stretchr/testify v1.7.0

require github.com/mailru/easyjson v0.7.7

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)
4 changes: 4 additions & 0 deletions hw10_program_optimization/go.sum
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
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/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
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=
Expand Down
40 changes: 21 additions & 19 deletions hw10_program_optimization/stats.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package hw10programoptimization

import (
"encoding/json"
"bufio"
"errors"
"fmt"
"io"
"regexp"
"strings"

"github.com/mailru/easyjson" //nolint:depguard
)

type User struct {
Expand All @@ -20,7 +22,13 @@ type User struct {

type DomainStat map[string]int

var ErrEmptyDomain = errors.New("empty domain")

func GetDomainStat(r io.Reader, domain string) (DomainStat, error) {
if domain == "" {
return nil, ErrEmptyDomain
}

u, err := getUsers(r)
if err != nil {
return nil, fmt.Errorf("get users error: %w", err)
Expand All @@ -31,35 +39,29 @@ func GetDomainStat(r io.Reader, domain string) (DomainStat, error) {
type users [100_000]User

func getUsers(r io.Reader) (result users, err error) {
content, err := io.ReadAll(r)
if err != nil {
return
}
scanner := bufio.NewScanner(r)
var i int

lines := strings.Split(string(content), "\n")
for i, line := range lines {
for scanner.Scan() {
var user User
if err = json.Unmarshal([]byte(line), &user); err != nil {
if err = easyjson.Unmarshal(scanner.Bytes(), &user); err != nil {
return
}

result[i] = user
i++
}
return

return result, scanner.Err()
}

func countDomains(u users, domain string) (DomainStat, error) {
result := make(DomainStat)
domain = strings.ToLower(domain)

for _, user := range u {
matched, err := regexp.Match("\\."+domain, []byte(user.Email))
if err != nil {
return nil, 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.Contains(user.Email, "."+domain) {
result[strings.ToLower(strings.SplitN(user.Email, "@", 2)[1])]++
}
}
return result, nil
Expand Down
127 changes: 127 additions & 0 deletions hw10_program_optimization/stats_easyjson.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion hw10_program_optimization/stats_optimization_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"testing"
"time"

"github.com/stretchr/testify/require"
"github.com/stretchr/testify/require" //nolint:depguard
)

const (
Expand Down
72 changes: 67 additions & 5 deletions hw10_program_optimization/stats_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build !bench
// +build !bench

package hw10programoptimization
Expand All @@ -6,15 +7,30 @@ import (
"bytes"
"testing"

"github.com/stretchr/testify/require"
"github.com/stretchr/testify/require" //nolint:depguard
)

func TestGetDomainStat(t *testing.T) {
data := `{"Id":1,"Name":"Howard Mendoza","Username":"0Oliver","Email":"[email protected]","Phone":"6-866-899-36-79","Password":"InAQJvsq","Address":"Blackbird Place 25"}
{"Id":2,"Name":"Jesse Vasquez","Username":"qRichardson","Email":"[email protected]","Phone":"9-373-949-64-00","Password":"SiZLeNSGn","Address":"Fulton Hill 80"}
{"Id":3,"Name":"Clarence Olson","Username":"RachelAdams","Email":"[email protected]","Phone":"988-48-97","Password":"71kuz3gA5w","Address":"Monterey Park 39"}
{"Id":4,"Name":"Gregory Reid","Username":"tButler","Email":"[email protected]","Phone":"520-04-16","Password":"r639qLNu","Address":"Sunfield Park 20"}
{"Id":5,"Name":"Janice Rose","Username":"KeithHart","Email":"[email protected]","Phone":"146-91-01","Password":"acSBF5","Address":"Russell Trail 61"}`
{"Id":2,"Name":"Jesse Vasquez","Username":"qRichardson","Email":"[email protected]","Phone":"9-373-949-64-00","Password":"SiZLeNSGn","Address":"Fulton Hill 80"}
{"Id":3,"Name":"Clarence Olson","Username":"RachelAdams","Email":"[email protected]","Phone":"988-48-97","Password":"71kuz3gA5w","Address":"Monterey Park 39"}
{"Id":4,"Name":"Gregory Reid","Username":"tButler","Email":"[email protected]","Phone":"520-04-16","Password":"r639qLNu","Address":"Sunfield Park 20"}
{"Id":5,"Name":"Janice Rose","Username":"KeithHart","Email":"[email protected]","Phone":"146-91-01","Password":"acSBF5","Address":"Russell Trail 61"}`

data2 := `{"Id":1,"Name":"Howard Mendoza","Username":"0Oliver","Email":"aliquid_qui_ea@я.ру","Phone":"6-866-899-36-79","Password":"InAQJvsq","Address":"Blackbird Place 25"}
{"Id":2,"Name":"Jesse Vasquez","Username":"qRichardson","Email":"mLynch@я.ру","Phone":"6-866-899-36-79","Password":"InAQJvsq","Address":"Blackbird Place 25"}`

data3 := `{"Id":1,"Name":"Howard Mendoza","Username":"0Oliver","Email":"aliquid_qui_ea@Browsedrive","Phone":"6-866-899-36-79","Password":"InAQJvsq","Address":"Blackbird Place 25"}
{"Id":2,"Name":"Jesse Vasquez","Username":"qRichardson","Email":"[email protected]","Phone":"9-373-949-64-00","Password":"SiZLeNSGn","Address":"Fulton Hill 80"}
{"Id":3,"Name":"Clarence Olson","Username":"RachelAdams","Email":"RoseSmith@Browsecat","Phone":"988-48-97","Password":"71kuz3gA5w","Address":"Monterey Park 39"}`

data4 := `{"Id":1,"Name":"Howard Mendoza","Username":"0Oliver","Email":"@browsedrive.su","Phone":"6-866-899-36-79","Password":"InAQJvsq","Address":"Blackbird Place 25"}
{"Id":2,"Name":"Jesse Vasquez","Username":"qRichardson","Email":"@browsecat.com","Phone":"9-373-949-64-00","Password":"SiZLeNSGn","Address":"Fulton Hill 80"}
{"Id":3,"Name":"Clarence Olson","Username":"RachelAdams","Email":"[email protected]","Phone":"988-48-97","Password":"71kuz3gA5w","Address":"Monterey Park 39"}`

data5 := `{"Id":1,"Name":"Howard Mendoza","Username":"0Oliver","Email":"aliquid_qui_ea@","Phone":"6-866-899-36-79","Password":"InAQJvsq","Address":"Blackbird Place 25"}
{"Id":2,"Name":"Jesse Vasquez","Username":"qRichardson","Email":"[email protected]","Phone":"9-373-949-64-00","Password":"SiZLeNSGn","Address":"Fulton Hill 80"}
{"Id":3,"Name":"Clarence Olson","Username":"RachelAdams","Email":"RoseSmith@","Phone":"988-48-97","Password":"71kuz3gA5w","Address":"Monterey Park 39"}`

t.Run("find 'com'", func(t *testing.T) {
result, err := GetDomainStat(bytes.NewBufferString(data), "com")
Expand All @@ -36,4 +52,50 @@ func TestGetDomainStat(t *testing.T) {
require.NoError(t, err)
require.Equal(t, DomainStat{}, result)
})

t.Run("find empty domain", func(t *testing.T) {
_, err := GetDomainStat(bytes.NewBufferString(data), "")
require.ErrorIs(t, err, ErrEmptyDomain)
})

t.Run("find domain with capital letter", func(t *testing.T) {
result, err := GetDomainStat(bytes.NewBufferString(data), "Com")
require.NoError(t, err)
require.Equal(t, DomainStat{
"browsecat.com": 2,
"linktype.com": 1,
}, result)
})

t.Run("find cyrillic 'ру'", func(t *testing.T) {
result, err := GetDomainStat(bytes.NewBufferString(data2), "ру")
require.NoError(t, err)
require.Equal(t, DomainStat{
"я.ру": 2,
}, result)
})

t.Run("find 'com' without domain", func(t *testing.T) {
result, err := GetDomainStat(bytes.NewBufferString(data3), "com")
require.NoError(t, err)
require.Equal(t, DomainStat{
"browsecat.com": 1,
}, result)
})

t.Run("find 'com' without user name", func(t *testing.T) {
result, err := GetDomainStat(bytes.NewBufferString(data4), "com")
require.NoError(t, err)
require.Equal(t, DomainStat{
"browsecat.com": 1,
}, result)
})

t.Run("find 'com' none symbols after @", func(t *testing.T) {
result, err := GetDomainStat(bytes.NewBufferString(data5), "com")
require.NoError(t, err)
require.Equal(t, DomainStat{
"browsecat.com": 1,
}, result)
})
}

0 comments on commit 9488b41

Please sign in to comment.