def get_row_failures(df, value_cols, type_cols, verbose=False, outfile=None):
    """
    Input: already validated DataFrame, value & type column names,
    and output options.
    Get details on each detected issue, row by row.
    Output: DataFrame with type & value validation columns,
    plus an "issues" column with a dictionary of every problem
    for that row.
    """
    # set temporary numeric index
    df["num"] = list(range(len(df)))
    # get column names for value & type validations
    names = value_cols.union(type_cols)
    # drop all non validation columns
    value_problems = df[names.union(["num"])]
    # drop validation columns that contain no problems
    failing_items = value_problems.dropna(how="all", subset=names)
    if not len(failing_items):
        if verbose:
            print("No problems")
        return []
    failing_items = failing_items.dropna(how="all", axis=1)
    # get names of the failing items
    bad_items = list(failing_items.index)
    # get index numbers of the failing items
    bad_indices = list(failing_items["num"])
    failing_items['issues'] = failing_items.drop("num", axis=1).apply(make_row_dict, axis=1).values
    # take output and print/write to file
    print_row_failures(failing_items, verbose, outfile)
    return failing_items