Skip to content

Commit 2b8dbde

Browse files
dshkolclaude
andcommitted
Format Python code with Black
Fix CI formatting check failures by running Black formatter on: - pycancensus/regions.py - pycancensus/datasets.py - pycancensus/intersect_geometry.py - pycancensus/vectors.py - pycancensus/core.py 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 349af61 commit 2b8dbde

5 files changed

Lines changed: 80 additions & 84 deletions

File tree

pycancensus/core.py

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -314,52 +314,46 @@ def _extract_vector_metadata(df, vectors, labels):
314314
"""Extract vector metadata from column names and store as attribute."""
315315
if not vectors:
316316
return df
317-
317+
318318
# Find vector columns - they have format "v_DATASET_NUM: Description"
319319
vector_cols = [col for col in df.columns if col.startswith("v_")]
320-
320+
321321
if not vector_cols:
322322
return df
323-
323+
324324
# Build metadata DataFrame
325325
metadata_rows = []
326326
rename_dict = {}
327-
327+
328328
for col in vector_cols:
329329
if ": " in col:
330330
# Column has format "v_CA21_1: Total - Population"
331331
parts = col.split(": ", 1)
332332
vector_code = parts[0]
333333
detail = parts[1] if len(parts) > 1 else ""
334-
335-
metadata_rows.append({
336-
"Vector": vector_code,
337-
"Detail": detail
338-
})
339-
334+
335+
metadata_rows.append({"Vector": vector_code, "Detail": detail})
336+
340337
# For short labels, rename column to just the vector code
341338
if labels == "short":
342339
rename_dict[col] = vector_code
343340
else:
344341
# Column is already just the vector code
345342
vector_code = col
346343
# Try to get detail from vector list if available
347-
metadata_rows.append({
348-
"Vector": vector_code,
349-
"Detail": ""
350-
})
351-
344+
metadata_rows.append({"Vector": vector_code, "Detail": ""})
345+
352346
# Create metadata DataFrame
353347
if metadata_rows:
354348
metadata_df = pd.DataFrame(metadata_rows)
355-
349+
356350
# Rename columns if using short labels
357351
if rename_dict:
358352
df = df.rename(columns=rename_dict)
359-
353+
360354
# Store metadata as attribute (always store, but mainly useful with short labels)
361-
df.attrs['census_vectors'] = metadata_df
362-
355+
df.attrs["census_vectors"] = metadata_df
356+
363357
return df
364358

365359

pycancensus/datasets.py

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -139,20 +139,20 @@ def get_dataset_attribution(dataset: str) -> str:
139139
def dataset_attribution(datasets):
140140
"""
141141
Get combined attribution text for multiple datasets.
142-
142+
143143
This function combines attribution text for multiple datasets, merging
144144
similar attributions that only differ by year.
145-
145+
146146
Parameters
147147
----------
148148
datasets : list of str
149149
List of dataset identifiers (e.g., ['CA06', 'CA16']).
150-
150+
151151
Returns
152152
-------
153153
list of str
154154
List of attribution strings, with similar attributions merged.
155-
155+
156156
Examples
157157
--------
158158
>>> import pycancensus as pc
@@ -162,32 +162,32 @@ def dataset_attribution(datasets):
162162
... print(attr)
163163
"""
164164
import re
165-
165+
166166
# Get all datasets info
167167
datasets_df = list_census_datasets(quiet=True)
168-
168+
169169
# Filter for requested datasets
170170
datasets = [d.upper() for d in datasets]
171171
dataset_rows = datasets_df[datasets_df["dataset"].isin(datasets)]
172-
172+
173173
if len(dataset_rows) == 0:
174174
raise ValueError(f"No valid datasets found in {datasets}")
175-
175+
176176
# Get attribution texts
177177
attributions = dataset_rows["attribution"].tolist()
178-
178+
179179
# Group similar attributions that differ only by year
180180
# Create a mapping of pattern to actual attributions
181181
pattern_map = {}
182-
182+
183183
for attr in attributions:
184184
# Replace 4-digit years with placeholder to create pattern
185-
pattern = re.sub(r'\d{4}', '{{YEAR}}', attr)
186-
185+
pattern = re.sub(r"\d{4}", "{{YEAR}}", attr)
186+
187187
if pattern not in pattern_map:
188188
pattern_map[pattern] = []
189189
pattern_map[pattern].append(attr)
190-
190+
191191
# For each pattern, merge the years
192192
result = []
193193
for pattern, attr_list in pattern_map.items():
@@ -199,19 +199,19 @@ def dataset_attribution(datasets):
199199
# Extract all years from the attributions
200200
all_years = []
201201
for attr in attr_list:
202-
years = re.findall(r'\d{4}', attr)
202+
years = re.findall(r"\d{4}", attr)
203203
all_years.extend(years)
204-
204+
205205
# Remove duplicates and sort
206206
unique_years = sorted(list(set(all_years)))
207-
207+
208208
# Replace {{YEAR}} placeholder with merged years
209209
if len(unique_years) > 0:
210-
year_string = ', '.join(unique_years)
211-
merged = pattern.replace('{{YEAR}}', year_string)
210+
year_string = ", ".join(unique_years)
211+
merged = pattern.replace("{{YEAR}}", year_string)
212212
result.append(merged)
213213
else:
214214
# No years found, just use first attribution
215215
result.append(attr_list[0])
216-
216+
217217
return result

