Skip to content

Commit 2cb2f08

Browse files
committed
2016-07-01
Version 0.1.2 pre-release
1 parent 8bb2802 commit 2cb2f08

14 files changed

Lines changed: 2222 additions & 539 deletions

README.rst

Lines changed: 83 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,92 @@
99

1010
Welcome to uszipcode Documentation
1111
==================================
12-
``uszipcode`` is the most powerful and easy to use zipcode information searchengine in Python. Besides geometry data (also boundary info), several useful census data points are also served: `population`, `population density`, `total wage`, `average annual wage`, `house of units`, `land area`, `water area`. The geometry and geocoding data I am using is from google map API on Oct 2015. To know more about the data, `click here <http://pythonhosted.org/uszipcode/uszipcode/data/__init__.html#module-uszipcode.data>`_. `Another pupolar zipcode Python extension <https://pypi.python.org/pypi/zipcode>`_ has lat, lng accuracy issue, which doesn't give me reliable results of searching by coordinate and radius.
12+
``uszipcode`` is the **most powerful and easy to use programmable zipcode database, and also a searchengine** in Python. Besides geometry data (also boundary info), several useful census data points are also served: `population`, `population density`, `total wage`, `average annual wage`, `house of units`, `land area`, `water area`. The geometry and geocoding data I am using is from google map API on Mar 2016. `To know more about the data, click here <http://pythonhosted.org/uszipcode/uszipcode/data/__init__.html#module-uszipcode.data>`_. Another `popular zipcode Python extension <https://pypi.python.org/pypi/zipcode>`_ has lat, lng accuracy issue, which doesn't give me reliable results of searching by coordinate and radius.
1313

1414
**Highlight**:
1515

16-
1. `Rich methods <http://pythonhosted.org/uszipcode/index.html#list-of-the-way-you-can-search>`_ are provided for getting zipcode anyway you want.
17-
2. `Fuzzy city name and state name <http://pythonhosted.org/uszipcode/index.html#search-by-city-and-state>`_ allows you to search **WITHOUT using exactly accurate input**. **This is very helpful if you need to build a web app with it**.
18-
3. You can easily `sort your results <http://pythonhosted.org/uszipcode/index.html#sortby-descending-and-returns-keyword>`_ by `population`, `area`, `wealthy` and etc...
16+
- `Rich information <http://pythonhosted.org/uszipcode/uszipcode/searchengine.html#uszipcode.searchengine.Zipcode>`_ of zipcode is available.
17+
18+
.. code-block:: python
19+
20+
>>> from uszipcode import ZipcodeSearchEngine
21+
>>> search = ZipcodeSearchEngine()
22+
>>> zipcode = search.by_zipcode("10001")
23+
>>> print(zipcode)
24+
{
25+
"City": "New York",
26+
"Density": 34035.48387096774,
27+
"HouseOfUnits": 12476,
28+
"LandArea": 0.62,
29+
"Latitude": 40.75368539999999,
30+
"Longitude": -73.9991637,
31+
"NEBoundLatitude": 40.8282129,
32+
"NEBoundLongitude": -73.9321059,
33+
"Population": 21102,
34+
"SWBoundLatitude": 40.743451,
35+
"SWBoungLongitude": -74.00794499999998,
36+
"State": "NY",
37+
"TotalWages": 1031960117.0,
38+
"WaterArea": 0.0,
39+
"Wealthy": 48903.42702113544,
40+
"Zipcode": "10001",
41+
"ZipcodeType": "Standard"
42+
}
43+
44+
- `Rich search methods <http://pythonhosted.org/uszipcode/index.html#list-of-the-way-you-can-search>`_ are provided for getting zipcode in the way you want.
45+
46+
.. code-block:: python
47+
48+
# Search zipcode within 30 miles, ordered from closest to farthest
49+
>>> res = search.by_coordinate(39.122229, -77.133578, radius=30, returns=5)
50+
>>> len(res) # by default 5 results returned
51+
5
52+
>>> for zipcode in res:
53+
... # do whatever you want...
54+
55+
# Find top 10 population zipcode
56+
>>> res = search.by_population(lower=0, upper=999999999,
57+
... sort_by="Population", ascending=False, returns=10)
58+
59+
# Find top 10 largest land area zipcode
60+
>>> res = search.by_landarea(lower=0, upper=999999999,
61+
... sort_by="LandArea", ascending=False, returns=10)
62+
63+
# Find top 10 most wealthy zipcode in new york
64+
>>> res = search.find(city="newyork", wealthy_lower=100000,
65+
... sort_by="Wealthy", returns=10) # at least $100,000 annual income
66+
67+
- `Fuzzy city name and state name search <http://pythonhosted.org/uszipcode/index.html#search-by-city-and-state>`_ **enables case, space insensitive, typo tolerant input**. **You don't have to know the correct spelling of the city or state**. This is very helpful if you need to build a web app with it.
68+
69+
.. code-block:: python
70+
71+
# Looking for Chicago and IL, but entered wrong spelling.
72+
>>> res = search.by_city_and_state("cicago", "il")
73+
>>> len(res) # 56 zipcodes in Chicago
74+
56
75+
>>> zipcode = res[0]
76+
>>> zipcode.City
77+
'Chicago'
78+
>>> zipcode.State
79+
'IL'
80+
81+
- You can easily `sort your results <http://pythonhosted.org/uszipcode/index.html#sortby-descending-and-returns-keyword>`_ by `population`, `area`, `wealthy` and etc...
82+
83+
.. code-block:: python
84+
85+
# Find top 10 population zipcode
86+
>>> res = search.by_population(lower=0, upper=999999999,
87+
... sort_by="Population", ascending=False, returns=10)
88+
>>> for zipcode in res:
89+
... # do whatever you want...
90+
91+
- Easy export to csv. Result set can be easily export to csv.
92+
93+
.. code-block:: python
94+
95+
# Find all zipcode in new york
96+
>>> res = search.by_city(city="New York", returns=0)
97+
>>> search.export_to_csv(res, "result.csv")
1998
2099
21100
**Quick Links**

