<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def diff(new_dict, old_dict, iter_prefix='__iter__', np_allclose=False, **kwargs):
 """ return the difference between two dict_like objects Parameters new_dict: dict old_dict: dict iter_prefix: str prefix to use for list and tuple indexes np_allclose: bool if True, try using numpy.allclose to assess differences **kwargs: keyword arguments to parse to numpy.allclose Returns ------- outcome: dict Containing none or more of: - "insertions" : list of (path, val) - "deletions" : list of (path, val) - "changes" : list of (path, (val1, val2)) - "uncomparable" : list of (path, (val1, val2)) Examples -------- {} {'changes': [(('b',), (2, 3)), (('c',), (5, 4))], 'deletions': [(('d',), 6)], 'insertions': [(('a',), 1)]} {'changes': [(('a', '__iter__2'), (1, 2))], 'deletions': [(('a', '__iter__1', 'd'), 2)], 'insertions': [(('a', '__iter__1', 'c'), 2)]} {'changes': [(('a',), (1, 1.0000000001))]} {} """

    if np_allclose:
        try:
            import numpy
        except ImportError:
            raise ValueError("to use np_allclose, numpy must be installed")

    dct1_flat = flatten(new_dict, all_iters=iter_prefix)
    dct2_flat = flatten(old_dict, all_iters=iter_prefix)

    outcome = {'insertions': [], 'deletions': [],
               'changes': [], 'uncomparable': []}

    for path, val in dct1_flat.items():
        if path not in dct2_flat:
            outcome['insertions'].append((path, val))
            continue
        other_val = dct2_flat.pop(path)
        if np_allclose:
            try:
                if numpy.allclose(val, other_val, **kwargs):
                    continue
            except Exception:
                pass
        try:
            if val != other_val:
                outcome['changes'].append((path, (val, other_val)))
        except Exception:
            outcome['uncomparable'].append((path, (val, other_val)))

    for path2, val2 in dct2_flat.items():
        outcome['deletions'].append((path2, val2))

    # remove any empty lists and sort
    for key in list(outcome.keys()):
        if not outcome[key]:
            outcome.pop(key)
        try:
            outcome[key] = sorted(outcome[key])
        except Exception:
            pass

    return outcome