<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def lookup(val, field=None, use_cache=True):
 """ Semi-fuzzy state lookup. This method will make a best effort attempt at finding the state based on the lookup value provided. * two digits will search for FIPS code * two letters will search for state abbreviation * anything else will try to match the metaphone of state names Metaphone is used to allow for incorrect, but phonetically accurate, spelling of state names. Exact matches can be done on any attribute on State objects by passing the `field` argument. This skips the fuzzy-ish matching and does an exact, case-sensitive comparison against the specified field. This method caches non-None results, but can the cache can be bypassed with the `use_cache=False` argument. """


    import jellyfish

    if field is None:
        if FIPS_RE.match(val):
            field = 'fips'
        elif ABBR_RE.match(val):
            val = val.upper()
            field = 'abbr'
        else:
            val = jellyfish.metaphone(val)
            field = 'name_metaphone'

    # see if result is in cache
    cache_key = "%s:%s" % (field, val)
    if use_cache and cache_key in _lookup_cache:
        return _lookup_cache[cache_key]

    for state in STATES_AND_TERRITORIES:
        if val == getattr(state, field):
            _lookup_cache[cache_key] = state
            return state