def sort_by(iterable,
            sortstr=None,
            reverse=False,
            col_map=None,
            default_type=None,
            default_value=None):
    """sort an iterable, cast to ``col_map.get(colkey, default_type)``,
    and default to ``default_value``.

    Args:
        iterable (iterable): iterable of lines/rows
    Kwargs:
        sortstr (None, str): comma separated list of column index (``1,2,3``)
        reverse (bool): (True, Descending), (False, Ascending) default: False
        col_map (None, dict): dict mapping column n to a typefunc
        default_type (None, callable): type callable (default: None)
        default_value (\*): default N/A value for columns not specified
                            in col_map (default: None)
    Returns:
        list: sorted list of lines/rows
    """
    # raise Exception()
    def keyfunc_iter(obj, sortstr=sortstr, col_map=col_map):
        """Parse and yield column values according to ``sortstr`` and ``col_map``

        Args:
            obj (object): obj to sort (as from ``sorted(keyfunc=thisfunc)``)
            sortstr (str): sort string of comma-separated columns
            col_map (None, dict): dict mapping column n to a typefunc (default: None)
        Yields:
            object: typecasted column value
        """
        if sortstr:
            column_sequence = get_list_from_str(sortstr, typefunc=int)
        else:
            column_sequence = xrange(len(obj.result))
        log.debug(('column_sequence', column_sequence))
        if col_map is None:
            col_map = {}
        for n in column_sequence:
            type_func = col_map.get(str(n), default_type)
            retval = default_value
            if n < len(obj.result):
                colvalue = obj.result[n]
                if type_func:
                    try:
                        retval = type_func(colvalue)
                    except __HOLE__ as e:
                        e.msg += "\n" + repr((type_func, colvalue, e,))
                        raise
                else:
                    retval = colvalue
            else:
                retval = default_value
            yield retval

    def keyfunc(obj, sortstr=sortstr, col_map=col_map):
        """key function (e.g. for ``sorted(key=keyfunc)``)

        Args:
            obj (PylineResult): ``obj.result = ['col1', 'col2', 'coln']``
        Returns:
            tuple: (col2, col0, col1)
        """
        keyvalue = tuple(keyfunc_iter(obj, sortstr, col_map))
        errdata = [
            (('keyvalue', keyvalue),
              ('sortstr', sortstr))]
        log.debug((errdata,))
        return keyvalue

    sorted_values = sorted(iterable,
                  key=keyfunc,
                  reverse=reverse)
    return sorted_values
dataset/ETHPy150Open westurner/pyline/pyline.py/sort_by