Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
census_area.egg-info/
census_area/__pycache__/

docs/_build/
docs/_build/
venv
9 changes: 4 additions & 5 deletions census_area/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def geo_tract(self, fields, geojson_geometry, year=None, **kwargs):
within = 'state:{state} county:{county}'.format(**context)

tract_id = tract['properties']['TRACT']
result = self.get(fields,
result = self.get(tuple(fields),
HashDict({'for': 'tract:{}'.format(tract_id),
'in': within}),
year,
Expand Down Expand Up @@ -171,7 +171,7 @@ def geo_blockgroup(self, fields, geojson_geometry, year=None, **kwargs):
'tract': block_group['properties']['TRACT']}
within = 'state:{state} county:{county} tract:{tract}'.format(**context)

tract_blockgroups = self.get(fields,
tract_blockgroups = self.get(tuple(fields),
HashDict({'for': 'block group:*',
'in': within}),
year,
Expand Down Expand Up @@ -302,7 +302,7 @@ def state_place_block(self, *args, **kwargs):
'''
return self._state_place_area(self.geo_block, *args, **kwargs)

@supported_years(2020, 2010)
@supported_years(2020, 2010, 2000)
def geo_block(self, fields, geojson_geometry, year):
'''
Retrieve variable values for blocks intersecting with an arbitrary
Expand Down Expand Up @@ -332,7 +332,7 @@ def geo_block(self, fields, geojson_geometry, year):
'tract': block['properties']['TRACT']}
within = 'state:{state} county:{county} tract:{tract}'.format(**context)

tract_blocks = self.get(fields,
tract_blocks = self.get(tuple(fields),
HashDict({'for': 'block:*',
'in': within}),
year)
Expand All @@ -343,7 +343,6 @@ def geo_block(self, fields, geojson_geometry, year):
if result:
result, = result
else:
breakpoint()
result = {}

yield block, result, intersection_proportion
Expand Down
30 changes: 30 additions & 0 deletions test_geo_block_2000.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import os
from census_area import SF1Client

API_KEY = os.environ.get('CENSUS_API_KEY')
if not API_KEY:
raise SystemExit('Set the CENSUS_API_KEY environment variable first.')

# Small polygon covering a few blocks in Chicago's Loop
geometry = {
'type': 'Polygon',
'coordinates': [[
[-87.6320, 41.8827],
[-87.6290, 41.8827],
[-87.6290, 41.8850],
[-87.6320, 41.8850],
[-87.6320, 41.8827],
]]
}

client = SF1Client(API_KEY)

print('Querying geo_block for year 2000...')
results = list(client.geo_block(['P001001'], geometry, year=2000))
print(f'Found {len(results)} blocks\n')

for block, result, proportion in results:
props = block['properties']
print(f"Block {props['STATE']}{props['COUNTY']}{props['TRACT']}{props['BLOCK']}"
f" population={result.get('P001001', 'N/A')}"
f" overlap={proportion:.1%}")
Binary file not shown.
106 changes: 106 additions & 0 deletions tests/test_geo_block.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import pytest
from unittest.mock import patch, MagicMock

from census_area import PLClient
from census_area.variables import GEO_URLS


TEST_GEOMETRY = {
'type': 'Polygon',
'coordinates': [[
[-87.65, 41.85],
[-87.64, 41.85],
[-87.64, 41.86],
[-87.65, 41.86],
[-87.65, 41.85],
]]
}


def make_block_feature(state='17', county='031', tract='839100', block='1001'):
return {
'type': 'Feature',
'geometry': {
'type': 'Polygon',
'coordinates': [[
[-87.649, 41.850],
[-87.641, 41.850],
[-87.641, 41.859],
[-87.649, 41.859],
[-87.649, 41.850],
]]
},
'properties': {
'STATE': state,
'COUNTY': county,
'TRACT': tract,
'BLOCK': block,
}
}


@pytest.fixture
def client():
return PLClient('fake_api_key')


@pytest.mark.parametrize('year', [2000, 2010, 2020])
def test_geo_block_uses_correct_url_for_year(client, year):
with patch('census_area.core.AreaFilter') as MockAreaFilter, \
patch.object(client, 'get', return_value=[]):
MockAreaFilter.return_value = []
list(client.geo_block(['P001001'], TEST_GEOMETRY, year=year))
MockAreaFilter.assert_called_once_with(TEST_GEOMETRY, GEO_URLS['blocks'][year])


def test_geo_block_yields_block_result_and_proportion(client):
block_feature = make_block_feature()
census_data = [{'state': '17', 'county': '031', 'tract': '839100',
'block': '1001', 'P001001': '42'}]

with patch('census_area.core.AreaFilter') as MockAreaFilter, \
patch.object(client, 'get', return_value=census_data):
MockAreaFilter.return_value = [(block_feature, 0.75)]
results = list(client.geo_block(['P001001'], TEST_GEOMETRY, year=2020))

assert len(results) == 1
block, result, proportion = results[0]
assert block == block_feature
assert result['P001001'] == '42'
assert proportion == 0.75


def test_geo_block_2000(client):
block_feature = make_block_feature()
census_data = [{'state': '17', 'county': '031', 'tract': '839100',
'block': '1001', 'P001001': '42'}]

with patch('census_area.core.AreaFilter') as MockAreaFilter, \
patch.object(client, 'get', return_value=census_data):
MockAreaFilter.return_value = [(block_feature, 1.0)]
results = list(client.geo_block(['P001001'], TEST_GEOMETRY, year=2000))

assert len(results) == 1
_, result, proportion = results[0]
assert result['P001001'] == '42'
assert proportion == 1.0


def test_geo_block_empty_result_when_block_not_in_census_response(client):
block_feature = make_block_feature(block='1001')
census_data = [{'state': '17', 'county': '031', 'tract': '839100',
'block': '9999', 'P001001': '10'}]

with patch('census_area.core.AreaFilter') as MockAreaFilter, \
patch.object(client, 'get', return_value=census_data):
MockAreaFilter.return_value = [(block_feature, 1.0)]
results = list(client.geo_block(['P001001'], TEST_GEOMETRY, year=2020))

assert len(results) == 1
_, result, _ = results[0]
assert result == {}


def test_geo_block_unsupported_year_raises(client):
with pytest.raises(Exception):
list(client.geo_block(['P001001'], TEST_GEOMETRY, year=1990))