create_doctree.py

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
11
#!/usr/bin/env python
22
# -*- coding: utf-8 -*-
33

4-
from __future__ import print_function
5-
from docfly import Docfly
6-
import os, shutil
4+
import docfly
75

6+
# Uncomment this if you follow Sanhe's Sphinx Doc Style Guide
7+
#--- Manually Made Doc ---
8+
# doc = docfly.DocTree("source")
9+
# doc.fly(table_of_content_header="Table of Content (目录)")
10+
11+
#--- Api Reference Doc ---
812
package_name = "uszipcode"
913

10-
try:
11-
shutil.rmtree(os.path.join("source", package_name))
12-
except Exception as e:
13-
print(e)
14-
15-
docfly = Docfly(
16-
package_name,
14+
doc = docfly.ApiReferenceDoc(
15+
package_name,
1716
dst="source",
1817
ignore=[
19-
"%s.zzz_manual_install.py" % package_name,
2018
"%s.packages" % package_name,
19+
"%s.zzz_manual_install.py" % package_name,
2120
]
2221
)
23-
docfly.fly()
22+
doc.fly()

source/index.rst

Lines changed: 88 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Start the search engine, do some basic search::
3737
False
3838

3939

40-
Context manager works too (to keep connection safe, RECOMMENDED)::
40+
Context manager works too (automatically disconnect database. RECOMMENDED)::
4141

4242
>>> with ZipcodeSearchEngine() as search:
4343
... zipcode = search.by_zipcode(10030)
@@ -62,13 +62,13 @@ Context manager works too (to keep connection safe, RECOMMENDED)::
6262
"ZipcodeType": "Standard"
6363
}
6464

65-
For all available zipcode attributes, :class:`click here <uszipcode.searchengine.Zipcode>`.
66-
6765
There are two method you may need:
6866

