From db289cb5c8bafaeec1ae040be5fc1a6b1eb54204 Mon Sep 17 00:00:00 2001 From: Bel LaPointe Date: Thu, 27 Jan 2022 18:11:11 -0700 Subject: [PATCH] impl and test zip.Get, MilesTo, GetStatesWithin, FromCityState --- zip/zip.go | 47 +++++++++++++++++++++++++++++++++++++++++------ zip/zip_test.go | 23 ++++++++++++++++++++++- 2 files changed, 63 insertions(+), 7 deletions(-) diff --git a/zip/zip.go b/zip/zip.go index a5a8c54..6f17573 100644 --- a/zip/zip.go +++ b/zip/zip.go @@ -2,7 +2,6 @@ package zip import ( _ "embed" - "local/truckstop/logtr" "math" "strconv" "strings" @@ -21,11 +20,13 @@ type Zip struct { var zips map[string]Zip func init() { + if len(zips) > 0 { + return + } zips = map[string]Zip{} trim := func(s string) string { return strings.Trim(s, `"`) } - logtr.Infof("%d", len(csv)) for _, line := range strings.Split(csv, "\n")[1:] { strs := strings.Split(line, ",") if len(strs) < 5 { @@ -34,17 +35,26 @@ func init() { zip := trim(strs[0]) lat, _ := strconv.ParseFloat(trim(strs[1]), 32) lng, _ := strconv.ParseFloat(trim(strs[2]), 32) - city := trim(strs[3]) - state := trim(strs[4]) + city := trim(alphafy(strs[3])) + state := strings.ToUpper(trim(strs[4])) zips[zip] = Zip{ Lat: lat, Lng: lng, City: city, 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 { @@ -73,3 +83,28 @@ func Get(zip string) 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{} +} diff --git a/zip/zip_test.go b/zip/zip_test.go index 15c7da6..6387572 100644 --- a/zip/zip_test.go +++ b/zip/zip_test.go @@ -1,7 +1,28 @@ package zip -import "testing" +import ( + "fmt" + "sort" + "testing" +) func TestZip(t *testing.T) { _ = 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) + } }