Want to get involved? We're always looking for ideas and content for Weekly Challenges.
SUBMIT YOUR IDEAugly solution but its a worker
Took some extra steps with filters that probably would've dropped out with the join. Couldn't conceptualize the correct order to approach it which is why I used the filters.
Yes, I understand that this is an Alteryx assignment. But when I see one of these that I consider fairly unsuited to Alteryx as a problem-solving tool, I like to whip out a solution in Python. And I have done so here and gotten identical results to the given output. So check it out if you are curious, feedback welcome:
#!/usr/bin/python3
import csv
from pprint import PrettyPrinter
pp = PrettyPrinter()
assignments_dict = dict()
def count_tokens( t ):
# Takes a string in form "x-y" and splits it into x, y and returns
# the *list* [x, y] where x and y are strings in %0d format.
#
# Example: "12-047" returns ["012", "047"]
return_list = list()
( start_t, end_t ) = t.split( '-' )
b = int(start_t)
e = int(end_t)
for i in range( b, e+1):
return_list.append( f"%03d" % i )
return return_list
def parse_tokens( s ):
# Takes a string of all the ZIP prefix assignments, or other
# strings indicating totality, etc. Returns a list of all the
# three-digit prefixes (or list of other strings) represented by
# the input.
#
# Examples:
#
# "12, 047-051, 093" returns [ "012", "047", "048", "049", "050", "051", "093" ]
#
# "entire" or "International" returns [ "entire" ]
#
# NOTE: "rest" is returned in a context where it may be added to
# other prefixes. When "entire" is returned, the data constraints
# say it will be the only element for that state/region code. The
# script does not error-check for this.
# Handle the special cases and return immediately:
if s == "rest of state":
return [ "rest" ]
elif s == "entire state" or s == "entire area":
return [ "entire" ]
elif s == "International":
return [ "entire" ]
s.replace( " ", "" )
tokens = s.split( ',' )
return_list = list()
for t in tokens:
# If a string is in form "x-y" handle with count_tokens and
# add the elements:
if "-" in t:
return_list += count_tokens( t )
else:
# Otherwise, just convert to three-character integer and
# append this element:
t_i = int( t )
t = "%03d" % t_i
return_list.append( t )
# Just return the list we spent the loop above building:
return return_list
# Read in all the assignments into assignments_dict, keyed by state.
# Each elemnt is a dictionary keyed on prefixes with values of the
# relevant "assignment":
with open('assignments.csv', newline='') as csvfile:
assignments_reader = csv.reader(csvfile)
# Throw away the headers
next(assignments_reader, None) # skip the headers
for row in assignments_reader:
( state, tokens, assignment ) = row
t_list = parse_tokens( tokens )
for t in t_list:
if state not in assignments_dict:
assignments_dict[state] = dict()
if t not in assignments_dict[ state ]:
assignments_dict[ state ][ t ] = assignment
else:
print( "FATAL: duplicate assignment of state / tokens assignment: %s / %s / %s "
% ( state, tokens, assignment ) )
exit( 1 )
# Read in each zipcode element, determine the state, match the special
# cases if present, then match the first three digits. Any given
# combination should lead to an assignment, which can be printed
# immediately. If a case doesn't work, error out the whole script
# with a fatal error:
with open('zipcodes.csv', newline='') as csvfile:
zipcodes_reader = csv.reader(csvfile)
# Throw away the headers
next( zipcodes_reader, None )
for row in zipcodes_reader:
( state, zip ) = row
if state not in assignments_dict:
assignment = assignments_dict[ 'International' ][ 'entire' ]
elif 'entire' in assignments_dict[ state ]:
assignment = assignments_dict[ state ][ 'entire' ]
elif zip[0:3] in assignments_dict[ state ]:
assignment = assignments_dict[ state ][ zip[0:3] ]
elif 'rest' in assignments_dict[ state ]:
assignment = assignments_dict[ state ][ 'rest' ]
else:
print( "FATAL: can't happen case" )
exit( 1 )
print( "%s,%s,%s" % (state, zip, assignment) )
-