Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix PC encoding for Brazil #36

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
51 changes: 51 additions & 0 deletions pgeocode.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import numpy as np
import pandas as pd


__version__ = "0.2.1"

STORAGE_DIR = os.environ.get(
Expand Down Expand Up @@ -250,8 +251,26 @@ def query_postal_code(self, codes):
if isinstance(codes, str):
codes = [codes]
single_entry = True
check_zip_code = _CheckPostalCode(codes)
try:
if not check_zip_code(codes):
warnings.warn(
f"{codes} is a invalid postal code for {self.country}"
)
except NotImplementedError:
pass
else:
single_entry = False
for code in codes:
check_zip_code = _CheckPostalCode(code)
try:
if not check_zip_code(code):
warnings.warn(
f"{code} is a invalid"
+ f"postal code for {self.country}"
)
except NotImplementedError:
pass

if not isinstance(codes, pd.DataFrame):
codes = pd.DataFrame(codes, columns=["postal_code"])
Expand Down Expand Up @@ -385,3 +404,35 @@ def haversine_distance(x, y):

c = 2 * np.arcsin(np.sqrt(a))
return EARTH_RADIUS * c


class _CheckPostalCode:
def __init__(self, country):
self.country = country
self.implemented = ["BR"]

def __call__(self, postal_code):
if self.country not in self.implemented:
raise NotImplementedError
else:
return self._check_is_valid_zip_code(postal_code)

def _is_valid_zip_brazil(self, zip_code):
# in the Brazil de zip_codes valids in Geoname are terminated
# with 000 e have 8 digits
if isinstance(zip_code, list):
zip_code = "".join(zip_code)
if isinstance(zip_code, str) and zip_code.find("-") != -1:
zip_code = "".join(zip_code.split("-"))

if not isinstance(zip_code, str):
zip_code = str(zip_code)

return all([len(zip_code) == 8, zip_code[5:] == "000"])

def _check_is_valid_zip_code(self, zip_code):
# each country have a deferent postal code format
if isinstance(zip_code, list):
zip_code = "".join(zip_code)

return self._is_valid_zip_brazil(zip_code)
25 changes: 24 additions & 1 deletion test_pgeocode.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@
from numpy.testing import assert_allclose, assert_array_equal

import pgeocode
from pgeocode import GeoDistance, Nominatim, haversine_distance
from pgeocode import (
GeoDistance,
Nominatim,
haversine_distance,
_CheckPostalCode,
)


@pytest.fixture
Expand Down Expand Up @@ -179,3 +184,21 @@ def test_haversine_distance():
d_pred = haversine_distance(x, y)
# same distance +/- 3 km
assert_allclose(d_ref, d_pred, atol=3)


class TestCheckPostalCode:
""" Test for class CheckPostalCode"""

a = _CheckPostalCode("BR")

def test_is_valid_zip_brazil_false(self, zip_code="69000-010"):
assert self.a._is_valid_zip_brazil(zip_code) is False

def test_check_is_valid_zip_code_false(self, zip_code="69000-010"):
assert self.a._check_is_valid_zip_code(zip_code) is False

def test_is_valid_zip_brazil_true(self, zip_code="69000-000"):
assert self.a._is_valid_zip_brazil(zip_code) is True

def test_check_is_valid_zip_code_true(self, zip_code="69000-000"):
assert self.a._check_is_valid_zip_code(zip_code) is True