impl and test zip.Get, MilesTo, GetStatesWithin, FromCityState

Bel LaPointe 2022-01-27 18:11:11 -07:00
parent 128c98dfbd
commit db289cb5c8
2 changed files with 63 additions and 7 deletions

View File

@ -2,7 +2,6 @@ package zip
import ( import (
_ "embed" _ "embed"
"local/truckstop/logtr"
"math" "math"
"strconv" "strconv"
"strings" "strings"
@ -21,11 +20,13 @@ type Zip struct {
var zips map[string]Zip var zips map[string]Zip
func init() { func init() {
if len(zips) > 0 {
return
}
zips = map[string]Zip{} zips = map[string]Zip{}
trim := func(s string) string { trim := func(s string) string {
return strings.Trim(s, `"`) return strings.Trim(s, `"`)
} }
logtr.Infof("%d", len(csv))
for _, line := range strings.Split(csv, "\n")[1:] { for _, line := range strings.Split(csv, "\n")[1:] {
strs := strings.Split(line, ",") strs := strings.Split(line, ",")
if len(strs) < 5 { if len(strs) < 5 {
@ -34,17 +35,26 @@ func init() {
zip := trim(strs[0]) zip := trim(strs[0])
lat, _ := strconv.ParseFloat(trim(strs[1]), 32) lat, _ := strconv.ParseFloat(trim(strs[1]), 32)
lng, _ := strconv.ParseFloat(trim(strs[2]), 32) lng, _ := strconv.ParseFloat(trim(strs[2]), 32)
city := trim(strs[3]) city := trim(alphafy(strs[3]))
state := trim(strs[4]) state := strings.ToUpper(trim(strs[4]))
zips[zip] = Zip{ zips[zip] = Zip{
Lat: lat, Lat: lat,
Lng: lng, Lng: lng,
City: city, City: city,
State: state, State: state,
} }
logtr.Infof("%+v", zips[zip])
} }
logtr.Infof("%+v to %+v = %v", Get("27006"), Get("84059"), Get("27006").MilesTo(Get("84059"))) }
func alphafy(s string) string {
bs := make([]byte, 0, len(s)+1)
for i := range s {
if (s[i] < 'a' || s[i] > 'z') && (s[i] < 'A' || s[i] > 'Z') {
} else {
bs = append(bs, s[i])
}
}
return strings.ToLower(string(bs))
} }
func (zip Zip) MilesTo(other Zip) int { func (zip Zip) MilesTo(other Zip) int {
@ -73,3 +83,28 @@ func Get(zip string) Zip {
} }
return Zip{} return Zip{}
} }
func GetStatesWithin(zip Zip, miles int) []string {
states := map[string]struct{}{}
for _, other := range zips {
if zip.MilesTo(other) <= miles {
states[other.State] = struct{}{}
}
}
result := []string{}
for state := range states {
result = append(result, state)
}
return result
}
func FromCityState(city, state string) Zip {
city = alphafy(city)
state = strings.ToUpper(state)
for _, z := range zips {
if z.City == city && z.State == state {
return z
}
}
return Zip{}
}

View File

@ -1,7 +1,28 @@
package zip package zip
import "testing" import (
"fmt"
"sort"
"testing"
)
func TestZip(t *testing.T) { func TestZip(t *testing.T) {
_ = true _ = true
zip27006 := Get("27006")
zip84059 := Get("84059")
t.Logf("27006 = %+v", zip27006)
t.Logf("84059 = %+v", zip84059)
if zip27006.MilesTo(zip84059) < 1800 {
t.Error("failed to compute miles from advance to ut")
}
sorted := func(s []string) []string {
sort.Strings(s)
return s
}
if got := GetStatesWithin(Get("27006"), 100); fmt.Sprint(sorted(got)) != fmt.Sprint(sorted([]string{"NC", "SC", "TN", "VA"})) {
t.Error(got)
}
if got := FromCityState("ADVANCE", "nc"); got != zip27006 {
t.Error(got)
}
} }