mainegeo.townships
Town and township name standardization and parsing utilities.
This module provides functions for parsing and normalizing township names and looking up their canonical names.
All functions in this module are intended to be run on a string containing a single
town or township, unless specifically indicated otherwise. For help parsing multi-town
election reporting units into single town strings, see mainegeo.elections.
1"""Town and township name standardization and parsing utilities. 2 3This module provides functions for parsing and normalizing township names 4and looking up their canonical names. 5 6All functions in this module are intended to be run on a string containing a single 7town or township, unless specifically indicated otherwise. For help parsing multi-town 8election reporting units into single town strings, see `mainegeo.elections`. 9""" 10 11__docformat__ = 'google' 12 13__all__ = [ 14 'is_unnamed_township', 15 'clean_code', 16 'clean_codes', 17 'has_alias', 18 'extract_alias', 19 'clean_township', 20 'strip_region', 21 'strip_suffix', 22 'toggle_suffix', 23 'normalize_suffix', 24 'strip_town', 25 'clean_town' 26] 27 28from re import IGNORECASE 29from mainegeo._vendor import ( 30 replace_all, 31 squish, 32 match_case, 33 normalize_whitespace, 34 chain_operations 35) 36from mainegeo.entities import TownType 37from mainegeo.patterns import ( 38 UNNAMED_PATTERN, 39 UNNAMED_ELEMENTS_PATTERN, 40 CLEAN_TOWNSHIP_PATTERN, 41 NON_ALIAS_PATTERN, 42 GNIS_PATTERN, 43 ABBREVIATIONS, 44 SUFFIX_REPLACEMENTS, 45 SUFFIX_PATTERN, 46 LAST_REGION_PATTERN, 47 VALID_AMPERSANDS_PATTERN, 48 INVALID_PUNCTUATION_PATTERN, 49 CONTAINS_JUNIOR_SUFFIX_PATTERN, 50 ENDSWITH_JUNIOR_SUFFIX_PATTERN 51) 52 53def is_unnamed_township(town: str) -> bool: 54 """ 55 Check if a string contains an unnamed township. 56 57 Args: 58 town: A single town or township 59 60 Returns: 61 True if input contains an unnamed township, else False 62 63 Examples: 64 >>> is_unnamed_township('T5 R7') 65 True 66 67 >>> is_unnamed_township('CROSS LAKE TWP (T17 R5)') 68 True 69 70 >>> is_unnamed_township('CROSS LAKE TWP') 71 False 72 """ 73 return UNNAMED_PATTERN.search(town) is not None 74 75def clean_code(town: str) -> str: 76 """ 77 Normalize punctuation and spacing of township code and drop text that is not part of the township code. 78 79 Args: 80 town: A single town or township 81 82 Returns: 83 Normalized township string, or unmodified string if input does not contain township 84 85 Examples: 86 >>> clean_code('T4/R3 TWP') 87 'T4 R3' 88 89 >>> clean_code('T10SD') 90 'T10 SD' 91 92 >>> clean_code('FLETCHERS LANDING TWP (T8 SD)') 93 'T8 SD' 94 """ 95 if is_unnamed_township(town) is False: 96 return town 97 else: 98 elements = UNNAMED_ELEMENTS_PATTERN.findall(town) 99 formatted_elements = [CLEAN_TOWNSHIP_PATTERN.sub('', e) for e in elements] 100 return ' '.join(formatted_elements) 101 102def clean_codes(towns: str) -> str: 103 """ 104 Normalize punctation and spacing of township codes in-place. 105 106 Args: 107 towns: String with one or more towns or townships 108 109 Returns: 110 Input string with punctuation and spacing normalized for all township codes 111 112 Examples: 113 >>> clean_codes('ASHLAND -- T12/R13, T9/R8') 114 'ASHLAND -- T12 R13, T9 R8' 115 116 >>> clean_codes('T4/R3 TWP') 117 'T4 R3 TWP' 118 119 >>> clean_codes('BARNARD TWP/EBEEMEE TWP (T5-R9 NWP)/T4R9 NWP TWP') 120 'BARNARD TWP/EBEEMEE TWP (T5 R9 NWP)/T4 R9 NWP TWP' 121 """ 122 townships = UNNAMED_PATTERN.findall(towns) 123 cleaned = list(map(clean_code, townships)) 124 return replace_all(dict(zip(townships, cleaned)), towns) 125 126def has_alias(town: str) -> str: 127 """ 128 Check if input has both an unnamed township and a township alias. 129 130 Args: 131 town: A single town or township 132 133 Returns: 134 True if town string contains a township code and alias, else False 135 136 Examples: 137 >>> has_alias('CROSS LAKE TWP (T17 R5)') 138 True 139 140 >>> has_alias('EBEEMEE TWP') 141 False 142 143 >>> has_alias('PRENTISS TWP T7 R3 NBPP') 144 True 145 146 >>> has_alias('T7 R3 NBPP TWP') 147 False 148 """ 149 if is_unnamed_township(town) is False: 150 return False 151 else: 152 return len(NON_ALIAS_PATTERN.sub('', town).strip()) > 0 153 154def extract_alias(town: str) -> str: 155 """ 156 Extract the township alias from a string that contains both an alias and a code. 157 158 Args: 159 town: A single town or township 160 161 Returns: 162 Input string with township code removed. 163 164 Examples: 165 >>> extract_alias('CROSS LAKE TWP (T17 R5)') 166 'CROSS LAKE TWP' 167 168 >>> extract_alias('T3 Indian Purchase Twp') 169 'Indian Purchase Twp' 170 171 >>> extract_alias('Rockwood Strip (T1 R1) Twp') 172 'Rockwood Strip Twp' 173 174 >>> extract_alias('T7 R3 NBPP (PRENTISS TWP)') 175 'PRENTISS TWP' 176 """ 177 if has_alias(town): 178 return squish(NON_ALIAS_PATTERN.sub('', town)) 179 180def clean_township(town: str) -> str: 181 """ 182 Normalize punctuation and spacing of township code and alias. 183 184 Args: 185 town: A single town or township 186 187 Returns: 188 Normalized township string, or unmodified string if input does not contain township 189 190 Examples: 191 >>> clean_township('T4/R3 TWP') 192 'T4 R3' 193 194 >>> clean_township('T10SD') 195 'T10 SD' 196 197 >>> clean_township('CROSS LAKE TWP (T17 R5)') 198 'CROSS LAKE TWP T17 R5' 199 """ 200 if is_unnamed_township(town) is False: 201 return town 202 else: 203 alias = extract_alias(town) 204 code = clean_code(town) 205 return ' '.join(filter(None, [alias, code])) 206 207def strip_region(town: str) -> str: 208 return LAST_REGION_PATTERN.sub('', town) 209 210def strip_suffix(town: str) -> str: 211 """ 212 Strips valid terminal suffix from town string. 213 214 Context-sensitive: ignores suffix substrings if they are not in a valid 215 suffix context. 216 217 This method is used to generate plausible aliases for further testing. 218 Its intended use is alias generation and not routine cleanup. 219 220 Args: 221 town: A single town or township 222 223 Returns: 224 Town with valid terminal suffix stripped 225 226 Examples: 227 >>> strip_suffix('RANGELEY PLANTATION') 228 'RANGELEY' 229 230 >>> strip_suffix('Passamaquoddy Indian Township') 231 'Passamaquoddy Indian Township' 232 233 >>> strip_suffix('Indian Stream Township') 234 'Indian Stream' 235 236 >>> strip_suffix('Matinicus Isle Plt') 237 'Matinicus Isle' 238 """ 239 return SUFFIX_PATTERN.sub('', town) 240 241def toggle_suffix(town: str, town_type: TownType = None) -> str: 242 """ 243 Adds or removes a township suffix to grants, gores, and islands. 244 245 The TWP suffix is not canonical for all grants, gores, and islands. 246 This method is used to generate plausible aliases for further testing. 247 Its intended use is alias generation and not routine cleanup. 248 249 Args: 250 town: A single town or township 251 town_type: A `TownType` class. If provided, will increase accuracy. 252 253 Returns: 254 Gore, grant or island with township suffix added or removed, or else town 255 256 Examples: 257 >>> toggle_suffix('MOXIE GORE TWP') 258 'MOXIE GORE' 259 260 >>> toggle_suffix('HOPKINS ACADEMY GRANT') 261 'HOPKINS ACADEMY GRANT TWP' 262 263 >>> toggle_suffix('LOUDS ISLAND', TownType.UNORGANIZED) 264 'LOUDS ISLAND TWP' 265 266 >>> toggle_suffix('CHEBEAGUE ISLAND', TownType.TOWN) 267 'CHEBEAGUE ISLAND' 268 """ 269 if town_type not in (TownType.UNORGANIZED, TownType.ISLAND, None): 270 return town 271 elif ENDSWITH_JUNIOR_SUFFIX_PATTERN.match(town): 272 return town + match_case(' TWP', town) 273 elif CONTAINS_JUNIOR_SUFFIX_PATTERN.match(town): 274 return town[0:-4] 275 else: 276 return town 277 278def normalize_suffix(town: str) -> str: 279 """ 280 Normalize variations in geotype suffix abbreviation and location. 281 282 Does not alter pluralization. Pads suffix with whitespace if needed. 283 284 Args: 285 town: A single town or township 286 287 Returns: 288 Town with normalized suffix 289 290 Examples: 291 >>> normalize_suffix('City of Portland') 292 'Portland' 293 294 >>> normalize_suffix('MATINICUS ISLE PLANTATION') 295 'MATINICUS ISLE PLT' 296 297 >>> normalize_suffix('MARIONTWPS') 298 'MARION TWPS' 299 300 >>> normalize_suffix('Indian Township') 301 'Indian Twp' 302 """ 303 gnis_format = GNIS_PATTERN.match(town.upper()) 304 305 if gnis_format is None: 306 town_name = town 307 else: 308 name = gnis_format.group('town') 309 suffix = ABBREVIATIONS.get(gnis_format.group('geotype')) 310 town_name = ' '.join(filter(None, [name, suffix])) 311 312 normalized = replace_all(SUFFIX_REPLACEMENTS, town_name, IGNORECASE) 313 return match_case(normalized, town, preserve_mixed_case=False) 314 315def strip_town(town: str) -> str: 316 """ 317 Strip invalid punctuation and whitespace from a town name substring. 318 319 This function performs the following operations: 320 1. Strip leading and trailing whitespace and squish internal whitespace 321 2. Replace ampersands ('&') that are recognized as part of a canonical town 322 name with 'and' 323 3. Strip all punctuation except hyphens ('-') that are recognized as 324 part of a canonical town name 325 326 Args: 327 town: A single town or township 328 329 Returns: 330 Town name with punctuation stripped 331 332 Examples: 333 >>> strip_town("Loud's Island") 334 'Louds Island' 335 336 >>> strip_town('Dover-Foxcroft -- ') 337 'Dover-Foxcroft' 338 339 >>> strip_town('Taunton & Raynham Academy Grant') 340 'Taunton and Raynham Academy Grant' 341 """ 342 town_name = normalize_whitespace(town) 343 town_name = VALID_AMPERSANDS_PATTERN.sub('and', town_name) 344 town_name = INVALID_PUNCTUATION_PATTERN.sub('', town_name) 345 town_name = town_name.strip() 346 return match_case(town_name, town, preserve_mixed_case=False) 347 348def clean_town(town: str) -> str: 349 """ 350 Clean and format town name. 351 352 Operations performed: 353 1. Strip or replace punctuation 354 2. Normalize whitespace 355 3. Abbreviate geotype suffixes 356 4. Normalize township codes 357 358 Args: 359 town: A single town or township 360 361 Returns: 362 Town name with punctuation stripped and formatting applied 363 364 Examples: 365 >>> clean_town('City of Portland') 366 'Portland' 367 368 >>> clean_town('T8/R11 TWP') 369 'T8 R11' 370 371 >>> clean_town('CROSS LAKE TWP (T17 R5)') 372 'CROSS LAKE TWP T17 R5' 373 374 >>> clean_town('King & Bartlett Township') 375 'King and Bartlett Twp' 376 377 >>> clean_town('MARIONTWPS ()') 378 'MARION TWPS' 379 """ 380 cleaning_functions = [ 381 strip_town 382 , normalize_suffix 383 , clean_township 384 , normalize_whitespace 385 ] 386 return chain_operations(town, cleaning_functions)
54def is_unnamed_township(town: str) -> bool: 55 """ 56 Check if a string contains an unnamed township. 57 58 Args: 59 town: A single town or township 60 61 Returns: 62 True if input contains an unnamed township, else False 63 64 Examples: 65 >>> is_unnamed_township('T5 R7') 66 True 67 68 >>> is_unnamed_township('CROSS LAKE TWP (T17 R5)') 69 True 70 71 >>> is_unnamed_township('CROSS LAKE TWP') 72 False 73 """ 74 return UNNAMED_PATTERN.search(town) is not None
Check if a string contains an unnamed township.
Arguments:
- town: A single town or township
Returns:
True if input contains an unnamed township, else False
Examples:
>>> is_unnamed_township('T5 R7') True>>> is_unnamed_township('CROSS LAKE TWP (T17 R5)') True>>> is_unnamed_township('CROSS LAKE TWP') False
76def clean_code(town: str) -> str: 77 """ 78 Normalize punctuation and spacing of township code and drop text that is not part of the township code. 79 80 Args: 81 town: A single town or township 82 83 Returns: 84 Normalized township string, or unmodified string if input does not contain township 85 86 Examples: 87 >>> clean_code('T4/R3 TWP') 88 'T4 R3' 89 90 >>> clean_code('T10SD') 91 'T10 SD' 92 93 >>> clean_code('FLETCHERS LANDING TWP (T8 SD)') 94 'T8 SD' 95 """ 96 if is_unnamed_township(town) is False: 97 return town 98 else: 99 elements = UNNAMED_ELEMENTS_PATTERN.findall(town) 100 formatted_elements = [CLEAN_TOWNSHIP_PATTERN.sub('', e) for e in elements] 101 return ' '.join(formatted_elements)
Normalize punctuation and spacing of township code and drop text that is not part of the township code.
Arguments:
- town: A single town or township
Returns:
Normalized township string, or unmodified string if input does not contain township
Examples:
>>> clean_code('T4/R3 TWP') 'T4 R3'>>> clean_code('T10SD') 'T10 SD'>>> clean_code('FLETCHERS LANDING TWP (T8 SD)') 'T8 SD'
103def clean_codes(towns: str) -> str: 104 """ 105 Normalize punctation and spacing of township codes in-place. 106 107 Args: 108 towns: String with one or more towns or townships 109 110 Returns: 111 Input string with punctuation and spacing normalized for all township codes 112 113 Examples: 114 >>> clean_codes('ASHLAND -- T12/R13, T9/R8') 115 'ASHLAND -- T12 R13, T9 R8' 116 117 >>> clean_codes('T4/R3 TWP') 118 'T4 R3 TWP' 119 120 >>> clean_codes('BARNARD TWP/EBEEMEE TWP (T5-R9 NWP)/T4R9 NWP TWP') 121 'BARNARD TWP/EBEEMEE TWP (T5 R9 NWP)/T4 R9 NWP TWP' 122 """ 123 townships = UNNAMED_PATTERN.findall(towns) 124 cleaned = list(map(clean_code, townships)) 125 return replace_all(dict(zip(townships, cleaned)), towns)
Normalize punctation and spacing of township codes in-place.
Arguments:
- towns: String with one or more towns or townships
Returns:
Input string with punctuation and spacing normalized for all township codes
Examples:
>>> clean_codes('ASHLAND -- T12/R13, T9/R8') 'ASHLAND -- T12 R13, T9 R8'>>> clean_codes('T4/R3 TWP') 'T4 R3 TWP'>>> clean_codes('BARNARD TWP/EBEEMEE TWP (T5-R9 NWP)/T4R9 NWP TWP') 'BARNARD TWP/EBEEMEE TWP (T5 R9 NWP)/T4 R9 NWP TWP'
127def has_alias(town: str) -> str: 128 """ 129 Check if input has both an unnamed township and a township alias. 130 131 Args: 132 town: A single town or township 133 134 Returns: 135 True if town string contains a township code and alias, else False 136 137 Examples: 138 >>> has_alias('CROSS LAKE TWP (T17 R5)') 139 True 140 141 >>> has_alias('EBEEMEE TWP') 142 False 143 144 >>> has_alias('PRENTISS TWP T7 R3 NBPP') 145 True 146 147 >>> has_alias('T7 R3 NBPP TWP') 148 False 149 """ 150 if is_unnamed_township(town) is False: 151 return False 152 else: 153 return len(NON_ALIAS_PATTERN.sub('', town).strip()) > 0
Check if input has both an unnamed township and a township alias.
Arguments:
- town: A single town or township
Returns:
True if town string contains a township code and alias, else False
Examples:
>>> has_alias('CROSS LAKE TWP (T17 R5)') True>>> has_alias('EBEEMEE TWP') False>>> has_alias('PRENTISS TWP T7 R3 NBPP') True>>> has_alias('T7 R3 NBPP TWP') False
155def extract_alias(town: str) -> str: 156 """ 157 Extract the township alias from a string that contains both an alias and a code. 158 159 Args: 160 town: A single town or township 161 162 Returns: 163 Input string with township code removed. 164 165 Examples: 166 >>> extract_alias('CROSS LAKE TWP (T17 R5)') 167 'CROSS LAKE TWP' 168 169 >>> extract_alias('T3 Indian Purchase Twp') 170 'Indian Purchase Twp' 171 172 >>> extract_alias('Rockwood Strip (T1 R1) Twp') 173 'Rockwood Strip Twp' 174 175 >>> extract_alias('T7 R3 NBPP (PRENTISS TWP)') 176 'PRENTISS TWP' 177 """ 178 if has_alias(town): 179 return squish(NON_ALIAS_PATTERN.sub('', town))
Extract the township alias from a string that contains both an alias and a code.
Arguments:
- town: A single town or township
Returns:
Input string with township code removed.
Examples:
>>> extract_alias('CROSS LAKE TWP (T17 R5)') 'CROSS LAKE TWP'>>> extract_alias('T3 Indian Purchase Twp') 'Indian Purchase Twp'>>> extract_alias('Rockwood Strip (T1 R1) Twp') 'Rockwood Strip Twp'>>> extract_alias('T7 R3 NBPP (PRENTISS TWP)') 'PRENTISS TWP'
181def clean_township(town: str) -> str: 182 """ 183 Normalize punctuation and spacing of township code and alias. 184 185 Args: 186 town: A single town or township 187 188 Returns: 189 Normalized township string, or unmodified string if input does not contain township 190 191 Examples: 192 >>> clean_township('T4/R3 TWP') 193 'T4 R3' 194 195 >>> clean_township('T10SD') 196 'T10 SD' 197 198 >>> clean_township('CROSS LAKE TWP (T17 R5)') 199 'CROSS LAKE TWP T17 R5' 200 """ 201 if is_unnamed_township(town) is False: 202 return town 203 else: 204 alias = extract_alias(town) 205 code = clean_code(town) 206 return ' '.join(filter(None, [alias, code]))
Normalize punctuation and spacing of township code and alias.
Arguments:
- town: A single town or township
Returns:
Normalized township string, or unmodified string if input does not contain township
Examples:
>>> clean_township('T4/R3 TWP') 'T4 R3'>>> clean_township('T10SD') 'T10 SD'>>> clean_township('CROSS LAKE TWP (T17 R5)') 'CROSS LAKE TWP T17 R5'
211def strip_suffix(town: str) -> str: 212 """ 213 Strips valid terminal suffix from town string. 214 215 Context-sensitive: ignores suffix substrings if they are not in a valid 216 suffix context. 217 218 This method is used to generate plausible aliases for further testing. 219 Its intended use is alias generation and not routine cleanup. 220 221 Args: 222 town: A single town or township 223 224 Returns: 225 Town with valid terminal suffix stripped 226 227 Examples: 228 >>> strip_suffix('RANGELEY PLANTATION') 229 'RANGELEY' 230 231 >>> strip_suffix('Passamaquoddy Indian Township') 232 'Passamaquoddy Indian Township' 233 234 >>> strip_suffix('Indian Stream Township') 235 'Indian Stream' 236 237 >>> strip_suffix('Matinicus Isle Plt') 238 'Matinicus Isle' 239 """ 240 return SUFFIX_PATTERN.sub('', town)
Strips valid terminal suffix from town string.
Context-sensitive: ignores suffix substrings if they are not in a valid suffix context.
This method is used to generate plausible aliases for further testing. Its intended use is alias generation and not routine cleanup.
Arguments:
- town: A single town or township
Returns:
Town with valid terminal suffix stripped
Examples:
>>> strip_suffix('RANGELEY PLANTATION') 'RANGELEY'>>> strip_suffix('Passamaquoddy Indian Township') 'Passamaquoddy Indian Township'>>> strip_suffix('Indian Stream Township') 'Indian Stream'>>> strip_suffix('Matinicus Isle Plt') 'Matinicus Isle'
242def toggle_suffix(town: str, town_type: TownType = None) -> str: 243 """ 244 Adds or removes a township suffix to grants, gores, and islands. 245 246 The TWP suffix is not canonical for all grants, gores, and islands. 247 This method is used to generate plausible aliases for further testing. 248 Its intended use is alias generation and not routine cleanup. 249 250 Args: 251 town: A single town or township 252 town_type: A `TownType` class. If provided, will increase accuracy. 253 254 Returns: 255 Gore, grant or island with township suffix added or removed, or else town 256 257 Examples: 258 >>> toggle_suffix('MOXIE GORE TWP') 259 'MOXIE GORE' 260 261 >>> toggle_suffix('HOPKINS ACADEMY GRANT') 262 'HOPKINS ACADEMY GRANT TWP' 263 264 >>> toggle_suffix('LOUDS ISLAND', TownType.UNORGANIZED) 265 'LOUDS ISLAND TWP' 266 267 >>> toggle_suffix('CHEBEAGUE ISLAND', TownType.TOWN) 268 'CHEBEAGUE ISLAND' 269 """ 270 if town_type not in (TownType.UNORGANIZED, TownType.ISLAND, None): 271 return town 272 elif ENDSWITH_JUNIOR_SUFFIX_PATTERN.match(town): 273 return town + match_case(' TWP', town) 274 elif CONTAINS_JUNIOR_SUFFIX_PATTERN.match(town): 275 return town[0:-4] 276 else: 277 return town
Adds or removes a township suffix to grants, gores, and islands.
The TWP suffix is not canonical for all grants, gores, and islands. This method is used to generate plausible aliases for further testing. Its intended use is alias generation and not routine cleanup.
Arguments:
- town: A single town or township
- town_type: A
TownTypeclass. If provided, will increase accuracy.
Returns:
Gore, grant or island with township suffix added or removed, or else town
Examples:
>>> toggle_suffix('MOXIE GORE TWP') 'MOXIE GORE'>>> toggle_suffix('HOPKINS ACADEMY GRANT') 'HOPKINS ACADEMY GRANT TWP'>>> toggle_suffix('LOUDS ISLAND', TownType.UNORGANIZED) 'LOUDS ISLAND TWP'>>> toggle_suffix('CHEBEAGUE ISLAND', TownType.TOWN) 'CHEBEAGUE ISLAND'
279def normalize_suffix(town: str) -> str: 280 """ 281 Normalize variations in geotype suffix abbreviation and location. 282 283 Does not alter pluralization. Pads suffix with whitespace if needed. 284 285 Args: 286 town: A single town or township 287 288 Returns: 289 Town with normalized suffix 290 291 Examples: 292 >>> normalize_suffix('City of Portland') 293 'Portland' 294 295 >>> normalize_suffix('MATINICUS ISLE PLANTATION') 296 'MATINICUS ISLE PLT' 297 298 >>> normalize_suffix('MARIONTWPS') 299 'MARION TWPS' 300 301 >>> normalize_suffix('Indian Township') 302 'Indian Twp' 303 """ 304 gnis_format = GNIS_PATTERN.match(town.upper()) 305 306 if gnis_format is None: 307 town_name = town 308 else: 309 name = gnis_format.group('town') 310 suffix = ABBREVIATIONS.get(gnis_format.group('geotype')) 311 town_name = ' '.join(filter(None, [name, suffix])) 312 313 normalized = replace_all(SUFFIX_REPLACEMENTS, town_name, IGNORECASE) 314 return match_case(normalized, town, preserve_mixed_case=False)
Normalize variations in geotype suffix abbreviation and location.
Does not alter pluralization. Pads suffix with whitespace if needed.
Arguments:
- town: A single town or township
Returns:
Town with normalized suffix
Examples:
>>> normalize_suffix('City of Portland') 'Portland'>>> normalize_suffix('MATINICUS ISLE PLANTATION') 'MATINICUS ISLE PLT'>>> normalize_suffix('MARIONTWPS') 'MARION TWPS'>>> normalize_suffix('Indian Township') 'Indian Twp'
316def strip_town(town: str) -> str: 317 """ 318 Strip invalid punctuation and whitespace from a town name substring. 319 320 This function performs the following operations: 321 1. Strip leading and trailing whitespace and squish internal whitespace 322 2. Replace ampersands ('&') that are recognized as part of a canonical town 323 name with 'and' 324 3. Strip all punctuation except hyphens ('-') that are recognized as 325 part of a canonical town name 326 327 Args: 328 town: A single town or township 329 330 Returns: 331 Town name with punctuation stripped 332 333 Examples: 334 >>> strip_town("Loud's Island") 335 'Louds Island' 336 337 >>> strip_town('Dover-Foxcroft -- ') 338 'Dover-Foxcroft' 339 340 >>> strip_town('Taunton & Raynham Academy Grant') 341 'Taunton and Raynham Academy Grant' 342 """ 343 town_name = normalize_whitespace(town) 344 town_name = VALID_AMPERSANDS_PATTERN.sub('and', town_name) 345 town_name = INVALID_PUNCTUATION_PATTERN.sub('', town_name) 346 town_name = town_name.strip() 347 return match_case(town_name, town, preserve_mixed_case=False)
Strip invalid punctuation and whitespace from a town name substring.
This function performs the following operations:
- Strip leading and trailing whitespace and squish internal whitespace
- Replace ampersands ('&') that are recognized as part of a canonical town name with 'and'
- Strip all punctuation except hyphens ('-') that are recognized as part of a canonical town name
Arguments:
- town: A single town or township
Returns:
Town name with punctuation stripped
Examples:
>>> strip_town("Loud's Island") 'Louds Island'>>> strip_town('Dover-Foxcroft -- ') 'Dover-Foxcroft'>>> strip_town('Taunton & Raynham Academy Grant') 'Taunton and Raynham Academy Grant'
349def clean_town(town: str) -> str: 350 """ 351 Clean and format town name. 352 353 Operations performed: 354 1. Strip or replace punctuation 355 2. Normalize whitespace 356 3. Abbreviate geotype suffixes 357 4. Normalize township codes 358 359 Args: 360 town: A single town or township 361 362 Returns: 363 Town name with punctuation stripped and formatting applied 364 365 Examples: 366 >>> clean_town('City of Portland') 367 'Portland' 368 369 >>> clean_town('T8/R11 TWP') 370 'T8 R11' 371 372 >>> clean_town('CROSS LAKE TWP (T17 R5)') 373 'CROSS LAKE TWP T17 R5' 374 375 >>> clean_town('King & Bartlett Township') 376 'King and Bartlett Twp' 377 378 >>> clean_town('MARIONTWPS ()') 379 'MARION TWPS' 380 """ 381 cleaning_functions = [ 382 strip_town 383 , normalize_suffix 384 , clean_township 385 , normalize_whitespace 386 ] 387 return chain_operations(town, cleaning_functions)
Clean and format town name.
Operations performed:
- Strip or replace punctuation
- Normalize whitespace
- Abbreviate geotype suffixes
- Normalize township codes
Arguments:
- town: A single town or township
Returns:
Town name with punctuation stripped and formatting applied
Examples:
>>> clean_town('City of Portland') 'Portland'>>> clean_town('T8/R11 TWP') 'T8 R11'>>> clean_town('CROSS LAKE TWP (T17 R5)') 'CROSS LAKE TWP T17 R5'>>> clean_town('King & Bartlett Township') 'King and Bartlett Twp'>>> clean_town('MARIONTWPS ()') 'MARION TWPS'