pycancensus/intersect_geometry.py

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ def get_intersecting_geometries(
2727
) -> Union[List[str], Dict[str, List[str]]]:
2828
"""
2929
Get identifiers for census regions intersecting a geometry.
30-
30+
3131
This function returns a list of regions that intersect a given geometry input.
3232
This list of regions can be used directly to query census when one is interested
3333
in census data for a particular geographic region that does not coincide with
3434
defined census geometries.
35-
35+
3636
Parameters
3737
----------
3838
dataset : str
@@ -53,27 +53,27 @@ def get_intersecting_geometries(
5353
api_key : str, optional
5454
API key for CensusMapper API. If None, uses environment variable
5555
or previously set key.
56-
56+
5757
Returns
5858
-------
5959
List[str] or Dict[str, List[str]]
6060
If simplified=True, returns a list of region identifiers.
6161
If simplified=False, returns a dictionary with level as key and
6262
list of region IDs as value, suitable for use with get_census().
63-
63+
6464
Examples
6565
--------
6666
>>> import pycancensus as pc
6767
>>> from shapely.geometry import Point
68-
>>>
68+
>>>
6969
>>> # Example using a Point from lat/lon coordinates
7070
>>> point_geo = Point(-123.25149, 49.27026)
7171
>>> regions = pc.get_intersecting_geometries(
72-
... dataset='CA21',
73-
... level='CT',
72+
... dataset='CA21',
73+
... level='CT',
7474
... geometry=point_geo
7575
... )
76-
>>>
76+
>>>
7777
>>> # Use regions to get census data
7878
>>> census_data = pc.get_census(
7979
... dataset='CA21',
@@ -84,43 +84,43 @@ def get_intersecting_geometries(
8484
"""
8585
# Validate inputs
8686
validate_dataset(dataset)
87-
87+
8888
if api_key is None:
8989
api_key = get_api_key()
9090
if api_key is None:
9191
raise ValueError(
9292
"API key required. Set with set_api_key() or CANCENSUS_API_KEY "
9393
"environment variable."
9494
)
95-
95+
9696
# Process geometry input
9797
processed_geometry = _process_geometry_input(geometry)
98-
98+
9999
# Ensure geometry is in WGS84 (EPSG:4326)
100100
if processed_geometry.crs is None:
101101
warnings.warn("No CRS specified for geometry, assuming WGS84 (EPSG:4326)")
102-
processed_geometry = processed_geometry.set_crs('EPSG:4326')
102+
processed_geometry = processed_geometry.set_crs("EPSG:4326")
103103
elif processed_geometry.crs.to_epsg() != 4326:
104-
processed_geometry = processed_geometry.to_crs('EPSG:4326')
105-
104+
processed_geometry = processed_geometry.to_crs("EPSG:4326")
105+
106106
# Union multiple geometries if needed
107107
if len(processed_geometry) > 1:
108108
geometry_union = unary_union(processed_geometry.geometry)
109-
processed_geometry = gpd.GeoSeries([geometry_union], crs='EPSG:4326')
110-
109+
processed_geometry = gpd.GeoSeries([geometry_union], crs="EPSG:4326")
110+
111111
# Convert to GeoJSON
112112
geojson_str = processed_geometry.to_json()
113-
113+
114114
# Calculate area in square meters (approximate for WGS84)
115115
# Using area in degrees^2 * conversion factor for rough area estimate
116116
area = processed_geometry.area.iloc[0]
117117
# Convert from square degrees to approximate square meters at equator
118-
area_m2 = area * (111320 ** 2) # Rough conversion
119-
118+
area_m2 = area * (111320**2) # Rough conversion
119+
120120
# Create cache key
121121
param_string = f"dataset={dataset}&level={level}&geometry={geojson_str}"
122122
cache_key = f"intersect_{hashlib.md5(param_string.encode()).hexdigest()}"
123-
123+
124124
# Check cache first
125125
if use_cache:
126126
cached_data = get_cached_data(cache_key)
@@ -137,7 +137,7 @@ def get_intersecting_geometries(
137137
result = _query_intersecting_geometries_api(
138138
dataset, level, geojson_str, area_m2, api_key, quiet
139139
)
140-
140+
141141
# Format output based on simplified parameter
142142
if simplified:
143143
# Return simple list of region IDs
@@ -162,7 +162,7 @@ def _process_geometry_input(geometry) -> gpd.GeoSeries:
162162
return geometry.geometry
163163
elif isinstance(geometry, gpd.GeoSeries):
164164
return geometry
165-
elif hasattr(geometry, '__geo_interface__'):
165+
elif hasattr(geometry, "__geo_interface__"):
166166
# Shapely geometry or similar
167167
return gpd.GeoSeries([geometry])
168168
else:
@@ -173,12 +173,11 @@ def _process_geometry_input(geometry) -> gpd.GeoSeries:
173173

174174

175175
def _query_intersecting_geometries_api(
176-
dataset: str, level: str, geojson_str: str, area: float,
177-
api_key: str, quiet: bool
176+
dataset: str, level: str, geojson_str: str, area: float, api_key: str, quiet: bool
178177
) -> Any:
179178
"""Query the CensusMapper API for intersecting geometries."""
180179
base_url = "https://censusmapper.ca/api/v1/"
181-
180+
182181
# Prepare request data
183182
request_data = {
184183
"dataset": dataset,
@@ -187,10 +186,10 @@ def _query_intersecting_geometries_api(
187186
"area": area,
188187
"api_key": api_key,
189188
}
190-
189+
191190
if not quiet:
192191
print("Querying CensusMapper API for intersecting geometries...")
193-
192+
194193
try:
195194
response = requests.post(
196195
f"{base_url}intersecting_geographies",
@@ -199,19 +198,21 @@ def _query_intersecting_geometries_api(
199198
timeout=60,
200199
)
201200
response.raise_for_status()
202-
201+
203202
result = response.json()
204-
203+
205204
if not quiet:
206205
if isinstance(result, list):
207206
print(f"✅ Found {len(result)} intersecting regions")
208207
elif isinstance(result, dict):
209-
total = sum(len(v) if isinstance(v, list) else 1 for v in result.values())
208+
total = sum(
209+
len(v) if isinstance(v, list) else 1 for v in result.values()
210+
)
210211
print(f"✅ Found {total} intersecting regions")
211-
212+
212213
return result
213-
214+
214215
except requests.exceptions.RequestException as e:
215216
raise RuntimeError(f"API request failed: {e}")
216217
except Exception as e:
217-
raise RuntimeError(f"Failed to process API response: {e}")
218+
raise RuntimeError(f"Failed to process API response: {e}")

pycancensus/regions.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,17 @@ def list_census_regions(
8282

8383
# Parse CSV response
8484
import io
85+
8586
df = pd.read_csv(io.StringIO(response.text))
8687

8788
# Map column names to match expected output format
8889
# CSV columns: name, geo_uid, type, population, flag, CMA_UID, CD_UID, PR_UID
8990
# Expected: region, name, level, pop, municipal_status, CMA_UID, CD_UID, PR_UID
9091
column_mapping = {
91-
'geo_uid': 'region',
92-
'type': 'level',
93-
'population': 'pop',
94-
'flag': 'municipal_status',
92+
"geo_uid": "region",
93+
"type": "level",
94+
"population": "pop",
95+
"flag": "municipal_status",
9596
}
9697

9798
df = df.rename(columns=column_mapping)

0 commit comments

Comments
 (0)