69-
1. You can use ``to_json()`` method to return json encoded string.
70-
2. You can use ``to_dict()`` method to return dictionary data.
71-
67+
- You can use :meth:`~Zipcode.to_json()` method to return json encoded string.
68+
- You can use :meth:`~Zipcode.to_dict()` method to return dictionary data.
69+
- You can use :meth:`~Zipcode.to_OrderedDict()` method to return ordered dictionary data.
70+
- You can use :meth:`~Zipcode.keys()` method to return available attribute list.
71+
- You can use :meth:`~Zipcode.values()` method to return attributes' values.
7272

7373
.. _search_way:
7474

@@ -88,6 +88,7 @@ Here's the list of the ways you can search zipcode:
8888
- `by estimated total annual wage <by_total_wage_>`_
8989
- `by estimated average total annual wage <by_wealthy_>`_
9090
- `by estimated house of units <by_house_>`_
91+
- `advance search search <find_>`_
9192

9293
You also should know `this trick <keyword_>`_ to sort your results.
9394

@@ -115,12 +116,11 @@ Short state name also works:
115116
.. code-block:: python
116117
117118
>>> res = search.by_city_and_state("cicago", "il") # smartly guess what you are looking for
118-
>>> len(res)
119+
>>> len(res) # 56 zipcodes in Chicago
119120
56
120121
>>> zipcode = res[0]
121122
>>> zipcode.City
122123
'Chicago'
123-
124124
>>> zipcode.State
125125
'IL'
126126
@@ -280,35 +280,98 @@ You can search all zipcode by defining its total house of units lower bound or u
280280
.. code-block:: python
281281
282282
>>> res = search.by_house(lower=20000)
283-
>>> for zipcode in res:
284-
... # do whatever you want...
285283
286284
287-
.. _keyword:
285+
.. _find:
288286

289-
Sortby, Descending and Returns Keyword
287+
Advance Search
290288
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
291-
``by_prefix``, ``by_population``, ``by_density``, ``by_totalwages``, ``by_wealthy``, ``by_house`` methods support ``sortby``, ``descending`` and ``returns`` keyword.
289+
In addition, above methods can mix each other to implement very advance search:
290+
291+
**Find most people-living zipcode in New York**
292+
293+
.. code-block:: python
294+
295+
res = search.find(
296+
city="new york",
297+
sort_by="Population", ascending=False,
298+
)
299+
300+
**Find all zipcode in California that prefix is "999"**
301+
302+
.. code-block:: python
303+
304+
res = search.find(
305+
state="califor",
306+
prefix="95",
307+
sort_by="HouseOfUnits", ascending=False,
308+
returns=100,
309+
)
310+
311+
**Find top 10 richest zipcode near Silicon Valley**
292312

293-
- ``sortby``: string, default ``"Zipcode"``,the order of attributes that query results been returned
294-
- ``descending``: boolean, default False, is in descending order
295-
- ``returns``: maxiumum number of zipcode can be returned, use 0 for unlimited
313+
.. code-block:: python
314+
315+
# Find top 10 richest zipcode near Silicon Valley
316+
lat, lng = 37.391184, -122.082235
317+
radius = 100
318+
res = search.find(
319+
lat=lat,
320+
lng=lng,
321+
radius=radius,
322+
sort_by="Wealthy", ascending=False,
323+
returns=10,
324+
)
325+
326+
**Find zipcode that average personal annual income greater than $100,000 near Silicon Valley, order by distance**
327+
328+
.. code-block:: python
329+
330+
lat, lng = 37.391184, -122.082235
331+
radius = 100
332+
res = search.find(
333+
lat=lat,
334+
lng=lng,
335+
radius=radius,
336+
wealthy_lower=60000,
337+
sort_by="Dist",
338+
ascending=True,
339+
returns=0,
340+
)
341+
342+
343+
.. _sort:
344+
345+
Sort result
346+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
347+
``by_city_and_state``, ``by_city``, ``by_state``, ``by_prefix``, ``by_population``, ``by_density``, ``by_totalwages``, ``by_wealthy``, ``by_house`` methods all support ``sort_by``, ``ascending`` keyword.
296348

