def iterproblems(table, constraints, expected_header):

    outhdr = ('name', 'row', 'field', 'value', 'error')
    yield outhdr

    it = iter(table)
    actual_header = next(it)

    if expected_header is None:
        flds = list(map(text_type, actual_header))
    else:
        expected_flds = list(map(text_type, expected_header))
        actual_flds = list(map(text_type, actual_header))
        try:
            assert expected_flds == actual_flds
        except Exception as e:
            yield ('__header__', 0, None, None, type(e).__name__)
        flds = expected_flds

    # setup getters
    if constraints:
        constraints = [dict(**c) for c in constraints]  # ensure list of dicts
        for constraint in constraints:
            if constraint not in 'getter':
                if 'field' in constraint:
                    # should ensure FieldSelectionError if bad field in
                    # constraint
                    indices = asindices(flds, constraint['field'])
                    getter = operator.itemgetter(*indices)
                    constraint['getter'] = getter

    # generate problems
    expected_len = len(flds)
    for i, row in enumerate(it):
        row = tuple(row)

        # row length constraint
        l = None
        try:
            l = len(row)
            assert l == expected_len
        except Exception as e:
            yield ('__len__', i+1, None, l, type(e).__name__)

        # user defined constraints
        if constraints:
            row = Record(row, flds)
            for constraint in constraints:
                name = constraint.get('name', None)
                field = constraint.get('field', None)
                assertion = constraint.get('assertion', None)
                test = constraint.get('test', None)
                getter = constraint.get('getter', lambda x: x)
                try:
                    target = getter(row)
                except Exception as e:
                    # getting target value failed, report problem
                    yield (name, i+1, field, None, type(e).__name__)
                else:
                    value = target if field else None
                    if test is not None:
                        try:
                            test(target)
                        except Exception as e:
                            # test raised exception, report problem
                            yield (name, i+1, field, value, type(e).__name__)
                    if assertion is not None:
                        try:
                            assert assertion(target)
                        except Exception as e:
                            # assertion raised exception, report problem
                            yield (name, i+1, field, value, type(e).__name__)
dataset/ETHPy150Open alimanfoo/petl/petl/transform/validation.py/iterproblems/swapped operands of `not in`