Skip to content

Commit

Permalink
2016-07-01
Browse files Browse the repository at this point in the history
Version 0.1.2 pre-release
  • Loading branch information
MacHu-GWU committed Jul 1, 2016
1 parent 8bb2802 commit 2cb2f08
Show file tree
Hide file tree
Showing 14 changed files with 2,222 additions and 539 deletions.
87 changes: 83 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,92 @@

Welcome to uszipcode Documentation
==================================
``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.
``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.

**Highlight**:

1. `Rich methods <http://pythonhosted.org/uszipcode/index.html#list-of-the-way-you-can-search>`_ are provided for getting zipcode anyway you want.
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**.
3. You can easily `sort your results <http://pythonhosted.org/uszipcode/index.html#sortby-descending-and-returns-keyword>`_ by `population`, `area`, `wealthy` and etc...
- `Rich information <http://pythonhosted.org/uszipcode/uszipcode/searchengine.html#uszipcode.searchengine.Zipcode>`_ of zipcode is available.

.. code-block:: python
>>> from uszipcode import ZipcodeSearchEngine
>>> search = ZipcodeSearchEngine()
>>> zipcode = search.by_zipcode("10001")
>>> print(zipcode)
{
"City": "New York",
"Density": 34035.48387096774,
"HouseOfUnits": 12476,
"LandArea": 0.62,
"Latitude": 40.75368539999999,
"Longitude": -73.9991637,
"NEBoundLatitude": 40.8282129,
"NEBoundLongitude": -73.9321059,
"Population": 21102,
"SWBoundLatitude": 40.743451,
"SWBoungLongitude": -74.00794499999998,
"State": "NY",
"TotalWages": 1031960117.0,
"WaterArea": 0.0,
"Wealthy": 48903.42702113544,
"Zipcode": "10001",
"ZipcodeType": "Standard"
}
- `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.

.. code-block:: python
# Search zipcode within 30 miles, ordered from closest to farthest
>>> res = search.by_coordinate(39.122229, -77.133578, radius=30, returns=5)
>>> len(res) # by default 5 results returned
5
>>> for zipcode in res:
... # do whatever you want...
# Find top 10 population zipcode
>>> res = search.by_population(lower=0, upper=999999999,
... sort_by="Population", ascending=False, returns=10)
# Find top 10 largest land area zipcode
>>> res = search.by_landarea(lower=0, upper=999999999,
... sort_by="LandArea", ascending=False, returns=10)
# Find top 10 most wealthy zipcode in new york
>>> res = search.find(city="newyork", wealthy_lower=100000,
... sort_by="Wealthy", returns=10) # at least $100,000 annual income
- `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.

.. code-block:: python
# Looking for Chicago and IL, but entered wrong spelling.
>>> res = search.by_city_and_state("cicago", "il")
>>> len(res) # 56 zipcodes in Chicago
56
>>> zipcode = res[0]
>>> zipcode.City
'Chicago'
>>> zipcode.State
'IL'
- You can easily `sort your results <http://pythonhosted.org/uszipcode/index.html#sortby-descending-and-returns-keyword>`_ by `population`, `area`, `wealthy` and etc...

.. code-block:: python
# Find top 10 population zipcode
>>> res = search.by_population(lower=0, upper=999999999,
... sort_by="Population", ascending=False, returns=10)
>>> for zipcode in res:
... # do whatever you want...
- Easy export to csv. Result set can be easily export to csv.

.. code-block:: python
# Find all zipcode in new york
>>> res = search.by_city(city="New York", returns=0)
>>> search.export_to_csv(res, "result.csv")
**Quick Links**
Expand Down
23 changes: 11 additions & 12 deletions create_doctree.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import print_function
from docfly import Docfly
import os, shutil
import docfly

# Uncomment this if you follow Sanhe's Sphinx Doc Style Guide
#--- Manually Made Doc ---
# doc = docfly.DocTree("source")
# doc.fly(table_of_content_header="Table of Content (目录)")

#--- Api Reference Doc ---
package_name = "uszipcode"

try:
shutil.rmtree(os.path.join("source", package_name))
except Exception as e:
print(e)