297-
Here's an example to find the top 100 richest zipcode, sorted by average annual wage:
349+
- ``sort_by``: attribute name(s), case insensitive. Accepts an attribute name or a list for a nested sort. By default ordered by ``Zipcode``. All valid attribute name is :class:`listed here <uszipcode.searchengine.Zipcode>`
350+
- ``ascending``: boolean or list, default ``True``, sort ascending vs. descending. Specify list for multiple sort orders
298351

299352
.. code-block:: python
300353
301-
>>> res = search.by_wealthy(lower=100000, sortby="Wealthy", descending=True, returns=100)
354+
# Search zipcode that average annual income per person greater than $100,000
355+
>>> res = search.by_wealthy(lower=100000, sort_by="Wealthy", ascending=True)
302356
>>> for zipcode in res:
303-
... # do whatever you want...
357+
... print(zipcode.Wealthy) # should be in ascending order
358+
304359
305-
.. include:: about.rst
360+
.. _limit:
306361

362+
Restrict number of results to return
363+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
364+
Every search method support ``returns`` keyword to limit number of results to return. Zero is for unlimited. The default limit is 5.
307365

308-
Indices and tables
309-
==================
366+
Here's an example to find the top 10 most people zipcode, sorted by population:
310367

311-
* :ref:`genindex`
312-
* :ref:`modindex`
313-
* :ref:`search`
368+
.. code-block:: python
369+
370+
# Find the top 10 population zipcode
371+
>>> res = search.by_population(upper=999999999, sort_by="population", ascending=False, returns=10)
372+
>>> len(res)
373+
10
374+
>>> for zipcode in res:
375+
... print(zipcode.Population) # should be in descending order
314376
377+
.. include:: about.rst

source/uszipcode/__init__.rst

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ uszipcode
22
=========
33

44
.. automodule:: uszipcode
5-
:members:
5+
:members:
66

7-
subpackage and modules
8-
----------------------
7+
sub packages and modules
8+
------------------------
99

1010
.. toctree::
1111
:maxdepth: 1
1212

13-
data <data/__init__>
14-
searchengine <searchengine>
13+
data <data/__init__>
14+
searchengine <searchengine>
15+

source/uszipcode/data/__init__.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ data
22
====
33

44
.. automodule:: uszipcode.data
5-
:members:
5+
:members:
66

7-
subpackage and modules
8-
----------------------
7+
sub packages and modules
8+
------------------------
99

1010
.. toctree::
1111
:maxdepth: 1
1212

13+

source/uszipcode/searchengine.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ searchengine
22
============
33

44
.. automodule:: uszipcode.searchengine
5-
:members:
5+
:members:

tests/test_all.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
4+
"""
5+
elementary_path unittest.
6+
"""
7+
8+
if __name__ == "__main__":
9+
import py
10+
py.test.cmdline.main("--tb=native") # use native python trace back

tests/test_fuzzywuzzy.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ def test_all():
1313
assert res[2][0] == "a cow boy"
1414

1515

16+
#--- Unittest ---
1617
if __name__ == "__main__":
1718
import py
18-
py.test.cmdline.main("--tb=native -s")
19+
import os
20+
py.test.cmdline.main("%s --tb=native -s" % os.path.basename(__file__))

tests/test_haversine.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ def test_all():
1313
assert abs(great_circle(lyon, paris, miles=True)/243.589575 - 1.0) <= delta
1414

1515

16+
#--- Unittest ---
1617
if __name__ == "__main__":
1718
import py
18-
py.test.cmdline.main("--tb=native -s")
19+
import os
20+
py.test.cmdline.main("%s --tb=native -s" % os.path.basename(__file__))

0 commit comments

Comments
 (0)