def cm_report(cm, labels, sep='\t'):
    """
    Returns a pretty printed confusion matrix as a string.
    :param cm: The confusion matrix to use. Should support subscript with pair.
    :param labels: The labels to use for the classes.
    :param sep: The seperator to use between columns of the matrix.
    :return: A string with a confusion matrix given by *cm*.
    """
    columnwidth = max([len(x) for x in labels])
    cm_lines = ["Colums show what the true values(rows) were classified as."]

    # The following is used to output each cell of the table. By passing a keyword argument 'format' to the string
    # format function, the format of the output value can be set
    cell = "{:{format}}"
    names_format = "<{}".format(columnwidth)  # The names are left-justified
    col_format = ">{}".format(columnwidth)  # The columns are right formatted

    # Create the header string
    header_cells = [cell.format(label, format=col_format) for label in [""]+labels]
    header = sep.join(header_cells)
    cm_lines.append(header)

    # Print rows
    for i, label in enumerate(labels):
        row = []
        # This will be the label for the row
        row_label = cell.format(label, format=names_format)
        row.append(row_label)

        # The matrix cells are created as a list of strings
        cells = [cell.format(cm[i, j], format=col_format) for j in range(len(labels))]
        row.extend(cells)

        row_string = sep.join(row)
        cm_lines.append(row_string)

    return '\n'.join(cm_lines)