docfly = Docfly(
package_name,
doc = docfly.ApiReferenceDoc(
package_name,
dst="source",
ignore=[
"%s.zzz_manual_install.py" % package_name,
"%s.packages" % package_name,
"%s.zzz_manual_install.py" % package_name,
]
)
docfly.fly()
doc.fly()
113 changes: 88 additions & 25 deletions source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Start the search engine, do some basic search::
False


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

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

For all available zipcode attributes, :class:`click here <uszipcode.searchengine.Zipcode>`.

There are two method you may need:

1. You can use ``to_json()`` method to return json encoded string.
2. You can use ``to_dict()`` method to return dictionary data.

- You can use :meth:`~Zipcode.to_json()` method to return json encoded string.
- You can use :meth:`~Zipcode.to_dict()` method to return dictionary data.
- You can use :meth:`~Zipcode.to_OrderedDict()` method to return ordered dictionary data.
- You can use :meth:`~Zipcode.keys()` method to return available attribute list.
- You can use :meth:`~Zipcode.values()` method to return attributes' values.

.. _search_way:

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

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

Expand Down Expand Up @@ -115,12 +116,11 @@ Short state name also works:
.. code-block:: python
>>> res = search.by_city_and_state("cicago", "il") # smartly guess what you are looking for
>>> len(res)
>>> len(res) # 56 zipcodes in Chicago
56
>>> zipcode = res[0]
>>> zipcode.City
'Chicago'
>>> zipcode.State
'IL'
Expand Down Expand Up @@ -280,35 +280,98 @@ You can search all zipcode by defining its total house of units lower bound or u
.. code-block:: python
>>> res = search.by_house(lower=20000)
>>> for zipcode in res:
... # do whatever you want...
.. _keyword:
.. _find:

Sortby, Descending and Returns Keyword
Advance Search
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
``by_prefix``, ``by_population``, ``by_density``, ``by_totalwages``, ``by_wealthy``, ``by_house`` methods support ``sortby``, ``descending`` and ``returns`` keyword.
In addition, above methods can mix each other to implement very advance search:

**Find most people-living zipcode in New York**

.. code-block:: python
res = search.find(
city="new york",
sort_by="Population", ascending=False,
)
**Find all zipcode in California that prefix is "999"**

.. code-block:: python
res = search.find(
state="califor",
prefix="95",
sort_by="HouseOfUnits", ascending=False,
returns=100,
)
**Find top 10 richest zipcode near Silicon Valley**

- ``sortby``: string, default ``"Zipcode"``,the order of attributes that query results been returned
- ``descending``: boolean, default False, is in descending order
- ``returns``: maxiumum number of zipcode can be returned, use 0 for unlimited
.. code-block:: python
# Find top 10 richest zipcode near Silicon Valley
lat, lng = 37.391184, -122.082235
radius = 100
res = search.find(
lat=lat,
lng=lng,
radius=radius,
sort_by="Wealthy", ascending=False,
returns=10,
)
**Find zipcode that average personal annual income greater than $100,000 near Silicon Valley, order by distance**

.. code-block:: python
lat, lng = 37.391184, -122.082235
radius = 100
res = search.find(
lat=lat,
lng=lng,
radius=radius,
wealthy_lower=60000,
sort_by="Dist",
ascending=True,
returns=0,
)
.. _sort:

Sort result
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
``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.

Here's an example to find the top 100 richest zipcode, sorted by average annual wage:
- ``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>`
- ``ascending``: boolean or list, default ``True``, sort ascending vs. descending. Specify list for multiple sort orders

.. code-block:: python
>>> res = search.by_wealthy(lower=100000, sortby="Wealthy", descending=True, returns=100)
# Search zipcode that average annual income per person greater than $100,000
>>> res = search.by_wealthy(lower=100000, sort_by="Wealthy", ascending=True)
>>> for zipcode in res:
... # do whatever you want...
... print(zipcode.Wealthy) # should be in ascending order
.. include:: about.rst
.. _limit:

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

Indices and tables
==================
Here's an example to find the top 10 most people zipcode, sorted by population:

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
.. code-block:: python
# Find the top 10 population zipcode
>>> res = search.by_population(upper=999999999, sort_by="population", ascending=False, returns=10)
>>> len(res)
10
>>> for zipcode in res:
... print(zipcode.Population) # should be in descending order
.. include:: about.rst
11 changes: 6 additions & 5 deletions source/uszipcode/__init__.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ uszipcode
=========

.. automodule:: uszipcode
:members:
:members:

subpackage and modules
----------------------
sub packages and modules
------------------------

.. toctree::
:maxdepth: 1

data <data/__init__>
searchengine <searchengine>
data <data/__init__>
searchengine <searchengine>

7 changes: 4 additions & 3 deletions source/uszipcode/data/__init__.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ data
====

.. automodule:: uszipcode.data
:members:
:members:

subpackage and modules
----------------------
sub packages and modules
------------------------

.. toctree::
:maxdepth: 1


2 changes: 1 addition & 1 deletion source/uszipcode/searchengine.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ searchengine
============

.. automodule:: uszipcode.searchengine
:members:
:members:
10 changes: 10 additions & 0 deletions tests/test_all.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
elementary_path unittest.
"""

if __name__ == "__main__":
import py
py.test.cmdline.main("--tb=native") # use native python trace back
4 changes: 3 additions & 1 deletion tests/test_fuzzywuzzy.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ def test_all():
assert res[2][0] == "a cow boy"


#--- Unittest ---
if __name__ == "__main__":
import py
py.test.cmdline.main("--tb=native -s")
import os
py.test.cmdline.main("%s --tb=native -s" % os.path.basename(__file__))
4 changes: 3 additions & 1 deletion tests/test_haversine.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ def test_all():
assert abs(great_circle(lyon, paris, miles=True)/243.589575 - 1.0) <= delta


#--- Unittest ---
if __name__ == "__main__":
import py
py.test.cmdline.main("--tb=native -s")
import os
py.test.cmdline.main("%s --tb=native -s" % os.path.basename(__file__))
Loading

0 comments on commit 2cb2f08

Please sign in to comment.